xref: /freebsd/crypto/openssl/crypto/conf/conf_api.c (revision c9cf7b5c)
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