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);
int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
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 */
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 (ctx->untrusted_certs != NULL) {
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,
X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
| 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
* the given list of certs containing all possible intermediate certificates and
* optionally the (possible) trust anchor(s). See also ssl_add_cert_chain().
* Builds up the chain of intermediate CA certificates
* starting from of the given certificate <cert> as high up as possible using
* 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
* 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.
*
* 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.
* 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.
* 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.
*
* returns a pointer to a stack of (up_ref'ed) X509 certificates containing:
* - 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
* 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;
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;
}
csc = X509_STORE_CTX_new();
csc = X509_STORE_CTX_new_with_libctx(libctx, propq);
if (csc == NULL)
goto err;

View File

@ -151,7 +151,7 @@ int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx,
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,
cert, ctx->untrusted_certs))
goto err;

View File

@ -3,9 +3,8 @@
=head1 NAME
ossl_cmp_asn1_octet_string_set1,
ossl_cmp_asn1_octet_string_set1_bytes,
ossl_cmp_build_cert_chain
- misc internal utility functions
ossl_cmp_asn1_octet_string_set1_bytes
- ASN.1 octet string utility functions
=head1 SYNOPSIS
@ -16,32 +15,19 @@ ossl_cmp_build_cert_chain
int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
const unsigned char *bytes, int len);
STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert);
=head1 DESCRIPTION
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
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
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.
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).
string (with the given length) or NULL.
=head1 RETURN VALUES
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.
All functions return 1 on success, 0 on error.
=head1 HISTORY

View File

@ -2,19 +2,38 @@
=head1 NAME
ossl_cmp_build_cert_chain,
ossl_cmp_msg_protect,
ossl_cmp_msg_add_extraCerts
- functions for producing CMP message protection
=head1 SYNOPSIS
#include "cmp_int.h"
#include "cmp_local.h"
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);
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_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
=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
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
@ -35,7 +54,13 @@ CMP is defined in RFC 4210 (and CRMF in RFC 4211).
=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

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 */
static int execute_cmp_build_cert_chain_test(CMP_PROTECT_TEST_FIXTURE *fixture)
{
STACK_OF(X509) *result = NULL;
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,
fixture->cert))) {
if (TEST_ptr(chain)) {
/* Check whether chain built is equal to the expected one */
ret = TEST_int_eq(0, STACK_OF_X509_cmp(result, fixture->chain));
sk_X509_pop_free(result, X509_free);
ret = TEST_int_eq(0, STACK_OF_X509_cmp(chain, fixture->chain));
sk_X509_pop_free(chain, X509_free);
}
return ret;
}