]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
1212818e | 2 | * Copyright 2000-2018 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" |
c9ecb131 | 14 | #include "internal/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 RL |
176 | |
177 | CONF *NCONF_new(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) { | |
186 | CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); | |
26a7d938 | 187 | return NULL; |
0f113f3e | 188 | } |
d86b6915 | 189 | |
0f113f3e MC |
190 | return ret; |
191 | } | |
d86b6915 RL |
192 | |
193 | void NCONF_free(CONF *conf) | |
0f113f3e MC |
194 | { |
195 | if (conf == NULL) | |
196 | return; | |
197 | conf->meth->destroy(conf); | |
198 | } | |
d86b6915 RL |
199 | |
200 | void NCONF_free_data(CONF *conf) | |
0f113f3e MC |
201 | { |
202 | if (conf == NULL) | |
203 | return; | |
204 | conf->meth->destroy_data(conf); | |
205 | } | |
d86b6915 RL |
206 | |
207 | int NCONF_load(CONF *conf, const char *file, long *eline) | |
0f113f3e MC |
208 | { |
209 | if (conf == NULL) { | |
210 | CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); | |
211 | return 0; | |
212 | } | |
d86b6915 | 213 | |
0f113f3e MC |
214 | return conf->meth->load(conf, file, eline); |
215 | } | |
d86b6915 | 216 | |
4b618848 | 217 | #ifndef OPENSSL_NO_STDIO |
0f113f3e MC |
218 | int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) |
219 | { | |
220 | BIO *btmp; | |
221 | int ret; | |
75ebbd9a | 222 | if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { |
0f113f3e MC |
223 | CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); |
224 | return 0; | |
225 | } | |
226 | ret = NCONF_load_bio(conf, btmp, eline); | |
227 | BIO_free(btmp); | |
228 | return ret; | |
229 | } | |
d86b6915 RL |
230 | #endif |
231 | ||
0f113f3e MC |
232 | int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) |
233 | { | |
234 | if (conf == NULL) { | |
235 | CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); | |
236 | return 0; | |
237 | } | |
238 | ||
239 | return conf->meth->load_bio(conf, bp, eline); | |
240 | } | |
241 | ||
242 | STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) | |
243 | { | |
244 | if (conf == NULL) { | |
245 | CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); | |
246 | return NULL; | |
247 | } | |
248 | ||
249 | if (section == NULL) { | |
250 | CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); | |
251 | return NULL; | |
252 | } | |
253 | ||
254 | return _CONF_get_section_values(conf, section); | |
255 | } | |
256 | ||
257 | char *NCONF_get_string(const CONF *conf, const char *group, const char *name) | |
258 | { | |
259 | char *s = _CONF_get_string(conf, group, name); | |
260 | ||
261 | /* | |
262 | * Since we may get a value from an environment variable even if conf is | |
263 | * NULL, let's check the value first | |
264 | */ | |
265 | if (s) | |
266 | return s; | |
267 | ||
268 | if (conf == NULL) { | |
269 | CONFerr(CONF_F_NCONF_GET_STRING, | |
270 | CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); | |
271 | return NULL; | |
272 | } | |
273 | CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); | |
274 | ERR_add_error_data(4, "group=", group, " name=", name); | |
275 | return NULL; | |
276 | } | |
277 | ||
c9ecb131 P |
278 | static int default_is_number(const CONF *conf, char c) |
279 | { | |
280 | return ossl_isdigit(c); | |
281 | } | |
282 | ||
283 | static int default_to_int(const CONF *conf, char c) | |
284 | { | |
285 | return (int)(c - '0'); | |
286 | } | |
287 | ||
0f113f3e MC |
288 | int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, |
289 | long *result) | |
290 | { | |
291 | char *str; | |
c9ecb131 P |
292 | long res; |
293 | int (*is_number)(const CONF *, char) = &default_is_number; | |
294 | int (*to_int)(const CONF *, char) = &default_to_int; | |
0f113f3e MC |
295 | |
296 | if (result == NULL) { | |
297 | CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); | |
298 | return 0; | |
299 | } | |
300 | ||
301 | str = NCONF_get_string(conf, group, name); | |
302 | ||
303 | if (str == NULL) | |
304 | return 0; | |
305 | ||
c9ecb131 P |
306 | if (conf != NULL) { |
307 | if (conf->meth->is_number != NULL) | |
308 | is_number = conf->meth->is_number; | |
309 | if (conf->meth->to_int != NULL) | |
310 | to_int = conf->meth->to_int; | |
311 | } | |
312 | for (res = 0; is_number(conf, *str); str++) { | |
313 | const int d = to_int(conf, *str); | |
314 | ||
315 | if (res > (LONG_MAX - d) / 10L) { | |
316 | CONFerr(CONF_F_NCONF_GET_NUMBER_E, CONF_R_NUMBER_TOO_LARGE); | |
317 | return 0; | |
c36b39b5 | 318 | } |
c9ecb131 P |
319 | res = res * 10 + d; |
320 | } | |
0f113f3e | 321 | |
c9ecb131 | 322 | *result = res; |
0f113f3e MC |
323 | return 1; |
324 | } | |
d86b6915 | 325 | |
4b618848 | 326 | #ifndef OPENSSL_NO_STDIO |
9dd5ae65 | 327 | int NCONF_dump_fp(const CONF *conf, FILE *out) |
0f113f3e MC |
328 | { |
329 | BIO *btmp; | |
330 | int ret; | |
75ebbd9a | 331 | if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) { |
0f113f3e MC |
332 | CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); |
333 | return 0; | |
334 | } | |
335 | ret = NCONF_dump_bio(conf, btmp); | |
336 | BIO_free(btmp); | |
337 | return ret; | |
338 | } | |
d86b6915 RL |
339 | #endif |
340 | ||
9dd5ae65 | 341 | int NCONF_dump_bio(const CONF *conf, BIO *out) |
0f113f3e MC |
342 | { |
343 | if (conf == NULL) { | |
344 | CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); | |
345 | return 0; | |
346 | } | |
d86b6915 | 347 | |
0f113f3e MC |
348 | return conf->meth->dump(conf, out); |
349 | } | |
7253fd55 RS |
350 | |
351 | /* | |
352 | * These routines call the C malloc/free, to avoid intermixing with | |
353 | * OpenSSL function pointers before the library is initialized. | |
354 | */ | |
355 | OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void) | |
356 | { | |
357 | OPENSSL_INIT_SETTINGS *ret = malloc(sizeof(*ret)); | |
358 | ||
23dc8feb F |
359 | if (ret == NULL) |
360 | return NULL; | |
361 | ||
362 | memset(ret, 0, sizeof(*ret)); | |
df1f538f VD |
363 | ret->flags = DEFAULT_CONF_MFLAGS; |
364 | ||
7253fd55 RS |
365 | return ret; |
366 | } | |
367 | ||
368 | ||
691064c4 | 369 | #ifndef OPENSSL_NO_STDIO |
df1f538f VD |
370 | int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, |
371 | const char *filename) | |
372 | { | |
373 | char *newfilename = NULL; | |
374 | ||
375 | if (filename != NULL) { | |
376 | newfilename = strdup(filename); | |
377 | if (newfilename == NULL) | |
378 | return 0; | |
379 | } | |
380 | ||
381 | free(settings->filename); | |
382 | settings->filename = newfilename; | |
383 | ||
384 | return 1; | |
385 | } | |
386 | ||
387 | void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, | |
388 | unsigned long flags) | |
389 | { | |
390 | settings->flags = flags; | |
391 | } | |
392 | ||
cda3ae5b RS |
393 | int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, |
394 | const char *appname) | |
7253fd55 | 395 | { |
cda3ae5b | 396 | char *newappname = NULL; |
dae00d63 | 397 | |
cda3ae5b RS |
398 | if (appname != NULL) { |
399 | newappname = strdup(appname); | |
400 | if (newappname == NULL) | |
dae00d63 MC |
401 | return 0; |
402 | } | |
403 | ||
cda3ae5b RS |
404 | free(settings->appname); |
405 | settings->appname = newappname; | |
dae00d63 MC |
406 | |
407 | return 1; | |
7253fd55 | 408 | } |
691064c4 | 409 | #endif |
7253fd55 RS |
410 | |
411 | void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings) | |
412 | { | |
df1f538f | 413 | free(settings->filename); |
cda3ae5b | 414 | free(settings->appname); |
7253fd55 RS |
415 | free(settings); |
416 | } |