xref: /freebsd/crypto/openssl/crypto/conf/conf_api.c (revision b077aed3)
1e71b7053SJung-uk Kim /*
2b077aed3SPierre Pronchery  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3ddd58736SKris Kennaway  *
4b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (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>
18b077aed3SPierre Pronchery #include "conf_local.h"
19ddd58736SKris Kennaway 
20e71b7053SJung-uk Kim static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf);
211f13597dSJung-uk Kim static void value_free_stack_doall(CONF_VALUE *a);
22ddd58736SKris Kennaway 
_CONF_get_section(const CONF * conf,const char * section)235c87c606SMark Murray CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
24ddd58736SKris Kennaway {
25b077aed3SPierre Pronchery     CONF_VALUE vv;
26ddd58736SKris Kennaway 
27b077aed3SPierre Pronchery     if (conf == NULL || section == NULL)
28e71b7053SJung-uk Kim         return NULL;
29ddd58736SKris Kennaway     vv.name = NULL;
305c87c606SMark Murray     vv.section = (char *)section;
31b077aed3SPierre Pronchery     return conf->data != NULL ? lh_CONF_VALUE_retrieve(conf->data, &vv) : NULL;
32ddd58736SKris Kennaway }
33ddd58736SKris Kennaway 
STACK_OF(CONF_VALUE)345c87c606SMark Murray STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
355c87c606SMark Murray                                                const char *section)
36ddd58736SKris Kennaway {
37ddd58736SKris Kennaway     CONF_VALUE *v;
38ddd58736SKris Kennaway 
39ddd58736SKris Kennaway     v = _CONF_get_section(conf, section);
40b077aed3SPierre Pronchery     if (v == NULL)
41e71b7053SJung-uk Kim         return NULL;
42b077aed3SPierre Pronchery     return ((STACK_OF(CONF_VALUE) *)v->value);
43ddd58736SKris Kennaway }
44ddd58736SKris Kennaway 
_CONF_add_string(CONF * conf,CONF_VALUE * section,CONF_VALUE * value)45ddd58736SKris Kennaway int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
46ddd58736SKris Kennaway {
47ddd58736SKris Kennaway     CONF_VALUE *v = NULL;
48ddd58736SKris Kennaway     STACK_OF(CONF_VALUE) *ts;
49ddd58736SKris Kennaway 
50ddd58736SKris Kennaway     ts = (STACK_OF(CONF_VALUE) *)section->value;
51ddd58736SKris Kennaway 
52ddd58736SKris Kennaway     value->section = section->section;
53b077aed3SPierre Pronchery     if (!sk_CONF_VALUE_push(ts, value))
54ddd58736SKris Kennaway         return 0;
55ddd58736SKris Kennaway 
561f13597dSJung-uk Kim     v = lh_CONF_VALUE_insert(conf->data, value);
576f9291ceSJung-uk Kim     if (v != NULL) {
58db522d3aSSimon L. B. Nielsen         (void)sk_CONF_VALUE_delete_ptr(ts, v);
59ddd58736SKris Kennaway         OPENSSL_free(v->name);
60ddd58736SKris Kennaway         OPENSSL_free(v->value);
61ddd58736SKris Kennaway         OPENSSL_free(v);
62ddd58736SKris Kennaway     }
63ddd58736SKris Kennaway     return 1;
64ddd58736SKris Kennaway }
65ddd58736SKris Kennaway 
_CONF_get_string(const CONF * conf,const char * section,const char * name)666f9291ceSJung-uk Kim char *_CONF_get_string(const CONF *conf, const char *section,
676f9291ceSJung-uk Kim                        const char *name)
68ddd58736SKris Kennaway {
69ddd58736SKris Kennaway     CONF_VALUE *v, vv;
70ddd58736SKris Kennaway     char *p;
71ddd58736SKris Kennaway 
726f9291ceSJung-uk Kim     if (name == NULL)
73e71b7053SJung-uk Kim         return NULL;
74b077aed3SPierre Pronchery     if (conf == NULL)
75b077aed3SPierre Pronchery         return ossl_safe_getenv(name);
76b077aed3SPierre Pronchery     if (conf->data == NULL)
77b077aed3SPierre Pronchery         return NULL;
786f9291ceSJung-uk Kim     if (section != NULL) {
795c87c606SMark Murray         vv.name = (char *)name;
805c87c606SMark Murray         vv.section = (char *)section;
811f13597dSJung-uk Kim         v = lh_CONF_VALUE_retrieve(conf->data, &vv);
826f9291ceSJung-uk Kim         if (v != NULL)
83e71b7053SJung-uk Kim             return v->value;
846f9291ceSJung-uk Kim         if (strcmp(section, "ENV") == 0) {
85c9cf7b5cSJung-uk Kim             p = ossl_safe_getenv(name);
866f9291ceSJung-uk Kim             if (p != NULL)
87e71b7053SJung-uk Kim                 return p;
88ddd58736SKris Kennaway         }
89ddd58736SKris Kennaway     }
90ddd58736SKris Kennaway     vv.section = "default";
915c87c606SMark Murray     vv.name = (char *)name;
921f13597dSJung-uk Kim     v = lh_CONF_VALUE_retrieve(conf->data, &vv);
93b077aed3SPierre Pronchery     if (v == NULL)
94e71b7053SJung-uk Kim         return NULL;
95b077aed3SPierre Pronchery     return v->value;
96ddd58736SKris Kennaway }
97ddd58736SKris Kennaway 
conf_value_hash(const CONF_VALUE * v)981f13597dSJung-uk Kim static unsigned long conf_value_hash(const CONF_VALUE *v)
99ddd58736SKris Kennaway {
100e71b7053SJung-uk Kim     return (OPENSSL_LH_strhash(v->section) << 2) ^ OPENSSL_LH_strhash(v->name);
101ddd58736SKris Kennaway }
1026f9291ceSJung-uk Kim 
conf_value_cmp(const CONF_VALUE * a,const CONF_VALUE * b)1031f13597dSJung-uk Kim static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
104ddd58736SKris Kennaway {
105ddd58736SKris Kennaway     int i;
106ddd58736SKris Kennaway 
1076f9291ceSJung-uk Kim     if (a->section != b->section) {
108ddd58736SKris Kennaway         i = strcmp(a->section, b->section);
109b077aed3SPierre Pronchery         if (i != 0)
110e71b7053SJung-uk Kim             return i;
111ddd58736SKris Kennaway     }
1126f9291ceSJung-uk Kim 
113b077aed3SPierre Pronchery     if (a->name != NULL && b->name != NULL)
114b077aed3SPierre Pronchery         return strcmp(a->name, b->name);
115b077aed3SPierre Pronchery     if (a->name == b->name)
116e71b7053SJung-uk Kim         return 0;
117b077aed3SPierre Pronchery     return (a->name == NULL) ? -1 : 1;
118ddd58736SKris Kennaway }
1196f9291ceSJung-uk Kim 
_CONF_new_data(CONF * conf)1201f13597dSJung-uk Kim int _CONF_new_data(CONF *conf)
1211f13597dSJung-uk Kim {
122b077aed3SPierre Pronchery     if (conf == NULL)
1231f13597dSJung-uk Kim         return 0;
124e71b7053SJung-uk Kim     if (conf->data == NULL) {
125e71b7053SJung-uk Kim         conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp);
1261f13597dSJung-uk Kim         if (conf->data == NULL)
1271f13597dSJung-uk Kim             return 0;
1281f13597dSJung-uk Kim     }
1291f13597dSJung-uk Kim     return 1;
1301f13597dSJung-uk Kim }
1311f13597dSJung-uk Kim 
132e71b7053SJung-uk Kim typedef LHASH_OF(CONF_VALUE) LH_CONF_VALUE;
133e71b7053SJung-uk Kim 
134e71b7053SJung-uk Kim IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, LH_CONF_VALUE);
135e71b7053SJung-uk Kim 
_CONF_free_data(CONF * conf)1361f13597dSJung-uk Kim void _CONF_free_data(CONF *conf)
1371f13597dSJung-uk Kim {
138b077aed3SPierre Pronchery     if (conf == NULL)
139b077aed3SPierre Pronchery         return;
140b077aed3SPierre Pronchery 
141b077aed3SPierre Pronchery     OPENSSL_free(conf->includedir);
142b077aed3SPierre Pronchery     if (conf->data == NULL)
1436f9291ceSJung-uk Kim         return;
1441f13597dSJung-uk Kim 
145e71b7053SJung-uk Kim     /* evil thing to make sure the 'OPENSSL_free()' works as expected */
146e71b7053SJung-uk Kim     lh_CONF_VALUE_set_down_load(conf->data, 0);
147e71b7053SJung-uk Kim     lh_CONF_VALUE_doall_LH_CONF_VALUE(conf->data, value_free_hash, conf->data);
1481f13597dSJung-uk Kim 
1496f9291ceSJung-uk Kim     /*
1506f9291ceSJung-uk Kim      * We now have only 'section' entries in the hash table. Due to problems
1516f9291ceSJung-uk Kim      * with
1526f9291ceSJung-uk Kim      */
1531f13597dSJung-uk Kim 
154e71b7053SJung-uk Kim     lh_CONF_VALUE_doall(conf->data, value_free_stack_doall);
1551f13597dSJung-uk Kim     lh_CONF_VALUE_free(conf->data);
1561f13597dSJung-uk Kim }
1571f13597dSJung-uk Kim 
value_free_hash(const CONF_VALUE * a,LHASH_OF (CONF_VALUE)* conf)158e71b7053SJung-uk Kim static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
1591f13597dSJung-uk Kim {
1601f13597dSJung-uk Kim     if (a->name != NULL)
1611f13597dSJung-uk Kim         (void)lh_CONF_VALUE_delete(conf, a);
1621f13597dSJung-uk Kim }
1631f13597dSJung-uk Kim 
value_free_stack_doall(CONF_VALUE * a)1641f13597dSJung-uk Kim static void value_free_stack_doall(CONF_VALUE *a)
1651f13597dSJung-uk Kim {
1661f13597dSJung-uk Kim     CONF_VALUE *vv;
1671f13597dSJung-uk Kim     STACK_OF(CONF_VALUE) *sk;
1681f13597dSJung-uk Kim     int i;
1691f13597dSJung-uk Kim 
1706f9291ceSJung-uk Kim     if (a->name != NULL)
1716f9291ceSJung-uk Kim         return;
1721f13597dSJung-uk Kim 
1731f13597dSJung-uk Kim     sk = (STACK_OF(CONF_VALUE) *)a->value;
1746f9291ceSJung-uk Kim     for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
1751f13597dSJung-uk Kim         vv = sk_CONF_VALUE_value(sk, i);
1761f13597dSJung-uk Kim         OPENSSL_free(vv->value);
1771f13597dSJung-uk Kim         OPENSSL_free(vv->name);
1781f13597dSJung-uk Kim         OPENSSL_free(vv);
1791f13597dSJung-uk Kim     }
1806f9291ceSJung-uk Kim     sk_CONF_VALUE_free(sk);
1811f13597dSJung-uk Kim     OPENSSL_free(a->section);
1821f13597dSJung-uk Kim     OPENSSL_free(a);
1831f13597dSJung-uk Kim }
184ddd58736SKris Kennaway 
_CONF_new_section(CONF * conf,const char * section)1855c87c606SMark Murray CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
186ddd58736SKris Kennaway {
1871f13597dSJung-uk Kim     STACK_OF(CONF_VALUE) *sk = NULL;
188e71b7053SJung-uk Kim     int i;
189ddd58736SKris Kennaway     CONF_VALUE *v = NULL, *vv;
190ddd58736SKris Kennaway 
1911f13597dSJung-uk Kim     if ((sk = sk_CONF_VALUE_new_null()) == NULL)
192ddd58736SKris Kennaway         goto err;
193e71b7053SJung-uk Kim     if ((v = OPENSSL_malloc(sizeof(*v))) == NULL)
194ddd58736SKris Kennaway         goto err;
195ddd58736SKris Kennaway     i = strlen(section) + 1;
1961f13597dSJung-uk Kim     if ((v->section = OPENSSL_malloc(i)) == NULL)
197ddd58736SKris Kennaway         goto err;
198ddd58736SKris Kennaway 
199ddd58736SKris Kennaway     memcpy(v->section, section, i);
200ddd58736SKris Kennaway     v->name = NULL;
201ddd58736SKris Kennaway     v->value = (char *)sk;
202ddd58736SKris Kennaway 
2031f13597dSJung-uk Kim     vv = lh_CONF_VALUE_insert(conf->data, v);
204e71b7053SJung-uk Kim     if (vv != NULL || lh_CONF_VALUE_error(conf->data) > 0)
205dea77ea6SJung-uk Kim         goto err;
206e71b7053SJung-uk Kim     return v;
207e71b7053SJung-uk Kim 
208ddd58736SKris Kennaway  err:
2096f9291ceSJung-uk Kim     sk_CONF_VALUE_free(sk);
2106f9291ceSJung-uk Kim     if (v != NULL)
211e71b7053SJung-uk Kim         OPENSSL_free(v->section);
2126f9291ceSJung-uk Kim     OPENSSL_free(v);
213e71b7053SJung-uk Kim     return NULL;
214ddd58736SKris Kennaway }
215