/src/openssl30/crypto/conf/conf_def.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * | 
| 4 |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
| 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 | 
| 8 |  |  */ | 
| 9 |  |  | 
| 10 |  | /* Part of the code in here was originally in conf.c, which is now removed */ | 
| 11 |  |  | 
| 12 |  | #include <stdio.h> | 
| 13 |  | #include <string.h> | 
| 14 |  | #include "e_os.h" /* struct stat */ | 
| 15 |  | #ifdef __TANDEM | 
| 16 |  | # include <sys/types.h> /* needed for stat.h */ | 
| 17 |  | # include <sys/stat.h> /* struct stat */ | 
| 18 |  | #endif | 
| 19 |  | #include "internal/cryptlib.h" | 
| 20 |  | #include "internal/o_dir.h" | 
| 21 |  | #include <openssl/lhash.h> | 
| 22 |  | #include <openssl/conf.h> | 
| 23 |  | #include <openssl/conf_api.h> | 
| 24 |  | #include "conf_local.h" | 
| 25 |  | #include "conf_def.h" | 
| 26 |  | #include <openssl/buffer.h> | 
| 27 |  | #include <openssl/err.h> | 
| 28 |  | #ifndef OPENSSL_NO_POSIX_IO | 
| 29 |  | # include <sys/stat.h> | 
| 30 |  | # ifdef _WIN32 | 
| 31 |  | #  define stat    _stat | 
| 32 |  | # endif | 
| 33 |  | #endif | 
| 34 |  |  | 
| 35 |  | #ifndef S_ISDIR | 
| 36 |  | # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) | 
| 37 |  | #endif | 
| 38 |  |  | 
| 39 |  | /* | 
| 40 |  |  * The maximum length we can grow a value to after variable expansion. 64k | 
| 41 |  |  * should be more than enough for all reasonable uses. | 
| 42 |  |  */ | 
| 43 | 23.1k | #define MAX_CONF_VALUE_LENGTH       65536 | 
| 44 |  |  | 
| 45 |  | static int is_keytype(const CONF *conf, char c, unsigned short type); | 
| 46 |  | static char *eat_ws(CONF *conf, char *p); | 
| 47 |  | static void trim_ws(CONF *conf, char *start); | 
| 48 |  | static char *eat_alpha_numeric(CONF *conf, char *p); | 
| 49 |  | static void clear_comments(CONF *conf, char *p); | 
| 50 |  | static int str_copy(CONF *conf, char *section, char **to, char *from); | 
| 51 |  | static char *scan_quote(CONF *conf, char *p); | 
| 52 |  | static char *scan_dquote(CONF *conf, char *p); | 
| 53 | 434k | #define scan_esc(conf,p)        (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) | 
| 54 |  | #ifndef OPENSSL_NO_POSIX_IO | 
| 55 |  | static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx, | 
| 56 |  |                             char **dirpath); | 
| 57 |  | static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx); | 
| 58 |  | #endif | 
| 59 |  |  | 
| 60 |  | static CONF *def_create(CONF_METHOD *meth); | 
| 61 |  | static int def_init_default(CONF *conf); | 
| 62 |  | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 63 |  | static int def_init_WIN32(CONF *conf); | 
| 64 |  | #endif | 
| 65 |  | static int def_destroy(CONF *conf); | 
| 66 |  | static int def_destroy_data(CONF *conf); | 
| 67 |  | static int def_load(CONF *conf, const char *name, long *eline); | 
| 68 |  | static int def_load_bio(CONF *conf, BIO *bp, long *eline); | 
| 69 |  | static int def_dump(const CONF *conf, BIO *bp); | 
| 70 |  | static int def_is_number(const CONF *conf, char c); | 
| 71 |  | static int def_to_int(const CONF *conf, char c); | 
| 72 |  |  | 
| 73 |  | static CONF_METHOD default_method = { | 
| 74 |  |     "OpenSSL default", | 
| 75 |  |     def_create, | 
| 76 |  |     def_init_default, | 
| 77 |  |     def_destroy, | 
| 78 |  |     def_destroy_data, | 
| 79 |  |     def_load_bio, | 
| 80 |  |     def_dump, | 
| 81 |  |     def_is_number, | 
| 82 |  |     def_to_int, | 
| 83 |  |     def_load | 
| 84 |  | }; | 
| 85 |  |  | 
| 86 |  | CONF_METHOD *NCONF_default(void) | 
| 87 | 8.72k | { | 
| 88 | 8.72k |     return &default_method; | 
| 89 | 8.72k | } | 
| 90 |  |  | 
| 91 |  | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 92 |  | static CONF_METHOD WIN32_method = { | 
| 93 |  |     "WIN32", | 
| 94 |  |     def_create, | 
| 95 |  |     def_init_WIN32, | 
| 96 |  |     def_destroy, | 
| 97 |  |     def_destroy_data, | 
| 98 |  |     def_load_bio, | 
| 99 |  |     def_dump, | 
| 100 |  |     def_is_number, | 
| 101 |  |     def_to_int, | 
| 102 |  |     def_load | 
| 103 |  | }; | 
| 104 |  |  | 
| 105 |  | CONF_METHOD *NCONF_WIN32(void) | 
| 106 | 0 | { | 
| 107 | 0 |     return &WIN32_method; | 
| 108 | 0 | } | 
| 109 |  | #endif | 
| 110 |  |  | 
| 111 |  | static CONF *def_create(CONF_METHOD *meth) | 
| 112 | 8.72k | { | 
| 113 | 8.72k |     CONF *ret; | 
| 114 |  |  | 
| 115 | 8.72k |     ret = OPENSSL_malloc(sizeof(*ret)); | 
| 116 | 8.72k |     if (ret != NULL) | 
| 117 | 8.72k |         if (meth->init(ret) == 0) { | 
| 118 | 0 |             OPENSSL_free(ret); | 
| 119 | 0 |             ret = NULL; | 
| 120 | 0 |         } | 
| 121 | 8.72k |     return ret; | 
| 122 | 8.72k | } | 
| 123 |  |  | 
| 124 |  | static int def_init_default(CONF *conf) | 
| 125 | 11.8k | { | 
| 126 | 11.8k |     if (conf == NULL) | 
| 127 | 0 |         return 0; | 
| 128 |  |  | 
| 129 | 11.8k |     memset(conf, 0, sizeof(*conf)); | 
| 130 | 11.8k |     conf->meth = &default_method; | 
| 131 | 11.8k |     conf->meth_data = (void *)CONF_type_default; | 
| 132 |  |  | 
| 133 | 11.8k |     return 1; | 
| 134 | 11.8k | } | 
| 135 |  |  | 
| 136 |  | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 137 |  | static int def_init_WIN32(CONF *conf) | 
| 138 | 0 | { | 
| 139 | 0 |     if (conf == NULL) | 
| 140 | 0 |         return 0; | 
| 141 |  |  | 
| 142 | 0 |     memset(conf, 0, sizeof(*conf)); | 
| 143 | 0 |     conf->meth = &WIN32_method; | 
| 144 | 0 |     conf->meth_data = (void *)CONF_type_win32; | 
| 145 |  | 
 | 
| 146 | 0 |     return 1; | 
| 147 | 0 | } | 
| 148 |  | #endif | 
| 149 |  |  | 
| 150 |  | static int def_destroy(CONF *conf) | 
| 151 | 8.72k | { | 
| 152 | 8.72k |     if (def_destroy_data(conf)) { | 
| 153 | 8.72k |         OPENSSL_free(conf); | 
| 154 | 8.72k |         return 1; | 
| 155 | 8.72k |     } | 
| 156 | 0 |     return 0; | 
| 157 | 8.72k | } | 
| 158 |  |  | 
| 159 |  | static int def_destroy_data(CONF *conf) | 
| 160 | 11.8k | { | 
| 161 | 11.8k |     if (conf == NULL) | 
| 162 | 0 |         return 0; | 
| 163 | 11.8k |     _CONF_free_data(conf); | 
| 164 | 11.8k |     return 1; | 
| 165 | 11.8k | } | 
| 166 |  |  | 
| 167 |  | static int def_load(CONF *conf, const char *name, long *line) | 
| 168 | 36 | { | 
| 169 | 36 |     int ret; | 
| 170 | 36 |     BIO *in = NULL; | 
| 171 |  |  | 
| 172 |  | #ifdef OPENSSL_SYS_VMS | 
| 173 |  |     in = BIO_new_file(name, "r"); | 
| 174 |  | #else | 
| 175 | 36 |     in = BIO_new_file(name, "rb"); | 
| 176 | 36 | #endif | 
| 177 | 36 |     if (in == NULL) { | 
| 178 | 36 |         if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) | 
| 179 | 36 |             ERR_raise(ERR_LIB_CONF, CONF_R_NO_SUCH_FILE); | 
| 180 | 0 |         else | 
| 181 | 36 |             ERR_raise(ERR_LIB_CONF, ERR_R_SYS_LIB); | 
| 182 | 36 |         return 0; | 
| 183 | 36 |     } | 
| 184 |  |  | 
| 185 | 0 |     ret = def_load_bio(conf, in, line); | 
| 186 | 0 |     BIO_free(in); | 
| 187 |  | 
 | 
| 188 | 0 |     return ret; | 
| 189 | 36 | } | 
| 190 |  |  | 
| 191 |  |  | 
| 192 |  | /* Parse a boolean value and fill in *flag. Return 0 on error. */ | 
| 193 |  | static int parsebool(const char *pval, int *flag) | 
| 194 | 2.67k | { | 
| 195 | 2.67k |     if (OPENSSL_strcasecmp(pval, "on") == 0 | 
| 196 | 2.67k |             || OPENSSL_strcasecmp(pval, "true") == 0) { | 
| 197 | 1.96k |         *flag = 1; | 
| 198 | 1.96k |     } else if (OPENSSL_strcasecmp(pval, "off") == 0 | 
| 199 | 707 |             || OPENSSL_strcasecmp(pval, "false") == 0) { | 
| 200 | 599 |         *flag = 0; | 
| 201 | 599 |     } else { | 
| 202 | 108 |         ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA); | 
| 203 | 108 |         return 0; | 
| 204 | 108 |     } | 
| 205 | 2.56k |     return 1; | 
| 206 | 2.67k | } | 
| 207 |  |  | 
| 208 |  | static int def_load_bio(CONF *conf, BIO *in, long *line) | 
| 209 | 3.13k | { | 
| 210 |  | /* The macro BUFSIZE conflicts with a system macro in VxWorks */ | 
| 211 | 20.4M | #define CONFBUFSIZE     512 | 
| 212 | 3.13k |     int bufnum = 0, i, ii; | 
| 213 | 3.13k |     BUF_MEM *buff = NULL; | 
| 214 | 3.13k |     char *s, *p, *end; | 
| 215 | 3.13k |     int again; | 
| 216 | 3.13k |     int first_call = 1; | 
| 217 | 3.13k |     long eline = 0; | 
| 218 | 3.13k |     char btmp[DECIMAL_SIZE(eline) + 1]; | 
| 219 | 3.13k |     CONF_VALUE *v = NULL, *tv; | 
| 220 | 3.13k |     CONF_VALUE *sv = NULL; | 
| 221 | 3.13k |     char *section = NULL, *buf; | 
| 222 | 3.13k |     char *start, *psection, *pname; | 
| 223 | 3.13k |     void *h = (void *)(conf->data); | 
| 224 | 3.13k |     STACK_OF(BIO) *biosk = NULL; | 
| 225 | 3.13k | #ifndef OPENSSL_NO_POSIX_IO | 
| 226 | 3.13k |     char *dirpath = NULL; | 
| 227 | 3.13k |     OPENSSL_DIR_CTX *dirctx = NULL; | 
| 228 | 3.13k | #endif | 
| 229 | 3.13k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 
| 230 | 3.13k |     int numincludes = 0; | 
| 231 | 3.13k | #endif | 
| 232 |  |  | 
| 233 | 3.13k |     if ((buff = BUF_MEM_new()) == NULL) { | 
| 234 | 0 |         ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); | 
| 235 | 0 |         goto err; | 
| 236 | 0 |     } | 
| 237 |  |  | 
| 238 | 3.13k |     section = OPENSSL_strdup("default"); | 
| 239 | 3.13k |     if (section == NULL) { | 
| 240 | 0 |         ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 241 | 0 |         goto err; | 
| 242 | 0 |     } | 
| 243 |  |  | 
| 244 | 3.13k |     if (_CONF_new_data(conf) == 0) { | 
| 245 | 0 |         ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 246 | 0 |         goto err; | 
| 247 | 0 |     } | 
| 248 |  |  | 
| 249 | 3.13k |     sv = _CONF_new_section(conf, section); | 
| 250 | 3.13k |     if (sv == NULL) { | 
| 251 | 0 |         ERR_raise(ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | 
| 252 | 0 |         goto err; | 
| 253 | 0 |     } | 
| 254 |  |  | 
| 255 | 3.13k |     bufnum = 0; | 
| 256 | 3.13k |     again = 0; | 
| 257 | 6.80M |     for (;;) { | 
| 258 | 6.80M |         if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { | 
| 259 | 0 |             ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); | 
| 260 | 0 |             goto err; | 
| 261 | 0 |         } | 
| 262 | 6.80M |         p = &(buff->data[bufnum]); | 
| 263 | 6.80M |         *p = '\0'; | 
| 264 | 6.80M |  read_retry: | 
| 265 | 6.80M |         if (in != NULL && BIO_gets(in, p, CONFBUFSIZE - 1) < 0) | 
| 266 | 0 |             goto err; | 
| 267 | 6.80M |         p[CONFBUFSIZE - 1] = '\0'; | 
| 268 | 6.80M |         ii = i = strlen(p); | 
| 269 | 6.80M |         if (first_call) { | 
| 270 |  |             /* Other BOMs imply unsupported multibyte encoding, | 
| 271 |  |              * so don't strip them and let the error raise */ | 
| 272 | 3.13k |             const unsigned char utf8_bom[3] = {0xEF, 0xBB, 0xBF}; | 
| 273 |  |  | 
| 274 | 3.13k |             if (i >= 3 && memcmp(p, utf8_bom, 3) == 0) { | 
| 275 | 3 |                 memmove(p, p + 3, i - 3); | 
| 276 | 3 |                 p[i - 3] = 0; | 
| 277 | 3 |                 i -= 3; | 
| 278 | 3 |                 ii -= 3; | 
| 279 | 3 |             } | 
| 280 | 3.13k |             first_call = 0; | 
| 281 | 3.13k |         } | 
| 282 | 6.80M |         if (i == 0 && !again) { | 
| 283 |  |             /* the currently processed BIO is NULL or at EOF */ | 
| 284 | 2.17k |             BIO *parent; | 
| 285 |  |  | 
| 286 | 2.17k | #ifndef OPENSSL_NO_POSIX_IO | 
| 287 |  |             /* continue processing with the next file from directory */ | 
| 288 | 2.17k |             if (dirctx != NULL) { | 
| 289 | 197 |                 BIO *next; | 
| 290 |  |  | 
| 291 | 197 |                 if ((next = get_next_file(dirpath, &dirctx)) != NULL) { | 
| 292 | 121 |                     BIO_vfree(in); | 
| 293 | 121 |                     in = next; | 
| 294 | 121 |                     goto read_retry; | 
| 295 | 121 |                 } else { | 
| 296 | 76 |                     OPENSSL_free(dirpath); | 
| 297 | 76 |                     dirpath = NULL; | 
| 298 | 76 |                 } | 
| 299 | 197 |             } | 
| 300 | 2.05k | #endif | 
| 301 |  |             /* no more files in directory, continue with processing parent */ | 
| 302 | 2.05k |             if ((parent = sk_BIO_pop(biosk)) == NULL) { | 
| 303 |  |                 /* everything processed get out of the loop */ | 
| 304 | 1.98k |                 break; | 
| 305 | 1.98k |             } else { | 
| 306 | 76 |                 BIO_vfree(in); | 
| 307 | 76 |                 in = parent; | 
| 308 | 76 |                 goto read_retry; | 
| 309 | 76 |             } | 
| 310 | 2.05k |         } | 
| 311 | 6.80M |         again = 0; | 
| 312 | 13.5M |         while (i > 0) { | 
| 313 | 6.84M |             if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) | 
| 314 | 122k |                 break; | 
| 315 | 6.71M |             else | 
| 316 | 6.71M |                 i--; | 
| 317 | 6.84M |         } | 
| 318 |  |         /* | 
| 319 |  |          * we removed some trailing stuff so there is a new line on the end. | 
| 320 |  |          */ | 
| 321 | 6.80M |         if (ii && i == ii) | 
| 322 | 81.1k |             again = 1;          /* long line */ | 
| 323 | 6.72M |         else { | 
| 324 | 6.72M |             p[i] = '\0'; | 
| 325 | 6.72M |             eline++;            /* another input line */ | 
| 326 | 6.72M |         } | 
| 327 |  |  | 
| 328 |  |         /* we now have a line with trailing \r\n removed */ | 
| 329 |  |  | 
| 330 |  |         /* i is the number of bytes */ | 
| 331 | 6.80M |         bufnum += i; | 
| 332 |  |  | 
| 333 | 6.80M |         v = NULL; | 
| 334 |  |         /* check for line continuation */ | 
| 335 | 6.80M |         if (bufnum >= 1) { | 
| 336 |  |             /* | 
| 337 |  |              * If we have bytes and the last char '\\' and second last char | 
| 338 |  |              * is not '\\' | 
| 339 |  |              */ | 
| 340 | 125k |             p = &(buff->data[bufnum - 1]); | 
| 341 | 125k |             if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { | 
| 342 | 1.27k |                 bufnum--; | 
| 343 | 1.27k |                 again = 1; | 
| 344 | 1.27k |             } | 
| 345 | 125k |         } | 
| 346 | 6.80M |         if (again) | 
| 347 | 82.0k |             continue; | 
| 348 | 6.72M |         bufnum = 0; | 
| 349 | 6.72M |         buf = buff->data; | 
| 350 |  |  | 
| 351 | 6.72M |         clear_comments(conf, buf); | 
| 352 | 6.72M |         s = eat_ws(conf, buf); | 
| 353 | 6.72M |         if (IS_EOF(conf, *s)) | 
| 354 | 6.68M |             continue;           /* blank line */ | 
| 355 | 35.2k |         if (*s == '[') { | 
| 356 | 3.09k |             char *ss; | 
| 357 |  |  | 
| 358 | 3.09k |             s++; | 
| 359 | 3.09k |             start = eat_ws(conf, s); | 
| 360 | 3.09k |             ss = start; | 
| 361 | 3.85k |  again: | 
| 362 | 3.85k |             end = eat_alpha_numeric(conf, ss); | 
| 363 | 3.85k |             p = eat_ws(conf, end); | 
| 364 | 3.85k |             if (*p != ']') { | 
| 365 | 872 |                 if (*p != '\0' && ss != p) { | 
| 366 | 763 |                     ss = p; | 
| 367 | 763 |                     goto again; | 
| 368 | 763 |                 } | 
| 369 | 872 |                 ERR_raise(ERR_LIB_CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); | 
| 370 | 109 |                 goto err; | 
| 371 | 872 |             } | 
| 372 | 2.98k |             *end = '\0'; | 
| 373 | 2.98k |             if (!str_copy(conf, NULL, §ion, start)) | 
| 374 | 0 |                 goto err; | 
| 375 | 2.98k |             if ((sv = _CONF_get_section(conf, section)) == NULL) | 
| 376 | 2.51k |                 sv = _CONF_new_section(conf, section); | 
| 377 | 2.98k |             if (sv == NULL) { | 
| 378 | 0 |                 ERR_raise(ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | 
| 379 | 0 |                 goto err; | 
| 380 | 0 |             } | 
| 381 | 2.98k |             continue; | 
| 382 | 32.1k |         } else { | 
| 383 | 32.1k |             pname = s; | 
| 384 | 32.1k |             end = eat_alpha_numeric(conf, s); | 
| 385 | 32.1k |             if ((end[0] == ':') && (end[1] == ':')) { | 
| 386 | 10.7k |                 *end = '\0'; | 
| 387 | 10.7k |                 end += 2; | 
| 388 | 10.7k |                 psection = pname; | 
| 389 | 10.7k |                 pname = end; | 
| 390 | 10.7k |                 end = eat_alpha_numeric(conf, end); | 
| 391 | 21.3k |             } else { | 
| 392 | 21.3k |                 psection = section; | 
| 393 | 21.3k |             } | 
| 394 | 32.1k |             p = eat_ws(conf, end); | 
| 395 | 32.1k |             if (strncmp(pname, ".pragma", 7) == 0 | 
| 396 | 32.1k |                 && (p != pname + 7 || *p == '=')) { | 
| 397 | 2.81k |                 char *pval; | 
| 398 |  |  | 
| 399 | 2.81k |                 if (*p == '=') { | 
| 400 | 1.66k |                     p++; | 
| 401 | 1.66k |                     p = eat_ws(conf, p); | 
| 402 | 1.66k |                 } | 
| 403 | 2.81k |                 trim_ws(conf, p); | 
| 404 |  |  | 
| 405 |  |                 /* Pragma values take the form keyword:value */ | 
| 406 | 2.81k |                 pval = strchr(p, ':'); | 
| 407 | 2.81k |                 if (pval == NULL || pval == p || pval[1] == '\0') { | 
| 408 | 27 |                     ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA); | 
| 409 | 27 |                     goto err; | 
| 410 | 27 |                 } | 
| 411 |  |  | 
| 412 | 2.78k |                 *pval++ = '\0'; | 
| 413 | 2.78k |                 trim_ws(conf, p); | 
| 414 | 2.78k |                 pval = eat_ws(conf, pval); | 
| 415 |  |  | 
| 416 |  |                 /* | 
| 417 |  |                  * Known pragmas: | 
| 418 |  |                  * | 
| 419 |  |                  * dollarid     takes "on", "true or "off", "false" | 
| 420 |  |                  * abspath      takes "on", "true or "off", "false" | 
| 421 |  |                  * includedir   directory prefix | 
| 422 |  |                  */ | 
| 423 | 2.78k |                 if (strcmp(p, "dollarid") == 0) { | 
| 424 | 664 |                     if (!parsebool(pval, &conf->flag_dollarid)) | 
| 425 | 5 |                         goto err; | 
| 426 | 2.11k |                 } else if (strcmp(p, "abspath") == 0) { | 
| 427 | 661 |                     if (!parsebool(pval, &conf->flag_abspath)) | 
| 428 | 48 |                         goto err; | 
| 429 | 1.45k |                 } else if (strcmp(p, "includedir") == 0) { | 
| 430 | 312 |                     OPENSSL_free(conf->includedir); | 
| 431 | 312 |                     if ((conf->includedir = OPENSSL_strdup(pval)) == NULL) { | 
| 432 | 0 |                         ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 433 | 0 |                         goto err; | 
| 434 | 0 |                     } | 
| 435 | 312 |                 } | 
| 436 |  |  | 
| 437 |  |                 /* | 
| 438 |  |                  * We *ignore* any unknown pragma. | 
| 439 |  |                  */ | 
| 440 | 2.73k |                 continue; | 
| 441 | 29.3k |             } else if (strncmp(pname, ".include", 8) == 0 | 
| 442 | 29.3k |                 && (p != pname + 8 || *p == '=')) { | 
| 443 | 1.07k |                 char *include = NULL; | 
| 444 | 1.07k |                 BIO *next; | 
| 445 | 1.07k |                 const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE"); | 
| 446 | 1.07k |                 char *include_path = NULL; | 
| 447 |  |  | 
| 448 | 1.07k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 
| 449 |  |                 /* | 
| 450 |  |                  * The include processing below can cause the "conf" fuzzer to | 
| 451 |  |                  * timeout due to the fuzzer inserting large and complicated | 
| 452 |  |                  * includes - with a large amount of time spent in | 
| 453 |  |                  * OPENSSL_strlcat/OPENSSL_strcpy. This is not a security | 
| 454 |  |                  * concern because config files should never come from untrusted | 
| 455 |  |                  * sources. We just set an arbitrary limit on the allowed | 
| 456 |  |                  * number of includes when fuzzing to prevent this timeout. | 
| 457 |  |                  */ | 
| 458 | 1.07k |                 if (numincludes++ > 10) | 
| 459 | 17 |                     goto err; | 
| 460 | 1.06k | #endif | 
| 461 |  |  | 
| 462 | 1.06k |                 if (include_dir == NULL) | 
| 463 | 1.06k |                     include_dir = conf->includedir; | 
| 464 |  |  | 
| 465 | 1.06k |                 if (*p == '=') { | 
| 466 | 342 |                     p++; | 
| 467 | 342 |                     p = eat_ws(conf, p); | 
| 468 | 342 |                 } | 
| 469 | 1.06k |                 trim_ws(conf, p); | 
| 470 | 1.06k |                 if (!str_copy(conf, psection, &include, p)) | 
| 471 | 2 |                     goto err; | 
| 472 |  |  | 
| 473 | 1.06k |                 if (include_dir != NULL && !ossl_is_absolute_path(include)) { | 
| 474 | 137 |                     size_t newlen = strlen(include_dir) + strlen(include) + 2; | 
| 475 |  |  | 
| 476 | 137 |                     include_path = OPENSSL_malloc(newlen); | 
| 477 | 137 |                     if (include_path == NULL) { | 
| 478 | 0 |                         ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 479 | 0 |                         OPENSSL_free(include); | 
| 480 | 0 |                         goto err; | 
| 481 | 0 |                     } | 
| 482 |  |  | 
| 483 | 137 |                     OPENSSL_strlcpy(include_path, include_dir, newlen); | 
| 484 | 137 |                     if (!ossl_ends_with_dirsep(include_path)) | 
| 485 | 113 |                         OPENSSL_strlcat(include_path, "/", newlen); | 
| 486 | 137 |                     OPENSSL_strlcat(include_path, include, newlen); | 
| 487 | 137 |                     OPENSSL_free(include); | 
| 488 | 923 |                 } else { | 
| 489 | 923 |                     include_path = include; | 
| 490 | 923 |                 } | 
| 491 |  |  | 
| 492 | 1.06k |                 if (conf->flag_abspath | 
| 493 | 1.06k |                         && !ossl_is_absolute_path(include_path)) { | 
| 494 | 9 |                     ERR_raise(ERR_LIB_CONF, CONF_R_RELATIVE_PATH); | 
| 495 | 9 |                     OPENSSL_free(include_path); | 
| 496 | 9 |                     goto err; | 
| 497 | 9 |                 } | 
| 498 |  |  | 
| 499 |  |                 /* get the BIO of the included file */ | 
| 500 | 1.05k | #ifndef OPENSSL_NO_POSIX_IO | 
| 501 | 1.05k |                 next = process_include(include_path, &dirctx, &dirpath); | 
| 502 | 1.05k |                 if (include_path != dirpath) { | 
| 503 |  |                     /* dirpath will contain include in case of a directory */ | 
| 504 | 930 |                     OPENSSL_free(include_path); | 
| 505 | 930 |                 } | 
| 506 |  | #else | 
| 507 |  |                 next = BIO_new_file(include_path, "r"); | 
| 508 |  |                 OPENSSL_free(include_path); | 
| 509 |  | #endif | 
| 510 |  |  | 
| 511 | 1.05k |                 if (next != NULL) { | 
| 512 |  |                     /* push the currently processing BIO onto stack */ | 
| 513 | 137 |                     if (biosk == NULL) { | 
| 514 | 79 |                         if ((biosk = sk_BIO_new_null()) == NULL) { | 
| 515 | 0 |                             ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 516 | 0 |                             BIO_free(next); | 
| 517 | 0 |                             goto err; | 
| 518 | 0 |                         } | 
| 519 | 79 |                     } | 
| 520 | 137 |                     if (!sk_BIO_push(biosk, in)) { | 
| 521 | 0 |                         ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 522 | 0 |                         BIO_free(next); | 
| 523 | 0 |                         goto err; | 
| 524 | 0 |                     } | 
| 525 |  |                     /* continue with reading from the included BIO */ | 
| 526 | 137 |                     in = next; | 
| 527 | 137 |                 } | 
| 528 | 1.05k |                 continue; | 
| 529 | 28.2k |             } else if (*p != '=') { | 
| 530 | 688 |                 ERR_raise_data(ERR_LIB_CONF, CONF_R_MISSING_EQUAL_SIGN, | 
| 531 | 688 |                                "HERE-->%s", p); | 
| 532 | 688 |                 goto err; | 
| 533 | 688 |             } | 
| 534 | 27.5k |             *end = '\0'; | 
| 535 | 27.5k |             p++; | 
| 536 | 27.5k |             start = eat_ws(conf, p); | 
| 537 | 27.5k |             trim_ws(conf, start); | 
| 538 |  |  | 
| 539 | 27.5k |             if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) { | 
| 540 | 0 |                 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 541 | 0 |                 goto err; | 
| 542 | 0 |             } | 
| 543 | 27.5k |             v->name = OPENSSL_strdup(pname); | 
| 544 | 27.5k |             v->value = NULL; | 
| 545 | 27.5k |             if (v->name == NULL) { | 
| 546 | 0 |                 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 547 | 0 |                 goto err; | 
| 548 | 0 |             } | 
| 549 | 27.5k |             if (!str_copy(conf, psection, &(v->value), start)) | 
| 550 | 243 |                 goto err; | 
| 551 |  |  | 
| 552 | 27.3k |             if (strcmp(psection, section) != 0) { | 
| 553 | 10.7k |                 if ((tv = _CONF_get_section(conf, psection)) | 
| 554 | 10.7k |                     == NULL) | 
| 555 | 8.42k |                     tv = _CONF_new_section(conf, psection); | 
| 556 | 10.7k |                 if (tv == NULL) { | 
| 557 | 0 |                     ERR_raise(ERR_LIB_CONF, | 
| 558 | 0 |                               CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | 
| 559 | 0 |                     goto err; | 
| 560 | 0 |                 } | 
| 561 | 10.7k |             } else | 
| 562 | 16.6k |                 tv = sv; | 
| 563 | 27.3k |             if (_CONF_add_string(conf, tv, v) == 0) { | 
| 564 | 0 |                 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 565 | 0 |                 goto err; | 
| 566 | 0 |             } | 
| 567 | 27.3k |             v = NULL; | 
| 568 | 27.3k |         } | 
| 569 | 35.2k |     } | 
| 570 | 1.98k |     BUF_MEM_free(buff); | 
| 571 | 1.98k |     OPENSSL_free(section); | 
| 572 |  |     /* | 
| 573 |  |      * No need to pop, since we only get here if the stack is empty. | 
| 574 |  |      * If this causes a BIO leak, THE ISSUE IS SOMEWHERE ELSE! | 
| 575 |  |      */ | 
| 576 | 1.98k |     sk_BIO_free(biosk); | 
| 577 | 1.98k |     return 1; | 
| 578 |  |  | 
| 579 | 1.14k |  err: | 
| 580 | 1.14k |     BUF_MEM_free(buff); | 
| 581 | 1.14k |     OPENSSL_free(section); | 
| 582 |  |     /* | 
| 583 |  |      * Since |in| is the first element of the stack and should NOT be freed | 
| 584 |  |      * here, we cannot use sk_BIO_pop_free().  Instead, we pop and free one | 
| 585 |  |      * BIO at a time, making sure that the last one popped isn't. | 
| 586 |  |      */ | 
| 587 | 1.20k |     while (sk_BIO_num(biosk) > 0) { | 
| 588 | 61 |         BIO *popped = sk_BIO_pop(biosk); | 
| 589 | 61 |         BIO_vfree(in); | 
| 590 | 61 |         in = popped; | 
| 591 | 61 |     } | 
| 592 | 1.14k |     sk_BIO_free(biosk); | 
| 593 | 1.14k | #ifndef OPENSSL_NO_POSIX_IO | 
| 594 | 1.14k |     OPENSSL_free(dirpath); | 
| 595 | 1.14k |     if (dirctx != NULL) | 
| 596 | 45 |         OPENSSL_DIR_end(&dirctx); | 
| 597 | 1.14k | #endif | 
| 598 | 1.14k |     if (line != NULL) | 
| 599 | 1.14k |         *line = eline; | 
| 600 | 1.14k |     BIO_snprintf(btmp, sizeof(btmp), "%ld", eline); | 
| 601 | 1.14k |     ERR_add_error_data(2, "line ", btmp); | 
| 602 | 1.14k |     if (h != conf->data) { | 
| 603 | 1.14k |         CONF_free(conf->data); | 
| 604 | 1.14k |         conf->data = NULL; | 
| 605 | 1.14k |     } | 
| 606 | 1.14k |     if (v != NULL) { | 
| 607 | 243 |         OPENSSL_free(v->name); | 
| 608 | 243 |         OPENSSL_free(v->value); | 
| 609 | 243 |         OPENSSL_free(v); | 
| 610 | 243 |     } | 
| 611 | 1.14k |     return 0; | 
| 612 | 3.13k | } | 
| 613 |  |  | 
| 614 |  | static void clear_comments(CONF *conf, char *p) | 
| 615 | 19.3M | { | 
| 616 | 19.3M |     for (;;) { | 
| 617 | 19.3M |         if (IS_FCOMMENT(conf, *p)) { | 
| 618 | 0 |             *p = '\0'; | 
| 619 | 0 |             return; | 
| 620 | 0 |         } | 
| 621 | 19.3M |         if (!IS_WS(conf, *p)) { | 
| 622 | 19.3M |             break; | 
| 623 | 19.3M |         } | 
| 624 | 1.63k |         p++; | 
| 625 | 1.63k |     } | 
| 626 |  |  | 
| 627 | 94.0M |     for (;;) { | 
| 628 | 94.0M |         if (IS_COMMENT(conf, *p)) { | 
| 629 | 537k |             *p = '\0'; | 
| 630 | 537k |             return; | 
| 631 | 537k |         } | 
| 632 | 93.5M |         if (IS_DQUOTE(conf, *p)) { | 
| 633 | 0 |             p = scan_dquote(conf, p); | 
| 634 | 0 |             continue; | 
| 635 | 0 |         } | 
| 636 | 93.5M |         if (IS_QUOTE(conf, *p)) { | 
| 637 | 21.3k |             p = scan_quote(conf, p); | 
| 638 | 21.3k |             continue; | 
| 639 | 21.3k |         } | 
| 640 | 93.4M |         if (IS_ESC(conf, *p)) { | 
| 641 | 387k |             p = scan_esc(conf, p); | 
| 642 | 387k |             continue; | 
| 643 | 387k |         } | 
| 644 | 93.1M |         if (IS_EOF(conf, *p)) | 
| 645 | 18.8M |             return; | 
| 646 | 74.2M |         else | 
| 647 | 74.2M |             p++; | 
| 648 | 93.1M |     } | 
| 649 | 19.3M | } | 
| 650 |  |  | 
| 651 |  | static int str_copy(CONF *conf, char *section, char **pto, char *from) | 
| 652 | 78.2k | { | 
| 653 | 78.2k |     int q, r, rr = 0, to = 0, len = 0; | 
| 654 | 78.2k |     char *s, *e, *rp, *p, *rrp, *np, *cp, v; | 
| 655 | 78.2k |     BUF_MEM *buf; | 
| 656 |  |  | 
| 657 | 78.2k |     if ((buf = BUF_MEM_new()) == NULL) | 
| 658 | 0 |         return 0; | 
| 659 |  |  | 
| 660 | 78.2k |     len = strlen(from) + 1; | 
| 661 | 78.2k |     if (!BUF_MEM_grow(buf, len)) | 
| 662 | 0 |         goto err; | 
| 663 |  |  | 
| 664 | 22.3M |     for (;;) { | 
| 665 | 22.3M |         if (IS_QUOTE(conf, *from)) { | 
| 666 | 17.4k |             q = *from; | 
| 667 | 17.4k |             from++; | 
| 668 | 22.7M |             while (!IS_EOF(conf, *from) && (*from != q)) { | 
| 669 | 22.7M |                 if (IS_ESC(conf, *from)) { | 
| 670 | 28.9k |                     from++; | 
| 671 | 28.9k |                     if (IS_EOF(conf, *from)) | 
| 672 | 782 |                         break; | 
| 673 | 28.9k |                 } | 
| 674 | 22.7M |                 buf->data[to++] = *(from++); | 
| 675 | 22.7M |             } | 
| 676 | 17.4k |             if (*from == q) | 
| 677 | 15.2k |                 from++; | 
| 678 | 22.3M |         } else if (IS_DQUOTE(conf, *from)) { | 
| 679 | 0 |             q = *from; | 
| 680 | 0 |             from++; | 
| 681 | 0 |             while (!IS_EOF(conf, *from)) { | 
| 682 | 0 |                 if (*from == q) { | 
| 683 | 0 |                     if (*(from + 1) == q) { | 
| 684 | 0 |                         from++; | 
| 685 | 0 |                     } else { | 
| 686 | 0 |                         break; | 
| 687 | 0 |                     } | 
| 688 | 0 |                 } | 
| 689 | 0 |                 buf->data[to++] = *(from++); | 
| 690 | 0 |             } | 
| 691 | 0 |             if (*from == q) | 
| 692 | 0 |                 from++; | 
| 693 | 22.3M |         } else if (IS_ESC(conf, *from)) { | 
| 694 | 45.3k |             from++; | 
| 695 | 45.3k |             v = *(from++); | 
| 696 | 45.3k |             if (IS_EOF(conf, v)) | 
| 697 | 975 |                 break; | 
| 698 | 44.4k |             else if (v == 'r') | 
| 699 | 962 |                 v = '\r'; | 
| 700 | 43.4k |             else if (v == 'n') | 
| 701 | 689 |                 v = '\n'; | 
| 702 | 42.7k |             else if (v == 'b') | 
| 703 | 856 |                 v = '\b'; | 
| 704 | 41.9k |             else if (v == 't') | 
| 705 | 418 |                 v = '\t'; | 
| 706 | 44.4k |             buf->data[to++] = v; | 
| 707 | 22.2M |         } else if (IS_EOF(conf, *from)) | 
| 708 | 76.7k |             break; | 
| 709 | 22.1M |         else if (*from == '$' | 
| 710 | 22.1M |                  && (!conf->flag_dollarid | 
| 711 | 40.1k |                      || from[1] == '{' | 
| 712 | 40.1k |                      || from[1] == '(')) { | 
| 713 | 23.5k |             size_t newsize; | 
| 714 |  |  | 
| 715 |  |             /* try to expand it */ | 
| 716 | 23.5k |             rrp = NULL; | 
| 717 | 23.5k |             s = &(from[1]); | 
| 718 | 23.5k |             if (*s == '{') | 
| 719 | 938 |                 q = '}'; | 
| 720 | 22.6k |             else if (*s == '(') | 
| 721 | 951 |                 q = ')'; | 
| 722 | 21.7k |             else | 
| 723 | 21.7k |                 q = 0; | 
| 724 |  |  | 
| 725 | 23.5k |             if (q) | 
| 726 | 1.88k |                 s++; | 
| 727 | 23.5k |             cp = section; | 
| 728 | 23.5k |             e = np = s; | 
| 729 | 7.37M |             while (IS_ALNUM(conf, *e) | 
| 730 | 7.37M |                    || (conf->flag_dollarid && IS_DOLLAR(conf, *e))) | 
| 731 | 7.35M |                 e++; | 
| 732 | 23.5k |             if ((e[0] == ':') && (e[1] == ':')) { | 
| 733 | 2.00k |                 cp = np; | 
| 734 | 2.00k |                 rrp = e; | 
| 735 | 2.00k |                 rr = *e; | 
| 736 | 2.00k |                 *rrp = '\0'; | 
| 737 | 2.00k |                 e += 2; | 
| 738 | 2.00k |                 np = e; | 
| 739 | 3.32k |                 while (IS_ALNUM(conf, *e) | 
| 740 | 3.32k |                        || (conf->flag_dollarid && IS_DOLLAR(conf, *e))) | 
| 741 | 1.31k |                     e++; | 
| 742 | 2.00k |             } | 
| 743 | 23.5k |             r = *e; | 
| 744 | 23.5k |             *e = '\0'; | 
| 745 | 23.5k |             rp = e; | 
| 746 | 23.5k |             if (q) { | 
| 747 | 1.88k |                 if (r != q) { | 
| 748 | 135 |                     ERR_raise(ERR_LIB_CONF, CONF_R_NO_CLOSE_BRACE); | 
| 749 | 135 |                     goto err; | 
| 750 | 135 |                 } | 
| 751 | 1.75k |                 e++; | 
| 752 | 1.75k |             } | 
| 753 |  |             /*- | 
| 754 |  |              * So at this point we have | 
| 755 |  |              * np which is the start of the name string which is | 
| 756 |  |              *   '\0' terminated. | 
| 757 |  |              * cp which is the start of the section string which is | 
| 758 |  |              *   '\0' terminated. | 
| 759 |  |              * e is the 'next point after'. | 
| 760 |  |              * r and rr are the chars replaced by the '\0' | 
| 761 |  |              * rp and rrp is where 'r' and 'rr' came from. | 
| 762 |  |              */ | 
| 763 | 23.4k |             p = _CONF_get_string(conf, cp, np); | 
| 764 | 23.4k |             if (rrp != NULL) | 
| 765 | 1.99k |                 *rrp = rr; | 
| 766 | 23.4k |             *rp = r; | 
| 767 | 23.4k |             if (p == NULL) { | 
| 768 | 356 |                 ERR_raise(ERR_LIB_CONF, CONF_R_VARIABLE_HAS_NO_VALUE); | 
| 769 | 356 |                 goto err; | 
| 770 | 356 |             } | 
| 771 | 23.1k |             newsize = strlen(p) + buf->length - (e - from); | 
| 772 | 23.1k |             if (newsize > MAX_CONF_VALUE_LENGTH) { | 
| 773 | 9 |                 ERR_raise(ERR_LIB_CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG); | 
| 774 | 9 |                 goto err; | 
| 775 | 9 |             } | 
| 776 | 23.0k |             if (!BUF_MEM_grow_clean(buf, newsize)) { | 
| 777 | 0 |                 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 778 | 0 |                 goto err; | 
| 779 | 0 |             } | 
| 780 | 10.2M |             while (*p) | 
| 781 | 10.2M |                 buf->data[to++] = *(p++); | 
| 782 |  |  | 
| 783 |  |             /* | 
| 784 |  |              * Since we change the pointer 'from', we also have to change the | 
| 785 |  |              * perceived length of the string it points at.  /RL | 
| 786 |  |              */ | 
| 787 | 23.0k |             len -= e - from; | 
| 788 | 23.0k |             from = e; | 
| 789 |  |  | 
| 790 |  |             /* | 
| 791 |  |              * In case there were no braces or parenthesis around the | 
| 792 |  |              * variable reference, we have to put back the character that was | 
| 793 |  |              * replaced with a '\0'.  /RL | 
| 794 |  |              */ | 
| 795 | 23.0k |             *rp = r; | 
| 796 | 23.0k |         } else | 
| 797 | 22.1M |             buf->data[to++] = *(from++); | 
| 798 | 22.3M |     } | 
| 799 | 77.7k |     buf->data[to] = '\0'; | 
| 800 | 77.7k |     OPENSSL_free(*pto); | 
| 801 | 77.7k |     *pto = buf->data; | 
| 802 | 77.7k |     OPENSSL_free(buf); | 
| 803 | 77.7k |     return 1; | 
| 804 | 500 |  err: | 
| 805 | 500 |     BUF_MEM_free(buf); | 
| 806 | 500 |     return 0; | 
| 807 | 78.2k | } | 
| 808 |  |  | 
| 809 |  | #ifndef OPENSSL_NO_POSIX_IO | 
| 810 |  | /* | 
| 811 |  |  * Check whether included path is a directory. | 
| 812 |  |  * Returns next BIO to process and in case of a directory | 
| 813 |  |  * also an opened directory context and the include path. | 
| 814 |  |  */ | 
| 815 |  | static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx, | 
| 816 |  |                             char **dirpath) | 
| 817 | 10.4k | { | 
| 818 | 10.4k |     struct stat st; | 
| 819 | 10.4k |     BIO *next; | 
| 820 |  |  | 
| 821 | 10.4k |     if (stat(include, &st) < 0) { | 
| 822 | 2.41k |         ERR_raise_data(ERR_LIB_SYS, errno, "calling stat(%s)", include); | 
| 823 |  |         /* missing include file is not fatal error */ | 
| 824 | 2.41k |         return NULL; | 
| 825 | 2.41k |     } | 
| 826 |  |  | 
| 827 | 8.02k |     if (S_ISDIR(st.st_mode)) { | 
| 828 | 7.97k |         if (*dirctx != NULL) { | 
| 829 | 0 |             ERR_raise_data(ERR_LIB_CONF, CONF_R_RECURSIVE_DIRECTORY_INCLUDE, | 
| 830 | 0 |                            "%s", include); | 
| 831 | 0 |             return NULL; | 
| 832 | 0 |         } | 
| 833 |  |         /* a directory, load its contents */ | 
| 834 | 7.97k |         if ((next = get_next_file(include, dirctx)) != NULL) | 
| 835 | 6.99k |             *dirpath = include; | 
| 836 | 7.97k |         return next; | 
| 837 | 7.97k |     } | 
| 838 |  |  | 
| 839 | 51 |     next = BIO_new_file(include, "r"); | 
| 840 | 51 |     return next; | 
| 841 | 8.02k | } | 
| 842 |  |  | 
| 843 |  | /* | 
| 844 |  |  * Get next file from the directory path. | 
| 845 |  |  * Returns BIO of the next file to read and updates dirctx. | 
| 846 |  |  */ | 
| 847 |  | static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) | 
| 848 | 21.8k | { | 
| 849 | 21.8k |     const char *filename; | 
| 850 | 21.8k |     size_t pathlen; | 
| 851 |  |  | 
| 852 | 21.8k |     pathlen = strlen(path); | 
| 853 | 717k |     while ((filename = OPENSSL_DIR_read(dirctx, path)) != NULL) { | 
| 854 | 709k |         size_t namelen; | 
| 855 |  |  | 
| 856 | 709k |         namelen = strlen(filename); | 
| 857 |  |  | 
| 858 |  |  | 
| 859 | 709k |         if ((namelen > 5 | 
| 860 | 709k |              && OPENSSL_strcasecmp(filename + namelen - 5, ".conf") == 0) | 
| 861 | 709k |              || (namelen > 4 | 
| 862 | 603k |                  && OPENSSL_strcasecmp(filename + namelen - 4, ".cnf") == 0)) { | 
| 863 | 105k |             size_t newlen; | 
| 864 | 105k |             char *newpath; | 
| 865 | 105k |             BIO *bio; | 
| 866 |  |  | 
| 867 | 105k |             newlen = pathlen + namelen + 2; | 
| 868 | 105k |             newpath = OPENSSL_zalloc(newlen); | 
| 869 | 105k |             if (newpath == NULL) { | 
| 870 | 0 |                 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); | 
| 871 | 0 |                 break; | 
| 872 | 0 |             } | 
| 873 |  | #ifdef OPENSSL_SYS_VMS | 
| 874 |  |             /* | 
| 875 |  |              * If the given path isn't clear VMS syntax, | 
| 876 |  |              * we treat it as on Unix. | 
| 877 |  |              */ | 
| 878 |  |             if (path[pathlen - 1] == ']' | 
| 879 |  |                 || path[pathlen - 1] == '>' | 
| 880 |  |                 || path[pathlen - 1] == ':') { | 
| 881 |  |                 /* Clear VMS directory syntax, just copy as is */ | 
| 882 |  |                 OPENSSL_strlcpy(newpath, path, newlen); | 
| 883 |  |             } | 
| 884 |  | #endif | 
| 885 | 105k |             if (newpath[0] == '\0') { | 
| 886 | 105k |                 OPENSSL_strlcpy(newpath, path, newlen); | 
| 887 | 105k |                 OPENSSL_strlcat(newpath, "/", newlen); | 
| 888 | 105k |             } | 
| 889 | 105k |             OPENSSL_strlcat(newpath, filename, newlen); | 
| 890 |  |  | 
| 891 | 105k |             bio = BIO_new_file(newpath, "r"); | 
| 892 | 105k |             OPENSSL_free(newpath); | 
| 893 |  |             /* Errors when opening files are non-fatal. */ | 
| 894 | 105k |             if (bio != NULL) | 
| 895 | 13.9k |                 return bio; | 
| 896 | 105k |         } | 
| 897 | 709k |     } | 
| 898 | 7.87k |     OPENSSL_DIR_end(dirctx); | 
| 899 | 7.87k |     *dirctx = NULL; | 
| 900 | 7.87k |     return NULL; | 
| 901 | 21.8k | } | 
| 902 |  | #endif | 
| 903 |  |  | 
| 904 |  | static int is_keytype(const CONF *conf, char c, unsigned short type) | 
| 905 | 1.01G | { | 
| 906 | 1.01G |     const unsigned short * keytypes = (const unsigned short *) conf->meth_data; | 
| 907 | 1.01G |     unsigned char key = (unsigned char)c; | 
| 908 |  |  | 
| 909 |  | #ifdef CHARSET_EBCDIC | 
| 910 |  | # if CHAR_BIT > 8 | 
| 911 |  |     if (key > 255) { | 
| 912 |  |         /* key is out of range for os_toascii table */ | 
| 913 |  |         return 0; | 
| 914 |  |     } | 
| 915 |  | # endif | 
| 916 |  |     /* convert key from ebcdic to ascii */ | 
| 917 |  |     key = os_toascii[key]; | 
| 918 |  | #endif | 
| 919 |  |  | 
| 920 | 1.01G |     if (key > 127) { | 
| 921 |  |         /* key is not a seven bit ascii character */ | 
| 922 | 48.4M |         return 0; | 
| 923 | 48.4M |     } | 
| 924 |  |  | 
| 925 | 967M |     return (keytypes[key] & type) ? 1 : 0; | 
| 926 | 1.01G | } | 
| 927 |  |  | 
| 928 |  | static char *eat_ws(CONF *conf, char *p) | 
| 929 | 19.6M | { | 
| 930 | 19.6M |     while (IS_WS(conf, *p) && (!IS_EOF(conf, *p))) | 
| 931 | 14.9k |         p++; | 
| 932 | 19.6M |     return p; | 
| 933 | 19.6M | } | 
| 934 |  |  | 
| 935 |  | static void trim_ws(CONF *conf, char *start) | 
| 936 | 119k | { | 
| 937 | 119k |     char *p = start; | 
| 938 |  |  | 
| 939 | 83.6M |     while (!IS_EOF(conf, *p)) | 
| 940 | 83.4M |         p++; | 
| 941 | 119k |     p--; | 
| 942 | 122k |     while ((p >= start) && IS_WS(conf, *p)) | 
| 943 | 2.63k |         p--; | 
| 944 | 119k |     p++; | 
| 945 | 119k |     *p = '\0'; | 
| 946 | 119k | } | 
| 947 |  |  | 
| 948 |  | static char *eat_alpha_numeric(CONF *conf, char *p) | 
| 949 | 109k | { | 
| 950 | 18.5M |     for (;;) { | 
| 951 | 18.5M |         if (IS_ESC(conf, *p)) { | 
| 952 | 47.2k |             p = scan_esc(conf, p); | 
| 953 | 47.2k |             continue; | 
| 954 | 47.2k |         } | 
| 955 | 18.5M |         if (!(IS_ALNUM_PUNCT(conf, *p) | 
| 956 | 18.5M |               || (conf->flag_dollarid && IS_DOLLAR(conf, *p)))) | 
| 957 | 109k |             return p; | 
| 958 | 18.3M |         p++; | 
| 959 | 18.3M |     } | 
| 960 | 109k | } | 
| 961 |  |  | 
| 962 |  | static char *scan_quote(CONF *conf, char *p) | 
| 963 | 21.3k | { | 
| 964 | 21.3k |     int q = *p; | 
| 965 |  |  | 
| 966 | 21.3k |     p++; | 
| 967 | 48.7M |     while (!(IS_EOF(conf, *p)) && (*p != q)) { | 
| 968 | 48.7M |         if (IS_ESC(conf, *p)) { | 
| 969 | 147k |             p++; | 
| 970 | 147k |             if (IS_EOF(conf, *p)) | 
| 971 | 632 |                 return p; | 
| 972 | 147k |         } | 
| 973 | 48.7M |         p++; | 
| 974 | 48.7M |     } | 
| 975 | 20.6k |     if (*p == q) | 
| 976 | 17.7k |         p++; | 
| 977 | 20.6k |     return p; | 
| 978 | 21.3k | } | 
| 979 |  |  | 
| 980 |  | static char *scan_dquote(CONF *conf, char *p) | 
| 981 | 0 | { | 
| 982 | 0 |     int q = *p; | 
| 983 |  | 
 | 
| 984 | 0 |     p++; | 
| 985 | 0 |     while (!(IS_EOF(conf, *p))) { | 
| 986 | 0 |         if (*p == q) { | 
| 987 | 0 |             if (*(p + 1) == q) { | 
| 988 | 0 |                 p++; | 
| 989 | 0 |             } else { | 
| 990 | 0 |                 break; | 
| 991 | 0 |             } | 
| 992 | 0 |         } | 
| 993 | 0 |         p++; | 
| 994 | 0 |     } | 
| 995 | 0 |     if (*p == q) | 
| 996 | 0 |         p++; | 
| 997 | 0 |     return p; | 
| 998 | 0 | } | 
| 999 |  |  | 
| 1000 |  | static void dump_value_doall_arg(const CONF_VALUE *a, BIO *out) | 
| 1001 | 0 | { | 
| 1002 | 0 |     if (a->name) | 
| 1003 | 0 |         BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); | 
| 1004 | 0 |     else | 
| 1005 | 0 |         BIO_printf(out, "[[%s]]\n", a->section); | 
| 1006 | 0 | } | 
| 1007 |  |  | 
| 1008 |  | IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, BIO); | 
| 1009 |  |  | 
| 1010 |  | static int def_dump(const CONF *conf, BIO *out) | 
| 1011 | 0 | { | 
| 1012 | 0 |     lh_CONF_VALUE_doall_BIO(conf->data, dump_value_doall_arg, out); | 
| 1013 | 0 |     return 1; | 
| 1014 | 0 | } | 
| 1015 |  |  | 
| 1016 |  | static int def_is_number(const CONF *conf, char c) | 
| 1017 | 0 | { | 
| 1018 | 0 |     return IS_NUMBER(conf, c); | 
| 1019 | 0 | } | 
| 1020 |  |  | 
| 1021 |  | static int def_to_int(const CONF *conf, char c) | 
| 1022 | 0 | { | 
| 1023 | 0 |     return c - '0'; | 
| 1024 | 0 | } |