]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
33388b44 | 2 | * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. |
d86b6915 | 3 | * |
2044d382 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
62867571 RS |
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 | |
d86b6915 RL |
8 | */ |
9 | ||
07016a8a | 10 | #include "e_os.h" |
d86b6915 | 11 | #include <stdio.h> |
7253fd55 | 12 | #include <string.h> |
176db6dc | 13 | #include "internal/conf.h" |
25f2138b | 14 | #include "crypto/ctype.h" |
d86b6915 RL |
15 | #include <openssl/crypto.h> |
16 | #include <openssl/err.h> | |
17 | #include <openssl/conf.h> | |
18 | #include <openssl/conf_api.h> | |
19 | #include <openssl/lhash.h> | |
20 | ||
0f113f3e | 21 | static CONF_METHOD *default_CONF_method = NULL; |
d86b6915 | 22 | |
b7a26e6d DSH |
23 | /* Init a 'CONF' structure from an old LHASH */ |
24 | ||
3c1d6bbc | 25 | void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) |
0f113f3e MC |
26 | { |
27 | if (default_CONF_method == NULL) | |
28 | default_CONF_method = NCONF_default(); | |
b7a26e6d | 29 | |
0f113f3e MC |
30 | default_CONF_method->init(conf); |
31 | conf->data = hash; | |
32 | } | |
b7a26e6d | 33 | |
0f113f3e MC |
34 | /* |
35 | * The following section contains the "CONF classic" functions, rewritten in | |
36 | * terms of the new CONF interface. | |
37 | */ | |
d86b6915 RL |
38 | |
39 | int CONF_set_default_method(CONF_METHOD *meth) | |
0f113f3e MC |
40 | { |
41 | default_CONF_method = meth; | |
42 | return 1; | |
43 | } | |
d86b6915 | 44 | |
3c1d6bbc | 45 | LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, |
0f113f3e MC |
46 | long *eline) |
47 | { | |
48 | LHASH_OF(CONF_VALUE) *ltmp; | |
49 | BIO *in = NULL; | |
d86b6915 | 50 | |
bc36ee62 | 51 | #ifdef OPENSSL_SYS_VMS |
0f113f3e | 52 | in = BIO_new_file(file, "r"); |
d86b6915 | 53 | #else |
0f113f3e | 54 | in = BIO_new_file(file, "rb"); |
d86b6915 | 55 | #endif |
0f113f3e MC |
56 | if (in == NULL) { |
57 | CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); | |
58 | return NULL; | |
59 | } | |
d86b6915 | 60 | |
0f113f3e MC |
61 | ltmp = CONF_load_bio(conf, in, eline); |
62 | BIO_free(in); | |
d86b6915 | 63 | |
0f113f3e MC |
64 | return ltmp; |
65 | } | |
d86b6915 | 66 | |
4b618848 | 67 | #ifndef OPENSSL_NO_STDIO |
3c1d6bbc | 68 | LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, |
0f113f3e MC |
69 | long *eline) |
70 | { | |
71 | BIO *btmp; | |
72 | LHASH_OF(CONF_VALUE) *ltmp; | |
75ebbd9a | 73 | if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { |
0f113f3e MC |
74 | CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); |
75 | return NULL; | |
76 | } | |
77 | ltmp = CONF_load_bio(conf, btmp, eline); | |
78 | BIO_free(btmp); | |
79 | return ltmp; | |
80 | } | |
d86b6915 RL |
81 | #endif |
82 | ||
3c1d6bbc | 83 | LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, |
0f113f3e MC |
84 | long *eline) |
85 | { | |
86 | CONF ctmp; | |
87 | int ret; | |
d86b6915 | 88 | |
0f113f3e | 89 | CONF_set_nconf(&ctmp, conf); |
d86b6915 | 90 | |
0f113f3e MC |
91 | ret = NCONF_load_bio(&ctmp, bp, eline); |
92 | if (ret) | |
93 | return ctmp.data; | |
94 | return NULL; | |
95 | } | |
d86b6915 | 96 | |
3c1d6bbc | 97 | STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, |
0f113f3e MC |
98 | const char *section) |
99 | { | |
100 | if (conf == NULL) { | |
101 | return NULL; | |
102 | } else { | |
103 | CONF ctmp; | |
104 | CONF_set_nconf(&ctmp, conf); | |
105 | return NCONF_get_section(&ctmp, section); | |
106 | } | |
107 | } | |
108 | ||
109 | char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, | |
110 | const char *name) | |
111 | { | |
112 | if (conf == NULL) { | |
113 | return NCONF_get_string(NULL, group, name); | |
114 | } else { | |
115 | CONF ctmp; | |
116 | CONF_set_nconf(&ctmp, conf); | |
117 | return NCONF_get_string(&ctmp, group, name); | |
118 | } | |
119 | } | |
120 | ||
121 | long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, | |
122 | const char *name) | |
123 | { | |
124 | int status; | |
125 | long result = 0; | |
126 | ||
c9ecb131 | 127 | ERR_set_mark(); |
0f113f3e MC |
128 | if (conf == NULL) { |
129 | status = NCONF_get_number_e(NULL, group, name, &result); | |
130 | } else { | |
131 | CONF ctmp; | |
132 | CONF_set_nconf(&ctmp, conf); | |
133 | status = NCONF_get_number_e(&ctmp, group, name, &result); | |
134 | } | |
c9ecb131 P |
135 | ERR_pop_to_mark(); |
136 | return status == 0 ? 0L : result; | |
0f113f3e | 137 | } |
d86b6915 | 138 | |
3c1d6bbc | 139 | void CONF_free(LHASH_OF(CONF_VALUE) *conf) |
0f113f3e MC |
140 | { |
141 | CONF ctmp; | |
142 | CONF_set_nconf(&ctmp, conf); | |
143 | NCONF_free_data(&ctmp); | |
144 | } | |
d86b6915 | 145 | |
4b618848 | 146 | #ifndef OPENSSL_NO_STDIO |
3c1d6bbc | 147 | int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) |
0f113f3e MC |
148 | { |
149 | BIO *btmp; | |
150 | int ret; | |
151 | ||
75ebbd9a | 152 | if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) { |
0f113f3e MC |
153 | CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); |
154 | return 0; | |
155 | } | |
156 | ret = CONF_dump_bio(conf, btmp); | |
157 | BIO_free(btmp); | |
158 | return ret; | |
159 | } | |
d86b6915 RL |
160 | #endif |
161 | ||
3c1d6bbc | 162 | int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) |
0f113f3e MC |
163 | { |
164 | CONF ctmp; | |
165 | CONF_set_nconf(&ctmp, conf); | |
166 | return NCONF_dump_bio(&ctmp, out); | |
167 | } | |
168 | ||
169 | /* | |
170 | * The following section contains the "New CONF" functions. They are | |
171 | * completely centralised around a new CONF structure that may contain | |
172 | * basically anything, but at least a method pointer and a table of data. | |
173 | * These functions are also written in terms of the bridge functions used by | |
174 | * the "CONF classic" functions, for consistency. | |
175 | */ | |
d86b6915 | 176 | |
d8652be0 | 177 | CONF *NCONF_new_ex(OPENSSL_CTX *libctx, CONF_METHOD *meth) |
0f113f3e MC |
178 | { |
179 | CONF *ret; | |
d86b6915 | 180 | |
0f113f3e MC |
181 | if (meth == NULL) |
182 | meth = NCONF_default(); | |
d86b6915 | 183 | |
0f113f3e MC |
184 | ret = meth->create(meth); |
185 | if (ret == NULL) { | |
22e27978 | 186 | CONFerr(0, ERR_R_MALLOC_FAILURE); |
26a7d938 | 187 | return NULL; |
0f113f3e | 188 | } |
22e27978 | 189 | ret->libctx = libctx; |
d86b6915 | 190 | |
0f113f3e MC |
191 | return ret; |
192 | } | |
d86b6915 | 193 | |
22e27978 SL |
194 | CONF *NCONF_new(CONF_METHOD *meth) |
195 | { | |
d8652be0 | 196 | return NCONF_new_ex(NULL, meth); |
22e27978 SL |
197 | } |
198 | ||
d86b6915 | 199 | void NCONF_free(CONF *conf) |
0f113f3e MC |
200 | { |
201 | if (conf == NULL) | |
202 | return; | |
203 | conf->meth->destroy(conf); | |
204 | } | |
d86b6915 RL |
205 | |
206 | void NCONF_free_data(CONF *conf) | |
0f113f3e MC |
207 | { |
208 | if (conf == NULL) | |
209 | return; | |
210 | conf->meth->destroy_data(conf); | |
211 | } | |
d86b6915 RL |
212 | |
213 | int NCONF_load(CONF *conf, const char *file, long *eline) | |
0f113f3e MC |
214 | { |
215 | if (conf == NULL) { | |
216 | CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); | |
217 | return 0; | |
218 | } | |
d86b6915 | 219 | |
0f113f3e MC |
220 | return conf->meth->load(conf, file, eline); |
221 | } | |
d86b6915 | 222 | |
4b618848 | 223 | #ifndef OPENSSL_NO_STDIO |
0f113f3e MC |
224 | int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) |
225 | { | |
226 | BIO *btmp; | |
227 | int ret; | |
75ebbd9a | 228 | if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { |
0f113f3e MC |
229 | CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); |
230 | return 0; | |
231 | } | |
232 | ret = NCONF_load_bio(conf, btmp, eline); | |
233 | BIO_free(btmp); | |
234 | return ret; | |
235 | } | |
d86b6915 RL |
236 | #endif |
237 | ||
0f113f3e MC |
238 | int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) |
239 | { | |
240 | if (conf == NULL) { | |
241 | CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); | |
242 | return 0; | |
243 | } | |
244 | ||
245 | return conf->meth->load_bio(conf, bp, eline); | |
246 | } | |
247 | ||
248 | STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) | |
249 | { | |
250 | if (conf == NULL) { | |
251 | CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); | |
252 | return NULL; | |
253 | } | |
254 | ||
255 | if (section == NULL) { | |
256 | CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); | |
257 | return NULL; | |
258 | } | |
259 | ||
260 | return _CONF_get_section_values(conf, section); | |
261 | } | |
262 | ||
263 | char *NCONF_get_string(const CONF *conf, const char *group, const char *name) | |
264 | { | |
265 | char *s = _CONF_get_string(conf, group, name); | |
266 | ||
267 | /* | |
268 | * Since we may get a value from an environment variable even if conf is | |
269 | * NULL, let's check the value first | |
270 | */ | |
271 | if (s) | |
272 | return s; | |
273 | ||
274 | if (conf == NULL) { | |
275 | CONFerr(CONF_F_NCONF_GET_STRING, | |
276 | CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); | |
277 | return NULL; | |
278 | } | |
279 | CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); | |
280 | ERR_add_error_data(4, "group=", group, " name=", name); | |
281 | return NULL; | |
282 | } | |
283 | ||
c9ecb131 P |
284 | static int default_is_number(const CONF *conf, char c) |
285 | { | |
286 | return ossl_isdigit(c); | |
287 | } | |
288 | ||
289 | static int default_to_int(const CONF *conf, char c) | |
290 | { | |
291 | return (int)(c - '0'); | |
292 | } | |
293 | ||
0f113f3e MC |
294 | int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, |
295 | long *result) | |
296 | { | |
297 | char *str; | |
c9ecb131 P |
298 | long res; |
299 | int (*is_number)(const CONF *, char) = &default_is_number; | |
300 | int (*to_int)(const CONF *, char) = &default_to_int; | |
0f113f3e MC |
301 | |
302 | if (result == NULL) { | |
303 | CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); | |
304 | return 0; | |
305 | } | |
306 | ||
307 | str = NCONF_get_string(conf, group, name); | |
308 | ||
309 | if (str == NULL) | |
310 | return 0; | |
311 | ||
c9ecb131 P |
312 | if (conf != NULL) { |
313 | if (conf->meth->is_number != NULL) | |
314 | is_number = conf->meth->is_number; | |
315 | if (conf->meth->to_int != NULL) | |
316 | to_int = conf->meth->to_int; | |
317 | } | |
318 | for (res = 0; is_number(conf, *str); str++) { | |
319 | const int d = to_int(conf, *str); | |
320 | ||
321 | if (res > (LONG_MAX - d) / 10L) { | |
322 | CONFerr(CONF_F_NCONF_GET_NUMBER_E, CONF_R_NUMBER_TOO_LARGE); | |
323 | return 0; | |
c36b39b5 | 324 | } |
c9ecb131 P |
325 | res = res * 10 + d; |
326 | } | |
0f113f3e | 327 | |
c9ecb131 | 328 | *result = res; |
0f113f3e MC |
329 | return 1; |
330 | } | |
d86b6915 | 331 | |
4b618848 | 332 | #ifndef OPENSSL_NO_STDIO |
9dd5ae65 | 333 | int NCONF_dump_fp(const CONF *conf, FILE *out) |
0f113f3e MC |
334 | { |
335 | BIO *btmp; | |
336 | int ret; | |
75ebbd9a | 337 | if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) { |
0f113f3e MC |
338 | CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); |
339 | return 0; | |
340 | } | |
341 | ret = NCONF_dump_bio(conf, btmp); | |
342 | BIO_free(btmp); | |
343 | return ret; | |
344 | } | |
d86b6915 RL |
345 | #endif |
346 | ||
9dd5ae65 | 347 | int NCONF_dump_bio(const CONF *conf, BIO *out) |
0f113f3e MC |
348 | { |
349 | if (conf == NULL) { | |
350 | CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); | |
351 | return 0; | |
352 | } | |
d86b6915 | 353 | |
0f113f3e MC |
354 | return conf->meth->dump(conf, out); |
355 | } | |
7253fd55 RS |
356 | |
357 | /* | |
358 | * These routines call the C malloc/free, to avoid intermixing with | |
359 | * OpenSSL function pointers before the library is initialized. | |
360 | */ | |
361 | OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void) | |
362 | { | |
363 | OPENSSL_INIT_SETTINGS *ret = malloc(sizeof(*ret)); | |
364 | ||
23dc8feb F |
365 | if (ret == NULL) |
366 | return NULL; | |
367 | ||
368 | memset(ret, 0, sizeof(*ret)); | |
df1f538f VD |
369 | ret->flags = DEFAULT_CONF_MFLAGS; |
370 | ||
7253fd55 RS |
371 | return ret; |
372 | } | |
373 | ||
374 | ||
691064c4 | 375 | #ifndef OPENSSL_NO_STDIO |
df1f538f VD |
376 | int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, |
377 | const char *filename) | |
378 | { | |
379 | char *newfilename = NULL; | |
380 | ||
381 | if (filename != NULL) { | |
382 | newfilename = strdup(filename); | |
383 | if (newfilename == NULL) | |
384 | return 0; | |
385 | } | |
386 | ||
387 | free(settings->filename); | |
388 | settings->filename = newfilename; | |
389 | ||
390 | return 1; | |
391 | } | |
392 | ||
393 | void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, | |
394 | unsigned long flags) | |
395 | { | |
396 | settings->flags = flags; | |
397 | } | |
398 | ||
cda3ae5b RS |
399 | int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, |
400 | const char *appname) | |
7253fd55 | 401 | { |
cda3ae5b | 402 | char *newappname = NULL; |
dae00d63 | 403 | |
cda3ae5b RS |
404 | if (appname != NULL) { |
405 | newappname = strdup(appname); | |
406 | if (newappname == NULL) | |
dae00d63 MC |
407 | return 0; |
408 | } | |
409 | ||
cda3ae5b RS |
410 | free(settings->appname); |
411 | settings->appname = newappname; | |
dae00d63 MC |
412 | |
413 | return 1; | |
7253fd55 | 414 | } |
691064c4 | 415 | #endif |
7253fd55 RS |
416 | |
417 | void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings) | |
418 | { | |
df1f538f | 419 | free(settings->filename); |
cda3ae5b | 420 | free(settings->appname); |
7253fd55 RS |
421 | free(settings); |
422 | } |