1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-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/* Part of the code in here was originally in conf.c, which is now removed */ 11e1051a39Sopenharmony_ci 12e1051a39Sopenharmony_ci#include "e_os.h" 13e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 14e1051a39Sopenharmony_ci#include <stdlib.h> 15e1051a39Sopenharmony_ci#include <string.h> 16e1051a39Sopenharmony_ci#include <openssl/conf.h> 17e1051a39Sopenharmony_ci#include <openssl/conf_api.h> 18e1051a39Sopenharmony_ci#include "conf_local.h" 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_cistatic void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf); 21e1051a39Sopenharmony_cistatic void value_free_stack_doall(CONF_VALUE *a); 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ciCONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) 24e1051a39Sopenharmony_ci{ 25e1051a39Sopenharmony_ci CONF_VALUE vv; 26e1051a39Sopenharmony_ci 27e1051a39Sopenharmony_ci if (conf == NULL || section == NULL) 28e1051a39Sopenharmony_ci return NULL; 29e1051a39Sopenharmony_ci vv.name = NULL; 30e1051a39Sopenharmony_ci vv.section = (char *)section; 31e1051a39Sopenharmony_ci return conf->data != NULL ? lh_CONF_VALUE_retrieve(conf->data, &vv) : NULL; 32e1051a39Sopenharmony_ci} 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ciSTACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, 35e1051a39Sopenharmony_ci const char *section) 36e1051a39Sopenharmony_ci{ 37e1051a39Sopenharmony_ci CONF_VALUE *v; 38e1051a39Sopenharmony_ci 39e1051a39Sopenharmony_ci v = _CONF_get_section(conf, section); 40e1051a39Sopenharmony_ci if (v == NULL) 41e1051a39Sopenharmony_ci return NULL; 42e1051a39Sopenharmony_ci return ((STACK_OF(CONF_VALUE) *)v->value); 43e1051a39Sopenharmony_ci} 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ciint _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci CONF_VALUE *v = NULL; 48e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *ts; 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_ci ts = (STACK_OF(CONF_VALUE) *)section->value; 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_ci value->section = section->section; 53e1051a39Sopenharmony_ci if (!sk_CONF_VALUE_push(ts, value)) 54e1051a39Sopenharmony_ci return 0; 55e1051a39Sopenharmony_ci 56e1051a39Sopenharmony_ci v = lh_CONF_VALUE_insert(conf->data, value); 57e1051a39Sopenharmony_ci if (v != NULL) { 58e1051a39Sopenharmony_ci (void)sk_CONF_VALUE_delete_ptr(ts, v); 59e1051a39Sopenharmony_ci OPENSSL_free(v->name); 60e1051a39Sopenharmony_ci OPENSSL_free(v->value); 61e1051a39Sopenharmony_ci OPENSSL_free(v); 62e1051a39Sopenharmony_ci } 63e1051a39Sopenharmony_ci return 1; 64e1051a39Sopenharmony_ci} 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_cichar *_CONF_get_string(const CONF *conf, const char *section, 67e1051a39Sopenharmony_ci const char *name) 68e1051a39Sopenharmony_ci{ 69e1051a39Sopenharmony_ci CONF_VALUE *v, vv; 70e1051a39Sopenharmony_ci char *p; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci if (name == NULL) 73e1051a39Sopenharmony_ci return NULL; 74e1051a39Sopenharmony_ci if (conf == NULL) 75e1051a39Sopenharmony_ci return ossl_safe_getenv(name); 76e1051a39Sopenharmony_ci if (conf->data == NULL) 77e1051a39Sopenharmony_ci return NULL; 78e1051a39Sopenharmony_ci if (section != NULL) { 79e1051a39Sopenharmony_ci vv.name = (char *)name; 80e1051a39Sopenharmony_ci vv.section = (char *)section; 81e1051a39Sopenharmony_ci v = lh_CONF_VALUE_retrieve(conf->data, &vv); 82e1051a39Sopenharmony_ci if (v != NULL) 83e1051a39Sopenharmony_ci return v->value; 84e1051a39Sopenharmony_ci if (strcmp(section, "ENV") == 0) { 85e1051a39Sopenharmony_ci p = ossl_safe_getenv(name); 86e1051a39Sopenharmony_ci if (p != NULL) 87e1051a39Sopenharmony_ci return p; 88e1051a39Sopenharmony_ci } 89e1051a39Sopenharmony_ci } 90e1051a39Sopenharmony_ci vv.section = "default"; 91e1051a39Sopenharmony_ci vv.name = (char *)name; 92e1051a39Sopenharmony_ci v = lh_CONF_VALUE_retrieve(conf->data, &vv); 93e1051a39Sopenharmony_ci if (v == NULL) 94e1051a39Sopenharmony_ci return NULL; 95e1051a39Sopenharmony_ci return v->value; 96e1051a39Sopenharmony_ci} 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_cistatic unsigned long conf_value_hash(const CONF_VALUE *v) 99e1051a39Sopenharmony_ci{ 100e1051a39Sopenharmony_ci return (OPENSSL_LH_strhash(v->section) << 2) ^ OPENSSL_LH_strhash(v->name); 101e1051a39Sopenharmony_ci} 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_cistatic int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) 104e1051a39Sopenharmony_ci{ 105e1051a39Sopenharmony_ci int i; 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci if (a->section != b->section) { 108e1051a39Sopenharmony_ci i = strcmp(a->section, b->section); 109e1051a39Sopenharmony_ci if (i != 0) 110e1051a39Sopenharmony_ci return i; 111e1051a39Sopenharmony_ci } 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci if (a->name != NULL && b->name != NULL) 114e1051a39Sopenharmony_ci return strcmp(a->name, b->name); 115e1051a39Sopenharmony_ci if (a->name == b->name) 116e1051a39Sopenharmony_ci return 0; 117e1051a39Sopenharmony_ci return (a->name == NULL) ? -1 : 1; 118e1051a39Sopenharmony_ci} 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ciint _CONF_new_data(CONF *conf) 121e1051a39Sopenharmony_ci{ 122e1051a39Sopenharmony_ci if (conf == NULL) 123e1051a39Sopenharmony_ci return 0; 124e1051a39Sopenharmony_ci if (conf->data == NULL) { 125e1051a39Sopenharmony_ci conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp); 126e1051a39Sopenharmony_ci if (conf->data == NULL) 127e1051a39Sopenharmony_ci return 0; 128e1051a39Sopenharmony_ci } 129e1051a39Sopenharmony_ci return 1; 130e1051a39Sopenharmony_ci} 131e1051a39Sopenharmony_ci 132e1051a39Sopenharmony_citypedef LHASH_OF(CONF_VALUE) LH_CONF_VALUE; 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ciIMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, LH_CONF_VALUE); 135e1051a39Sopenharmony_ci 136e1051a39Sopenharmony_civoid _CONF_free_data(CONF *conf) 137e1051a39Sopenharmony_ci{ 138e1051a39Sopenharmony_ci if (conf == NULL) 139e1051a39Sopenharmony_ci return; 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci OPENSSL_free(conf->includedir); 142e1051a39Sopenharmony_ci if (conf->data == NULL) 143e1051a39Sopenharmony_ci return; 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ci /* evil thing to make sure the 'OPENSSL_free()' works as expected */ 146e1051a39Sopenharmony_ci lh_CONF_VALUE_set_down_load(conf->data, 0); 147e1051a39Sopenharmony_ci lh_CONF_VALUE_doall_LH_CONF_VALUE(conf->data, value_free_hash, conf->data); 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci /* 150e1051a39Sopenharmony_ci * We now have only 'section' entries in the hash table. Due to problems 151e1051a39Sopenharmony_ci * with 152e1051a39Sopenharmony_ci */ 153e1051a39Sopenharmony_ci 154e1051a39Sopenharmony_ci lh_CONF_VALUE_doall(conf->data, value_free_stack_doall); 155e1051a39Sopenharmony_ci lh_CONF_VALUE_free(conf->data); 156e1051a39Sopenharmony_ci} 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_cistatic void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf) 159e1051a39Sopenharmony_ci{ 160e1051a39Sopenharmony_ci if (a->name != NULL) 161e1051a39Sopenharmony_ci (void)lh_CONF_VALUE_delete(conf, a); 162e1051a39Sopenharmony_ci} 163e1051a39Sopenharmony_ci 164e1051a39Sopenharmony_cistatic void value_free_stack_doall(CONF_VALUE *a) 165e1051a39Sopenharmony_ci{ 166e1051a39Sopenharmony_ci CONF_VALUE *vv; 167e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *sk; 168e1051a39Sopenharmony_ci int i; 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_ci if (a->name != NULL) 171e1051a39Sopenharmony_ci return; 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ci sk = (STACK_OF(CONF_VALUE) *)a->value; 174e1051a39Sopenharmony_ci for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { 175e1051a39Sopenharmony_ci vv = sk_CONF_VALUE_value(sk, i); 176e1051a39Sopenharmony_ci OPENSSL_free(vv->value); 177e1051a39Sopenharmony_ci OPENSSL_free(vv->name); 178e1051a39Sopenharmony_ci OPENSSL_free(vv); 179e1051a39Sopenharmony_ci } 180e1051a39Sopenharmony_ci sk_CONF_VALUE_free(sk); 181e1051a39Sopenharmony_ci OPENSSL_free(a->section); 182e1051a39Sopenharmony_ci OPENSSL_free(a); 183e1051a39Sopenharmony_ci} 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ciCONF_VALUE *_CONF_new_section(CONF *conf, const char *section) 186e1051a39Sopenharmony_ci{ 187e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *sk = NULL; 188e1051a39Sopenharmony_ci int i; 189e1051a39Sopenharmony_ci CONF_VALUE *v = NULL, *vv; 190e1051a39Sopenharmony_ci 191e1051a39Sopenharmony_ci if ((sk = sk_CONF_VALUE_new_null()) == NULL) 192e1051a39Sopenharmony_ci goto err; 193e1051a39Sopenharmony_ci if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) 194e1051a39Sopenharmony_ci goto err; 195e1051a39Sopenharmony_ci i = strlen(section) + 1; 196e1051a39Sopenharmony_ci if ((v->section = OPENSSL_malloc(i)) == NULL) 197e1051a39Sopenharmony_ci goto err; 198e1051a39Sopenharmony_ci 199e1051a39Sopenharmony_ci memcpy(v->section, section, i); 200e1051a39Sopenharmony_ci v->name = NULL; 201e1051a39Sopenharmony_ci v->value = (char *)sk; 202e1051a39Sopenharmony_ci 203e1051a39Sopenharmony_ci vv = lh_CONF_VALUE_insert(conf->data, v); 204e1051a39Sopenharmony_ci if (vv != NULL || lh_CONF_VALUE_error(conf->data) > 0) 205e1051a39Sopenharmony_ci goto err; 206e1051a39Sopenharmony_ci return v; 207e1051a39Sopenharmony_ci 208e1051a39Sopenharmony_ci err: 209e1051a39Sopenharmony_ci sk_CONF_VALUE_free(sk); 210e1051a39Sopenharmony_ci if (v != NULL) 211e1051a39Sopenharmony_ci OPENSSL_free(v->section); 212e1051a39Sopenharmony_ci OPENSSL_free(v); 213e1051a39Sopenharmony_ci return NULL; 214e1051a39Sopenharmony_ci} 215