mirror of https://github.com/openssl/openssl
Add -reqin_new_tid option to apps/cmp.c and OSSL_CMP_MSG_update_transactionID()
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> (Merged from https://github.com/openssl/openssl/pull/11470)
This commit is contained in:
parent
6b326fc396
commit
143be4748e
46
apps/cmp.c
46
apps/cmp.c
|
@ -314,6 +314,7 @@ static char *opt_tls_host = NULL;
|
|||
static int opt_batch = 0;
|
||||
static int opt_repeat = 1;
|
||||
static char *opt_reqin = NULL;
|
||||
static int opt_reqin_new_tid = 0;
|
||||
static char *opt_reqout = NULL;
|
||||
static char *opt_rspin = NULL;
|
||||
static char *opt_rspout = NULL;
|
||||
|
@ -391,7 +392,7 @@ typedef enum OPTION_choice {
|
|||
OPT_TLS_EXTRA, OPT_TLS_TRUSTED, OPT_TLS_HOST,
|
||||
|
||||
OPT_BATCH, OPT_REPEAT,
|
||||
OPT_REQIN, OPT_REQOUT, OPT_RSPIN, OPT_RSPOUT,
|
||||
OPT_REQIN, OPT_REQIN_NEW_TID, OPT_REQOUT, OPT_RSPIN, OPT_RSPOUT,
|
||||
|
||||
OPT_USE_MOCK_SRV, OPT_PORT, OPT_MAX_MSGS,
|
||||
OPT_SRV_REF, OPT_SRV_SECRET,
|
||||
|
@ -594,6 +595,8 @@ const OPTIONS cmp_options[] = {
|
|||
{"repeat", OPT_REPEAT, 'n',
|
||||
"Invoke the transaction the given number of times. Default 1"},
|
||||
{"reqin", OPT_REQIN, 's', "Take sequence of CMP requests from file(s)"},
|
||||
{"reqin_new_tid", OPT_REQIN_NEW_TID, '-',
|
||||
"Use fresh transactionID for CMP requests read from -reqin"},
|
||||
{"reqout", OPT_REQOUT, 's', "Save sequence of CMP requests to file(s)"},
|
||||
{"rspin", OPT_RSPIN, 's',
|
||||
"Process sequence of CMP responses provided in file(s), skipping server"},
|
||||
|
@ -706,7 +709,8 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */
|
|||
{&opt_tls_extra}, {&opt_tls_trusted}, {&opt_tls_host},
|
||||
|
||||
{(char **)&opt_batch}, {(char **)&opt_repeat},
|
||||
{&opt_reqin}, {&opt_reqout}, {&opt_rspin}, {&opt_rspout},
|
||||
{&opt_reqin}, {(char **)&opt_reqin_new_tid},
|
||||
{&opt_reqout}, {&opt_rspin}, {&opt_rspout},
|
||||
|
||||
{(char **)&opt_use_mock_srv}, {&opt_port}, {(char **)&opt_max_msgs},
|
||||
{&opt_srv_ref}, {&opt_srv_secret},
|
||||
|
@ -1161,26 +1165,17 @@ static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx,
|
|||
if (req != NULL && opt_reqout != NULL
|
||||
&& !write_PKIMESSAGE(req, &opt_reqout))
|
||||
goto err;
|
||||
if (opt_reqin != NULL) {
|
||||
if (opt_rspin != NULL) {
|
||||
CMP_warn("-reqin is ignored since -rspin is present");
|
||||
} else {
|
||||
if ((req_new = read_PKIMESSAGE(&opt_reqin)) == NULL)
|
||||
goto err;
|
||||
/*-
|
||||
* The transaction ID in req_new may not be fresh.
|
||||
* In this case the Insta Demo CA correctly complains:
|
||||
* "Transaction id already in use."
|
||||
* The following workaround unfortunately requires re-protection.
|
||||
* See also https://github.com/mpeylo/cmpossl/issues/8
|
||||
*/
|
||||
#if defined(USE_TRANSACTIONID_WORKAROUND)
|
||||
hdr = OSSL_CMP_MSG_get0_header(req_new);
|
||||
if (!OSSL_CMP_CTX_set1_transactionID(hdr, NULL)
|
||||
|| !ossl_cmp_msg_protect(ctx, req_new))
|
||||
goto err;
|
||||
#endif
|
||||
}
|
||||
if (opt_reqin != NULL && opt_rspin == NULL) {
|
||||
if ((req_new = read_PKIMESSAGE(&opt_reqin)) == NULL)
|
||||
goto err;
|
||||
/*-
|
||||
* The transaction ID in req_new read from opt_reqin may not be fresh.
|
||||
* In this case the server may complain "Transaction id already in use."
|
||||
* The following workaround unfortunately requires re-protection.
|
||||
*/
|
||||
if (opt_reqin_new_tid
|
||||
&& !OSSL_CMP_MSG_update_transactionID(ctx, req_new))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (opt_rspin != NULL) {
|
||||
|
@ -2325,6 +2320,10 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *e)
|
|||
(void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_TOTAL_TIMEOUT,
|
||||
opt_total_timeout);
|
||||
|
||||
if (opt_reqin != NULL && opt_rspin != NULL)
|
||||
CMP_warn("-reqin is ignored since -rspin is present");
|
||||
if (opt_reqin_new_tid && opt_reqin == NULL)
|
||||
CMP_warn("-reqin_new_tid is ignored since -reqin is not present");
|
||||
if (opt_reqin != NULL || opt_reqout != NULL
|
||||
|| opt_rspin != NULL || opt_rspout != NULL || opt_use_mock_srv)
|
||||
(void)OSSL_CMP_CTX_set_transfer_cb(ctx, read_write_req_resp);
|
||||
|
@ -2899,6 +2898,9 @@ static int get_opts(int argc, char **argv)
|
|||
case OPT_REQIN:
|
||||
opt_reqin = opt_str("reqin");
|
||||
break;
|
||||
case OPT_REQIN_NEW_TID:
|
||||
opt_reqin_new_tid = 1;
|
||||
break;
|
||||
case OPT_REQOUT:
|
||||
opt_reqout = opt_str("reqout");
|
||||
break;
|
||||
|
|
|
@ -70,7 +70,8 @@ ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = {
|
|||
* so it is used directly
|
||||
*
|
||||
*/
|
||||
ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ERRORMSGCONTENT, errorDetails, ASN1_UTF8STRING)
|
||||
ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ERRORMSGCONTENT, errorDetails,
|
||||
ASN1_UTF8STRING)
|
||||
} ASN1_SEQUENCE_END(OSSL_CMP_ERRORMSGCONTENT)
|
||||
IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_ERRORMSGCONTENT)
|
||||
|
||||
|
@ -352,8 +353,10 @@ ASN1_CHOICE(OSSL_CMP_PKIBODY) = {
|
|||
ASN1_EXP(OSSL_CMP_PKIBODY, value.cr, OSSL_CRMF_MSGS, 2),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.cp, OSSL_CMP_CERTREPMESSAGE, 3),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.p10cr, X509_REQ, 4),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.popdecc, OSSL_CMP_POPODECKEYCHALLCONTENT, 5),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.popdecr, OSSL_CMP_POPODECKEYRESPCONTENT, 6),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.popdecc,
|
||||
OSSL_CMP_POPODECKEYCHALLCONTENT, 5),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.popdecr,
|
||||
OSSL_CMP_POPODECKEYRESPCONTENT, 6),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.kur, OSSL_CRMF_MSGS, 7),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.kup, OSSL_CMP_CERTREPMESSAGE, 8),
|
||||
ASN1_EXP(OSSL_CMP_PKIBODY, value.krr, OSSL_CRMF_MSGS, 9),
|
||||
|
|
|
@ -176,7 +176,7 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
|
|||
|
||||
if (*rep == NULL) {
|
||||
CMPerr(0, CMP_R_TRANSFER_ERROR); /* or receiving response */
|
||||
ERR_add_error_data(1, req_type_str);
|
||||
ERR_add_error_data(2, "request sent: ", req_type_str);
|
||||
ERR_add_error_data(2, ", expected response: ", expected_type_str);
|
||||
return 0;
|
||||
}
|
||||
|
@ -211,7 +211,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
|
|||
char buf[OSSL_CMP_PKISI_BUFLEN];
|
||||
|
||||
if (save_statusInfo(ctx, si)
|
||||
&& OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL)
|
||||
&& OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf,
|
||||
sizeof(buf)) != NULL)
|
||||
ERR_add_error_data(1, buf);
|
||||
if (emc->errorCode != NULL
|
||||
&& BIO_snprintf(buf, sizeof(buf), "; errorCode: %ld",
|
||||
|
|
|
@ -41,7 +41,8 @@ int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr)
|
|||
return (int)pvno;
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const OSSL_CMP_PKIHEADER *hdr)
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const
|
||||
OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
if (hdr == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
|
@ -266,6 +267,25 @@ int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* set ctx->transactionID in CMP header
|
||||
* if ctx->transactionID is NULL, a random one is created with 128 bit
|
||||
* according to section 5.1.1:
|
||||
*
|
||||
* It is RECOMMENDED that the clients fill the transactionID field with
|
||||
* 128 bits of (pseudo-) random data for the start of a transaction to
|
||||
* reduce the probability of having the transactionID in use at the server.
|
||||
*/
|
||||
int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
if (ctx->transactionID == NULL
|
||||
&& !set1_aostr_else_random(&ctx->transactionID, NULL,
|
||||
OSSL_CMP_TRANSACTIONID_LENGTH))
|
||||
return 0;
|
||||
return ossl_cmp_asn1_octet_string_set1(&hdr->transactionID,
|
||||
ctx->transactionID);
|
||||
}
|
||||
|
||||
/* fill in all fields of the hdr according to the info given in ctx */
|
||||
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
|
@ -316,21 +336,7 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
|||
ctx->recipNonce))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* set ctx->transactionID in CMP header
|
||||
* if ctx->transactionID is NULL, a random one is created with 128 bit
|
||||
* according to section 5.1.1:
|
||||
*
|
||||
* It is RECOMMENDED that the clients fill the transactionID field with
|
||||
* 128 bits of (pseudo-) random data for the start of a transaction to
|
||||
* reduce the probability of having the transactionID in use at the server.
|
||||
*/
|
||||
if (ctx->transactionID == NULL
|
||||
&& !set1_aostr_else_random(&ctx->transactionID, NULL,
|
||||
OSSL_CMP_TRANSACTIONID_LENGTH))
|
||||
return 0;
|
||||
if (!ossl_cmp_asn1_octet_string_set1(&hdr->transactionID,
|
||||
ctx->transactionID))
|
||||
if (!ossl_cmp_hdr_set_transactionID(ctx, hdr))
|
||||
return 0;
|
||||
|
||||
/*-
|
||||
|
|
|
@ -790,7 +790,7 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
|||
/* from cmp_status.c */
|
||||
int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
|
||||
const char *ossl_cmp_PKIStatus_to_string(int status);
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *s);
|
||||
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si);
|
||||
int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
|
||||
|
||||
|
@ -814,6 +814,7 @@ int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
|
|||
int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
|
||||
# define OSSL_CMP_TRANSACTIONID_LENGTH 16
|
||||
# define OSSL_CMP_SENDERNONCE_LENGTH 16
|
||||
int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
|
||||
|
||||
/* from cmp_msg.c */
|
||||
|
@ -885,13 +886,13 @@ OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
|
|||
int64_t poll_after);
|
||||
OSSL_CMP_PKISI *
|
||||
ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
|
||||
OSSL_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep,
|
||||
OSSL_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rc,
|
||||
int rsid);
|
||||
OSSL_CMP_POLLREP *
|
||||
ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc,
|
||||
int rid);
|
||||
OSSL_CMP_CERTRESPONSE *
|
||||
ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crepmsg,
|
||||
ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm,
|
||||
int rid);
|
||||
X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
|
||||
const OSSL_CMP_CERTRESPONSE *crep);
|
||||
|
@ -916,6 +917,6 @@ int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
|
|||
int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
const char *txt);
|
||||
int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,
|
||||
const char *txt, int errorCode, const char *details);
|
||||
const char *txt, int errorCode, const char *detail);
|
||||
|
||||
#endif /* !defined(OSSL_CRYPTO_CMP_LOCAL_H) */
|
||||
|
|
|
@ -584,9 +584,9 @@ int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
|
|||
return 0;
|
||||
|
||||
for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
|
||||
if ((itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i))) == NULL)
|
||||
return 0;
|
||||
if (!ossl_cmp_msg_gen_push0_ITAV(msg, itav)) {
|
||||
itav = OSSL_CMP_ITAV_dup(sk_OSSL_CMP_ITAV_value(itavs, i));
|
||||
if (itav == NULL
|
||||
|| !ossl_cmp_msg_gen_push0_ITAV(msg, itav)) {
|
||||
OSSL_CMP_ITAV_free(itav);
|
||||
return 0;
|
||||
}
|
||||
|
@ -982,6 +982,18 @@ X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
|
|||
return crt;
|
||||
}
|
||||
|
||||
int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
||||
{
|
||||
if (ctx == NULL || msg == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (!ossl_cmp_hdr_set_transactionID(ctx, msg->header))
|
||||
return 0;
|
||||
return msg->header->protectionAlg == NULL
|
||||
|| ossl_cmp_msg_protect(ctx, msg);
|
||||
}
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
|
|
|
@ -145,21 +145,18 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
|||
&& (msg->extraCerts = sk_X509_new_null()) == NULL)
|
||||
return 0;
|
||||
|
||||
if (ctx->clCert != NULL) {
|
||||
/* Make sure that our own cert gets sent, in the first position */
|
||||
if (!X509_up_ref(ctx->clCert))
|
||||
if (ctx->clCert != NULL && ctx->pkey != NULL) {
|
||||
/* make sure that our own cert is included in the first position */
|
||||
if (!ossl_cmp_sk_X509_add1_cert(msg->extraCerts, ctx->clCert, 1, 1))
|
||||
return 0;
|
||||
if (!sk_X509_push(msg->extraCerts, ctx->clCert)) {
|
||||
X509_free(ctx->clCert);
|
||||
return 0;
|
||||
}
|
||||
/* if we have untrusted store, try to add intermediate certs */
|
||||
/* if we have untrusted certs, try to add intermediate certs */
|
||||
if (ctx->untrusted_certs != NULL) {
|
||||
STACK_OF(X509) *chain =
|
||||
ossl_cmp_build_cert_chain(ctx->untrusted_certs, ctx->clCert);
|
||||
int res = ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain,
|
||||
1 /* no self-issued */,
|
||||
1 /* no duplicates */, 0);
|
||||
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
if (res == 0)
|
||||
return 0;
|
||||
|
@ -227,6 +224,15 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
|||
if (!ossl_assert(ctx != NULL && msg != NULL))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* For the case of re-protection remove pre-existing protection.
|
||||
* TODO: Consider also removing any pre-existing extraCerts.
|
||||
*/
|
||||
X509_ALGOR_free(msg->header->protectionAlg);
|
||||
msg->header->protectionAlg = NULL;
|
||||
ASN1_BIT_STRING_free(msg->protection);
|
||||
msg->protection = NULL;
|
||||
|
||||
if (ctx->unprotectedSend)
|
||||
return 1;
|
||||
|
||||
|
@ -238,84 +244,70 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
|||
&& !ossl_cmp_hdr_set1_senderKID(msg->header,
|
||||
ctx->referenceValue))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* add any additional certificates from ctx->extraCertsOut
|
||||
* while not needed to validate the signing cert, the option to do
|
||||
* this might be handy for certain use cases
|
||||
*/
|
||||
if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
|
||||
goto err;
|
||||
|
||||
if ((msg->protection =
|
||||
ossl_cmp_calc_protection(msg, ctx->secretValue, NULL)) == NULL)
|
||||
goto err;
|
||||
} else {
|
||||
} else if (ctx->clCert != NULL && ctx->pkey != NULL) {
|
||||
/*
|
||||
* use MSG_SIG_ALG according to 5.1.3.3 if client Certificate and
|
||||
* private key is given
|
||||
*/
|
||||
if (ctx->clCert != NULL && ctx->pkey != NULL) {
|
||||
const ASN1_OCTET_STRING *subjKeyIDStr = NULL;
|
||||
int algNID = 0;
|
||||
ASN1_OBJECT *alg = NULL;
|
||||
const ASN1_OCTET_STRING *subjKeyIDStr = NULL;
|
||||
int algNID = 0;
|
||||
ASN1_OBJECT *alg = NULL;
|
||||
|
||||
/* make sure that key and certificate match */
|
||||
if (!X509_check_private_key(ctx->clCert, ctx->pkey)) {
|
||||
CMPerr(0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (msg->header->protectionAlg == NULL)
|
||||
if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
|
||||
EVP_PKEY_id(ctx->pkey))) {
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
if ((alg = OBJ_nid2obj(algNID)) == NULL)
|
||||
goto err;
|
||||
if (!X509_ALGOR_set0(msg->header->protectionAlg,
|
||||
alg, V_ASN1_UNDEF, NULL)) {
|
||||
ASN1_OBJECT_free(alg);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* set senderKID to keyIdentifier of the used certificate according
|
||||
* to section 5.1.1
|
||||
*/
|
||||
subjKeyIDStr = X509_get0_subject_key_id(ctx->clCert);
|
||||
if (subjKeyIDStr == NULL)
|
||||
subjKeyIDStr = ctx->referenceValue; /* fallback */
|
||||
if (subjKeyIDStr != NULL
|
||||
&& !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Add ctx->clCert followed, if possible, by its chain built
|
||||
* from ctx->untrusted_certs, and then ctx->extraCertsOut
|
||||
*/
|
||||
if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
|
||||
goto err;
|
||||
|
||||
if ((msg->protection =
|
||||
ossl_cmp_calc_protection(msg, NULL, ctx->pkey)) == NULL)
|
||||
goto err;
|
||||
} else {
|
||||
CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
|
||||
/* make sure that key and certificate match */
|
||||
if (!X509_check_private_key(ctx->clCert, ctx->pkey)) {
|
||||
CMPerr(0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (msg->header->protectionAlg == NULL)
|
||||
if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
|
||||
EVP_PKEY_id(ctx->pkey))) {
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
if ((alg = OBJ_nid2obj(algNID)) == NULL)
|
||||
goto err;
|
||||
if (!X509_ALGOR_set0(msg->header->protectionAlg, alg,
|
||||
V_ASN1_UNDEF, NULL)) {
|
||||
ASN1_OBJECT_free(alg);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* set senderKID to keyIdentifier of the used certificate according
|
||||
* to section 5.1.1
|
||||
*/
|
||||
subjKeyIDStr = X509_get0_subject_key_id(ctx->clCert);
|
||||
if (subjKeyIDStr == NULL)
|
||||
subjKeyIDStr = ctx->referenceValue; /* fallback */
|
||||
if (subjKeyIDStr != NULL
|
||||
&& !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
|
||||
goto err;
|
||||
} else {
|
||||
CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
|
||||
goto err;
|
||||
}
|
||||
if ((msg->protection =
|
||||
ossl_cmp_calc_protection(msg, ctx->secretValue, ctx->pkey)) == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* If present, add ctx->clCert followed by its chain as far as possible.
|
||||
* Finally add any additional certificates from ctx->extraCertsOut;
|
||||
* even if not needed to validate the protection
|
||||
* the option to do this might be handy for certain use cases.
|
||||
*/
|
||||
if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* As required by RFC 4210 section 5.1.1., if the sender name is not known
|
||||
* to the client it set to NULL-DN. In this case for identification at least
|
||||
* the senderKID must be set, where we took the referenceValue as fallback.
|
||||
*/
|
||||
|
||||
if (ossl_cmp_general_name_is_NULL_DN(msg->header->sender)
|
||||
&& msg->header->senderKID == NULL)
|
||||
CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION);
|
||||
|
|
|
@ -221,7 +221,8 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
|||
if (si == NULL)
|
||||
goto err;
|
||||
/* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */
|
||||
if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM,
|
||||
if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx,
|
||||
OSSL_CMP_OPT_IMPLICIT_CONFIRM,
|
||||
ossl_cmp_hdr_has_implicitConfirm(hdr)
|
||||
&& srv_ctx->grantImplicitConfirm
|
||||
/* do not set if polling starts: */
|
||||
|
|
|
@ -15,9 +15,9 @@ ossl_cmp_msg_add_extraCerts
|
|||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
ossl_cmp_msg_protect() protects the given message B<msg> using an algorithm
|
||||
ossl_cmp_msg_protect() (re-)protects the given message B<msg> using an algorithm
|
||||
depending on the available context information given in the B<ctx>.
|
||||
If there is a secretValue it selects PBMAC. Else if there is a clCert
|
||||
If there is a secretValue it selects PBMAC, else if there is a clCert
|
||||
it selects Signature and uses B<ossl_cmp_msg_add_extraCerts()>.
|
||||
It also sets the protectionAlg field in the message header accordingly.
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ B<openssl> B<cmp>
|
|||
[B<-batch>]
|
||||
[B<-repeat> I<number>]
|
||||
[B<-reqin>] I<filenames>
|
||||
[B<-reqin_new_tid>]
|
||||
[B<-reqout>] I<filenames>
|
||||
[B<-rspin>] I<filenames>
|
||||
[B<-rspout>] I<filenames>
|
||||
|
@ -798,6 +799,13 @@ Multiple filenames may be given, separated by commas and/or whitespace
|
|||
(where in the latter case the whole argument must be enclosed in "...").
|
||||
As many files are read as needed for a complete transaction.
|
||||
|
||||
=item B<-reqin_new_tid>
|
||||
|
||||
Use a fresh transactionID for CMP request messages read using B<-reqin>,
|
||||
which requires re-protecting them as far as they were protected before.
|
||||
This may be needed in case the sequence of requests is reused
|
||||
and the CMP server complains that the transaction ID has already been used.
|
||||
|
||||
=item B<-reqout> I<filenames>
|
||||
|
||||
Save sequence of CMP requests to file(s).
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
=head1 NAME
|
||||
|
||||
OSSL_CMP_MSG_get0_header,
|
||||
OSSL_CMP_MSG_update_transactionID,
|
||||
d2i_OSSL_CMP_MSG_bio,
|
||||
i2d_OSSL_CMP_MSG_bio
|
||||
- function(s) manipulating CMP messages
|
||||
|
@ -12,17 +13,22 @@ i2d_OSSL_CMP_MSG_bio
|
|||
#include <openssl/cmp.h>
|
||||
|
||||
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
|
||||
int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg);
|
||||
int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
OSSL_CMP_MSG_get0_header returns the header of the given CMP message.
|
||||
OSSL_CMP_MSG_get0_header() returns the header of the given CMP message.
|
||||
|
||||
d2i_OSSL_CMP_MSG_bio parses an ASN.1-encoded OSSL_CMP_MSG from the BIO I<bio>.
|
||||
OSSL_CMP_MSG_update_transactionID() updates the transactionID field
|
||||
in the header of the given message according to the CMP_CTX.
|
||||
This requires re-protecting the message (if it was protected).
|
||||
|
||||
d2i_OSSL_CMP_MSG_bio() parses an ASN.1-encoded OSSL_CMP_MSG from the BIO I<bio>.
|
||||
It assigns a pointer to the new structure to I<*msg> if I<msg> is not NULL.
|
||||
|
||||
i2d_OSSL_CMP_MSG_bio writes the OSSL_CMP_MSG I<msg> in ASN.1 encoding
|
||||
i2d_OSSL_CMP_MSG_bio() writes the OSSL_CMP_MSG I<msg> in ASN.1 encoding
|
||||
to BIO I<bio>.
|
||||
|
||||
=head1 NOTES
|
||||
|
@ -36,7 +42,8 @@ or NULL if the respective entry does not exist and on error.
|
|||
|
||||
d2i_OSSL_CMP_MSG_bio() returns the parsed message or NULL on error.
|
||||
|
||||
i2d_OSSL_CMP_MSG_bio() returns 1 on success or 0 on error.
|
||||
i2d_OSSL_CMP_MSG_bio() and OSSL_CMP_MSG_update_transactionID()
|
||||
return 1 on success, 0 on error.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
|
|
|
@ -310,7 +310,8 @@ int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey);
|
|||
EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv);
|
||||
int OSSL_CMP_CTX_set1_issuer(OSSL_CMP_CTX *ctx, const X509_NAME *name);
|
||||
int OSSL_CMP_CTX_set1_subjectName(OSSL_CMP_CTX *ctx, const X509_NAME *name);
|
||||
int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, const GENERAL_NAME *name);
|
||||
int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
const GENERAL_NAME *name);
|
||||
int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts);
|
||||
int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx);
|
||||
int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo);
|
||||
|
@ -346,11 +347,13 @@ OSSL_CMP_PKISI *
|
|||
OSSL_CMP_STATUSINFO_new(int status, int fail_info, const char *text);
|
||||
|
||||
/* from cmp_hdr.c */
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const OSSL_CMP_PKIHEADER *hdr);
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const
|
||||
OSSL_CMP_PKIHEADER *hdr);
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr);
|
||||
|
||||
/* from cmp_msg.c */
|
||||
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
|
||||
int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg);
|
||||
int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg);
|
||||
|
||||
|
@ -387,7 +390,7 @@ typedef void (*OSSL_CMP_SRV_error_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
|
|||
const OSSL_CMP_MSG *req,
|
||||
const OSSL_CMP_PKISI *statusInfo,
|
||||
const ASN1_INTEGER *errorCode,
|
||||
const OSSL_CMP_PKIFREETEXT *errorDetails);
|
||||
const OSSL_CMP_PKIFREETEXT *errDetails);
|
||||
typedef int (*OSSL_CMP_SRV_certConf_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req,
|
||||
int certReqId,
|
||||
|
@ -418,10 +421,10 @@ X509 *OSSL_CMP_exec_IR_ses(OSSL_CMP_CTX *ctx);
|
|||
X509 *OSSL_CMP_exec_CR_ses(OSSL_CMP_CTX *ctx);
|
||||
X509 *OSSL_CMP_exec_P10CR_ses(OSSL_CMP_CTX *ctx);
|
||||
X509 *OSSL_CMP_exec_KUR_ses(OSSL_CMP_CTX *ctx);
|
||||
# define OSSL_CMP_IR OSSL_CMP_PKIBODY_IR
|
||||
# define OSSL_CMP_CR OSSL_CMP_PKIBODY_CR
|
||||
# define OSSL_CMP_P10CR OSSL_CMP_PKIBODY_P10CR
|
||||
# define OSSL_CMP_KUR OSSL_CMP_PKIBODY_KUR
|
||||
# define OSSL_CMP_IR OSSL_CMP_PKIBODY_IR
|
||||
# define OSSL_CMP_CR OSSL_CMP_PKIBODY_CR
|
||||
# define OSSL_CMP_P10CR OSSL_CMP_PKIBODY_P10CR
|
||||
# define OSSL_CMP_KUR OSSL_CMP_PKIBODY_KUR
|
||||
int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, int *checkAfter);
|
||||
int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info,
|
||||
const char **text);
|
||||
|
|
|
@ -4902,6 +4902,7 @@ i2d_X509_PUBKEY_bio ? 3_0_0 EXIST::FUNCTION:
|
|||
RSA_get0_pss_params ? 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA
|
||||
X509_cmp_timeframe ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_CMP_MSG_get0_header ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_MSG_update_transactionID ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
BIO_f_prefix ? 3_0_0 EXIST::FUNCTION:
|
||||
EVP_PKEY_CTX_new_from_name ? 3_0_0 EXIST::FUNCTION:
|
||||
EVP_PKEY_CTX_new_from_pkey ? 3_0_0 EXIST::FUNCTION:
|
||||
|
|
Loading…
Reference in New Issue