diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c index 4ba7b81087691..9628f0500ad56 100644 --- a/crypto/cmp/cmp_msg.c +++ b/crypto/cmp/cmp_msg.c @@ -145,34 +145,6 @@ static int add1_extension(X509_EXTENSIONS **pexts, int nid, int crit, void *ex) return res; } -/* Add extension list to the referenced extension stack, which may be NULL */ -static int add_extensions(STACK_OF(X509_EXTENSION) **target, - const STACK_OF(X509_EXTENSION) *exts) -{ - int i; - - if (target == NULL) - return 0; - - for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { - X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); - ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext); - int idx = X509v3_get_ext_by_OBJ(*target, obj, -1); - - /* Does extension exist in target? */ - if (idx != -1) { - /* Delete all extensions of same type */ - do { - X509_EXTENSION_free(sk_X509_EXTENSION_delete(*target, idx)); - idx = X509v3_get_ext_by_OBJ(*target, obj, -1); - } while (idx != -1); - } - if (!X509v3_add_ext(target, ext, -1)) - return 0; - } - return 1; -} - /* Add a CRL revocation reason code to extension stack, which may be NULL */ static int add_crl_reason_extension(X509_EXTENSIONS **pexts, int reason_code) { @@ -359,7 +331,7 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) && !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)) + && X509v3_add_extensions(&exts, ctx->reqExtensions) == NULL) goto err; if (sk_GENERAL_NAME_num(ctx->subjectAltNames) > 0 && !add1_extension(&exts, NID_subject_alt_name, diff --git a/crypto/x509/x509_v3.c b/crypto/x509/x509_v3.c index 1bb0a4b037bff..034b119a2b588 100644 --- a/crypto/x509/x509_v3.c +++ b/crypto/x509/x509_v3.c @@ -142,6 +142,36 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, return NULL; } +STACK_OF(X509_EXTENSION) + *X509v3_add_extensions(STACK_OF(X509_EXTENSION) **target, + const STACK_OF(X509_EXTENSION) *exts) +{ + int i; + + if (target == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext); + int idx = X509v3_get_ext_by_OBJ(*target, obj, -1); + + /* Does extension exist in target? */ + if (idx != -1) { + /* Delete all extensions of same type */ + do { + X509_EXTENSION_free(sk_X509_EXTENSION_delete(*target, idx)); + idx = X509v3_get_ext_by_OBJ(*target, obj, -1); + } while (idx != -1); + } + if (!X509v3_add_ext(target, ext, -1)) + return NULL; + } + return *target; +} + X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit, ASN1_OCTET_STRING *data) diff --git a/doc/man3/X509v3_get_ext_by_NID.pod b/doc/man3/X509v3_get_ext_by_NID.pod index 4010a71c4371a..0974c8641615f 100644 --- a/doc/man3/X509v3_get_ext_by_NID.pod +++ b/doc/man3/X509v3_get_ext_by_NID.pod @@ -4,7 +4,7 @@ X509v3_get_ext_count, X509v3_get_ext, X509v3_get_ext_by_NID, X509v3_get_ext_by_OBJ, X509v3_get_ext_by_critical, X509v3_delete_ext, -X509v3_add_ext, X509_get_ext_count, X509_get_ext, +X509v3_add_ext, X509v3_add_extensions, X509_get_ext_count, X509_get_ext, X509_get_ext_by_NID, X509_get_ext_by_OBJ, X509_get_ext_by_critical, X509_delete_ext, X509_add_ext, X509_CRL_get_ext_count, X509_CRL_get_ext, X509_CRL_get_ext_by_NID, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext_by_critical, @@ -29,6 +29,9 @@ X509_REVOKED_add_ext - extension stack utility functions X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *ex, int loc); + STACK_OF(X509_EXTENSION) + *X509v3_add_extensions(STACK_OF(X509_EXTENSION) **target, + const STACK_OF(X509_EXTENSION) *exts); int X509_get_ext_count(const X509 *x); X509_EXTENSION *X509_get_ext(const X509 *x, int loc); @@ -79,10 +82,16 @@ X509v3_delete_ext() deletes the extension with index I from I. The deleted extension is returned and must be freed by the caller. If I is an invalid index value, NULL is returned. -X509v3_add_ext() adds extension I to STACK I<*x> at position I. If -I is -1, the new extension is added to the end. If I<*x> is NULL, -a new STACK will be allocated. The passed extension I is duplicated -internally so it must be freed after use. +X509v3_add_ext() inserts extension I to STACK I<*x> at position I. +If I is -1, the new extension is added to the end. +A new STACK is allocated if I<*x> is NULL. +The passed extension I is duplicated so it must be freed after use. + +X509v3_add_extensions() adds the list of extensions I to STACK I<*target>. +The STACK I<*target> is returned unchanged if I is NULL or an empty list. +Otherwise a new stack is allocated if I<*target> is NULL. +An extension to be added +that has the same OID as a pre-existing one replaces this earlier one. X509_get_ext_count(), X509_get_ext(), X509_get_ext_by_NID(), X509_get_ext_by_OBJ(), X509_get_ext_by_critical(), X509_delete_ext() @@ -132,7 +141,8 @@ the extension index or -1 if an error occurs. X509v3_get_ext_by_NID() returns the extension index or negative values if an error occurs. -X509v3_add_ext() returns a STACK of extensions or NULL on error. +X509v3_add_ext() and X509v3_add_extensions() +return a STACK of extensions or NULL on error. X509_add_ext() returns 1 on success and 0 on error. @@ -140,6 +150,10 @@ X509_add_ext() returns 1 on success and 0 on error. L +=head1 HISTORY + +X509v3_add_extensions() was added in OpenSSL 3.4. + =head1 COPYRIGHT Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/openssl/x509.h.in b/include/openssl/x509.h.in index 838dc8cb28ec6..6f13feee09e96 100644 --- a/include/openssl/x509.h.in +++ b/include/openssl/x509.h.in @@ -899,6 +899,9 @@ X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *ex, int loc); +STACK_OF(X509_EXTENSION) + *X509v3_add_extensions(STACK_OF(X509_EXTENSION) **target, + const STACK_OF(X509_EXTENSION) *exts); int X509_get_ext_count(const X509 *x); int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); diff --git a/util/libcrypto.num b/util/libcrypto.num index e0474a0021dd9..f6096823999c3 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5629,6 +5629,7 @@ X509_ACERT_verify ? 3_4_0 EXIST::FUNCTION: X509_ACERT_get_ext_d2i ? 3_4_0 EXIST::FUNCTION: X509_ACERT_add1_ext_i2d ? 3_4_0 EXIST::FUNCTION: X509_ACERT_get0_extensions ? 3_4_0 EXIST::FUNCTION: +X509v3_add_extensions ? 3_4_0 EXIST::FUNCTION: OSSL_IETF_ATTR_SYNTAX_VALUE_it ? 3_4_0 EXIST::FUNCTION: OSSL_IETF_ATTR_SYNTAX_VALUE_free ? 3_4_0 EXIST::FUNCTION: OSSL_IETF_ATTR_SYNTAX_VALUE_new ? 3_4_0 EXIST::FUNCTION: