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