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