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