summaryrefslogtreecommitdiffstats
path: root/crypto/cmp/cmp_msg.c
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2021-01-12 12:16:32 +0100
committerDr. David von Oheimb <dev@ddvo.net>2021-01-21 17:53:26 +0100
commit3d46c81a7d6219fd51ccc3b16406f19b82d0176e (patch)
tree9f79b142da54607bf1bda4792ce74897126fac41 /crypto/cmp/cmp_msg.c
parent2039ac07b401932fa30a05ade80b3626e189d78a (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.c96
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