diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2021-01-12 12:16:32 +0100 |
---|---|---|
committer | Dr. David von Oheimb <dev@ddvo.net> | 2021-01-21 17:53:26 +0100 |
commit | 3d46c81a7d6219fd51ccc3b16406f19b82d0176e (patch) | |
tree | 9f79b142da54607bf1bda4792ce74897126fac41 /crypto/cmp/cmp_msg.c | |
parent | 2039ac07b401932fa30a05ade80b3626e189d78a (diff) |
CMP: Allow PKCS#10 input also for ir, cr, kur, and rr messages
Also update documentation regarding sources of certs and keys,
improve type of OSSL_CMP_exec_RR_ses(),
add tests for CSR-based cert revocation
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13841)
Diffstat (limited to 'crypto/cmp/cmp_msg.c')
-rw-r--r-- | crypto/cmp/cmp_msg.c | 96 |
1 files changed, 69 insertions, 27 deletions
diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c index 45cda58879..93e99f9610 100644 --- a/crypto/cmp/cmp_msg.c +++ b/crypto/cmp/cmp_msg.c @@ -79,6 +79,34 @@ static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex) return res; } +/* Add extension list to the referenced extension stack, which may be NULL */ +static int add_extensions(STACK_OF(X509_EXTENSION) **target, + const STACK_OF(X509_EXTENSION) *exts) +{ + int i; + + if (target == NULL) + return 0; + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext); + int idx = X509v3_get_ext_by_OBJ(*target, obj, -1); + + /* Does extension exist in target? */ + if (idx != -1) { + /* Delete all extensions of same type */ + do { + X509_EXTENSION_free(sk_X509_EXTENSION_delete(*target, idx)); + idx = X509v3_get_ext_by_OBJ(*target, obj, -1); + } while (idx != -1); + } + if (!X509v3_add_ext(target, ext, -1)) + return 0; + } + return 1; +} + /* Add a CRL revocation reason code to extension stack, which may be NULL */ static int add_crl_reason_extension(X509_EXTENSIONS **pexts, int reason_code) { @@ -186,18 +214,19 @@ OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype) (sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \ || OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1) -static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert, +static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, + const X509_NAME *ref_subj, int for_KUR) { if (ctx->subjectName != NULL) return ctx->subjectName; - if (refcert != NULL && (for_KUR || !HAS_SAN(ctx))) + if (ref_subj != NULL && (for_KUR || !HAS_SAN(ctx))) /* - * For KUR, copy subjectName from reference certificate. + * For KUR, copy subject from the reference. * For IR or CR, do the same only if there is no subjectAltName. */ - return X509_get_subject_name(refcert); + return ref_subj; return NULL; } @@ -208,13 +237,18 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) /* refcert defaults to current client cert */ EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0); STACK_OF(GENERAL_NAME) *default_sans = NULL; - const X509_NAME *subject = determine_subj(ctx, refcert, for_KUR); + const X509_NAME *ref_subj = + ctx->p10CSR != NULL ? X509_REQ_get_subject_name(ctx->p10CSR) : + refcert != NULL ? X509_get_subject_name(refcert) : NULL; + const X509_NAME *subject = determine_subj(ctx, ref_subj, for_KUR); const X509_NAME *issuer = ctx->issuer != NULL || refcert == NULL ? ctx->issuer : X509_get_issuer_name(refcert); int crit = ctx->setSubjectAltNameCritical || subject == NULL; /* 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) rkey = ctx->pkey; /* default is independent of ctx->oldCert */ if (rkey == NULL) { @@ -223,7 +257,7 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) return NULL; #endif } - if (for_KUR && refcert == NULL) { + if (for_KUR && refcert == NULL && ctx->p10CSR == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT); return NULL; } @@ -256,14 +290,12 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) if (refcert != NULL && !ctx->SubjectAltName_nodefault) default_sans = X509V3_get_d2i(X509_get0_extensions(refcert), NID_subject_alt_name, NULL, NULL); - /* exts are copied from ctx to allow reuse */ - if (ctx->reqExtensions != NULL) { - exts = sk_X509_EXTENSION_deep_copy(ctx->reqExtensions, - X509_EXTENSION_dup, - X509_EXTENSION_free); - if (exts == NULL) - goto err; - } + if (ctx->p10CSR != NULL + && (exts = X509_REQ_get_extensions(ctx->p10CSR)) == NULL) + goto err; + if (ctx->reqExtensions != NULL /* augment/override existing ones */ + && !add_extensions(&exts, ctx->reqExtensions)) + goto err; if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 && !add1_extension(&exts, NID_subject_alt_name, crit, ctx->subjectAltNames)) @@ -281,7 +313,7 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) /* end fill certTemplate, now set any controls */ /* for KUR, set OldCertId according to D.6 */ - if (for_KUR) { + if (for_KUR && refcert != NULL) { OSSL_CRMF_CERTID *cid = OSSL_CRMF_CERTID_gen(X509_get_issuer_name(refcert), X509_get0_serialNumber(refcert)); @@ -460,19 +492,27 @@ OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx) { OSSL_CMP_MSG *msg = NULL; OSSL_CMP_REVDETAILS *rd; + int ret; - if (!ossl_assert(ctx != NULL && ctx->oldCert != NULL)) + if (!ossl_assert(ctx != NULL && (ctx->oldCert != NULL + || ctx->p10CSR != NULL))) return NULL; if ((rd = OSSL_CMP_REVDETAILS_new()) == NULL) goto err; /* Fill the template from the contents of the certificate to be revoked */ - if (!OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, - NULL /* pubkey would be redundant */, - NULL /* subject would be redundant */, - X509_get_issuer_name(ctx->oldCert), - X509_get0_serialNumber(ctx->oldCert))) + ret = ctx->oldCert != NULL + ? OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, + NULL /* pubkey would be redundant */, + NULL /* subject would be redundant */, + X509_get_issuer_name(ctx->oldCert), + X509_get0_serialNumber(ctx->oldCert)) + : OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, + X509_REQ_get0_pubkey(ctx->p10CSR), + X509_REQ_get_subject_name(ctx->p10CSR), + NULL, NULL); + if (!ret) goto err; /* revocation reason code is optional */ @@ -513,7 +553,7 @@ OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si, OSSL_CRMF_CERTID *cid_copy = NULL; OSSL_CMP_MSG *msg = NULL; - if (!ossl_assert(ctx != NULL && si != NULL && cid != NULL)) + if (!ossl_assert(ctx != NULL && si != NULL)) return NULL; if ((msg = ossl_cmp_msg_create(ctx, OSSL_CMP_PKIBODY_RP)) == NULL) @@ -530,11 +570,13 @@ OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si, if ((rep->revCerts = sk_OSSL_CRMF_CERTID_new_null()) == NULL) goto err; - if ((cid_copy = OSSL_CRMF_CERTID_dup(cid)) == NULL) - goto err; - if (!sk_OSSL_CRMF_CERTID_push(rep->revCerts, cid_copy)) { - OSSL_CRMF_CERTID_free(cid_copy); - goto err; + if (cid != NULL) { + if ((cid_copy = OSSL_CRMF_CERTID_dup(cid)) == NULL) + goto err; + if (!sk_OSSL_CRMF_CERTID_push(rep->revCerts, cid_copy)) { + OSSL_CRMF_CERTID_free(cid_copy); + goto err; + } } if (!unprot_err |