diff options
Diffstat (limited to 'crypto/cmp/cmp_msg.c')
-rw-r--r-- | crypto/cmp/cmp_msg.c | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c index b244f1e17f0d..c8e467f3c21f 100644 --- a/crypto/cmp/cmp_msg.c +++ b/crypto/cmp/cmp_msg.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -274,7 +274,7 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) OSSL_CRMF_MSG *crm = NULL; X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->cert; /* refcert defaults to current client cert */ - EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0); + EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx); STACK_OF(GENERAL_NAME) *default_sans = NULL; const X509_NAME *ref_subj = refcert != NULL ? X509_get_subject_name(refcert) : NULL; @@ -286,15 +286,9 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) /* RFC5280: subjectAltName MUST be critical if subject is null */ X509_EXTENSIONS *exts = NULL; - if (rkey == NULL && ctx->p10CSR != NULL) - rkey = X509_REQ_get0_pubkey(ctx->p10CSR); - if (rkey == NULL && refcert != NULL) - rkey = X509_get0_pubkey(refcert); - if (rkey == NULL) - rkey = ctx->pkey; /* default is independent of ctx->oldCert */ if (rkey == NULL) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PUBLIC_KEY); return NULL; #endif } @@ -411,15 +405,9 @@ OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int type, if (type != OSSL_CMP_PKIBODY_P10CR) { EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); - /* - * privkey is NULL in case ctx->newPkey does not include a private key. - * We then may try to use ctx->pkey as fallback/default, but only - * if ctx-> newPkey does not include a (non-matching) public key: - */ - if (privkey == NULL && OSSL_CMP_CTX_get0_newPkey(ctx, 0) == NULL) - privkey = ctx->pkey; /* default is independent of ctx->oldCert */ - if (ctx->popoMethod == OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY); + /* privkey is ctx->newPkey (if private, else NULL) or ctx->pkey */ + if (ctx->popoMethod >= OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY_FOR_POPO); goto err; } if (crm == NULL) { @@ -794,15 +782,17 @@ int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus, return 1; } -OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info, - const char *text) +OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int certReqId, + int fail_info, const char *text) { OSSL_CMP_MSG *msg = NULL; OSSL_CMP_CERTSTATUS *certStatus = NULL; ASN1_OCTET_STRING *certHash = NULL; OSSL_CMP_PKISI *sinfo; - if (!ossl_assert(ctx != NULL && ctx->newCert != NULL)) + if (!ossl_assert(ctx != NULL && ctx->newCert != NULL + && (certReqId == OSSL_CMP_CERTREQID + || certReqId == OSSL_CMP_CERTREQID_NONE))) return NULL; if ((unsigned)fail_info > OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN) { @@ -816,10 +806,13 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info, if ((certStatus = OSSL_CMP_CERTSTATUS_new()) == NULL) goto err; /* consume certStatus into msg right away so it gets deallocated with msg */ - if (!sk_OSSL_CMP_CERTSTATUS_push(msg->body->value.certConf, certStatus)) + if (sk_OSSL_CMP_CERTSTATUS_push(msg->body->value.certConf, certStatus) < 1) { + OSSL_CMP_CERTSTATUS_free(certStatus); goto err; + } + /* set the ID of the certReq */ - if (!ASN1_INTEGER_set(certStatus->certReqId, OSSL_CMP_CERTREQID)) + if (!ASN1_INTEGER_set(certStatus->certReqId, certReqId)) goto err; /* * The hash of the certificate, using the same hash algorithm @@ -965,12 +958,12 @@ static int suitable_rid(const ASN1_INTEGER *certReqId, int rid) { int trid; - if (rid == -1) + if (rid == OSSL_CMP_CERTREQID_NONE) return 1; trid = ossl_cmp_asn1_get_int(certReqId); - if (trid == -1) { + if (trid == OSSL_CMP_CERTREQID_NONE) { ERR_raise(ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID); return 0; } @@ -1031,14 +1024,15 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm, /*- * Retrieve the newly enrolled certificate from the given certResponse crep. - * In case of indirect POPO uses the libctx and propq from ctx and private key. + * Uses libctx and propq from ctx, in case of indirect POPO also private key. * Returns a pointer to a copy of the found certificate, or NULL if not found. */ -X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep, - const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey) +X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_CERTRESPONSE *crep) { OSSL_CMP_CERTORENCCERT *coec; X509 *crt = NULL; + EVP_PKEY *pkey; if (!ossl_assert(crep != NULL && ctx != NULL)) return NULL; @@ -1051,6 +1045,8 @@ X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep, break; case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT: /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */ + pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); + /* pkey is ctx->newPkey (if private, else NULL) or ctx->pkey */ if (pkey == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY); return NULL; @@ -1084,6 +1080,20 @@ int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) || ossl_cmp_msg_protect(ctx, msg); } +int OSSL_CMP_MSG_update_recipNonce(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) +{ + if (ctx == NULL || msg == NULL || msg->header == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + if (ctx->recipNonce == NULL) /* nothing to do for 1st msg in transaction */ + return 1; + if (!ossl_cmp_asn1_octet_string_set1(&msg->header->recipNonce, + ctx->recipNonce)) + return 0; + return msg->header->protectionAlg == NULL || ossl_cmp_msg_protect(ctx, msg); +} + OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file, OSSL_LIB_CTX *libctx, const char *propq) { |