1e71b7053SJung-uk Kim /* 2e71b7053SJung-uk Kim * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3ddd58736SKris Kennaway * 4e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 8ddd58736SKris Kennaway */ 9ddd58736SKris Kennaway 10ddd58736SKris Kennaway /* Part of the code in here was originally in conf.c, which is now removed */ 11ddd58736SKris Kennaway 12e71b7053SJung-uk Kim #include "e_os.h" 13c9cf7b5cSJung-uk Kim #include "internal/cryptlib.h" 1412de4ed2SJung-uk Kim #include <stdlib.h> 15ddd58736SKris Kennaway #include <string.h> 16ddd58736SKris Kennaway #include <openssl/conf.h> 17ddd58736SKris Kennaway #include <openssl/conf_api.h> 18ddd58736SKris Kennaway 19e71b7053SJung-uk Kim static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf); 201f13597dSJung-uk Kim static void value_free_stack_doall(CONF_VALUE *a); 21ddd58736SKris Kennaway 22ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was get_section */ 235c87c606SMark Murray CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) 24ddd58736SKris Kennaway { 25ddd58736SKris Kennaway CONF_VALUE *v, vv; 26ddd58736SKris Kennaway 276f9291ceSJung-uk Kim if ((conf == NULL) || (section == NULL)) 28e71b7053SJung-uk Kim return NULL; 29ddd58736SKris Kennaway vv.name = NULL; 305c87c606SMark Murray vv.section = (char *)section; 311f13597dSJung-uk Kim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 32e71b7053SJung-uk Kim return v; 33ddd58736SKris Kennaway } 34ddd58736SKris Kennaway 35ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was CONF_get_section */ 365c87c606SMark Murray STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, 375c87c606SMark Murray const char *section) 38ddd58736SKris Kennaway { 39ddd58736SKris Kennaway CONF_VALUE *v; 40ddd58736SKris Kennaway 41ddd58736SKris Kennaway v = _CONF_get_section(conf, section); 42ddd58736SKris Kennaway if (v != NULL) 43ddd58736SKris Kennaway return ((STACK_OF(CONF_VALUE) *)v->value); 44ddd58736SKris Kennaway else 45e71b7053SJung-uk Kim return NULL; 46ddd58736SKris Kennaway } 47ddd58736SKris Kennaway 48ddd58736SKris Kennaway int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) 49ddd58736SKris Kennaway { 50ddd58736SKris Kennaway CONF_VALUE *v = NULL; 51ddd58736SKris Kennaway STACK_OF(CONF_VALUE) *ts; 52ddd58736SKris Kennaway 53ddd58736SKris Kennaway ts = (STACK_OF(CONF_VALUE) *)section->value; 54ddd58736SKris Kennaway 55ddd58736SKris Kennaway value->section = section->section; 566f9291ceSJung-uk Kim if (!sk_CONF_VALUE_push(ts, value)) { 57ddd58736SKris Kennaway return 0; 58ddd58736SKris Kennaway } 59ddd58736SKris Kennaway 601f13597dSJung-uk Kim v = lh_CONF_VALUE_insert(conf->data, value); 616f9291ceSJung-uk Kim if (v != NULL) { 62db522d3aSSimon L. B. Nielsen (void)sk_CONF_VALUE_delete_ptr(ts, v); 63ddd58736SKris Kennaway OPENSSL_free(v->name); 64ddd58736SKris Kennaway OPENSSL_free(v->value); 65ddd58736SKris Kennaway OPENSSL_free(v); 66ddd58736SKris Kennaway } 67ddd58736SKris Kennaway return 1; 68ddd58736SKris Kennaway } 69ddd58736SKris Kennaway 706f9291ceSJung-uk Kim char *_CONF_get_string(const CONF *conf, const char *section, 716f9291ceSJung-uk Kim const char *name) 72ddd58736SKris Kennaway { 73ddd58736SKris Kennaway CONF_VALUE *v, vv; 74ddd58736SKris Kennaway char *p; 75ddd58736SKris Kennaway 766f9291ceSJung-uk Kim if (name == NULL) 77e71b7053SJung-uk Kim return NULL; 786f9291ceSJung-uk Kim if (conf != NULL) { 796f9291ceSJung-uk Kim if (section != NULL) { 805c87c606SMark Murray vv.name = (char *)name; 815c87c606SMark Murray vv.section = (char *)section; 821f13597dSJung-uk Kim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 836f9291ceSJung-uk Kim if (v != NULL) 84e71b7053SJung-uk Kim return v->value; 856f9291ceSJung-uk Kim if (strcmp(section, "ENV") == 0) { 86c9cf7b5cSJung-uk Kim p = ossl_safe_getenv(name); 876f9291ceSJung-uk Kim if (p != NULL) 88e71b7053SJung-uk Kim return p; 89ddd58736SKris Kennaway } 90ddd58736SKris Kennaway } 91ddd58736SKris Kennaway vv.section = "default"; 925c87c606SMark Murray vv.name = (char *)name; 931f13597dSJung-uk Kim v = lh_CONF_VALUE_retrieve(conf->data, &vv); 94ddd58736SKris Kennaway if (v != NULL) 95e71b7053SJung-uk Kim return v->value; 96ddd58736SKris Kennaway else 97e71b7053SJung-uk Kim return NULL; 986f9291ceSJung-uk Kim } else 99c9cf7b5cSJung-uk Kim return ossl_safe_getenv(name); 100ddd58736SKris Kennaway } 101ddd58736SKris Kennaway 1021f13597dSJung-uk Kim static unsigned long conf_value_hash(const CONF_VALUE *v) 103ddd58736SKris Kennaway { 104e71b7053SJung-uk Kim return (OPENSSL_LH_strhash(v->section) << 2) ^ OPENSSL_LH_strhash(v->name); 105ddd58736SKris Kennaway } 1066f9291ceSJung-uk Kim 1071f13597dSJung-uk Kim static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) 108ddd58736SKris Kennaway { 109ddd58736SKris Kennaway int i; 110ddd58736SKris Kennaway 1116f9291ceSJung-uk Kim if (a->section != b->section) { 112ddd58736SKris Kennaway i = strcmp(a->section, b->section); 1136f9291ceSJung-uk Kim if (i) 114e71b7053SJung-uk Kim return i; 115ddd58736SKris Kennaway } 1166f9291ceSJung-uk Kim 1176f9291ceSJung-uk Kim if ((a->name != NULL) && (b->name != NULL)) { 1186f9291ceSJung-uk Kim i = strcmp(a->name, b->name); 119e71b7053SJung-uk Kim return i; 1206f9291ceSJung-uk Kim } else if (a->name == b->name) 121e71b7053SJung-uk Kim return 0; 122ddd58736SKris Kennaway else 123ddd58736SKris Kennaway return ((a->name == NULL) ? -1 : 1); 124ddd58736SKris Kennaway } 1256f9291ceSJung-uk Kim 1261f13597dSJung-uk Kim int _CONF_new_data(CONF *conf) 1271f13597dSJung-uk Kim { 1286f9291ceSJung-uk Kim if (conf == NULL) { 1291f13597dSJung-uk Kim return 0; 1301f13597dSJung-uk Kim } 131e71b7053SJung-uk Kim if (conf->data == NULL) { 132e71b7053SJung-uk Kim conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp); 1331f13597dSJung-uk Kim if (conf->data == NULL) 1341f13597dSJung-uk Kim return 0; 1351f13597dSJung-uk Kim } 1361f13597dSJung-uk Kim return 1; 1371f13597dSJung-uk Kim } 1381f13597dSJung-uk Kim 139e71b7053SJung-uk Kim typedef LHASH_OF(CONF_VALUE) LH_CONF_VALUE; 140e71b7053SJung-uk Kim 141e71b7053SJung-uk Kim IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, LH_CONF_VALUE); 142e71b7053SJung-uk Kim 1431f13597dSJung-uk Kim void _CONF_free_data(CONF *conf) 1441f13597dSJung-uk Kim { 1456f9291ceSJung-uk Kim if (conf == NULL || conf->data == NULL) 1466f9291ceSJung-uk Kim return; 1471f13597dSJung-uk Kim 148e71b7053SJung-uk Kim /* evil thing to make sure the 'OPENSSL_free()' works as expected */ 149e71b7053SJung-uk Kim lh_CONF_VALUE_set_down_load(conf->data, 0); 150e71b7053SJung-uk Kim lh_CONF_VALUE_doall_LH_CONF_VALUE(conf->data, value_free_hash, conf->data); 1511f13597dSJung-uk Kim 1526f9291ceSJung-uk Kim /* 1536f9291ceSJung-uk Kim * We now have only 'section' entries in the hash table. Due to problems 1546f9291ceSJung-uk Kim * with 1556f9291ceSJung-uk Kim */ 1561f13597dSJung-uk Kim 157e71b7053SJung-uk Kim lh_CONF_VALUE_doall(conf->data, value_free_stack_doall); 1581f13597dSJung-uk Kim lh_CONF_VALUE_free(conf->data); 1591f13597dSJung-uk Kim } 1601f13597dSJung-uk Kim 161e71b7053SJung-uk Kim static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf) 1621f13597dSJung-uk Kim { 1631f13597dSJung-uk Kim if (a->name != NULL) 1641f13597dSJung-uk Kim (void)lh_CONF_VALUE_delete(conf, a); 1651f13597dSJung-uk Kim } 1661f13597dSJung-uk Kim 1671f13597dSJung-uk Kim static void value_free_stack_doall(CONF_VALUE *a) 1681f13597dSJung-uk Kim { 1691f13597dSJung-uk Kim CONF_VALUE *vv; 1701f13597dSJung-uk Kim STACK_OF(CONF_VALUE) *sk; 1711f13597dSJung-uk Kim int i; 1721f13597dSJung-uk Kim 1736f9291ceSJung-uk Kim if (a->name != NULL) 1746f9291ceSJung-uk Kim return; 1751f13597dSJung-uk Kim 1761f13597dSJung-uk Kim sk = (STACK_OF(CONF_VALUE) *)a->value; 1776f9291ceSJung-uk Kim for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { 1781f13597dSJung-uk Kim vv = sk_CONF_VALUE_value(sk, i); 1791f13597dSJung-uk Kim OPENSSL_free(vv->value); 1801f13597dSJung-uk Kim OPENSSL_free(vv->name); 1811f13597dSJung-uk Kim OPENSSL_free(vv); 1821f13597dSJung-uk Kim } 1836f9291ceSJung-uk Kim sk_CONF_VALUE_free(sk); 1841f13597dSJung-uk Kim OPENSSL_free(a->section); 1851f13597dSJung-uk Kim OPENSSL_free(a); 1861f13597dSJung-uk Kim } 187ddd58736SKris Kennaway 188ddd58736SKris Kennaway /* Up until OpenSSL 0.9.5a, this was new_section */ 1895c87c606SMark Murray CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) 190ddd58736SKris Kennaway { 1911f13597dSJung-uk Kim STACK_OF(CONF_VALUE) *sk = NULL; 192e71b7053SJung-uk Kim int i; 193ddd58736SKris Kennaway CONF_VALUE *v = NULL, *vv; 194ddd58736SKris Kennaway 1951f13597dSJung-uk Kim if ((sk = sk_CONF_VALUE_new_null()) == NULL) 196ddd58736SKris Kennaway goto err; 197e71b7053SJung-uk Kim if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) 198ddd58736SKris Kennaway goto err; 199ddd58736SKris Kennaway i = strlen(section) + 1; 2001f13597dSJung-uk Kim if ((v->section = OPENSSL_malloc(i)) == NULL) 201ddd58736SKris Kennaway goto err; 202ddd58736SKris Kennaway 203ddd58736SKris Kennaway memcpy(v->section, section, i); 204ddd58736SKris Kennaway v->name = NULL; 205ddd58736SKris Kennaway v->value = (char *)sk; 206ddd58736SKris Kennaway 2071f13597dSJung-uk Kim vv = lh_CONF_VALUE_insert(conf->data, v); 208e71b7053SJung-uk Kim if (vv != NULL || lh_CONF_VALUE_error(conf->data) > 0) 209dea77ea6SJung-uk Kim goto err; 210e71b7053SJung-uk Kim return v; 211e71b7053SJung-uk Kim 212ddd58736SKris Kennaway err: 2136f9291ceSJung-uk Kim sk_CONF_VALUE_free(sk); 2146f9291ceSJung-uk Kim if (v != NULL) 215e71b7053SJung-uk Kim OPENSSL_free(v->section); 2166f9291ceSJung-uk Kim OPENSSL_free(v); 217e71b7053SJung-uk Kim return NULL; 218ddd58736SKris Kennaway } 219