summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2020-12-28 21:33:09 +0100
committerDr. David von Oheimb <dev@ddvo.net>2021-04-20 10:47:24 +0200
commit1c0eede9827b0962f1d752fa4ab5d436fa039da4 (patch)
tree87f7f312c5ca6351cb0aac262d7a02c976e5f8eb /crypto
parenta78c7c0bfe56d67022ca18cfabefc73926dde0ae (diff)
Improve ossl_cmp_build_cert_chain(); publish it as X509_build_chain()
Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14128)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/cmp/cmp_client.c5
-rw-r--r--crypto/cmp/cmp_ctx.c4
-rw-r--r--crypto/cmp/cmp_local.h4
-rw-r--r--crypto/cmp/cmp_protect.c5
-rw-r--r--crypto/cmp/cmp_util.c61
-rw-r--r--crypto/x509/x509_vfy.c42
-rw-r--r--crypto/x509/x_x509.c2
7 files changed, 49 insertions, 74 deletions
diff --git a/crypto/cmp/cmp_client.c b/crypto/cmp/cmp_client.c
index 728ec21968..54c8f5094b 100644
--- a/crypto/cmp/cmp_client.c
+++ b/crypto/cmp/cmp_client.c
@@ -496,9 +496,8 @@ int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info,
return fail_info;
ossl_cmp_debug(ctx, "trying to build chain for newly enrolled cert");
- chain = ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq,
- out_trusted /* may be NULL */,
- ctx->untrusted, cert);
+ chain = X509_build_chain(cert, ctx->untrusted, out_trusted /* maybe NULL */,
+ 0, ctx->libctx, ctx->propq);
if (sk_X509_num(chain) > 0)
X509_free(sk_X509_shift(chain)); /* remove leaf (EE) cert */
if (out_trusted != NULL) {
diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c
index 110361320d..7e7af63b4a 100644
--- a/crypto/cmp/cmp_ctx.c
+++ b/crypto/cmp/cmp_ctx.c
@@ -735,8 +735,8 @@ int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted,
return 0;
ossl_cmp_debug(ctx, "trying to build chain for own CMP signer cert");
- chain = ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq, own_trusted,
- ctx->untrusted, ctx->cert);
+ chain = X509_build_chain(ctx->cert, ctx->untrusted, own_trusted, 0,
+ ctx->libctx, ctx->propq);
if (chain == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_FAILED_BUILDING_OWN_CHAIN);
return 0;
diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h
index 1ec16d4b2b..b2a3382079 100644
--- a/crypto/cmp/cmp_local.h
+++ b/crypto/cmp/cmp_local.h
@@ -749,10 +749,6 @@ 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(OSSL_LIB_CTX *libctx, const char *propq,
- X509_STORE *store,
- STACK_OF(X509) *certs, X509 *cert);
/* from cmp_ctx.c */
int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c
index 45bea73d13..36a6597145 100644
--- a/crypto/cmp/cmp_protect.c
+++ b/crypto/cmp/cmp_protect.c
@@ -144,9 +144,8 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
if (ctx->chain == NULL) {
ossl_cmp_debug(ctx,
"trying to build chain for own CMP signer cert");
- ctx->chain =
- ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq, NULL,
- ctx->untrusted, ctx->cert);
+ ctx->chain = X509_build_chain(ctx->cert, ctx->untrusted, NULL, 0,
+ ctx->libctx, ctx->propq);
if (ctx->chain != NULL) {
ossl_cmp_debug(ctx,
"success building chain for own CMP signer cert");
diff --git a/crypto/cmp/cmp_util.c b/crypto/cmp/cmp_util.c
index 56f2b0eeb8..fbb8d1e249 100644
--- a/crypto/cmp/cmp_util.c
+++ b/crypto/cmp/cmp_util.c
@@ -220,67 +220,6 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
return 1;
}
-/*-
- * Builds a certificate chain starting from <cert>
- * using the optional list of intermediate CA certificates <certs>.
- * If <store> is NULL builds the chain as far down as possible, ignoring errors.
- * Else the chain must reach a trust anchor contained in <store>.
- *
- * Returns NULL on error, else a pointer to a stack of (up_ref'ed) certificates
- * starting with given EE certificate and followed by all available intermediate
- * certificates down towards any trust anchor but without including the latter.
- *
- * NOTE: If a non-NULL stack is returned the caller is responsible for freeing.
- * 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.
- */
-/* TODO this should be of more general interest and thus be exported. */
-STACK_OF(X509)
- *ossl_cmp_build_cert_chain(OSSL_LIB_CTX *libctx, const char *propq,
- X509_STORE *store,
- STACK_OF(X509) *certs, X509 *cert)
-{
- STACK_OF(X509) *chain = NULL, *result = NULL;
- X509_STORE *ts = store == NULL ? X509_STORE_new() : store;
- X509_STORE_CTX *csc = NULL;
-
- if (ts == NULL || cert == NULL) {
- ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
- goto err;
- }
-
- if ((csc = X509_STORE_CTX_new_ex(libctx, propq)) == NULL)
- goto err;
- if (store == NULL && certs != NULL
- && !ossl_cmp_X509_STORE_add1_certs(ts, certs, 0))
- goto err;
- if (!X509_STORE_CTX_init(csc, ts, cert,
- store == NULL ? NULL : certs))
- goto err;
- /* disable any cert status/revocation checking etc. */
- X509_VERIFY_PARAM_clear_flags(X509_STORE_CTX_get0_param(csc),
- ~(X509_V_FLAG_USE_CHECK_TIME
- | X509_V_FLAG_NO_CHECK_TIME));
-
- if (X509_verify_cert(csc) <= 0 && store != NULL)
- goto err;
- chain = X509_STORE_CTX_get0_chain(csc);
-
- /* result list to store the up_ref'ed not self-signed certificates */
- if (!ossl_x509_add_certs_new(&result, chain,
- X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
- | X509_ADD_FLAG_NO_SS)) {
- sk_X509_free(result);
- result = NULL;
- }
-
- err:
- if (store == NULL)
- X509_STORE_free(ts);
- X509_STORE_CTX_free(csc);
- return result;
-}
-
int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk,
const char *text)
{
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 01871b9090..cb541084df 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -3322,6 +3322,48 @@ static int build_chain(X509_STORE_CTX *ctx)
return -1;
}
+STACK_OF(X509) *X509_build_chain(X509 *target, STACK_OF(X509) *certs,
+ X509_STORE *store, int with_self_signed,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ int finish_chain = store != NULL;
+ X509_STORE_CTX *ctx;
+ int flags = X509_ADD_FLAG_UP_REF;
+ STACK_OF(X509) *result = NULL;
+
+ if (target == NULL) {
+ ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ if ((ctx = X509_STORE_CTX_new_ex(libctx, propq)) == NULL)
+ return NULL;
+ if (!X509_STORE_CTX_init(ctx, store, target, finish_chain ? certs : NULL))
+ goto err;
+ if (!finish_chain)
+ X509_STORE_CTX_set0_trusted_stack(ctx, certs);
+ if (!ossl_x509_add_cert_new(&ctx->chain, target, X509_ADD_FLAG_UP_REF)) {
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ goto err;
+ }
+ ctx->num_untrusted = 1;
+
+ if (!build_chain(ctx) && finish_chain)
+ goto err;
+
+ /* result list to store the up_ref'ed certificates */
+ if (sk_X509_num(ctx->chain) > 1 && !with_self_signed)
+ flags |= X509_ADD_FLAG_NO_SS;
+ if (!ossl_x509_add_certs_new(&result, ctx->chain, flags)) {
+ sk_X509_free(result);
+ result = NULL;
+ }
+
+ err:
+ X509_STORE_CTX_free(ctx);
+ return result;
+}
+
static const int minbits_table[] = { 80, 112, 128, 192, 256 };
static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table);
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index a4a169a97e..529d701bbb 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -129,7 +129,7 @@ X509 *d2i_X509(X509 **a, const unsigned char **in, long len)
cert = (X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (X509_it()));
/* Only cache the extensions if the cert object was passed in */
- if (cert != NULL && a != NULL) {
+ if (cert != NULL && a != NULL) { /* then cert == *a */
if (!ossl_x509v3_cache_extensions(cert)) {
if (free_on_error)
X509_free(cert);