]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/conf/conf_def.c
Deprecate NCONF_WIN32() function
[thirdparty/openssl.git] / crypto / conf / conf_def.c
CommitLineData
62867571 1/*
b524b808 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 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
d02b48c6
RE
8 */
9
d86b6915
RL
10/* Part of the code in here was originally in conf.c, which is now removed */
11
d02b48c6 12#include <stdio.h>
9887c71c 13#include <string.h>
b39fc560 14#include "internal/cryptlib.h"
b524b808 15#include "internal/o_dir.h"
ec577822
BM
16#include <openssl/lhash.h>
17#include <openssl/conf.h>
d86b6915
RL
18#include <openssl/conf_api.h>
19#include "conf_def.h"
ec577822
BM
20#include <openssl/buffer.h>
21#include <openssl/err.h>
b524b808
TM
22#ifndef OPENSSL_NO_POSIX_IO
23# include <sys/stat.h>
24# ifdef _WIN32
25# define stat _stat
26# define strcasecmp _stricmp
27# endif
28#endif
d02b48c6 29
f20aa69e
AP
30#ifndef S_ISDIR
31# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
32#endif
33
8a585601
MC
34/*
35 * The maximum length we can grow a value to after variable expansion. 64k
36 * should be more than enough for all reasonable uses.
37 */
38#define MAX_CONF_VALUE_LENGTH 65536
39
a9b7a06e 40static int is_keytype(const CONF *conf, char c, unsigned short type);
d86b6915 41static char *eat_ws(CONF *conf, char *p);
b524b808 42static void trim_ws(CONF *conf, char *start);
d86b6915
RL
43static char *eat_alpha_numeric(CONF *conf, char *p);
44static void clear_comments(CONF *conf, char *p);
0f113f3e 45static int str_copy(CONF *conf, char *section, char **to, char *from);
d86b6915
RL
46static char *scan_quote(CONF *conf, char *p);
47static char *scan_dquote(CONF *conf, char *p);
0f113f3e 48#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
b524b808
TM
49#ifndef OPENSSL_NO_POSIX_IO
50static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx,
51 char **dirpath);
52static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx);
53#endif
d86b6915
RL
54
55static CONF *def_create(CONF_METHOD *meth);
56static int def_init_default(CONF *conf);
7cfc0a55 57#if !OPENSSL_API_3
d86b6915 58static int def_init_WIN32(CONF *conf);
7cfc0a55 59#endif
d86b6915
RL
60static int def_destroy(CONF *conf);
61static int def_destroy_data(CONF *conf);
befb3e7a
RL
62static int def_load(CONF *conf, const char *name, long *eline);
63static int def_load_bio(CONF *conf, BIO *bp, long *eline);
9dd5ae65
BL
64static int def_dump(const CONF *conf, BIO *bp);
65static int def_is_number(const CONF *conf, char c);
66static int def_to_int(const CONF *conf, char c);
d86b6915 67
d86b6915 68static CONF_METHOD default_method = {
0f113f3e
MC
69 "OpenSSL default",
70 def_create,
71 def_init_default,
72 def_destroy,
73 def_destroy_data,
74 def_load_bio,
75 def_dump,
76 def_is_number,
77 def_to_int,
78 def_load
79};
d86b6915 80
7cfc0a55
RS
81CONF_METHOD *NCONF_default(void)
82{
83 return &default_method;
84}
85
86#if ! OPENSSL_API_3
d86b6915 87static CONF_METHOD WIN32_method = {
0f113f3e
MC
88 "WIN32",
89 def_create,
90 def_init_WIN32,
91 def_destroy,
92 def_destroy_data,
93 def_load_bio,
94 def_dump,
95 def_is_number,
96 def_to_int,
97 def_load
98};
d86b6915 99
3cb7c5cf 100CONF_METHOD *NCONF_WIN32(void)
0f113f3e
MC
101{
102 return &WIN32_method;
103}
7cfc0a55 104#endif
d02b48c6 105
d86b6915 106static CONF *def_create(CONF_METHOD *meth)
0f113f3e
MC
107{
108 CONF *ret;
109
b4faea50 110 ret = OPENSSL_malloc(sizeof(*ret));
90945fa3 111 if (ret != NULL)
0f113f3e
MC
112 if (meth->init(ret) == 0) {
113 OPENSSL_free(ret);
114 ret = NULL;
115 }
116 return ret;
117}
118
d86b6915 119static int def_init_default(CONF *conf)
0f113f3e
MC
120{
121 if (conf == NULL)
122 return 0;
d86b6915 123
0f113f3e
MC
124 conf->meth = &default_method;
125 conf->meth_data = (void *)CONF_type_default;
126 conf->data = NULL;
d02b48c6 127
0f113f3e
MC
128 return 1;
129}
8623f693 130
7cfc0a55 131#if ! OPENSSL_API_3
d86b6915 132static int def_init_WIN32(CONF *conf)
0f113f3e
MC
133{
134 if (conf == NULL)
135 return 0;
8623f693 136
0f113f3e
MC
137 conf->meth = &WIN32_method;
138 conf->meth_data = (void *)CONF_type_win32;
139 conf->data = NULL;
d86b6915 140
0f113f3e
MC
141 return 1;
142}
7cfc0a55 143#endif
d86b6915
RL
144
145static int def_destroy(CONF *conf)
0f113f3e
MC
146{
147 if (def_destroy_data(conf)) {
148 OPENSSL_free(conf);
149 return 1;
150 }
151 return 0;
152}
8623f693 153
d86b6915 154static int def_destroy_data(CONF *conf)
0f113f3e
MC
155{
156 if (conf == NULL)
157 return 0;
158 _CONF_free_data(conf);
159 return 1;
160}
8623f693 161
befb3e7a 162static int def_load(CONF *conf, const char *name, long *line)
0f113f3e
MC
163{
164 int ret;
165 BIO *in = NULL;
befb3e7a 166
bc36ee62 167#ifdef OPENSSL_SYS_VMS
0f113f3e 168 in = BIO_new_file(name, "r");
befb3e7a 169#else
0f113f3e 170 in = BIO_new_file(name, "rb");
befb3e7a 171#endif
0f113f3e
MC
172 if (in == NULL) {
173 if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
174 CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE);
175 else
176 CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB);
177 return 0;
178 }
befb3e7a 179
0f113f3e
MC
180 ret = def_load_bio(conf, in, line);
181 BIO_free(in);
befb3e7a 182
0f113f3e
MC
183 return ret;
184}
befb3e7a
RL
185
186static int def_load_bio(CONF *conf, BIO *in, long *line)
0f113f3e 187{
6a89a25c 188/* The macro BUFSIZE conflicts with a system macro in VxWorks */
0f113f3e
MC
189#define CONFBUFSIZE 512
190 int bufnum = 0, i, ii;
191 BUF_MEM *buff = NULL;
192 char *s, *p, *end;
193 int again;
194 long eline = 0;
195 char btmp[DECIMAL_SIZE(eline) + 1];
196 CONF_VALUE *v = NULL, *tv;
197 CONF_VALUE *sv = NULL;
198 char *section = NULL, *buf;
199 char *start, *psection, *pname;
200 void *h = (void *)(conf->data);
b524b808
TM
201 STACK_OF(BIO) *biosk = NULL;
202#ifndef OPENSSL_NO_POSIX_IO
203 char *dirpath = NULL;
204 OPENSSL_DIR_CTX *dirctx = NULL;
205#endif
0f113f3e
MC
206
207 if ((buff = BUF_MEM_new()) == NULL) {
208 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
209 goto err;
210 }
211
7644a9ae 212 section = OPENSSL_strdup("default");
0f113f3e
MC
213 if (section == NULL) {
214 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
215 goto err;
216 }
0f113f3e
MC
217
218 if (_CONF_new_data(conf) == 0) {
219 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
220 goto err;
221 }
222
223 sv = _CONF_new_section(conf, section);
224 if (sv == NULL) {
225 CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
226 goto err;
227 }
228
229 bufnum = 0;
230 again = 0;
231 for (;;) {
232 if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
233 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
234 goto err;
235 }
236 p = &(buff->data[bufnum]);
237 *p = '\0';
b524b808 238 read_retry:
0f113f3e
MC
239 BIO_gets(in, p, CONFBUFSIZE - 1);
240 p[CONFBUFSIZE - 1] = '\0';
241 ii = i = strlen(p);
b524b808
TM
242 if (i == 0 && !again) {
243 /* the currently processed BIO is at EOF */
244 BIO *parent;
245
246#ifndef OPENSSL_NO_POSIX_IO
247 /* continue processing with the next file from directory */
248 if (dirctx != NULL) {
249 BIO *next;
250
251 if ((next = get_next_file(dirpath, &dirctx)) != NULL) {
252 BIO_vfree(in);
253 in = next;
254 goto read_retry;
255 } else {
256 OPENSSL_free(dirpath);
257 dirpath = NULL;
258 }
259 }
260#endif
261 /* no more files in directory, continue with processing parent */
262 if ((parent = sk_BIO_pop(biosk)) == NULL) {
263 /* everything processed get out of the loop */
264 break;
265 } else {
266 BIO_vfree(in);
267 in = parent;
268 goto read_retry;
269 }
270 }
0f113f3e
MC
271 again = 0;
272 while (i > 0) {
273 if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
274 break;
275 else
276 i--;
277 }
278 /*
279 * we removed some trailing stuff so there is a new line on the end.
280 */
281 if (ii && i == ii)
282 again = 1; /* long line */
283 else {
284 p[i] = '\0';
285 eline++; /* another input line */
286 }
287
288 /* we now have a line with trailing \r\n removed */
289
290 /* i is the number of bytes */
291 bufnum += i;
292
293 v = NULL;
294 /* check for line continuation */
295 if (bufnum >= 1) {
296 /*
297 * If we have bytes and the last char '\\' and second last char
298 * is not '\\'
299 */
300 p = &(buff->data[bufnum - 1]);
301 if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
302 bufnum--;
303 again = 1;
304 }
305 }
306 if (again)
307 continue;
308 bufnum = 0;
309 buf = buff->data;
310
311 clear_comments(conf, buf);
312 s = eat_ws(conf, buf);
313 if (IS_EOF(conf, *s))
314 continue; /* blank line */
315 if (*s == '[') {
316 char *ss;
317
318 s++;
319 start = eat_ws(conf, s);
320 ss = start;
321 again:
322 end = eat_alpha_numeric(conf, ss);
323 p = eat_ws(conf, end);
324 if (*p != ']') {
325 if (*p != '\0' && ss != p) {
326 ss = p;
327 goto again;
328 }
329 CONFerr(CONF_F_DEF_LOAD_BIO,
330 CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
331 goto err;
332 }
333 *end = '\0';
334 if (!str_copy(conf, NULL, &section, start))
335 goto err;
336 if ((sv = _CONF_get_section(conf, section)) == NULL)
337 sv = _CONF_new_section(conf, section);
338 if (sv == NULL) {
339 CONFerr(CONF_F_DEF_LOAD_BIO,
340 CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
341 goto err;
342 }
343 continue;
344 } else {
345 pname = s;
0f113f3e
MC
346 end = eat_alpha_numeric(conf, s);
347 if ((end[0] == ':') && (end[1] == ':')) {
348 *end = '\0';
349 end += 2;
350 psection = pname;
351 pname = end;
352 end = eat_alpha_numeric(conf, end);
b524b808
TM
353 } else {
354 psection = section;
0f113f3e
MC
355 }
356 p = eat_ws(conf, end);
9d556033
TM
357 if (strncmp(pname, ".include", 8) == 0
358 && (p != pname + 8 || *p == '=')) {
b524b808
TM
359 char *include = NULL;
360 BIO *next;
7bb82f92
SL
361 const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE");
362 char *include_path = NULL;
b524b808 363
9d556033
TM
364 if (*p == '=') {
365 p++;
366 p = eat_ws(conf, p);
367 }
b524b808
TM
368 trim_ws(conf, p);
369 if (!str_copy(conf, psection, &include, p))
370 goto err;
7bb82f92
SL
371
372 if (include_dir != NULL) {
373 size_t newlen = strlen(include_dir) + strlen(include) + 2;
374
375 include_path = OPENSSL_malloc(newlen);
376 OPENSSL_strlcpy(include_path, include_dir, newlen);
377 OPENSSL_strlcat(include_path, "/", newlen);
378 OPENSSL_strlcat(include_path, include, newlen);
379 } else {
380 include_path = include;
381 }
382
b524b808
TM
383 /* get the BIO of the included file */
384#ifndef OPENSSL_NO_POSIX_IO
7bb82f92
SL
385 next = process_include(include_path, &dirctx, &dirpath);
386 if (include_path != dirpath) {
b524b808
TM
387 /* dirpath will contain include in case of a directory */
388 OPENSSL_free(include);
7bb82f92
SL
389 if (include_path != include)
390 OPENSSL_free(include_path);
b524b808
TM
391 }
392#else
7bb82f92 393 next = BIO_new_file(include_path, "r");
b524b808 394 OPENSSL_free(include);
7bb82f92
SL
395 if (include_path != include)
396 OPENSSL_free(include_path);
b524b808 397#endif
7bb82f92 398
b524b808
TM
399 if (next != NULL) {
400 /* push the currently processing BIO onto stack */
401 if (biosk == NULL) {
402 if ((biosk = sk_BIO_new_null()) == NULL) {
403 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
404 goto err;
405 }
406 }
407 if (!sk_BIO_push(biosk, in)) {
408 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
409 goto err;
410 }
411 /* continue with reading from the included BIO */
412 in = next;
413 }
414 continue;
415 } else if (*p != '=') {
0f113f3e
MC
416 CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN);
417 goto err;
418 }
419 *end = '\0';
420 p++;
421 start = eat_ws(conf, p);
b524b808 422 trim_ws(conf, start);
0f113f3e 423
75ebbd9a 424 if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) {
0f113f3e
MC
425 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
426 goto err;
427 }
a2371fa9 428 v->name = OPENSSL_strdup(pname);
0f113f3e
MC
429 v->value = NULL;
430 if (v->name == NULL) {
431 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
432 goto err;
433 }
0f113f3e
MC
434 if (!str_copy(conf, psection, &(v->value), start))
435 goto err;
436
437 if (strcmp(psection, section) != 0) {
438 if ((tv = _CONF_get_section(conf, psection))
439 == NULL)
440 tv = _CONF_new_section(conf, psection);
441 if (tv == NULL) {
442 CONFerr(CONF_F_DEF_LOAD_BIO,
443 CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
444 goto err;
445 }
446 } else
447 tv = sv;
0f113f3e
MC
448 if (_CONF_add_string(conf, tv, v) == 0) {
449 CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
450 goto err;
451 }
0f113f3e
MC
452 v = NULL;
453 }
454 }
25aaa98a 455 BUF_MEM_free(buff);
b548a1f1 456 OPENSSL_free(section);
85aebfcc
RL
457 /*
458 * No need to pop, since we only get here if the stack is empty.
459 * If this causes a BIO leak, THE ISSUE IS SOMEWHERE ELSE!
460 */
461 sk_BIO_free(biosk);
a2371fa9 462 return 1;
0f113f3e 463 err:
25aaa98a 464 BUF_MEM_free(buff);
b548a1f1 465 OPENSSL_free(section);
85aebfcc
RL
466 /*
467 * Since |in| is the first element of the stack and should NOT be freed
468 * here, we cannot use sk_BIO_pop_free(). Instead, we pop and free one
469 * BIO at a time, making sure that the last one popped isn't.
470 */
471 while (sk_BIO_num(biosk) > 0) {
472 BIO *popped = sk_BIO_pop(biosk);
473 BIO_vfree(in);
474 in = popped;
475 }
476 sk_BIO_free(biosk);
b524b808
TM
477#ifndef OPENSSL_NO_POSIX_IO
478 OPENSSL_free(dirpath);
479 if (dirctx != NULL)
480 OPENSSL_DIR_end(&dirctx);
481#endif
0f113f3e
MC
482 if (line != NULL)
483 *line = eline;
a2371fa9 484 BIO_snprintf(btmp, sizeof(btmp), "%ld", eline);
0f113f3e 485 ERR_add_error_data(2, "line ", btmp);
25aaa98a 486 if (h != conf->data) {
0f113f3e
MC
487 CONF_free(conf->data);
488 conf->data = NULL;
489 }
490 if (v != NULL) {
b548a1f1
RS
491 OPENSSL_free(v->name);
492 OPENSSL_free(v->value);
493 OPENSSL_free(v);
0f113f3e 494 }
a2371fa9 495 return 0;
0f113f3e 496}
8623f693 497
d86b6915 498static void clear_comments(CONF *conf, char *p)
0f113f3e
MC
499{
500 for (;;) {
501 if (IS_FCOMMENT(conf, *p)) {
502 *p = '\0';
503 return;
504 }
505 if (!IS_WS(conf, *p)) {
506 break;
507 }
508 p++;
509 }
510
511 for (;;) {
512 if (IS_COMMENT(conf, *p)) {
513 *p = '\0';
514 return;
515 }
516 if (IS_DQUOTE(conf, *p)) {
517 p = scan_dquote(conf, p);
518 continue;
519 }
520 if (IS_QUOTE(conf, *p)) {
521 p = scan_quote(conf, p);
522 continue;
523 }
524 if (IS_ESC(conf, *p)) {
525 p = scan_esc(conf, p);
526 continue;
527 }
528 if (IS_EOF(conf, *p))
529 return;
530 else
531 p++;
532 }
533}
d02b48c6 534
d86b6915 535static int str_copy(CONF *conf, char *section, char **pto, char *from)
0f113f3e
MC
536{
537 int q, r, rr = 0, to = 0, len = 0;
538 char *s, *e, *rp, *p, *rrp, *np, *cp, v;
539 BUF_MEM *buf;
540
541 if ((buf = BUF_MEM_new()) == NULL)
a2371fa9 542 return 0;
0f113f3e
MC
543
544 len = strlen(from) + 1;
545 if (!BUF_MEM_grow(buf, len))
546 goto err;
547
548 for (;;) {
549 if (IS_QUOTE(conf, *from)) {
550 q = *from;
551 from++;
552 while (!IS_EOF(conf, *from) && (*from != q)) {
553 if (IS_ESC(conf, *from)) {
554 from++;
555 if (IS_EOF(conf, *from))
556 break;
557 }
558 buf->data[to++] = *(from++);
559 }
560 if (*from == q)
561 from++;
562 } else if (IS_DQUOTE(conf, *from)) {
563 q = *from;
564 from++;
565 while (!IS_EOF(conf, *from)) {
566 if (*from == q) {
567 if (*(from + 1) == q) {
568 from++;
569 } else {
570 break;
571 }
572 }
573 buf->data[to++] = *(from++);
574 }
575 if (*from == q)
576 from++;
577 } else if (IS_ESC(conf, *from)) {
578 from++;
579 v = *(from++);
580 if (IS_EOF(conf, v))
581 break;
582 else if (v == 'r')
583 v = '\r';
584 else if (v == 'n')
585 v = '\n';
586 else if (v == 'b')
587 v = '\b';
588 else if (v == 't')
589 v = '\t';
590 buf->data[to++] = v;
591 } else if (IS_EOF(conf, *from))
592 break;
593 else if (*from == '$') {
8a585601
MC
594 size_t newsize;
595
0f113f3e
MC
596 /* try to expand it */
597 rrp = NULL;
598 s = &(from[1]);
599 if (*s == '{')
600 q = '}';
601 else if (*s == '(')
602 q = ')';
603 else
604 q = 0;
605
606 if (q)
607 s++;
608 cp = section;
609 e = np = s;
69e2b8d6 610 while (IS_ALNUM(conf, *e))
0f113f3e
MC
611 e++;
612 if ((e[0] == ':') && (e[1] == ':')) {
613 cp = np;
614 rrp = e;
615 rr = *e;
616 *rrp = '\0';
617 e += 2;
618 np = e;
69e2b8d6 619 while (IS_ALNUM(conf, *e))
0f113f3e
MC
620 e++;
621 }
622 r = *e;
623 *e = '\0';
624 rp = e;
625 if (q) {
626 if (r != q) {
627 CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE);
628 goto err;
629 }
630 e++;
631 }
50e735f9
MC
632 /*-
633 * So at this point we have
634 * np which is the start of the name string which is
635 * '\0' terminated.
636 * cp which is the start of the section string which is
637 * '\0' terminated.
638 * e is the 'next point after'.
639 * r and rr are the chars replaced by the '\0'
640 * rp and rrp is where 'r' and 'rr' came from.
641 */
0f113f3e
MC
642 p = _CONF_get_string(conf, cp, np);
643 if (rrp != NULL)
644 *rrp = rr;
645 *rp = r;
646 if (p == NULL) {
647 CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
648 goto err;
649 }
8a585601
MC
650 newsize = strlen(p) + buf->length - (e - from);
651 if (newsize > MAX_CONF_VALUE_LENGTH) {
652 CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG);
653 goto err;
654 }
655 if (!BUF_MEM_grow_clean(buf, newsize)) {
b0333e69
GP
656 CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
657 goto err;
658 }
0f113f3e
MC
659 while (*p)
660 buf->data[to++] = *(p++);
661
662 /*
663 * Since we change the pointer 'from', we also have to change the
664 * perceived length of the string it points at. /RL
665 */
666 len -= e - from;
667 from = e;
668
669 /*
670 * In case there were no braces or parenthesis around the
671 * variable reference, we have to put back the character that was
672 * replaced with a '\0'. /RL
673 */
674 *rp = r;
675 } else
676 buf->data[to++] = *(from++);
677 }
678 buf->data[to] = '\0';
b548a1f1 679 OPENSSL_free(*pto);
0f113f3e
MC
680 *pto = buf->data;
681 OPENSSL_free(buf);
a2371fa9 682 return 1;
0f113f3e 683 err:
25aaa98a 684 BUF_MEM_free(buf);
a2371fa9 685 return 0;
0f113f3e 686}
d02b48c6 687
b524b808
TM
688#ifndef OPENSSL_NO_POSIX_IO
689/*
690 * Check whether included path is a directory.
691 * Returns next BIO to process and in case of a directory
692 * also an opened directory context and the include path.
693 */
694static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx,
695 char **dirpath)
696{
2661d716 697 struct stat st;
b524b808
TM
698 BIO *next;
699
700 if (stat(include, &st) < 0) {
ff988500
RS
701 ERR_raise_data(ERR_LIB_SYS, errno,
702 "calling stat(%s)",
703 include);
b524b808
TM
704 /* missing include file is not fatal error */
705 return NULL;
706 }
707
f20aa69e 708 if (S_ISDIR(st.st_mode)) {
b524b808
TM
709 if (*dirctx != NULL) {
710 CONFerr(CONF_F_PROCESS_INCLUDE,
711 CONF_R_RECURSIVE_DIRECTORY_INCLUDE);
712 ERR_add_error_data(1, include);
713 return NULL;
714 }
715 /* a directory, load its contents */
716 if ((next = get_next_file(include, dirctx)) != NULL)
717 *dirpath = include;
718 return next;
719 }
720
721 next = BIO_new_file(include, "r");
722 return next;
723}
724
725/*
726 * Get next file from the directory path.
727 * Returns BIO of the next file to read and updates dirctx.
728 */
729static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx)
730{
731 const char *filename;
732
733 while ((filename = OPENSSL_DIR_read(dirctx, path)) != NULL) {
734 size_t namelen;
735
736 namelen = strlen(filename);
737
4f7c840a 738
b524b808
TM
739 if ((namelen > 5 && strcasecmp(filename + namelen - 5, ".conf") == 0)
740 || (namelen > 4 && strcasecmp(filename + namelen - 4, ".cnf") == 0)) {
741 size_t newlen;
742 char *newpath;
743 BIO *bio;
744
745 newlen = strlen(path) + namelen + 2;
746 newpath = OPENSSL_zalloc(newlen);
747 if (newpath == NULL) {
748 CONFerr(CONF_F_GET_NEXT_FILE, ERR_R_MALLOC_FAILURE);
749 break;
750 }
4f7c840a
RL
751#ifdef OPENSSL_SYS_VMS
752 /*
753 * If the given path isn't clear VMS syntax,
754 * we treat it as on Unix.
755 */
756 {
757 size_t pathlen = strlen(path);
758
759 if (path[pathlen - 1] == ']' || path[pathlen - 1] == '>'
760 || path[pathlen - 1] == ':') {
761 /* Clear VMS directory syntax, just copy as is */
762 OPENSSL_strlcpy(newpath, path, newlen);
763 }
764 }
b524b808 765#endif
4f7c840a
RL
766 if (newpath[0] == '\0') {
767 OPENSSL_strlcpy(newpath, path, newlen);
768 OPENSSL_strlcat(newpath, "/", newlen);
769 }
b524b808
TM
770 OPENSSL_strlcat(newpath, filename, newlen);
771
772 bio = BIO_new_file(newpath, "r");
773 OPENSSL_free(newpath);
774 /* Errors when opening files are non-fatal. */
775 if (bio != NULL)
776 return bio;
777 }
778 }
779 OPENSSL_DIR_end(dirctx);
780 *dirctx = NULL;
781 return NULL;
782}
783#endif
784
a9b7a06e
DMSP
785static int is_keytype(const CONF *conf, char c, unsigned short type)
786{
787 const unsigned short * keytypes = (const unsigned short *) conf->meth_data;
788 unsigned char key = (unsigned char)c;
789
790#ifdef CHARSET_EBCDIC
791# if CHAR_BIT > 8
792 if (key > 255) {
793 /* key is out of range for os_toascii table */
794 return 0;
795 }
796# endif
797 /* convert key from ebcdic to ascii */
798 key = os_toascii[key];
799#endif
800
801 if (key > 127) {
802 /* key is not a seven bit ascii character */
803 return 0;
804 }
805
806 return (keytypes[key] & type) ? 1 : 0;
807}
808
d86b6915 809static char *eat_ws(CONF *conf, char *p)
0f113f3e
MC
810{
811 while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
812 p++;
a2371fa9 813 return p;
0f113f3e 814}
d02b48c6 815
b524b808
TM
816static void trim_ws(CONF *conf, char *start)
817{
818 char *p = start;
819
820 while (!IS_EOF(conf, *p))
821 p++;
822 p--;
823 while ((p >= start) && IS_WS(conf, *p))
824 p--;
825 p++;
826 *p = '\0';
827}
828
d86b6915 829static char *eat_alpha_numeric(CONF *conf, char *p)
0f113f3e
MC
830{
831 for (;;) {
832 if (IS_ESC(conf, *p)) {
833 p = scan_esc(conf, p);
834 continue;
835 }
69e2b8d6 836 if (!IS_ALNUM_PUNCT(conf, *p))
a2371fa9 837 return p;
0f113f3e
MC
838 p++;
839 }
840}
d02b48c6 841
d86b6915 842static char *scan_quote(CONF *conf, char *p)
0f113f3e
MC
843{
844 int q = *p;
845
846 p++;
847 while (!(IS_EOF(conf, *p)) && (*p != q)) {
848 if (IS_ESC(conf, *p)) {
849 p++;
850 if (IS_EOF(conf, *p))
a2371fa9 851 return p;
0f113f3e
MC
852 }
853 p++;
854 }
855 if (*p == q)
856 p++;
a2371fa9 857 return p;
0f113f3e 858}
d86b6915
RL
859
860static char *scan_dquote(CONF *conf, char *p)
0f113f3e
MC
861{
862 int q = *p;
863
864 p++;
865 while (!(IS_EOF(conf, *p))) {
866 if (*p == q) {
867 if (*(p + 1) == q) {
868 p++;
869 } else {
870 break;
871 }
872 }
873 p++;
874 }
875 if (*p == q)
876 p++;
a2371fa9 877 return p;
0f113f3e 878}
d02b48c6 879
2a056de8 880static void dump_value_doall_arg(const CONF_VALUE *a, BIO *out)
0f113f3e
MC
881{
882 if (a->name)
883 BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
884 else
885 BIO_printf(out, "[[%s]]\n", a->section);
886}
d86b6915 887
2a056de8 888IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, BIO);
3c914840 889
9dd5ae65 890static int def_dump(const CONF *conf, BIO *out)
0f113f3e 891{
2a056de8 892 lh_CONF_VALUE_doall_BIO(conf->data, dump_value_doall_arg, out);
0f113f3e
MC
893 return 1;
894}
d02b48c6 895
9dd5ae65 896static int def_is_number(const CONF *conf, char c)
0f113f3e
MC
897{
898 return IS_NUMBER(conf, c);
899}
d02b48c6 900
9dd5ae65 901static int def_to_int(const CONF *conf, char c)
0f113f3e
MC
902{
903 return c - '0';
904}