Skip to content

Commit

Permalink
OSSL_CMP_CTX_setup_CRM(): Fix handling of defaults from CSR and refcert
Browse files Browse the repository at this point in the history
Also update and complete related documentation.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from openssl#17726)
  • Loading branch information
DDvO committed Mar 12, 2022
1 parent 2cb5211 commit c8c9234
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 20 deletions.
17 changes: 10 additions & 7 deletions crypto/cmp/cmp_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx,
if (ctx->subjectName != NULL)
return IS_NULL_DN(ctx->subjectName) ? NULL : ctx->subjectName;

if (ref_subj != NULL && (for_KUR || !HAS_SAN(ctx)))
if (ref_subj != NULL && (ctx->p10CSR != NULL || for_KUR || !HAS_SAN(ctx)))
/*
* For KUR, copy subject from the reference.
* For IR or CR, do the same only if there is no subjectAltName.
Expand Down Expand Up @@ -289,6 +289,8 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid)

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) {
Expand Down Expand Up @@ -327,22 +329,22 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid)
}

/* extensions */
if (refcert != NULL && !ctx->SubjectAltName_nodefault)
default_sans = X509V3_get_d2i(X509_get0_extensions(refcert),
NID_subject_alt_name, NULL, NULL);
if (ctx->p10CSR != NULL
&& (exts = X509_REQ_get_extensions(ctx->p10CSR)) == NULL)
goto err;
if (!ctx->SubjectAltName_nodefault && !HAS_SAN(ctx) && refcert != NULL
&& (default_sans = X509V3_get_d2i(X509_get0_extensions(refcert),
NID_subject_alt_name, NULL, NULL))
!= NULL
&& !add1_extension(&exts, NID_subject_alt_name, crit, default_sans))
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))
goto err;
if (!HAS_SAN(ctx) && default_sans != NULL
&& !add1_extension(&exts, NID_subject_alt_name, crit, default_sans))
goto err;
if (ctx->policies != NULL
&& !add1_extension(&exts, NID_certificate_policies,
ctx->setPoliciesCritical, ctx->policies))
Expand Down Expand Up @@ -566,6 +568,7 @@ OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx)
if (!sk_OSSL_CMP_REVDETAILS_push(msg->body->value.rr, rd))
goto err;
rd = NULL;
/* Revocation Passphrase according to section 5.3.19.9 could be set here */

if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
Expand Down
4 changes: 2 additions & 2 deletions doc/man1/openssl-cmp.pod.in
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ e.g., C<1.2.3.4:int:56789>.
The source of the private or public key for the certificate requested
in Initialization Request (IR), Certification Request(CR), or
Key Update Request (KUR).
Default is the public key in the PKCS#10 CSR given with the B<-csr> option,
if any, or else the current client key, if given.
Defaults to the public key in the PKCS#10 CSR given with the B<-csr> option,
the public key of the reference certificate, or the current client key.

=item B<-newkeypass> I<arg>

Expand Down
10 changes: 6 additions & 4 deletions doc/man3/OSSL_CMP_CTX_new.pod
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ OSSL_CMP_CTX_push1_subjectAltName() adds the given X509 name to the list of
alternate names on the certificate template request. This cannot be used if
any Subject Alternative Name extension is set via
OSSL_CMP_CTX_set0_reqExtensions().
By default, unless OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT has been set,
By default, unless B<OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT> has been set,
the Subject Alternative Names are copied from the reference certificate,
see OSSL_CMP_CTX_set1_oldCert().
If set and the subject DN is not set with OSSL_CMP_CTX_set1_subjectName() then
Expand All @@ -568,14 +568,16 @@ to the X509_EXTENSIONS of the requested certificate template.
OSSL_CMP_CTX_set1_oldCert() sets the old certificate to be updated in
Key Update Requests (KUR) or to be revoked in Revocation Requests (RR).
It must be given for RR, else it defaults to the CMP signer certificate.
The reference certificate determined in this way, if any, is also used for
deriving default subject DN and Subject Alternative Names and the
The I<reference certificate> determined in this way, if any, is also used for
deriving default subject DN, public key, Subject Alternative Names, and the
default issuer entry in the requested certificate template of IR/CR/KUR.
The subject of the reference certificate is used as the sender field value
in CMP message headers.
Its issuer is used as default recipient in CMP message headers.

OSSL_CMP_CTX_set1_p10CSR() sets the PKCS#10 CSR to be used in P10CR.
OSSL_CMP_CTX_set1_p10CSR() sets the PKCS#10 CSR to use in P10CR messages.
If such a CSR is provided, its subject, public key, and extension fields are
also used as fallback values for the certificate template of IR/CR/KUR messages.

OSSL_CMP_CTX_push0_genm_ITAV() adds I<itav> to the stack in the I<ctx> which
will be the body of a General Message sent with this context.
Expand Down
38 changes: 33 additions & 5 deletions doc/man3/OSSL_CMP_MSG_get0_header.pod
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,40 @@ in the header of the given message according to the CMP_CTX.
This requires re-protecting the message (if it was protected).

OSSL_CMP_CTX_setup_CRM() creates a CRMF certificate request message
from various information provided in the CMP context argument I<ctx>
for inclusion in a CMP request message based on details contained in I<ctx>.
If the CMP context does not include a subject name set via
L<OSSL_CMP_CTX_set1_subjectName(3)> but includes a reference certificate
then it copies the subject DN from there
if I<for_KUR> is set or the I<ctx> does not include a subjectAltName.
The I<rid> defines the request identifier to use, which typically is 0.
The I<rid> argument defines the request identifier to use, which typically is 0.

The subject DN to include in the certificate template is determined as follows.
If I<ctx> includes a subject name set via L<OSSL_CMP_CTX_set1_subjectName(3)>,
this name is used.
Otherwise, if a PKCS#10 CSR is given in I<ctx>, its subject is used.
Otherwise, if a reference certificate is given in I<ctx>
(see L<OSSL_CMP_CTX_set1_oldCert(3)>), its subject is used if I<for_KUR>
is nonzero or the I<ctx> does not include a Subject Alternative Name.

The public key to include is taken from any value set via
L<OSSL_CMP_CTX_set0_newPkey(3)>,
otherwise the public key of any PKCS#10 CSR is given in I<ctx>,
otherwise the public key of any reference certificate given in I<ctx>,
otherwise it is derived from the client private key if given in I<ctx>.

The set of X.509 extensions to include is computed as follows.
If a PKCS#10 CSR is present in I<ctx>, default extensions are taken from there,
otherwise the empty set is taken as the initial value.
If there is a reference certificate in I<ctx> and contains Subject Alternative
Names (SANs) and B<OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT> is not set,
these override any SANs from the PKCS#10 CSR.
The extensions are further augmented or overridden by any extensions with the
same OIDs included in the I<ctx> via L<OSSL_CMP_CTX_set0_reqExtensions(3)>.
The SANs are further overridden by any SANs included in I<ctx> via
L<OSSL_CMP_CTX_push1_subjectAltName(3)>.
Finally, policies are overridden by any policies included in I<ctx> via
L<OSSL_CMP_CTX_push0_policy(3)>.

OSSL_CMP_CTX_setup_CRM() also sets the sets the regToken control B<oldCertID>
for KUR messages using the issuer name and serial number of the reference
certificate, if present.

OSSL_CMP_MSG_read() loads a DER-encoded OSSL_CMP_MSG from I<file>.

Expand Down
4 changes: 2 additions & 2 deletions doc/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ section 6.3.
OSSL_CRMF_MSG_set1_regCtrl_protocolEncrKey() sets the protocolEncrKey control in
the given I<msg> copying the given I<pubkey> as value. See RFC 4211 section 6.6.

OSSL_CRMF_MSG_set1_regCtrl_oldCertID() sets the oldCertID control in the given
I<msg> copying the given I<cid> as value. See RFC 4211, section 6.5.
OSSL_CRMF_MSG_set1_regCtrl_oldCertID() sets the B<oldCertID> regToken control in
the given I<msg> copying the given I<cid> as value. See RFC 4211, section 6.5.

OSSL_CRMF_CERTID_gen produces an OSSL_CRMF_CERTID_gen structure copying the
given I<issuer> name and I<serial> number.
Expand Down

0 comments on commit c8c9234

Please sign in to comment.