1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: x509_lib.c,v 1.4 2022/07/24 21:41:29 tb Exp $ */
28edacedfSDaniel Fojt /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
38edacedfSDaniel Fojt * project 1999.
48edacedfSDaniel Fojt */
58edacedfSDaniel Fojt /* ====================================================================
68edacedfSDaniel Fojt * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
78edacedfSDaniel Fojt *
88edacedfSDaniel Fojt * Redistribution and use in source and binary forms, with or without
98edacedfSDaniel Fojt * modification, are permitted provided that the following conditions
108edacedfSDaniel Fojt * are met:
118edacedfSDaniel Fojt *
128edacedfSDaniel Fojt * 1. Redistributions of source code must retain the above copyright
138edacedfSDaniel Fojt * notice, this list of conditions and the following disclaimer.
148edacedfSDaniel Fojt *
158edacedfSDaniel Fojt * 2. Redistributions in binary form must reproduce the above copyright
168edacedfSDaniel Fojt * notice, this list of conditions and the following disclaimer in
178edacedfSDaniel Fojt * the documentation and/or other materials provided with the
188edacedfSDaniel Fojt * distribution.
198edacedfSDaniel Fojt *
208edacedfSDaniel Fojt * 3. All advertising materials mentioning features or use of this
218edacedfSDaniel Fojt * software must display the following acknowledgment:
228edacedfSDaniel Fojt * "This product includes software developed by the OpenSSL Project
238edacedfSDaniel Fojt * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
248edacedfSDaniel Fojt *
258edacedfSDaniel Fojt * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
268edacedfSDaniel Fojt * endorse or promote products derived from this software without
278edacedfSDaniel Fojt * prior written permission. For written permission, please contact
288edacedfSDaniel Fojt * licensing@OpenSSL.org.
298edacedfSDaniel Fojt *
308edacedfSDaniel Fojt * 5. Products derived from this software may not be called "OpenSSL"
318edacedfSDaniel Fojt * nor may "OpenSSL" appear in their names without prior written
328edacedfSDaniel Fojt * permission of the OpenSSL Project.
338edacedfSDaniel Fojt *
348edacedfSDaniel Fojt * 6. Redistributions of any form whatsoever must retain the following
358edacedfSDaniel Fojt * acknowledgment:
368edacedfSDaniel Fojt * "This product includes software developed by the OpenSSL Project
378edacedfSDaniel Fojt * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
388edacedfSDaniel Fojt *
398edacedfSDaniel Fojt * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
408edacedfSDaniel Fojt * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
418edacedfSDaniel Fojt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
428edacedfSDaniel Fojt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
438edacedfSDaniel Fojt * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
448edacedfSDaniel Fojt * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
458edacedfSDaniel Fojt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
468edacedfSDaniel Fojt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
478edacedfSDaniel Fojt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
488edacedfSDaniel Fojt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
498edacedfSDaniel Fojt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
508edacedfSDaniel Fojt * OF THE POSSIBILITY OF SUCH DAMAGE.
518edacedfSDaniel Fojt * ====================================================================
528edacedfSDaniel Fojt *
538edacedfSDaniel Fojt * This product includes cryptographic software written by Eric Young
548edacedfSDaniel Fojt * (eay@cryptsoft.com). This product includes software written by Tim
558edacedfSDaniel Fojt * Hudson (tjh@cryptsoft.com).
568edacedfSDaniel Fojt *
578edacedfSDaniel Fojt */
588edacedfSDaniel Fojt /* X509 v3 extension utilities */
598edacedfSDaniel Fojt
608edacedfSDaniel Fojt #include <stdio.h>
618edacedfSDaniel Fojt
628edacedfSDaniel Fojt #include <openssl/conf.h>
638edacedfSDaniel Fojt #include <openssl/err.h>
648edacedfSDaniel Fojt #include <openssl/x509v3.h>
658edacedfSDaniel Fojt
668edacedfSDaniel Fojt #include "ext_dat.h"
67*de0e0e4dSAntonio Huete Jimenez #include "x509_lcl.h"
688edacedfSDaniel Fojt
698edacedfSDaniel Fojt static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
708edacedfSDaniel Fojt
718edacedfSDaniel Fojt static int ext_cmp(const X509V3_EXT_METHOD * const *a,
728edacedfSDaniel Fojt const X509V3_EXT_METHOD * const *b);
738edacedfSDaniel Fojt static void ext_list_free(X509V3_EXT_METHOD *ext);
748edacedfSDaniel Fojt
758edacedfSDaniel Fojt int
X509V3_EXT_add(X509V3_EXT_METHOD * ext)768edacedfSDaniel Fojt X509V3_EXT_add(X509V3_EXT_METHOD *ext)
778edacedfSDaniel Fojt {
788edacedfSDaniel Fojt if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
798edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
808edacedfSDaniel Fojt return 0;
818edacedfSDaniel Fojt }
828edacedfSDaniel Fojt if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
838edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
848edacedfSDaniel Fojt return 0;
858edacedfSDaniel Fojt }
868edacedfSDaniel Fojt return 1;
878edacedfSDaniel Fojt }
888edacedfSDaniel Fojt
898edacedfSDaniel Fojt static int
ext_cmp(const X509V3_EXT_METHOD * const * a,const X509V3_EXT_METHOD * const * b)908edacedfSDaniel Fojt ext_cmp(const X509V3_EXT_METHOD * const *a, const X509V3_EXT_METHOD * const *b)
918edacedfSDaniel Fojt {
928edacedfSDaniel Fojt return ((*a)->ext_nid - (*b)->ext_nid);
938edacedfSDaniel Fojt }
948edacedfSDaniel Fojt
958edacedfSDaniel Fojt static int ext_cmp_BSEARCH_CMP_FN(const void *, const void *);
968edacedfSDaniel Fojt static int ext_cmp(const X509V3_EXT_METHOD * const *, const X509V3_EXT_METHOD * const *);
978edacedfSDaniel Fojt static const X509V3_EXT_METHOD * *OBJ_bsearch_ext(const X509V3_EXT_METHOD * *key, const X509V3_EXT_METHOD * const *base, int num);
988edacedfSDaniel Fojt
998edacedfSDaniel Fojt static int
ext_cmp_BSEARCH_CMP_FN(const void * a_,const void * b_)1008edacedfSDaniel Fojt ext_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
1018edacedfSDaniel Fojt {
1028edacedfSDaniel Fojt const X509V3_EXT_METHOD * const *a = a_;
1038edacedfSDaniel Fojt const X509V3_EXT_METHOD * const *b = b_;
1048edacedfSDaniel Fojt return ext_cmp(a, b);
1058edacedfSDaniel Fojt }
1068edacedfSDaniel Fojt
1078edacedfSDaniel Fojt static const X509V3_EXT_METHOD **
OBJ_bsearch_ext(const X509V3_EXT_METHOD ** key,const X509V3_EXT_METHOD * const * base,int num)1088edacedfSDaniel Fojt OBJ_bsearch_ext(const X509V3_EXT_METHOD **key,
1098edacedfSDaniel Fojt const X509V3_EXT_METHOD *const *base, int num)
1108edacedfSDaniel Fojt {
1118edacedfSDaniel Fojt return (const X509V3_EXT_METHOD **)OBJ_bsearch_(key, base, num,
1128edacedfSDaniel Fojt sizeof(const X509V3_EXT_METHOD *), ext_cmp_BSEARCH_CMP_FN);
1138edacedfSDaniel Fojt }
1148edacedfSDaniel Fojt
1158edacedfSDaniel Fojt const X509V3_EXT_METHOD *
X509V3_EXT_get_nid(int nid)1168edacedfSDaniel Fojt X509V3_EXT_get_nid(int nid)
1178edacedfSDaniel Fojt {
1188edacedfSDaniel Fojt X509V3_EXT_METHOD tmp;
1198edacedfSDaniel Fojt const X509V3_EXT_METHOD *t = &tmp, * const *ret;
1208edacedfSDaniel Fojt int idx;
1218edacedfSDaniel Fojt
1228edacedfSDaniel Fojt if (nid < 0)
1238edacedfSDaniel Fojt return NULL;
1248edacedfSDaniel Fojt tmp.ext_nid = nid;
1258edacedfSDaniel Fojt ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
1268edacedfSDaniel Fojt if (ret)
1278edacedfSDaniel Fojt return *ret;
1288edacedfSDaniel Fojt if (!ext_list)
1298edacedfSDaniel Fojt return NULL;
1308edacedfSDaniel Fojt idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
1318edacedfSDaniel Fojt if (idx == -1)
1328edacedfSDaniel Fojt return NULL;
1338edacedfSDaniel Fojt return sk_X509V3_EXT_METHOD_value(ext_list, idx);
1348edacedfSDaniel Fojt }
1358edacedfSDaniel Fojt
1368edacedfSDaniel Fojt const X509V3_EXT_METHOD *
X509V3_EXT_get(X509_EXTENSION * ext)1378edacedfSDaniel Fojt X509V3_EXT_get(X509_EXTENSION *ext)
1388edacedfSDaniel Fojt {
1398edacedfSDaniel Fojt int nid;
1408edacedfSDaniel Fojt
1418edacedfSDaniel Fojt if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
1428edacedfSDaniel Fojt return NULL;
1438edacedfSDaniel Fojt return X509V3_EXT_get_nid(nid);
1448edacedfSDaniel Fojt }
1458edacedfSDaniel Fojt
1468edacedfSDaniel Fojt int
X509V3_EXT_add_list(X509V3_EXT_METHOD * extlist)1478edacedfSDaniel Fojt X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
1488edacedfSDaniel Fojt {
1498edacedfSDaniel Fojt for (; extlist->ext_nid!=-1; extlist++)
1508edacedfSDaniel Fojt if (!X509V3_EXT_add(extlist))
1518edacedfSDaniel Fojt return 0;
1528edacedfSDaniel Fojt return 1;
1538edacedfSDaniel Fojt }
1548edacedfSDaniel Fojt
1558edacedfSDaniel Fojt int
X509V3_EXT_add_alias(int nid_to,int nid_from)1568edacedfSDaniel Fojt X509V3_EXT_add_alias(int nid_to, int nid_from)
1578edacedfSDaniel Fojt {
1588edacedfSDaniel Fojt const X509V3_EXT_METHOD *ext;
1598edacedfSDaniel Fojt X509V3_EXT_METHOD *tmpext;
1608edacedfSDaniel Fojt
1618edacedfSDaniel Fojt if (!(ext = X509V3_EXT_get_nid(nid_from))) {
1628edacedfSDaniel Fojt X509V3error(X509V3_R_EXTENSION_NOT_FOUND);
1638edacedfSDaniel Fojt return 0;
1648edacedfSDaniel Fojt }
1658edacedfSDaniel Fojt if (!(tmpext = malloc(sizeof(X509V3_EXT_METHOD)))) {
1668edacedfSDaniel Fojt X509V3error(ERR_R_MALLOC_FAILURE);
1678edacedfSDaniel Fojt return 0;
1688edacedfSDaniel Fojt }
1698edacedfSDaniel Fojt *tmpext = *ext;
1708edacedfSDaniel Fojt tmpext->ext_nid = nid_to;
1718edacedfSDaniel Fojt tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
1728edacedfSDaniel Fojt if (!X509V3_EXT_add(tmpext)) {
1738edacedfSDaniel Fojt free(tmpext);
1748edacedfSDaniel Fojt return 0;
1758edacedfSDaniel Fojt }
1768edacedfSDaniel Fojt return 1;
1778edacedfSDaniel Fojt }
1788edacedfSDaniel Fojt
1798edacedfSDaniel Fojt void
X509V3_EXT_cleanup(void)1808edacedfSDaniel Fojt X509V3_EXT_cleanup(void)
1818edacedfSDaniel Fojt {
1828edacedfSDaniel Fojt sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
1838edacedfSDaniel Fojt ext_list = NULL;
1848edacedfSDaniel Fojt }
1858edacedfSDaniel Fojt
1868edacedfSDaniel Fojt static void
ext_list_free(X509V3_EXT_METHOD * ext)1878edacedfSDaniel Fojt ext_list_free(X509V3_EXT_METHOD *ext)
1888edacedfSDaniel Fojt {
1898edacedfSDaniel Fojt if (ext->ext_flags & X509V3_EXT_DYNAMIC)
1908edacedfSDaniel Fojt free(ext);
1918edacedfSDaniel Fojt }
1928edacedfSDaniel Fojt
1938edacedfSDaniel Fojt /* Legacy function: we don't need to add standard extensions
1948edacedfSDaniel Fojt * any more because they are now kept in ext_dat.h.
1958edacedfSDaniel Fojt */
1968edacedfSDaniel Fojt
1978edacedfSDaniel Fojt int
X509V3_add_standard_extensions(void)1988edacedfSDaniel Fojt X509V3_add_standard_extensions(void)
1998edacedfSDaniel Fojt {
2008edacedfSDaniel Fojt return 1;
2018edacedfSDaniel Fojt }
2028edacedfSDaniel Fojt
2038edacedfSDaniel Fojt /* Return an extension internal structure */
2048edacedfSDaniel Fojt
2058edacedfSDaniel Fojt void *
X509V3_EXT_d2i(X509_EXTENSION * ext)2068edacedfSDaniel Fojt X509V3_EXT_d2i(X509_EXTENSION *ext)
2078edacedfSDaniel Fojt {
2088edacedfSDaniel Fojt const X509V3_EXT_METHOD *method;
2098edacedfSDaniel Fojt const unsigned char *p;
2108edacedfSDaniel Fojt
2118edacedfSDaniel Fojt if (!(method = X509V3_EXT_get(ext)))
2128edacedfSDaniel Fojt return NULL;
2138edacedfSDaniel Fojt p = ext->value->data;
2148edacedfSDaniel Fojt if (method->it)
2158edacedfSDaniel Fojt return ASN1_item_d2i(NULL, &p, ext->value->length,
2168edacedfSDaniel Fojt method->it);
2178edacedfSDaniel Fojt return method->d2i(NULL, &p, ext->value->length);
2188edacedfSDaniel Fojt }
2198edacedfSDaniel Fojt
2208edacedfSDaniel Fojt /* Get critical flag and decoded version of extension from a NID.
2218edacedfSDaniel Fojt * The "idx" variable returns the last found extension and can
2228edacedfSDaniel Fojt * be used to retrieve multiple extensions of the same NID.
2238edacedfSDaniel Fojt * However multiple extensions with the same NID is usually
2248edacedfSDaniel Fojt * due to a badly encoded certificate so if idx is NULL we
2258edacedfSDaniel Fojt * choke if multiple extensions exist.
2268edacedfSDaniel Fojt * The "crit" variable is set to the critical value.
2278edacedfSDaniel Fojt * The return value is the decoded extension or NULL on
2288edacedfSDaniel Fojt * error. The actual error can have several different causes,
2298edacedfSDaniel Fojt * the value of *crit reflects the cause:
2308edacedfSDaniel Fojt * >= 0, extension found but not decoded (reflects critical value).
2318edacedfSDaniel Fojt * -1 extension not found.
2328edacedfSDaniel Fojt * -2 extension occurs more than once.
2338edacedfSDaniel Fojt */
2348edacedfSDaniel Fojt
2358edacedfSDaniel Fojt void *
X509V3_get_d2i(const STACK_OF (X509_EXTENSION)* x,int nid,int * crit,int * idx)2368edacedfSDaniel Fojt X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx)
2378edacedfSDaniel Fojt {
2388edacedfSDaniel Fojt int lastpos, i;
2398edacedfSDaniel Fojt X509_EXTENSION *ex, *found_ex = NULL;
2408edacedfSDaniel Fojt
2418edacedfSDaniel Fojt if (!x) {
2428edacedfSDaniel Fojt if (idx)
2438edacedfSDaniel Fojt *idx = -1;
2448edacedfSDaniel Fojt if (crit)
2458edacedfSDaniel Fojt *crit = -1;
2468edacedfSDaniel Fojt return NULL;
2478edacedfSDaniel Fojt }
2488edacedfSDaniel Fojt if (idx)
2498edacedfSDaniel Fojt lastpos = *idx + 1;
2508edacedfSDaniel Fojt else
2518edacedfSDaniel Fojt lastpos = 0;
2528edacedfSDaniel Fojt if (lastpos < 0)
2538edacedfSDaniel Fojt lastpos = 0;
2548edacedfSDaniel Fojt for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
2558edacedfSDaniel Fojt ex = sk_X509_EXTENSION_value(x, i);
2568edacedfSDaniel Fojt if (OBJ_obj2nid(ex->object) == nid) {
2578edacedfSDaniel Fojt if (idx) {
2588edacedfSDaniel Fojt *idx = i;
2598edacedfSDaniel Fojt found_ex = ex;
2608edacedfSDaniel Fojt break;
2618edacedfSDaniel Fojt } else if (found_ex) {
2628edacedfSDaniel Fojt /* Found more than one */
2638edacedfSDaniel Fojt if (crit)
2648edacedfSDaniel Fojt *crit = -2;
2658edacedfSDaniel Fojt return NULL;
2668edacedfSDaniel Fojt }
2678edacedfSDaniel Fojt found_ex = ex;
2688edacedfSDaniel Fojt }
2698edacedfSDaniel Fojt }
2708edacedfSDaniel Fojt if (found_ex) {
2718edacedfSDaniel Fojt /* Found it */
2728edacedfSDaniel Fojt if (crit)
2738edacedfSDaniel Fojt *crit = X509_EXTENSION_get_critical(found_ex);
2748edacedfSDaniel Fojt return X509V3_EXT_d2i(found_ex);
2758edacedfSDaniel Fojt }
2768edacedfSDaniel Fojt
2778edacedfSDaniel Fojt /* Extension not found */
2788edacedfSDaniel Fojt if (idx)
2798edacedfSDaniel Fojt *idx = -1;
2808edacedfSDaniel Fojt if (crit)
2818edacedfSDaniel Fojt *crit = -1;
2828edacedfSDaniel Fojt return NULL;
2838edacedfSDaniel Fojt }
2848edacedfSDaniel Fojt
2858edacedfSDaniel Fojt /* This function is a general extension append, replace and delete utility.
2868edacedfSDaniel Fojt * The precise operation is governed by the 'flags' value. The 'crit' and
2878edacedfSDaniel Fojt * 'value' arguments (if relevant) are the extensions internal structure.
2888edacedfSDaniel Fojt */
2898edacedfSDaniel Fojt
2908edacedfSDaniel Fojt int
X509V3_add1_i2d(STACK_OF (X509_EXTENSION)** x,int nid,void * value,int crit,unsigned long flags)2918edacedfSDaniel Fojt X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
2928edacedfSDaniel Fojt int crit, unsigned long flags)
2938edacedfSDaniel Fojt {
2948edacedfSDaniel Fojt int extidx = -1;
2958edacedfSDaniel Fojt int errcode;
2968edacedfSDaniel Fojt X509_EXTENSION *ext, *extmp;
2978edacedfSDaniel Fojt unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
2988edacedfSDaniel Fojt
2998edacedfSDaniel Fojt /* If appending we don't care if it exists, otherwise
3008edacedfSDaniel Fojt * look for existing extension.
3018edacedfSDaniel Fojt */
3028edacedfSDaniel Fojt if (ext_op != X509V3_ADD_APPEND)
3038edacedfSDaniel Fojt extidx = X509v3_get_ext_by_NID(*x, nid, -1);
3048edacedfSDaniel Fojt
3058edacedfSDaniel Fojt /* See if extension exists */
3068edacedfSDaniel Fojt if (extidx >= 0) {
3078edacedfSDaniel Fojt /* If keep existing, nothing to do */
3088edacedfSDaniel Fojt if (ext_op == X509V3_ADD_KEEP_EXISTING)
3098edacedfSDaniel Fojt return 1;
3108edacedfSDaniel Fojt /* If default then its an error */
3118edacedfSDaniel Fojt if (ext_op == X509V3_ADD_DEFAULT) {
3128edacedfSDaniel Fojt errcode = X509V3_R_EXTENSION_EXISTS;
3138edacedfSDaniel Fojt goto err;
3148edacedfSDaniel Fojt }
3158edacedfSDaniel Fojt /* If delete, just delete it */
3168edacedfSDaniel Fojt if (ext_op == X509V3_ADD_DELETE) {
317*de0e0e4dSAntonio Huete Jimenez if ((extmp = sk_X509_EXTENSION_delete(*x, extidx)) == NULL)
3188edacedfSDaniel Fojt return -1;
319*de0e0e4dSAntonio Huete Jimenez X509_EXTENSION_free(extmp);
3208edacedfSDaniel Fojt return 1;
3218edacedfSDaniel Fojt }
3228edacedfSDaniel Fojt } else {
3238edacedfSDaniel Fojt /* If replace existing or delete, error since
3248edacedfSDaniel Fojt * extension must exist
3258edacedfSDaniel Fojt */
3268edacedfSDaniel Fojt if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
3278edacedfSDaniel Fojt (ext_op == X509V3_ADD_DELETE)) {
3288edacedfSDaniel Fojt errcode = X509V3_R_EXTENSION_NOT_FOUND;
3298edacedfSDaniel Fojt goto err;
3308edacedfSDaniel Fojt }
3318edacedfSDaniel Fojt }
3328edacedfSDaniel Fojt
3338edacedfSDaniel Fojt /* If we get this far then we have to create an extension:
3348edacedfSDaniel Fojt * could have some flags for alternative encoding schemes...
3358edacedfSDaniel Fojt */
3368edacedfSDaniel Fojt
3378edacedfSDaniel Fojt ext = X509V3_EXT_i2d(nid, crit, value);
3388edacedfSDaniel Fojt
3398edacedfSDaniel Fojt if (!ext) {
3408edacedfSDaniel Fojt X509V3error(X509V3_R_ERROR_CREATING_EXTENSION);
3418edacedfSDaniel Fojt return 0;
3428edacedfSDaniel Fojt }
3438edacedfSDaniel Fojt
3448edacedfSDaniel Fojt /* If extension exists replace it.. */
3458edacedfSDaniel Fojt if (extidx >= 0) {
3468edacedfSDaniel Fojt extmp = sk_X509_EXTENSION_value(*x, extidx);
3478edacedfSDaniel Fojt X509_EXTENSION_free(extmp);
3488edacedfSDaniel Fojt if (!sk_X509_EXTENSION_set(*x, extidx, ext))
3498edacedfSDaniel Fojt return -1;
3508edacedfSDaniel Fojt return 1;
3518edacedfSDaniel Fojt }
3528edacedfSDaniel Fojt
3538edacedfSDaniel Fojt if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
3548edacedfSDaniel Fojt return -1;
3558edacedfSDaniel Fojt if (!sk_X509_EXTENSION_push(*x, ext))
3568edacedfSDaniel Fojt return -1;
3578edacedfSDaniel Fojt
3588edacedfSDaniel Fojt return 1;
3598edacedfSDaniel Fojt
3608edacedfSDaniel Fojt err:
3618edacedfSDaniel Fojt if (!(flags & X509V3_ADD_SILENT))
3628edacedfSDaniel Fojt X509V3error(errcode);
3638edacedfSDaniel Fojt return 0;
3648edacedfSDaniel Fojt }
365