xref: /third_party/openssl/crypto/x509/v3_conf.c (revision e1051a39)
1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/* extension creation utilities */
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ci#include <stdio.h>
13e1051a39Sopenharmony_ci#include "crypto/ctype.h"
14e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
15e1051a39Sopenharmony_ci#include <openssl/conf.h>
16e1051a39Sopenharmony_ci#include <openssl/x509.h>
17e1051a39Sopenharmony_ci#include "crypto/x509.h"
18e1051a39Sopenharmony_ci#include <openssl/x509v3.h>
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_cistatic int v3_check_critical(const char **value);
21e1051a39Sopenharmony_cistatic int v3_check_generic(const char **value);
22e1051a39Sopenharmony_cistatic X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
23e1051a39Sopenharmony_ci                                    int crit, const char *value);
24e1051a39Sopenharmony_cistatic X509_EXTENSION *v3_generic_extension(const char *ext, const char *value,
25e1051a39Sopenharmony_ci                                            int crit, int type,
26e1051a39Sopenharmony_ci                                            X509V3_CTX *ctx);
27e1051a39Sopenharmony_cistatic char *conf_lhash_get_string(void *db, const char *section, const char *value);
28e1051a39Sopenharmony_cistatic STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, const char *section);
29e1051a39Sopenharmony_cistatic X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
30e1051a39Sopenharmony_ci                                  int ext_nid, int crit, void *ext_struc);
31e1051a39Sopenharmony_cistatic unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx,
32e1051a39Sopenharmony_ci                                   long *ext_len);
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_cistatic X509_EXTENSION *X509V3_EXT_nconf_int(CONF *conf, X509V3_CTX *ctx,
35e1051a39Sopenharmony_ci                                            const char *section,
36e1051a39Sopenharmony_ci                                            const char *name, const char *value)
37e1051a39Sopenharmony_ci{
38e1051a39Sopenharmony_ci    int crit;
39e1051a39Sopenharmony_ci    int ext_type;
40e1051a39Sopenharmony_ci    X509_EXTENSION *ret;
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_ci    crit = v3_check_critical(&value);
43e1051a39Sopenharmony_ci    if ((ext_type = v3_check_generic(&value)))
44e1051a39Sopenharmony_ci        return v3_generic_extension(name, value, crit, ext_type, ctx);
45e1051a39Sopenharmony_ci    ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
46e1051a39Sopenharmony_ci    if (!ret) {
47e1051a39Sopenharmony_ci        if (section != NULL)
48e1051a39Sopenharmony_ci            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION,
49e1051a39Sopenharmony_ci                           "section=%s, name=%s, value=%s",
50e1051a39Sopenharmony_ci                           section, name, value);
51e1051a39Sopenharmony_ci        else
52e1051a39Sopenharmony_ci            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION,
53e1051a39Sopenharmony_ci                           "name=%s, value=%s", name, value);
54e1051a39Sopenharmony_ci    }
55e1051a39Sopenharmony_ci    return ret;
56e1051a39Sopenharmony_ci}
57e1051a39Sopenharmony_ci
58e1051a39Sopenharmony_ciX509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name,
59e1051a39Sopenharmony_ci                                 const char *value)
60e1051a39Sopenharmony_ci{
61e1051a39Sopenharmony_ci    return X509V3_EXT_nconf_int(conf, ctx, NULL, name, value);
62e1051a39Sopenharmony_ci}
63e1051a39Sopenharmony_ci
64e1051a39Sopenharmony_ciX509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
65e1051a39Sopenharmony_ci                                     const char *value)
66e1051a39Sopenharmony_ci{
67e1051a39Sopenharmony_ci    int crit;
68e1051a39Sopenharmony_ci    int ext_type;
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_ci    crit = v3_check_critical(&value);
71e1051a39Sopenharmony_ci    if ((ext_type = v3_check_generic(&value)))
72e1051a39Sopenharmony_ci        return v3_generic_extension(OBJ_nid2sn(ext_nid),
73e1051a39Sopenharmony_ci                                    value, crit, ext_type, ctx);
74e1051a39Sopenharmony_ci    return do_ext_nconf(conf, ctx, ext_nid, crit, value);
75e1051a39Sopenharmony_ci}
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci/* CONF *conf:  Config file    */
78e1051a39Sopenharmony_ci/* char *value:  Value    */
79e1051a39Sopenharmony_cistatic X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
80e1051a39Sopenharmony_ci                                    int crit, const char *value)
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    const X509V3_EXT_METHOD *method;
83e1051a39Sopenharmony_ci    X509_EXTENSION *ext;
84e1051a39Sopenharmony_ci    STACK_OF(CONF_VALUE) *nval;
85e1051a39Sopenharmony_ci    void *ext_struc;
86e1051a39Sopenharmony_ci
87e1051a39Sopenharmony_ci    if (ext_nid == NID_undef) {
88e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
89e1051a39Sopenharmony_ci        return NULL;
90e1051a39Sopenharmony_ci    }
91e1051a39Sopenharmony_ci    if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) {
92e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION);
93e1051a39Sopenharmony_ci        return NULL;
94e1051a39Sopenharmony_ci    }
95e1051a39Sopenharmony_ci    /* Now get internal extension representation based on type */
96e1051a39Sopenharmony_ci    if (method->v2i) {
97e1051a39Sopenharmony_ci        if (*value == '@')
98e1051a39Sopenharmony_ci            nval = NCONF_get_section(conf, value + 1);
99e1051a39Sopenharmony_ci        else
100e1051a39Sopenharmony_ci            nval = X509V3_parse_list(value);
101e1051a39Sopenharmony_ci        if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) {
102e1051a39Sopenharmony_ci            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_EXTENSION_STRING,
103e1051a39Sopenharmony_ci                           "name=%s,section=%s", OBJ_nid2sn(ext_nid), value);
104e1051a39Sopenharmony_ci            if (*value != '@')
105e1051a39Sopenharmony_ci                sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
106e1051a39Sopenharmony_ci            return NULL;
107e1051a39Sopenharmony_ci        }
108e1051a39Sopenharmony_ci        ext_struc = method->v2i(method, ctx, nval);
109e1051a39Sopenharmony_ci        if (*value != '@')
110e1051a39Sopenharmony_ci            sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
111e1051a39Sopenharmony_ci        if (!ext_struc)
112e1051a39Sopenharmony_ci            return NULL;
113e1051a39Sopenharmony_ci    } else if (method->s2i) {
114e1051a39Sopenharmony_ci        if ((ext_struc = method->s2i(method, ctx, value)) == NULL)
115e1051a39Sopenharmony_ci            return NULL;
116e1051a39Sopenharmony_ci    } else if (method->r2i) {
117e1051a39Sopenharmony_ci        if (!ctx->db || !ctx->db_meth) {
118e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_CONFIG_DATABASE);
119e1051a39Sopenharmony_ci            return NULL;
120e1051a39Sopenharmony_ci        }
121e1051a39Sopenharmony_ci        if ((ext_struc = method->r2i(method, ctx, value)) == NULL)
122e1051a39Sopenharmony_ci            return NULL;
123e1051a39Sopenharmony_ci    } else {
124e1051a39Sopenharmony_ci        ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED,
125e1051a39Sopenharmony_ci                       "name=%s", OBJ_nid2sn(ext_nid));
126e1051a39Sopenharmony_ci        return NULL;
127e1051a39Sopenharmony_ci    }
128e1051a39Sopenharmony_ci
129e1051a39Sopenharmony_ci    ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
130e1051a39Sopenharmony_ci    if (method->it)
131e1051a39Sopenharmony_ci        ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
132e1051a39Sopenharmony_ci    else
133e1051a39Sopenharmony_ci        method->ext_free(ext_struc);
134e1051a39Sopenharmony_ci    return ext;
135e1051a39Sopenharmony_ci
136e1051a39Sopenharmony_ci}
137e1051a39Sopenharmony_ci
138e1051a39Sopenharmony_cistatic X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
139e1051a39Sopenharmony_ci                                  int ext_nid, int crit, void *ext_struc)
140e1051a39Sopenharmony_ci{
141e1051a39Sopenharmony_ci    unsigned char *ext_der = NULL;
142e1051a39Sopenharmony_ci    int ext_len;
143e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *ext_oct = NULL;
144e1051a39Sopenharmony_ci    X509_EXTENSION *ext;
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_ci    /* Convert internal representation to DER */
147e1051a39Sopenharmony_ci    if (method->it) {
148e1051a39Sopenharmony_ci        ext_der = NULL;
149e1051a39Sopenharmony_ci        ext_len =
150e1051a39Sopenharmony_ci            ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
151e1051a39Sopenharmony_ci        if (ext_len < 0)
152e1051a39Sopenharmony_ci            goto merr;
153e1051a39Sopenharmony_ci    } else {
154e1051a39Sopenharmony_ci        unsigned char *p;
155e1051a39Sopenharmony_ci
156e1051a39Sopenharmony_ci        ext_len = method->i2d(ext_struc, NULL);
157e1051a39Sopenharmony_ci        if (ext_len <= 0)
158e1051a39Sopenharmony_ci            goto merr;
159e1051a39Sopenharmony_ci        if ((ext_der = OPENSSL_malloc(ext_len)) == NULL)
160e1051a39Sopenharmony_ci            goto merr;
161e1051a39Sopenharmony_ci        p = ext_der;
162e1051a39Sopenharmony_ci        method->i2d(ext_struc, &p);
163e1051a39Sopenharmony_ci    }
164e1051a39Sopenharmony_ci    if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL)
165e1051a39Sopenharmony_ci        goto merr;
166e1051a39Sopenharmony_ci    ext_oct->data = ext_der;
167e1051a39Sopenharmony_ci    ext_der = NULL;
168e1051a39Sopenharmony_ci    ext_oct->length = ext_len;
169e1051a39Sopenharmony_ci
170e1051a39Sopenharmony_ci    ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
171e1051a39Sopenharmony_ci    if (!ext)
172e1051a39Sopenharmony_ci        goto merr;
173e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(ext_oct);
174e1051a39Sopenharmony_ci
175e1051a39Sopenharmony_ci    return ext;
176e1051a39Sopenharmony_ci
177e1051a39Sopenharmony_ci merr:
178e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
179e1051a39Sopenharmony_ci    OPENSSL_free(ext_der);
180e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(ext_oct);
181e1051a39Sopenharmony_ci    return NULL;
182e1051a39Sopenharmony_ci
183e1051a39Sopenharmony_ci}
184e1051a39Sopenharmony_ci
185e1051a39Sopenharmony_ci/* Given an internal structure, nid and critical flag create an extension */
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_ciX509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
188e1051a39Sopenharmony_ci{
189e1051a39Sopenharmony_ci    const X509V3_EXT_METHOD *method;
190e1051a39Sopenharmony_ci
191e1051a39Sopenharmony_ci    if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) {
192e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION);
193e1051a39Sopenharmony_ci        return NULL;
194e1051a39Sopenharmony_ci    }
195e1051a39Sopenharmony_ci    return do_ext_i2d(method, ext_nid, crit, ext_struc);
196e1051a39Sopenharmony_ci}
197e1051a39Sopenharmony_ci
198e1051a39Sopenharmony_ci/* Check the extension string for critical flag */
199e1051a39Sopenharmony_cistatic int v3_check_critical(const char **value)
200e1051a39Sopenharmony_ci{
201e1051a39Sopenharmony_ci    const char *p = *value;
202e1051a39Sopenharmony_ci
203e1051a39Sopenharmony_ci    if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
204e1051a39Sopenharmony_ci        return 0;
205e1051a39Sopenharmony_ci    p += 9;
206e1051a39Sopenharmony_ci    while (ossl_isspace(*p))
207e1051a39Sopenharmony_ci        p++;
208e1051a39Sopenharmony_ci    *value = p;
209e1051a39Sopenharmony_ci    return 1;
210e1051a39Sopenharmony_ci}
211e1051a39Sopenharmony_ci
212e1051a39Sopenharmony_ci/* Check extension string for generic extension and return the type */
213e1051a39Sopenharmony_cistatic int v3_check_generic(const char **value)
214e1051a39Sopenharmony_ci{
215e1051a39Sopenharmony_ci    int gen_type = 0;
216e1051a39Sopenharmony_ci    const char *p = *value;
217e1051a39Sopenharmony_ci
218e1051a39Sopenharmony_ci    if ((strlen(p) >= 4) && strncmp(p, "DER:", 4) == 0) {
219e1051a39Sopenharmony_ci        p += 4;
220e1051a39Sopenharmony_ci        gen_type = 1;
221e1051a39Sopenharmony_ci    } else if ((strlen(p) >= 5) && strncmp(p, "ASN1:", 5) == 0) {
222e1051a39Sopenharmony_ci        p += 5;
223e1051a39Sopenharmony_ci        gen_type = 2;
224e1051a39Sopenharmony_ci    } else
225e1051a39Sopenharmony_ci        return 0;
226e1051a39Sopenharmony_ci
227e1051a39Sopenharmony_ci    while (ossl_isspace(*p))
228e1051a39Sopenharmony_ci        p++;
229e1051a39Sopenharmony_ci    *value = p;
230e1051a39Sopenharmony_ci    return gen_type;
231e1051a39Sopenharmony_ci}
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ci/* Create a generic extension: for now just handle DER type */
234e1051a39Sopenharmony_cistatic X509_EXTENSION *v3_generic_extension(const char *ext, const char *value,
235e1051a39Sopenharmony_ci                                            int crit, int gen_type,
236e1051a39Sopenharmony_ci                                            X509V3_CTX *ctx)
237e1051a39Sopenharmony_ci{
238e1051a39Sopenharmony_ci    unsigned char *ext_der = NULL;
239e1051a39Sopenharmony_ci    long ext_len = 0;
240e1051a39Sopenharmony_ci    ASN1_OBJECT *obj = NULL;
241e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *oct = NULL;
242e1051a39Sopenharmony_ci    X509_EXTENSION *extension = NULL;
243e1051a39Sopenharmony_ci
244e1051a39Sopenharmony_ci    if ((obj = OBJ_txt2obj(ext, 0)) == NULL) {
245e1051a39Sopenharmony_ci        ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR,
246e1051a39Sopenharmony_ci                       "name=%s", ext);
247e1051a39Sopenharmony_ci        goto err;
248e1051a39Sopenharmony_ci    }
249e1051a39Sopenharmony_ci
250e1051a39Sopenharmony_ci    if (gen_type == 1)
251e1051a39Sopenharmony_ci        ext_der = OPENSSL_hexstr2buf(value, &ext_len);
252e1051a39Sopenharmony_ci    else if (gen_type == 2)
253e1051a39Sopenharmony_ci        ext_der = generic_asn1(value, ctx, &ext_len);
254e1051a39Sopenharmony_ci
255e1051a39Sopenharmony_ci    if (ext_der == NULL) {
256e1051a39Sopenharmony_ci        ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR,
257e1051a39Sopenharmony_ci                       "value=%s", value);
258e1051a39Sopenharmony_ci        goto err;
259e1051a39Sopenharmony_ci    }
260e1051a39Sopenharmony_ci
261e1051a39Sopenharmony_ci    if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
262e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
263e1051a39Sopenharmony_ci        goto err;
264e1051a39Sopenharmony_ci    }
265e1051a39Sopenharmony_ci
266e1051a39Sopenharmony_ci    oct->data = ext_der;
267e1051a39Sopenharmony_ci    oct->length = ext_len;
268e1051a39Sopenharmony_ci    ext_der = NULL;
269e1051a39Sopenharmony_ci
270e1051a39Sopenharmony_ci    extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
271e1051a39Sopenharmony_ci
272e1051a39Sopenharmony_ci err:
273e1051a39Sopenharmony_ci    ASN1_OBJECT_free(obj);
274e1051a39Sopenharmony_ci    ASN1_OCTET_STRING_free(oct);
275e1051a39Sopenharmony_ci    OPENSSL_free(ext_der);
276e1051a39Sopenharmony_ci    return extension;
277e1051a39Sopenharmony_ci
278e1051a39Sopenharmony_ci}
279e1051a39Sopenharmony_ci
280e1051a39Sopenharmony_cistatic unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx,
281e1051a39Sopenharmony_ci                                   long *ext_len)
282e1051a39Sopenharmony_ci{
283e1051a39Sopenharmony_ci    ASN1_TYPE *typ;
284e1051a39Sopenharmony_ci    unsigned char *ext_der = NULL;
285e1051a39Sopenharmony_ci
286e1051a39Sopenharmony_ci    typ = ASN1_generate_v3(value, ctx);
287e1051a39Sopenharmony_ci    if (typ == NULL)
288e1051a39Sopenharmony_ci        return NULL;
289e1051a39Sopenharmony_ci    *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
290e1051a39Sopenharmony_ci    ASN1_TYPE_free(typ);
291e1051a39Sopenharmony_ci    return ext_der;
292e1051a39Sopenharmony_ci}
293e1051a39Sopenharmony_ci
294e1051a39Sopenharmony_cistatic void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext)
295e1051a39Sopenharmony_ci{
296e1051a39Sopenharmony_ci    int idx;
297e1051a39Sopenharmony_ci    ASN1_OBJECT *obj;
298e1051a39Sopenharmony_ci
299e1051a39Sopenharmony_ci    obj = X509_EXTENSION_get_object(dext);
300e1051a39Sopenharmony_ci    while ((idx = X509v3_get_ext_by_OBJ(sk, obj, -1)) >= 0)
301e1051a39Sopenharmony_ci        X509_EXTENSION_free(X509v3_delete_ext(sk, idx));
302e1051a39Sopenharmony_ci}
303e1051a39Sopenharmony_ci
304e1051a39Sopenharmony_ci/*
305e1051a39Sopenharmony_ci * This is the main function: add a bunch of extensions based on a config
306e1051a39Sopenharmony_ci * file section to an extension STACK. Just check in case sk == NULL.
307e1051a39Sopenharmony_ci * Note that on error new elements may have been added to *sk if sk != NULL.
308e1051a39Sopenharmony_ci */
309e1051a39Sopenharmony_ciint X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
310e1051a39Sopenharmony_ci                            STACK_OF(X509_EXTENSION) **sk)
311e1051a39Sopenharmony_ci{
312e1051a39Sopenharmony_ci    X509_EXTENSION *ext;
313e1051a39Sopenharmony_ci    STACK_OF(CONF_VALUE) *nval;
314e1051a39Sopenharmony_ci    CONF_VALUE *val;
315e1051a39Sopenharmony_ci    int i;
316e1051a39Sopenharmony_ci
317e1051a39Sopenharmony_ci    if ((nval = NCONF_get_section(conf, section)) == NULL)
318e1051a39Sopenharmony_ci        return 0;
319e1051a39Sopenharmony_ci    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
320e1051a39Sopenharmony_ci        val = sk_CONF_VALUE_value(nval, i);
321e1051a39Sopenharmony_ci        if ((ext = X509V3_EXT_nconf_int(conf, ctx, val->section,
322e1051a39Sopenharmony_ci                                        val->name, val->value)) == NULL)
323e1051a39Sopenharmony_ci            return 0;
324e1051a39Sopenharmony_ci        if (sk != NULL) {
325e1051a39Sopenharmony_ci            if (ctx->flags == X509V3_CTX_REPLACE)
326e1051a39Sopenharmony_ci                delete_ext(*sk, ext);
327e1051a39Sopenharmony_ci            if (X509v3_add_ext(sk, ext, -1) == NULL) {
328e1051a39Sopenharmony_ci                X509_EXTENSION_free(ext);
329e1051a39Sopenharmony_ci                return 0;
330e1051a39Sopenharmony_ci            }
331e1051a39Sopenharmony_ci        }
332e1051a39Sopenharmony_ci        X509_EXTENSION_free(ext);
333e1051a39Sopenharmony_ci    }
334e1051a39Sopenharmony_ci    return 1;
335e1051a39Sopenharmony_ci}
336e1051a39Sopenharmony_ci
337e1051a39Sopenharmony_ci/*
338e1051a39Sopenharmony_ci * Add extensions to a certificate. Just check in case cert == NULL.
339e1051a39Sopenharmony_ci * Note that on error new elements may remain added to cert if cert != NULL.
340e1051a39Sopenharmony_ci */
341e1051a39Sopenharmony_ciint X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
342e1051a39Sopenharmony_ci                         X509 *cert)
343e1051a39Sopenharmony_ci{
344e1051a39Sopenharmony_ci    STACK_OF(X509_EXTENSION) **sk = NULL;
345e1051a39Sopenharmony_ci    if (cert != NULL)
346e1051a39Sopenharmony_ci        sk = &cert->cert_info.extensions;
347e1051a39Sopenharmony_ci    return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
348e1051a39Sopenharmony_ci}
349e1051a39Sopenharmony_ci
350e1051a39Sopenharmony_ci/*
351e1051a39Sopenharmony_ci * Add extensions to a CRL. Just check in case crl == NULL.
352e1051a39Sopenharmony_ci * Note that on error new elements may remain added to crl if crl != NULL.
353e1051a39Sopenharmony_ci */
354e1051a39Sopenharmony_ciint X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
355e1051a39Sopenharmony_ci                             X509_CRL *crl)
356e1051a39Sopenharmony_ci{
357e1051a39Sopenharmony_ci    STACK_OF(X509_EXTENSION) **sk = NULL;
358e1051a39Sopenharmony_ci    if (crl != NULL)
359e1051a39Sopenharmony_ci        sk = &crl->crl.extensions;
360e1051a39Sopenharmony_ci    return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
361e1051a39Sopenharmony_ci}
362e1051a39Sopenharmony_ci
363e1051a39Sopenharmony_ci/*
364e1051a39Sopenharmony_ci * Add extensions to certificate request. Just check in case req is NULL.
365e1051a39Sopenharmony_ci * Note that on error new elements may remain added to req if req != NULL.
366e1051a39Sopenharmony_ci */
367e1051a39Sopenharmony_ciint X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
368e1051a39Sopenharmony_ci                             X509_REQ *req)
369e1051a39Sopenharmony_ci{
370e1051a39Sopenharmony_ci    STACK_OF(X509_EXTENSION) *exts = NULL;
371e1051a39Sopenharmony_ci    int ret = X509V3_EXT_add_nconf_sk(conf, ctx, section, &exts);
372e1051a39Sopenharmony_ci
373e1051a39Sopenharmony_ci    if (ret && req != NULL && exts != NULL)
374e1051a39Sopenharmony_ci        ret = X509_REQ_add_extensions(req, exts);
375e1051a39Sopenharmony_ci    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
376e1051a39Sopenharmony_ci    return ret;
377e1051a39Sopenharmony_ci}
378e1051a39Sopenharmony_ci
379e1051a39Sopenharmony_ci/* Config database functions */
380e1051a39Sopenharmony_ci
381e1051a39Sopenharmony_cichar *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section)
382e1051a39Sopenharmony_ci{
383e1051a39Sopenharmony_ci    if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) {
384e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED);
385e1051a39Sopenharmony_ci        return NULL;
386e1051a39Sopenharmony_ci    }
387e1051a39Sopenharmony_ci    if (ctx->db_meth->get_string)
388e1051a39Sopenharmony_ci        return ctx->db_meth->get_string(ctx->db, name, section);
389e1051a39Sopenharmony_ci    return NULL;
390e1051a39Sopenharmony_ci}
391e1051a39Sopenharmony_ci
392e1051a39Sopenharmony_ciSTACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section)
393e1051a39Sopenharmony_ci{
394e1051a39Sopenharmony_ci    if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) {
395e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED);
396e1051a39Sopenharmony_ci        return NULL;
397e1051a39Sopenharmony_ci    }
398e1051a39Sopenharmony_ci    if (ctx->db_meth->get_section)
399e1051a39Sopenharmony_ci        return ctx->db_meth->get_section(ctx->db, section);
400e1051a39Sopenharmony_ci    return NULL;
401e1051a39Sopenharmony_ci}
402e1051a39Sopenharmony_ci
403e1051a39Sopenharmony_civoid X509V3_string_free(X509V3_CTX *ctx, char *str)
404e1051a39Sopenharmony_ci{
405e1051a39Sopenharmony_ci    if (!str)
406e1051a39Sopenharmony_ci        return;
407e1051a39Sopenharmony_ci    if (ctx->db_meth->free_string)
408e1051a39Sopenharmony_ci        ctx->db_meth->free_string(ctx->db, str);
409e1051a39Sopenharmony_ci}
410e1051a39Sopenharmony_ci
411e1051a39Sopenharmony_civoid X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
412e1051a39Sopenharmony_ci{
413e1051a39Sopenharmony_ci    if (!section)
414e1051a39Sopenharmony_ci        return;
415e1051a39Sopenharmony_ci    if (ctx->db_meth->free_section)
416e1051a39Sopenharmony_ci        ctx->db_meth->free_section(ctx->db, section);
417e1051a39Sopenharmony_ci}
418e1051a39Sopenharmony_ci
419e1051a39Sopenharmony_cistatic char *nconf_get_string(void *db, const char *section, const char *value)
420e1051a39Sopenharmony_ci{
421e1051a39Sopenharmony_ci    return NCONF_get_string(db, section, value);
422e1051a39Sopenharmony_ci}
423e1051a39Sopenharmony_ci
424e1051a39Sopenharmony_cistatic STACK_OF(CONF_VALUE) *nconf_get_section(void *db, const char *section)
425e1051a39Sopenharmony_ci{
426e1051a39Sopenharmony_ci    return NCONF_get_section(db, section);
427e1051a39Sopenharmony_ci}
428e1051a39Sopenharmony_ci
429e1051a39Sopenharmony_cistatic X509V3_CONF_METHOD nconf_method = {
430e1051a39Sopenharmony_ci    nconf_get_string,
431e1051a39Sopenharmony_ci    nconf_get_section,
432e1051a39Sopenharmony_ci    NULL,
433e1051a39Sopenharmony_ci    NULL
434e1051a39Sopenharmony_ci};
435e1051a39Sopenharmony_ci
436e1051a39Sopenharmony_civoid X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
437e1051a39Sopenharmony_ci{
438e1051a39Sopenharmony_ci    if (ctx == NULL) {
439e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER);
440e1051a39Sopenharmony_ci        return;
441e1051a39Sopenharmony_ci    }
442e1051a39Sopenharmony_ci    ctx->db_meth = &nconf_method;
443e1051a39Sopenharmony_ci    ctx->db = conf;
444e1051a39Sopenharmony_ci}
445e1051a39Sopenharmony_ci
446e1051a39Sopenharmony_civoid X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
447e1051a39Sopenharmony_ci                    X509_CRL *crl, int flags)
448e1051a39Sopenharmony_ci{
449e1051a39Sopenharmony_ci    if (ctx == NULL) {
450e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER);
451e1051a39Sopenharmony_ci        return;
452e1051a39Sopenharmony_ci    }
453e1051a39Sopenharmony_ci    ctx->flags = flags;
454e1051a39Sopenharmony_ci    ctx->issuer_cert = issuer;
455e1051a39Sopenharmony_ci    ctx->subject_cert = subj;
456e1051a39Sopenharmony_ci    ctx->subject_req = req;
457e1051a39Sopenharmony_ci    ctx->crl = crl;
458e1051a39Sopenharmony_ci    ctx->db_meth = NULL;
459e1051a39Sopenharmony_ci    ctx->db = NULL;
460e1051a39Sopenharmony_ci    ctx->issuer_pkey = NULL;
461e1051a39Sopenharmony_ci}
462e1051a39Sopenharmony_ci
463e1051a39Sopenharmony_ci/* For API backward compatibility, this is separate from X509V3_set_ctx() */
464e1051a39Sopenharmony_ciint X509V3_set_issuer_pkey(X509V3_CTX *ctx, EVP_PKEY *pkey)
465e1051a39Sopenharmony_ci{
466e1051a39Sopenharmony_ci    if (ctx == NULL) {
467e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER);
468e1051a39Sopenharmony_ci        return 0;
469e1051a39Sopenharmony_ci    }
470e1051a39Sopenharmony_ci    if (ctx->subject_cert == NULL && pkey != NULL) {
471e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_INVALID_ARGUMENT);
472e1051a39Sopenharmony_ci        return 0;
473e1051a39Sopenharmony_ci    }
474e1051a39Sopenharmony_ci    ctx->issuer_pkey = pkey;
475e1051a39Sopenharmony_ci    return 1;
476e1051a39Sopenharmony_ci}
477e1051a39Sopenharmony_ci
478e1051a39Sopenharmony_ci/* Old conf compatibility functions */
479e1051a39Sopenharmony_ci
480e1051a39Sopenharmony_ciX509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
481e1051a39Sopenharmony_ci                                const char *name, const char *value)
482e1051a39Sopenharmony_ci{
483e1051a39Sopenharmony_ci    CONF *ctmp;
484e1051a39Sopenharmony_ci    X509_EXTENSION *ret;
485e1051a39Sopenharmony_ci
486e1051a39Sopenharmony_ci    if ((ctmp = NCONF_new(NULL)) == NULL)
487e1051a39Sopenharmony_ci        return NULL;
488e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, conf);
489e1051a39Sopenharmony_ci    ret = X509V3_EXT_nconf(ctmp, ctx, name, value);
490e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, NULL);
491e1051a39Sopenharmony_ci    NCONF_free(ctmp);
492e1051a39Sopenharmony_ci    return ret;
493e1051a39Sopenharmony_ci}
494e1051a39Sopenharmony_ci
495e1051a39Sopenharmony_ciX509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
496e1051a39Sopenharmony_ci                                    X509V3_CTX *ctx, int ext_nid, const char *value)
497e1051a39Sopenharmony_ci{
498e1051a39Sopenharmony_ci    CONF *ctmp;
499e1051a39Sopenharmony_ci    X509_EXTENSION *ret;
500e1051a39Sopenharmony_ci
501e1051a39Sopenharmony_ci    if ((ctmp = NCONF_new(NULL)) == NULL)
502e1051a39Sopenharmony_ci        return NULL;
503e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, conf);
504e1051a39Sopenharmony_ci    ret = X509V3_EXT_nconf_nid(ctmp, ctx, ext_nid, value);
505e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, NULL);
506e1051a39Sopenharmony_ci    NCONF_free(ctmp);
507e1051a39Sopenharmony_ci    return ret;
508e1051a39Sopenharmony_ci}
509e1051a39Sopenharmony_ci
510e1051a39Sopenharmony_cistatic char *conf_lhash_get_string(void *db, const char *section, const char *value)
511e1051a39Sopenharmony_ci{
512e1051a39Sopenharmony_ci    return CONF_get_string(db, section, value);
513e1051a39Sopenharmony_ci}
514e1051a39Sopenharmony_ci
515e1051a39Sopenharmony_cistatic STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, const char *section)
516e1051a39Sopenharmony_ci{
517e1051a39Sopenharmony_ci    return CONF_get_section(db, section);
518e1051a39Sopenharmony_ci}
519e1051a39Sopenharmony_ci
520e1051a39Sopenharmony_cistatic X509V3_CONF_METHOD conf_lhash_method = {
521e1051a39Sopenharmony_ci    conf_lhash_get_string,
522e1051a39Sopenharmony_ci    conf_lhash_get_section,
523e1051a39Sopenharmony_ci    NULL,
524e1051a39Sopenharmony_ci    NULL
525e1051a39Sopenharmony_ci};
526e1051a39Sopenharmony_ci
527e1051a39Sopenharmony_civoid X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
528e1051a39Sopenharmony_ci{
529e1051a39Sopenharmony_ci    if (ctx == NULL) {
530e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER);
531e1051a39Sopenharmony_ci        return;
532e1051a39Sopenharmony_ci    }
533e1051a39Sopenharmony_ci    ctx->db_meth = &conf_lhash_method;
534e1051a39Sopenharmony_ci    ctx->db = lhash;
535e1051a39Sopenharmony_ci}
536e1051a39Sopenharmony_ci
537e1051a39Sopenharmony_ciint X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
538e1051a39Sopenharmony_ci                        const char *section, X509 *cert)
539e1051a39Sopenharmony_ci{
540e1051a39Sopenharmony_ci    CONF *ctmp;
541e1051a39Sopenharmony_ci    int ret;
542e1051a39Sopenharmony_ci
543e1051a39Sopenharmony_ci    if ((ctmp = NCONF_new(NULL)) == NULL)
544e1051a39Sopenharmony_ci        return 0;
545e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, conf);
546e1051a39Sopenharmony_ci    ret = X509V3_EXT_add_nconf(ctmp, ctx, section, cert);
547e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, NULL);
548e1051a39Sopenharmony_ci    NCONF_free(ctmp);
549e1051a39Sopenharmony_ci    return ret;
550e1051a39Sopenharmony_ci}
551e1051a39Sopenharmony_ci
552e1051a39Sopenharmony_ci/* Same as above but for a CRL */
553e1051a39Sopenharmony_ci
554e1051a39Sopenharmony_ciint X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
555e1051a39Sopenharmony_ci                            const char *section, X509_CRL *crl)
556e1051a39Sopenharmony_ci{
557e1051a39Sopenharmony_ci    CONF *ctmp;
558e1051a39Sopenharmony_ci    int ret;
559e1051a39Sopenharmony_ci
560e1051a39Sopenharmony_ci    if ((ctmp = NCONF_new(NULL)) == NULL)
561e1051a39Sopenharmony_ci        return 0;
562e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, conf);
563e1051a39Sopenharmony_ci    ret = X509V3_EXT_CRL_add_nconf(ctmp, ctx, section, crl);
564e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, NULL);
565e1051a39Sopenharmony_ci    NCONF_free(ctmp);
566e1051a39Sopenharmony_ci    return ret;
567e1051a39Sopenharmony_ci}
568e1051a39Sopenharmony_ci
569e1051a39Sopenharmony_ci/* Add extensions to certificate request */
570e1051a39Sopenharmony_ci
571e1051a39Sopenharmony_ciint X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
572e1051a39Sopenharmony_ci                            const char *section, X509_REQ *req)
573e1051a39Sopenharmony_ci{
574e1051a39Sopenharmony_ci    CONF *ctmp;
575e1051a39Sopenharmony_ci    int ret;
576e1051a39Sopenharmony_ci
577e1051a39Sopenharmony_ci    if ((ctmp = NCONF_new(NULL)) == NULL)
578e1051a39Sopenharmony_ci        return 0;
579e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, conf);
580e1051a39Sopenharmony_ci    ret = X509V3_EXT_REQ_add_nconf(ctmp, ctx, section, req);
581e1051a39Sopenharmony_ci    CONF_set_nconf(ctmp, NULL);
582e1051a39Sopenharmony_ci    NCONF_free(ctmp);
583e1051a39Sopenharmony_ci    return ret;
584e1051a39Sopenharmony_ci}
585