The branch master has been updated via ee46dfbf2c117a9532f887b478c9c65d8f30d50c (commit) via 4f7e08c83eca6667722f3d5848f28d37c821dc37 (commit) from 888bdbfd398c967daaa00cf6b3d104f0e3d26865 (commit)
- Log ----------------------------------------------------------------- commit ee46dfbf2c117a9532f887b478c9c65d8f30d50c Author: Dr. David von Oheimb <david.von.ohe...@siemens.com> Date: Wed Aug 19 20:16:53 2020 +0200 X509_dup: fix copying of libctx and propq using new ASN1_OP_DUP_POST cb operation Fixes #12680 Reviewed-by: Tomas Mraz <tm...@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/12687) commit 4f7e08c83eca6667722f3d5848f28d37c821dc37 Author: Dr. David von Oheimb <david.von.ohe...@siemens.com> Date: Mon Nov 23 12:54:39 2020 +0100 asn1t.h: Improve comments documenting ASN1_ITYPE_... and the 'funcs' field Also move the #define(s) for the ASN1_ITYPE_.. before their first use. Reviewed-by: Tomas Mraz <tm...@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/12687) ----------------------------------------------------------------------- Summary of changes: crypto/asn1/a_dup.c | 25 ++++++++++- crypto/x509/x_x509.c | 11 +++++ include/openssl/asn1t.h.in | 107 ++++++++++++++++++++++----------------------- test/cmp_msg_test.c | 18 ++------ 4 files changed, 91 insertions(+), 70 deletions(-) diff --git a/crypto/asn1/a_dup.c b/crypto/asn1/a_dup.c index 624fef9e5c..bdefa448ec 100644 --- a/crypto/asn1/a_dup.c +++ b/crypto/asn1/a_dup.c @@ -9,7 +9,7 @@ #include <stdio.h> #include "internal/cryptlib.h" -#include <openssl/asn1.h> +#include <openssl/asn1t.h> #ifndef NO_OLD_ASN1 @@ -48,14 +48,26 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x) void *ASN1_item_dup(const ASN1_ITEM *it, const void *x) { + ASN1_aux_cb *asn1_cb = NULL; unsigned char *b = NULL; const unsigned char *p; long i; - void *ret; + ASN1_VALUE *ret; if (x == NULL) return NULL; + if (it->itype == ASN1_ITYPE_SEQUENCE || it->itype == ASN1_ITYPE_CHOICE + || it->itype == ASN1_ITYPE_NDEF_SEQUENCE) { + const ASN1_AUX *aux = it->funcs; + + asn1_cb = aux != NULL ? aux->asn1_cb : NULL; + } + + if (asn1_cb != NULL + && !asn1_cb(ASN1_OP_DUP_PRE, (ASN1_VALUE **)&x, it, NULL)) + goto auxerr; + i = ASN1_item_i2d(x, &b, it); if (b == NULL) { ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); @@ -64,5 +76,14 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x) p = b; ret = ASN1_item_d2i(NULL, &p, i, it); OPENSSL_free(b); + + if (asn1_cb != NULL + && !asn1_cb(ASN1_OP_DUP_POST, &ret, it, (void *)x)) + goto auxerr; + return ret; + + auxerr: + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_AUX_ERROR, "Type=%s", it->sname); + return NULL; } diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c index f929fd2ae3..efcd7cd15c 100644 --- a/crypto/x509/x_x509.c +++ b/crypto/x509/x_x509.c @@ -97,6 +97,17 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ASN1_OCTET_STRING_free(ret->distinguishing_id); break; + case ASN1_OP_DUP_POST: + { + X509 *old = exarg; + + ret->libctx = old->libctx; + ret->propq = old->propq; + } + break; + + default: + break; } return 1; diff --git a/include/openssl/asn1t.h.in b/include/openssl/asn1t.h.in index 1eebd1f85a..2f40d1ca15 100644 --- a/include/openssl/asn1t.h.in +++ b/include/openssl/asn1t.h.in @@ -37,6 +37,55 @@ use OpenSSL::stackhash qw(generate_stack_macros); extern "C" { #endif +/*- + * These are the possible values for the itype field of the + * ASN1_ITEM structure and determine how it is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application-specific + * data and functions. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +# define ASN1_ITYPE_PRIMITIVE 0x0 +# define ASN1_ITYPE_SEQUENCE 0x1 +# define ASN1_ITYPE_CHOICE 0x2 +/* unused value 0x3 */ +# define ASN1_ITYPE_EXTERN 0x4 +# define ASN1_ITYPE_MSTRING 0x5 +# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ # define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)((iptr)())) @@ -557,64 +606,12 @@ struct ASN1_ITEM_st { const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains * the contents */ long tcount; /* Number of templates if SEQUENCE or CHOICE */ - const void *funcs; /* functions that handle this type */ + const void *funcs; /* further data and type-specific functions */ + /* funcs can be ASN1_PRIMITIVE_FUNCS*, ASN1_EXTERN_FUNCS*, or ASN1_AUX* */ long size; /* Structure size (usually) */ const char *sname; /* Structure name */ }; -/*- - * These are values for the itype field and - * determine how the type is interpreted. - * - * For PRIMITIVE types the underlying type - * determines the behaviour if items is NULL. - * - * Otherwise templates must contain a single - * template and the type is treated in the - * same way as the type specified in the template. - * - * For SEQUENCE types the templates field points - * to the members, the size field is the - * structure size. - * - * For CHOICE types the templates field points - * to each possible member (typically a union) - * and the 'size' field is the offset of the - * selector. - * - * The 'funcs' field is used for application - * specific functions. - * - * The EXTERN type uses a new style d2i/i2d. - * The new style should be used where possible - * because it avoids things like the d2i IMPLICIT - * hack. - * - * MSTRING is a multiple string type, it is used - * for a CHOICE of character strings where the - * actual strings all occupy an ASN1_STRING - * structure. In this case the 'utype' field - * has a special meaning, it is used as a mask - * of acceptable types using the B_ASN1 constants. - * - * NDEF_SEQUENCE is the same as SEQUENCE except - * that it will use indefinite length constructed - * encoding if requested. - * - */ - -# define ASN1_ITYPE_PRIMITIVE 0x0 - -# define ASN1_ITYPE_SEQUENCE 0x1 - -# define ASN1_ITYPE_CHOICE 0x2 - -# define ASN1_ITYPE_EXTERN 0x4 - -# define ASN1_ITYPE_MSTRING 0x5 - -# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 - /* * Cache for ASN1 tag and length, so we don't keep re-reading it for things * like CHOICE @@ -749,6 +746,8 @@ typedef struct ASN1_STREAM_ARG_st { # define ASN1_OP_STREAM_POST 11 # define ASN1_OP_DETACHED_PRE 12 # define ASN1_OP_DETACHED_POST 13 +# define ASN1_OP_DUP_PRE 14 +# define ASN1_OP_DUP_POST 15 /* Macro to implement a primitive type */ # define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) diff --git a/test/cmp_msg_test.c b/test/cmp_msg_test.c index cc5a6268fd..59b0a1777d 100644 --- a/test/cmp_msg_test.c +++ b/test/cmp_msg_test.c @@ -33,16 +33,6 @@ typedef struct test_fixture { static OSSL_LIB_CTX *libctx = NULL; static OSSL_PROVIDER *default_null_provider = NULL, *provider = NULL; -/* TODO(3.0) Clean this up - See issue #12680 */ -static X509 *X509_dup_ex(const X509 *cert) -{ - X509 *dup = X509_dup(cert); - - if (dup != NULL) - x509_set0_libctx(dup, libctx, NULL); - return dup; -} - static unsigned char ref[CMP_TEST_REFVALUE_LENGTH]; static void tear_down(CMP_MSG_TEST_FIXTURE *fixture) @@ -296,7 +286,7 @@ static int test_cmp_create_certconf(void) fixture->fail_info = 0; fixture->expected = 1; if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx, - X509_dup_ex(cert)))) { + X509_dup(cert)))) { tear_down(fixture); fixture = NULL; } @@ -310,7 +300,7 @@ static int test_cmp_create_certconf_badAlg(void) fixture->fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badAlg; fixture->expected = 1; if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx, - X509_dup_ex(cert)))) { + X509_dup(cert)))) { tear_down(fixture); fixture = NULL; } @@ -324,7 +314,7 @@ static int test_cmp_create_certconf_fail_info_max(void) fixture->fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_MAX; fixture->expected = 1; if (!TEST_true(ossl_cmp_ctx_set0_newCert(fixture->cmp_ctx, - X509_dup_ex(cert)))) { + X509_dup(cert)))) { tear_down(fixture); fixture = NULL; } @@ -405,7 +395,7 @@ static int execute_certrep_create(CMP_MSG_TEST_FIXTURE *fixture) cresp->certifiedKeyPair->certOrEncCert->type = OSSL_CMP_CERTORENCCERT_CERTIFICATE; if ((cresp->certifiedKeyPair->certOrEncCert->value.certificate = - X509_dup_ex(cert)) == NULL + X509_dup(cert)) == NULL || !sk_OSSL_CMP_CERTRESPONSE_push(crepmsg->response, cresp)) goto err; cresp = NULL;