cmp_util.c: Add OPENSSL_CTX parameter to ossl_cmp_build_cert_chain(), improve its doc

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11808)
This commit is contained in:
Dr. David von Oheimb 2020-05-13 16:03:26 +02:00
parent 1930b58642
commit 28e9f62b2d
7 changed files with 56 additions and 38 deletions

View File

@ -744,7 +744,9 @@ int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
const ASN1_OCTET_STRING *src); const ASN1_OCTET_STRING *src);
int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
const unsigned char *bytes, int len); const unsigned char *bytes, int len);
STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert); STACK_OF(X509)
*ossl_cmp_build_cert_chain(OPENSSL_CTX *libctx, const char *propq,
STACK_OF(X509) *certs, X509 *cert);
/* from cmp_ctx.c */ /* from cmp_ctx.c */
int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,

View File

@ -154,7 +154,8 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
/* if we have untrusted certs, try to add intermediate certs */ /* if we have untrusted certs, try to add intermediate certs */
if (ctx->untrusted_certs != NULL) { if (ctx->untrusted_certs != NULL) {
STACK_OF(X509) *chain = STACK_OF(X509) *chain =
ossl_cmp_build_cert_chain(ctx->untrusted_certs, ctx->cert); ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq,
ctx->untrusted_certs, ctx->cert);
int res = X509_add_certs(msg->extraCerts, chain, int res = X509_add_certs(msg->extraCerts, chain,
X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
| X509_ADD_FLAG_NO_SS); | X509_ADD_FLAG_NO_SS);

View File

@ -206,19 +206,19 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
} }
/*- /*-
* Builds up the certificate chain of certs as high up as possible using * Builds up the chain of intermediate CA certificates
* the given list of certs containing all possible intermediate certificates and * starting from of the given certificate <cert> as high up as possible using
* optionally the (possible) trust anchor(s). See also ssl_add_cert_chain(). * the given list of candidate certificates, similarly to ssl_add_cert_chain().
* *
* Intended use of this function is to find all the certificates above the trust * Intended use of this function is to find all the certificates above the trust
* anchor needed to verify an EE's own certificate. Those are supposed to be * anchor needed to verify an EE's own certificate. Those are supposed to be
* included in the ExtraCerts field of every first sent message of a transaction * included in the ExtraCerts field of every first CMP message of a transaction
* when MSG_SIG_ALG is utilized. * when MSG_SIG_ALG is utilized.
* *
* NOTE: This allocates a stack and increments the reference count of each cert, * NOTE: This allocates a stack and increments the reference count of each cert,
* so when not needed any more the stack and all its elements should be freed. * so when not needed any more the stack and all its elements should be freed.
* NOTE: in case there is more than one possibility for the chain, * NOTE: In case there is more than one possibility for the chain,
* OpenSSL seems to take the first one, check X509_verify_cert() for details. * OpenSSL seems to take the first one; check X509_verify_cert() for details.
* *
* returns a pointer to a stack of (up_ref'ed) X509 certificates containing: * returns a pointer to a stack of (up_ref'ed) X509 certificates containing:
* - the EE certificate given in the function arguments (cert) * - the EE certificate given in the function arguments (cert)
@ -226,7 +226,9 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
* whereas the (self-signed) trust anchor is not included * whereas the (self-signed) trust anchor is not included
* returns NULL on error * returns NULL on error
*/ */
STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert) STACK_OF(X509)
*ossl_cmp_build_cert_chain(OPENSSL_CTX *libctx, const char *propq,
STACK_OF(X509) *certs, X509 *cert)
{ {
STACK_OF(X509) *chain = NULL, *result = NULL; STACK_OF(X509) *chain = NULL, *result = NULL;
X509_STORE *store = X509_STORE_new(); X509_STORE *store = X509_STORE_new();
@ -237,7 +239,7 @@ STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert)
goto err; goto err;
} }
csc = X509_STORE_CTX_new(); csc = X509_STORE_CTX_new_with_libctx(libctx, propq);
if (csc == NULL) if (csc == NULL)
goto err; goto err;

View File

@ -151,7 +151,7 @@ int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx,
return 0; return 0;
} }
if ((csc = X509_STORE_CTX_new()) == NULL if ((csc = X509_STORE_CTX_new_with_libctx(ctx->libctx, ctx->propq)) == NULL
|| !X509_STORE_CTX_init(csc, trusted_store, || !X509_STORE_CTX_init(csc, trusted_store,
cert, ctx->untrusted_certs)) cert, ctx->untrusted_certs))
goto err; goto err;

View File

@ -3,9 +3,8 @@
=head1 NAME =head1 NAME
ossl_cmp_asn1_octet_string_set1, ossl_cmp_asn1_octet_string_set1,
ossl_cmp_asn1_octet_string_set1_bytes, ossl_cmp_asn1_octet_string_set1_bytes
ossl_cmp_build_cert_chain - ASN.1 octet string utility functions
- misc internal utility functions
=head1 SYNOPSIS =head1 SYNOPSIS
@ -16,32 +15,19 @@ ossl_cmp_build_cert_chain
int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
const unsigned char *bytes, int len); const unsigned char *bytes, int len);
STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert);
=head1 DESCRIPTION =head1 DESCRIPTION
ossl_cmp_asn1_octet_string_set1() frees any previous value of the variable ossl_cmp_asn1_octet_string_set1() frees any previous value of the variable
referenced via the I<tgt> argument and assigns either a copy of referenced via the I<tgt> argument and assigns either a copy of
the ASN1_OCTET_STRING given as the I<src> argument or NULL. the ASN1_OCTET_STRING given as the I<src> argument or NULL.
It returns 1 on success, 0 on error.
ossl_cmp_asn1_octet_string_set1_bytes() frees any previous value of the variable ossl_cmp_asn1_octet_string_set1_bytes() frees any previous value of the variable
referenced via the I<tgt> argument and assigns either a copy of the given byte referenced via the I<tgt> argument and assigns either a copy of the given byte
string (with the given length) or NULL. It returns 1 on success, 0 on error. string (with the given length) or NULL.
ossl_cmp_build_cert_chain() builds up the certificate chain of cert as high up
as possible using the given X509_STORE containing all possible intermediate
certificates and optionally the (possible) trust anchor(s).
=head1 RETURN VALUES =head1 RETURN VALUES
ossl_cmp_build_cert_chain() All functions return 1 on success, 0 on error.
returns NULL on error, else a pointer to a stack of (up_ref'ed) certificates
containing the EE certificate given in the function arguments (cert)
and all intermediate certificates up the chain toward the trust anchor.
The (self-signed) trust anchor is not included.
All other functions return 1 on success, 0 on error.
=head1 HISTORY =head1 HISTORY

View File

@ -2,19 +2,38 @@
=head1 NAME =head1 NAME
ossl_cmp_build_cert_chain,
ossl_cmp_msg_protect, ossl_cmp_msg_protect,
ossl_cmp_msg_add_extraCerts ossl_cmp_msg_add_extraCerts
- functions for producing CMP message protection - functions for producing CMP message protection
=head1 SYNOPSIS =head1 SYNOPSIS
#include "cmp_int.h" #include "cmp_local.h"
STACK_OF(X509)
*ossl_cmp_build_cert_chain(OPENSSL_CTX *libctx, const char *propq,
STACK_OF(X509) *certs, X509 *cert);
int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
=head1 DESCRIPTION =head1 DESCRIPTION
ossl_cmp_build_cert_chain() builds up the chain of intermediate CA certificates
starting from of the given certificate B<cert> as high up as possible using
the given list of candidate certificates, similarly to ssl_add_cert_chain().
It internally uses a B<X509_STORE_CTX> structure associated with the library
context I<libctx> and property query string I<propq>, both of which may be NULL.
Intended use of this function is to find all the certificates above the trust
anchor needed to verify an EE's own certificate.
Those are supposed to be included in the ExtraCerts field of every first
CMP message of a transaction when MSG_SIG_ALG is utilized.
This allocates a stack and increments the reference count of each cert,
so when not needed any more the stack and all its elements should be freed.
In case there is more than one possibility for the chain,
OpenSSL seems to take the first one; check X509_verify_cert() for details.
ossl_cmp_msg_protect() (re-)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>. depending on the available context information given in the B<ctx>.
If there is a secretValue it selects PBMAC, else if there is a protection cert If there is a secretValue it selects PBMAC, else if there is a protection cert
@ -35,7 +54,13 @@ CMP is defined in RFC 4210 (and CRMF in RFC 4211).
=head1 RETURN VALUES =head1 RETURN VALUES
All functions return 1 on success, 0 on error. ossl_cmp_build_cert_chain() returns NULL on error,
else a pointer to a stack of (up_ref'ed) certificates
containing the EE certificate given in the function arguments (cert)
and all intermediate certificates up the chain toward the trust anchor.
The (self-signed) trust anchor is not included.
All other functions return 1 on success, 0 on error.
=head1 HISTORY =head1 HISTORY

View File

@ -335,14 +335,16 @@ static int test_MSG_add_extraCerts(void)
/* The cert chain tests use EC certs so we skip them in no-ec builds */ /* The cert chain tests use EC certs so we skip them in no-ec builds */
static int execute_cmp_build_cert_chain_test(CMP_PROTECT_TEST_FIXTURE *fixture) static int execute_cmp_build_cert_chain_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{ {
STACK_OF(X509) *result = NULL;
int ret = 0; int ret = 0;
OSSL_CMP_CTX *ctx = fixture->cmp_ctx;
STACK_OF(X509) *chain =
ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq,
fixture->certs, fixture->cert);
if (TEST_ptr(result = ossl_cmp_build_cert_chain(fixture->certs, if (TEST_ptr(chain)) {
fixture->cert))) {
/* Check whether chain built is equal to the expected one */ /* Check whether chain built is equal to the expected one */
ret = TEST_int_eq(0, STACK_OF_X509_cmp(result, fixture->chain)); ret = TEST_int_eq(0, STACK_OF_X509_cmp(chain, fixture->chain));
sk_X509_pop_free(result, X509_free); sk_X509_pop_free(chain, X509_free);
} }
return ret; return ret;
} }