1/* 2 * Copyright 2000-2021 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#include "e_os.h" 11#include <stdio.h> 12#include <string.h> 13#include "internal/conf.h" 14#include "crypto/ctype.h" 15#include <openssl/crypto.h> 16#include <openssl/err.h> 17#include <openssl/conf.h> 18#include <openssl/conf_api.h> 19#include "conf_local.h" 20#include <openssl/lhash.h> 21 22static CONF_METHOD *default_CONF_method = NULL; 23 24/* Init a 'CONF' structure from an old LHASH */ 25 26void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) 27{ 28 if (default_CONF_method == NULL) 29 default_CONF_method = NCONF_default(); 30 31 default_CONF_method->init(conf); 32 conf->data = hash; 33} 34 35/* 36 * The following section contains the "CONF classic" functions, rewritten in 37 * terms of the new CONF interface. 38 */ 39 40int CONF_set_default_method(CONF_METHOD *meth) 41{ 42 default_CONF_method = meth; 43 return 1; 44} 45 46LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, 47 long *eline) 48{ 49 LHASH_OF(CONF_VALUE) *ltmp; 50 BIO *in = NULL; 51 52#ifdef OPENSSL_SYS_VMS 53 in = BIO_new_file(file, "r"); 54#else 55 in = BIO_new_file(file, "rb"); 56#endif 57 if (in == NULL) { 58 ERR_raise(ERR_LIB_CONF, ERR_R_SYS_LIB); 59 return NULL; 60 } 61 62 ltmp = CONF_load_bio(conf, in, eline); 63 BIO_free(in); 64 65 return ltmp; 66} 67 68#ifndef OPENSSL_NO_STDIO 69LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, 70 long *eline) 71{ 72 BIO *btmp; 73 LHASH_OF(CONF_VALUE) *ltmp; 74 if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { 75 ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); 76 return NULL; 77 } 78 ltmp = CONF_load_bio(conf, btmp, eline); 79 BIO_free(btmp); 80 return ltmp; 81} 82#endif 83 84LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, 85 long *eline) 86{ 87 CONF ctmp; 88 int ret; 89 90 CONF_set_nconf(&ctmp, conf); 91 92 ret = NCONF_load_bio(&ctmp, bp, eline); 93 if (ret) 94 return ctmp.data; 95 return NULL; 96} 97 98STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, 99 const char *section) 100{ 101 if (conf == NULL) { 102 return NULL; 103 } else { 104 CONF ctmp; 105 106 CONF_set_nconf(&ctmp, conf); 107 return NCONF_get_section(&ctmp, section); 108 } 109} 110 111char *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; 118 119 CONF_set_nconf(&ctmp, conf); 120 return NCONF_get_string(&ctmp, group, name); 121 } 122} 123 124long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, 125 const char *name) 126{ 127 int status; 128 long result = 0; 129 130 ERR_set_mark(); 131 if (conf == NULL) { 132 status = NCONF_get_number_e(NULL, group, name, &result); 133 } else { 134 CONF ctmp; 135 136 CONF_set_nconf(&ctmp, conf); 137 status = NCONF_get_number_e(&ctmp, group, name, &result); 138 } 139 ERR_pop_to_mark(); 140 return status == 0 ? 0L : result; 141} 142 143void CONF_free(LHASH_OF(CONF_VALUE) *conf) 144{ 145 CONF ctmp; 146 CONF_set_nconf(&ctmp, conf); 147 NCONF_free_data(&ctmp); 148} 149 150#ifndef OPENSSL_NO_STDIO 151int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) 152{ 153 BIO *btmp; 154 int ret; 155 156 if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) { 157 ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); 158 return 0; 159 } 160 ret = CONF_dump_bio(conf, btmp); 161 BIO_free(btmp); 162 return ret; 163} 164#endif 165 166int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) 167{ 168 CONF ctmp; 169 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 */ 181 182CONF *NCONF_new_ex(OSSL_LIB_CTX *libctx, CONF_METHOD *meth) 183{ 184 CONF *ret; 185 186 if (meth == NULL) 187 meth = NCONF_default(); 188 189 ret = meth->create(meth); 190 if (ret == NULL) { 191 ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); 192 return NULL; 193 } 194 ret->libctx = libctx; 195 196 return ret; 197} 198 199CONF *NCONF_new(CONF_METHOD *meth) 200{ 201 return NCONF_new_ex(NULL, meth); 202} 203 204void NCONF_free(CONF *conf) 205{ 206 if (conf == NULL) 207 return; 208 conf->meth->destroy(conf); 209} 210 211void NCONF_free_data(CONF *conf) 212{ 213 if (conf == NULL) 214 return; 215 conf->meth->destroy_data(conf); 216} 217 218OSSL_LIB_CTX *NCONF_get0_libctx(const CONF *conf) 219{ 220 return conf->libctx; 221} 222 223typedef STACK_OF(OPENSSL_CSTRING) SECTION_NAMES; 224 225IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, SECTION_NAMES); 226 227static 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 234static int section_name_cmp(OPENSSL_CSTRING const *a, OPENSSL_CSTRING const *b) 235{ 236 return strcmp(*a, *b); 237} 238 239STACK_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 250int NCONF_load(CONF *conf, const char *file, long *eline) 251{ 252 if (conf == NULL) { 253 ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF); 254 return 0; 255 } 256 257 return conf->meth->load(conf, file, eline); 258} 259 260#ifndef OPENSSL_NO_STDIO 261int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) 262{ 263 BIO *btmp; 264 int ret; 265 if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { 266 ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); 267 return 0; 268 } 269 ret = NCONF_load_bio(conf, btmp, eline); 270 BIO_free(btmp); 271 return ret; 272} 273#endif 274 275int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) 276{ 277 if (conf == NULL) { 278 ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF); 279 return 0; 280 } 281 282 return conf->meth->load_bio(conf, bp, eline); 283} 284 285STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) 286{ 287 if (conf == NULL) { 288 ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF); 289 return NULL; 290 } 291 292 if (section == NULL) { 293 ERR_raise(ERR_LIB_CONF, CONF_R_NO_SECTION); 294 return NULL; 295 } 296 297 return _CONF_get_section_values(conf, section); 298} 299 300char *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) { 312 ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); 313 return NULL; 314 } 315 ERR_raise_data(ERR_LIB_CONF, CONF_R_NO_VALUE, 316 "group=%s name=%s", group, name); 317 return NULL; 318} 319 320static int default_is_number(const CONF *conf, char c) 321{ 322 return ossl_isdigit(c); 323} 324 325static int default_to_int(const CONF *conf, char c) 326{ 327 return (int)(c - '0'); 328} 329 330int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, 331 long *result) 332{ 333 char *str; 334 long res; 335 int (*is_number)(const CONF *, char) = &default_is_number; 336 int (*to_int)(const CONF *, char) = &default_to_int; 337 338 if (result == NULL) { 339 ERR_raise(ERR_LIB_CONF, ERR_R_PASSED_NULL_PARAMETER); 340 return 0; 341 } 342 343 str = NCONF_get_string(conf, group, name); 344 345 if (str == NULL) 346 return 0; 347 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) { 358 ERR_raise(ERR_LIB_CONF, CONF_R_NUMBER_TOO_LARGE); 359 return 0; 360 } 361 res = res * 10 + d; 362 } 363 364 *result = res; 365 return 1; 366} 367 368long _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 380#ifndef OPENSSL_NO_STDIO 381int NCONF_dump_fp(const CONF *conf, FILE *out) 382{ 383 BIO *btmp; 384 int ret; 385 if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) { 386 ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); 387 return 0; 388 } 389 ret = NCONF_dump_bio(conf, btmp); 390 BIO_free(btmp); 391 return ret; 392} 393#endif 394 395int NCONF_dump_bio(const CONF *conf, BIO *out) 396{ 397 if (conf == NULL) { 398 ERR_raise(ERR_LIB_CONF, CONF_R_NO_CONF); 399 return 0; 400 } 401 402 return conf->meth->dump(conf, out); 403} 404 405/* 406 * These routines call the C malloc/free, to avoid intermixing with 407 * OpenSSL function pointers before the library is initialized. 408 */ 409OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void) 410{ 411 OPENSSL_INIT_SETTINGS *ret = malloc(sizeof(*ret)); 412 413 if (ret == NULL) 414 return NULL; 415 416 memset(ret, 0, sizeof(*ret)); 417 ret->flags = DEFAULT_CONF_MFLAGS; 418 419 return ret; 420} 421 422 423#ifndef OPENSSL_NO_STDIO 424int 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 441void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, 442 unsigned long flags) 443{ 444 settings->flags = flags; 445} 446 447int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, 448 const char *appname) 449{ 450 char *newappname = NULL; 451 452 if (appname != NULL) { 453 newappname = strdup(appname); 454 if (newappname == NULL) 455 return 0; 456 } 457 458 free(settings->appname); 459 settings->appname = newappname; 460 461 return 1; 462} 463#endif 464 465void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings) 466{ 467 free(settings->filename); 468 free(settings->appname); 469 free(settings); 470} 471