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)
{
&& !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,
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)
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,
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);
The deleted extension is returned and must be freed by the caller.
If I<loc> is an invalid index value, NULL is returned.
-X509v3_add_ext() adds extension I<ex> to STACK I<*x> at position I<loc>. If
-I<loc> 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<ex> is duplicated
-internally so it must be freed after use.
+X509v3_add_ext() inserts extension I<ex> to STACK I<*x> at position I<loc>.
+If I<loc> is -1, the new extension is added to the end.
+A new STACK is allocated if I<*x> is NULL.
+The passed extension I<ex> is duplicated so it must be freed after use.
+
+X509v3_add_extensions() adds the list of extensions I<exts> to STACK I<*target>.
+The STACK I<*target> is returned unchanged if I<exts> 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()
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.
L<X509V3_get_d2i(3)>
+=head1 HISTORY
+
+X509v3_add_extensions() was added in OpenSSL 3.4.
+
=head1 COPYRIGHT
Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
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);
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: