/src/openssl30/crypto/conf/conf_api.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | | * this file except in compliance with the License. You can obtain a copy |
6 | | * in the file LICENSE in the source distribution or at |
7 | | * https://www.openssl.org/source/license.html |
8 | | */ |
9 | | |
10 | | /* Part of the code in here was originally in conf.c, which is now removed */ |
11 | | |
12 | | #include "e_os.h" |
13 | | #include "internal/cryptlib.h" |
14 | | #include <stdlib.h> |
15 | | #include <string.h> |
16 | | #include <openssl/conf.h> |
17 | | #include <openssl/conf_api.h> |
18 | | #include "conf_local.h" |
19 | | |
20 | | static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf); |
21 | | static void value_free_stack_doall(CONF_VALUE *a); |
22 | | |
23 | | CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) |
24 | 82.6k | { |
25 | 82.6k | CONF_VALUE vv; |
26 | | |
27 | 82.6k | if (conf == NULL || section == NULL) |
28 | 0 | return NULL; |
29 | 82.6k | vv.name = NULL; |
30 | 82.6k | vv.section = (char *)section; |
31 | 82.6k | return conf->data != NULL ? lh_CONF_VALUE_retrieve(conf->data, &vv) : NULL; |
32 | 82.6k | } |
33 | | |
34 | | STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, |
35 | | const char *section) |
36 | 0 | { |
37 | 0 | CONF_VALUE *v; |
38 | |
|
39 | 0 | v = _CONF_get_section(conf, section); |
40 | 0 | if (v == NULL) |
41 | 0 | return NULL; |
42 | 0 | return ((STACK_OF(CONF_VALUE) *)v->value); |
43 | 0 | } |
44 | | |
45 | | int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) |
46 | 338k | { |
47 | 338k | CONF_VALUE *v = NULL; |
48 | 338k | STACK_OF(CONF_VALUE) *ts; |
49 | | |
50 | 338k | ts = (STACK_OF(CONF_VALUE) *)section->value; |
51 | | |
52 | 338k | value->section = section->section; |
53 | 338k | if (!sk_CONF_VALUE_push(ts, value)) |
54 | 0 | return 0; |
55 | | |
56 | 338k | v = lh_CONF_VALUE_insert(conf->data, value); |
57 | 338k | if (v != NULL) { |
58 | 162k | (void)sk_CONF_VALUE_delete_ptr(ts, v); |
59 | 162k | OPENSSL_free(v->name); |
60 | 162k | OPENSSL_free(v->value); |
61 | 162k | OPENSSL_free(v); |
62 | 162k | } |
63 | 338k | return 1; |
64 | 338k | } |
65 | | |
66 | | char *_CONF_get_string(const CONF *conf, const char *section, |
67 | | const char *name) |
68 | 65.5k | { |
69 | 65.5k | CONF_VALUE *v, vv; |
70 | 65.5k | char *p; |
71 | | |
72 | 65.5k | if (name == NULL) |
73 | 0 | return NULL; |
74 | 65.5k | if (conf == NULL) |
75 | 0 | return ossl_safe_getenv(name); |
76 | 65.5k | if (conf->data == NULL) |
77 | 0 | return NULL; |
78 | 65.5k | if (section != NULL) { |
79 | 65.5k | vv.name = (char *)name; |
80 | 65.5k | vv.section = (char *)section; |
81 | 65.5k | v = lh_CONF_VALUE_retrieve(conf->data, &vv); |
82 | 65.5k | if (v != NULL) |
83 | 54.0k | return v->value; |
84 | 11.5k | if (strcmp(section, "ENV") == 0) { |
85 | 2.91k | p = ossl_safe_getenv(name); |
86 | 2.91k | if (p != NULL) |
87 | 1.66k | return p; |
88 | 2.91k | } |
89 | 11.5k | } |
90 | 9.86k | vv.section = "default"; |
91 | 9.86k | vv.name = (char *)name; |
92 | 9.86k | v = lh_CONF_VALUE_retrieve(conf->data, &vv); |
93 | 9.86k | if (v == NULL) |
94 | 1.03k | return NULL; |
95 | 8.83k | return v->value; |
96 | 9.86k | } |
97 | | |
98 | | static unsigned long conf_value_hash(const CONF_VALUE *v) |
99 | 738k | { |
100 | 738k | return (OPENSSL_LH_strhash(v->section) << 2) ^ OPENSSL_LH_strhash(v->name); |
101 | 738k | } |
102 | | |
103 | | static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) |
104 | 564k | { |
105 | 564k | int i; |
106 | | |
107 | 564k | if (a->section != b->section) { |
108 | 139k | i = strcmp(a->section, b->section); |
109 | 139k | if (i != 0) |
110 | 5.37k | return i; |
111 | 139k | } |
112 | | |
113 | 559k | if (a->name != NULL && b->name != NULL) |
114 | 403k | return strcmp(a->name, b->name); |
115 | 155k | if (a->name == b->name) |
116 | 28.8k | return 0; |
117 | 126k | return (a->name == NULL) ? -1 : 1; |
118 | 155k | } |
119 | | |
120 | | int _CONF_new_data(CONF *conf) |
121 | 12.2k | { |
122 | 12.2k | if (conf == NULL) |
123 | 0 | return 0; |
124 | 12.2k | if (conf->data == NULL) { |
125 | 12.2k | conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp); |
126 | 12.2k | if (conf->data == NULL) |
127 | 0 | return 0; |
128 | 12.2k | } |
129 | 12.2k | return 1; |
130 | 12.2k | } |
131 | | |
132 | | typedef LHASH_OF(CONF_VALUE) LH_CONF_VALUE; |
133 | | |
134 | | IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, LH_CONF_VALUE); |
135 | | |
136 | | void _CONF_free_data(CONF *conf) |
137 | 16.9k | { |
138 | 16.9k | if (conf == NULL) |
139 | 0 | return; |
140 | | |
141 | 16.9k | OPENSSL_free(conf->includedir); |
142 | 16.9k | if (conf->data == NULL) |
143 | 4.70k | return; |
144 | | |
145 | | /* evil thing to make sure the 'OPENSSL_free()' works as expected */ |
146 | 12.2k | lh_CONF_VALUE_set_down_load(conf->data, 0); |
147 | 12.2k | lh_CONF_VALUE_doall_LH_CONF_VALUE(conf->data, value_free_hash, conf->data); |
148 | | |
149 | | /* |
150 | | * We now have only 'section' entries in the hash table. Due to problems |
151 | | * with |
152 | | */ |
153 | | |
154 | 12.2k | lh_CONF_VALUE_doall(conf->data, value_free_stack_doall); |
155 | 12.2k | lh_CONF_VALUE_free(conf->data); |
156 | 12.2k | } |
157 | | |
158 | | static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf) |
159 | 241k | { |
160 | 241k | if (a->name != NULL) |
161 | 175k | (void)lh_CONF_VALUE_delete(conf, a); |
162 | 241k | } |
163 | | |
164 | | static void value_free_stack_doall(CONF_VALUE *a) |
165 | 66.0k | { |
166 | 66.0k | CONF_VALUE *vv; |
167 | 66.0k | STACK_OF(CONF_VALUE) *sk; |
168 | 66.0k | int i; |
169 | | |
170 | 66.0k | if (a->name != NULL) |
171 | 0 | return; |
172 | | |
173 | 66.0k | sk = (STACK_OF(CONF_VALUE) *)a->value; |
174 | 241k | for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { |
175 | 175k | vv = sk_CONF_VALUE_value(sk, i); |
176 | 175k | OPENSSL_free(vv->value); |
177 | 175k | OPENSSL_free(vv->name); |
178 | 175k | OPENSSL_free(vv); |
179 | 175k | } |
180 | 66.0k | sk_CONF_VALUE_free(sk); |
181 | 66.0k | OPENSSL_free(a->section); |
182 | 66.0k | OPENSSL_free(a); |
183 | 66.0k | } |
184 | | |
185 | | CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) |
186 | 66.0k | { |
187 | 66.0k | STACK_OF(CONF_VALUE) *sk = NULL; |
188 | 66.0k | int i; |
189 | 66.0k | CONF_VALUE *v = NULL, *vv; |
190 | | |
191 | 66.0k | if ((sk = sk_CONF_VALUE_new_null()) == NULL) |
192 | 0 | goto err; |
193 | 66.0k | if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) |
194 | 0 | goto err; |
195 | 66.0k | i = strlen(section) + 1; |
196 | 66.0k | if ((v->section = OPENSSL_malloc(i)) == NULL) |
197 | 0 | goto err; |
198 | | |
199 | 66.0k | memcpy(v->section, section, i); |
200 | 66.0k | v->name = NULL; |
201 | 66.0k | v->value = (char *)sk; |
202 | | |
203 | 66.0k | vv = lh_CONF_VALUE_insert(conf->data, v); |
204 | 66.0k | if (vv != NULL || lh_CONF_VALUE_error(conf->data) > 0) |
205 | 0 | goto err; |
206 | 66.0k | return v; |
207 | | |
208 | 0 | err: |
209 | 0 | sk_CONF_VALUE_free(sk); |
210 | 0 | if (v != NULL) |
211 | 0 | OPENSSL_free(v->section); |
212 | 0 | OPENSSL_free(v); |
213 | 0 | return NULL; |
214 | 66.0k | } |