1 /* 2 * ! \file ssl/ssl_conf.c \brief SSL configuration functions 3 */ 4 /* ==================================================================== 5 * Copyright (c) 2012 The OpenSSL Project. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. All advertising materials mentioning features or use of this 20 * software must display the following acknowledgment: 21 * "This product includes software developed by the OpenSSL Project 22 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 23 * 24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25 * endorse or promote products derived from this software without 26 * prior written permission. For written permission, please contact 27 * openssl-core@openssl.org. 28 * 29 * 5. Products derived from this software may not be called "OpenSSL" 30 * nor may "OpenSSL" appear in their names without prior written 31 * permission of the OpenSSL Project. 32 * 33 * 6. Redistributions of any form whatsoever must retain the following 34 * acknowledgment: 35 * "This product includes software developed by the OpenSSL Project 36 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 49 * OF THE POSSIBILITY OF SUCH DAMAGE. 50 * ==================================================================== 51 * 52 * This product includes cryptographic software written by Eric Young 53 * (eay@cryptsoft.com). This product includes software written by Tim 54 * Hudson (tjh@cryptsoft.com). 55 * 56 */ 57 58 #ifdef REF_CHECK 59 # include <assert.h> 60 #endif 61 #include <stdio.h> 62 #include "ssl_locl.h" 63 #include <openssl/conf.h> 64 #include <openssl/objects.h> 65 #ifndef OPENSSL_NO_DH 66 # include <openssl/dh.h> 67 #endif 68 69 /* 70 * structure holding name tables. This is used for pemitted elements in lists 71 * such as TLSv1 and single command line switches such as no_tls1 72 */ 73 74 typedef struct { 75 const char *name; 76 int namelen; 77 unsigned int name_flags; 78 unsigned long option_value; 79 } ssl_flag_tbl; 80 81 /* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */ 82 #define SSL_TFLAG_INV 0x1 83 /* Flags refers to cert_flags not options */ 84 #define SSL_TFLAG_CERT 0x2 85 /* Option can only be used for clients */ 86 #define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT 87 /* Option can only be used for servers */ 88 #define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER 89 #define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER) 90 91 #define SSL_FLAG_TBL(str, flag) \ 92 {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag} 93 #define SSL_FLAG_TBL_SRV(str, flag) \ 94 {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag} 95 #define SSL_FLAG_TBL_CLI(str, flag) \ 96 {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag} 97 #define SSL_FLAG_TBL_INV(str, flag) \ 98 {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag} 99 #define SSL_FLAG_TBL_SRV_INV(str, flag) \ 100 {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag} 101 #define SSL_FLAG_TBL_CERT(str, flag) \ 102 {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag} 103 104 /* 105 * Opaque structure containing SSL configuration context. 106 */ 107 108 struct ssl_conf_ctx_st { 109 /* 110 * Various flags indicating (among other things) which options we will 111 * recognise. 112 */ 113 unsigned int flags; 114 /* Prefix and length of commands */ 115 char *prefix; 116 size_t prefixlen; 117 /* SSL_CTX or SSL structure to perform operations on */ 118 SSL_CTX *ctx; 119 SSL *ssl; 120 /* Pointer to SSL or SSL_CTX options field or NULL if none */ 121 unsigned long *poptions; 122 /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */ 123 unsigned int *pcert_flags; 124 /* Current flag table being worked on */ 125 const ssl_flag_tbl *tbl; 126 /* Size of table */ 127 size_t ntbl; 128 }; 129 130 static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl, 131 const char *name, int namelen, int onoff) 132 { 133 /* If name not relevant for context skip */ 134 if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH)) 135 return 0; 136 if (namelen == -1) { 137 if (strcmp(tbl->name, name)) 138 return 0; 139 } else if (tbl->namelen != namelen 140 || strncasecmp(tbl->name, name, namelen)) 141 return 0; 142 if (cctx->poptions) { 143 if (tbl->name_flags & SSL_TFLAG_INV) 144 onoff ^= 1; 145 if (tbl->name_flags & SSL_TFLAG_CERT) { 146 if (onoff) 147 *cctx->pcert_flags |= tbl->option_value; 148 else 149 *cctx->pcert_flags &= ~tbl->option_value; 150 } else { 151 if (onoff) 152 *cctx->poptions |= tbl->option_value; 153 else 154 *cctx->poptions &= ~tbl->option_value; 155 } 156 } 157 return 1; 158 } 159 160 static int ssl_set_option_list(const char *elem, int len, void *usr) 161 { 162 SSL_CONF_CTX *cctx = usr; 163 size_t i; 164 const ssl_flag_tbl *tbl; 165 int onoff = 1; 166 /* 167 * len == -1 indicates not being called in list context, just for single 168 * command line switches, so don't allow +, -. 169 */ 170 if (elem == NULL) 171 return 0; 172 if (len != -1) { 173 if (*elem == '+') { 174 elem++; 175 len--; 176 onoff = 1; 177 } else if (*elem == '-') { 178 elem++; 179 len--; 180 onoff = 0; 181 } 182 } 183 for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) { 184 if (ssl_match_option(cctx, tbl, elem, len, onoff)) 185 return 1; 186 } 187 return 0; 188 } 189 190 /* Single command line switches with no argument e.g. -no_ssl3 */ 191 static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd) 192 { 193 static const ssl_flag_tbl ssl_option_single[] = { 194 SSL_FLAG_TBL("no_ssl2", SSL_OP_NO_SSLv2), 195 SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3), 196 SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1), 197 SSL_FLAG_TBL("no_tls1_1", SSL_OP_NO_TLSv1_1), 198 SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2), 199 SSL_FLAG_TBL("bugs", SSL_OP_ALL), 200 SSL_FLAG_TBL("no_comp", SSL_OP_NO_COMPRESSION), 201 SSL_FLAG_TBL_SRV("ecdh_single", SSL_OP_SINGLE_ECDH_USE), 202 #ifndef OPENSSL_NO_TLSEXT 203 SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET), 204 #endif 205 SSL_FLAG_TBL_SRV("serverpref", SSL_OP_CIPHER_SERVER_PREFERENCE), 206 SSL_FLAG_TBL("legacy_renegotiation", 207 SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), 208 SSL_FLAG_TBL_SRV("legacy_server_connect", 209 SSL_OP_LEGACY_SERVER_CONNECT), 210 SSL_FLAG_TBL_SRV("no_resumption_on_reneg", 211 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), 212 SSL_FLAG_TBL_SRV_INV("no_legacy_server_connect", 213 SSL_OP_LEGACY_SERVER_CONNECT), 214 SSL_FLAG_TBL_CERT("strict", SSL_CERT_FLAG_TLS_STRICT), 215 #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL 216 SSL_FLAG_TBL_CERT("debug_broken_protocol", 217 SSL_CERT_FLAG_BROKEN_PROTOCOL), 218 #endif 219 }; 220 cctx->tbl = ssl_option_single; 221 cctx->ntbl = sizeof(ssl_option_single) / sizeof(ssl_flag_tbl); 222 return ssl_set_option_list(cmd, -1, cctx); 223 } 224 225 /* Set supported signature algorithms */ 226 static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value) 227 { 228 int rv; 229 if (cctx->ssl) 230 rv = SSL_set1_sigalgs_list(cctx->ssl, value); 231 /* NB: ctx == NULL performs syntax checking only */ 232 else 233 rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value); 234 return rv > 0; 235 } 236 237 /* Set supported client signature algorithms */ 238 static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, 239 const char *value) 240 { 241 int rv; 242 if (cctx->ssl) 243 rv = SSL_set1_client_sigalgs_list(cctx->ssl, value); 244 /* NB: ctx == NULL performs syntax checking only */ 245 else 246 rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value); 247 return rv > 0; 248 } 249 250 static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value) 251 { 252 int rv; 253 if (cctx->ssl) 254 rv = SSL_set1_curves_list(cctx->ssl, value); 255 /* NB: ctx == NULL performs syntax checking only */ 256 else 257 rv = SSL_CTX_set1_curves_list(cctx->ctx, value); 258 return rv > 0; 259 } 260 261 #ifndef OPENSSL_NO_ECDH 262 /* ECDH temporary parameters */ 263 static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value) 264 { 265 int onoff = -1, rv = 1; 266 if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) 267 return -2; 268 if (cctx->flags & SSL_CONF_FLAG_FILE) { 269 if (*value == '+') { 270 onoff = 1; 271 value++; 272 } 273 if (*value == '-') { 274 onoff = 0; 275 value++; 276 } 277 if (!strcasecmp(value, "automatic")) { 278 if (onoff == -1) 279 onoff = 1; 280 } else if (onoff != -1) 281 return 0; 282 } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { 283 if (!strcmp(value, "auto")) 284 onoff = 1; 285 } 286 287 if (onoff != -1) { 288 if (cctx->ctx) 289 rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff); 290 else if (cctx->ssl) 291 rv = SSL_set_ecdh_auto(cctx->ssl, onoff); 292 } else { 293 EC_KEY *ecdh; 294 int nid; 295 nid = EC_curve_nist2nid(value); 296 if (nid == NID_undef) 297 nid = OBJ_sn2nid(value); 298 if (nid == 0) 299 return 0; 300 ecdh = EC_KEY_new_by_curve_name(nid); 301 if (!ecdh) 302 return 0; 303 if (cctx->ctx) 304 rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh); 305 else if (cctx->ssl) 306 rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh); 307 EC_KEY_free(ecdh); 308 } 309 310 return rv > 0; 311 } 312 #endif 313 static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value) 314 { 315 int rv = 1; 316 if (cctx->ctx) 317 rv = SSL_CTX_set_cipher_list(cctx->ctx, value); 318 if (cctx->ssl) 319 rv = SSL_set_cipher_list(cctx->ssl, value); 320 return rv > 0; 321 } 322 323 static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) 324 { 325 static const ssl_flag_tbl ssl_protocol_list[] = { 326 SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK), 327 SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2), 328 SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3), 329 SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1), 330 SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1), 331 SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2) 332 }; 333 if (!(cctx->flags & SSL_CONF_FLAG_FILE)) 334 return -2; 335 cctx->tbl = ssl_protocol_list; 336 cctx->ntbl = sizeof(ssl_protocol_list) / sizeof(ssl_flag_tbl); 337 return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); 338 } 339 340 static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) 341 { 342 static const ssl_flag_tbl ssl_option_list[] = { 343 SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET), 344 SSL_FLAG_TBL_INV("EmptyFragments", 345 SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS), 346 SSL_FLAG_TBL("Bugs", SSL_OP_ALL), 347 SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION), 348 SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE), 349 SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation", 350 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), 351 SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE), 352 SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), 353 SSL_FLAG_TBL("UnsafeLegacyRenegotiation", 354 SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), 355 }; 356 if (!(cctx->flags & SSL_CONF_FLAG_FILE)) 357 return -2; 358 if (value == NULL) 359 return -3; 360 cctx->tbl = ssl_option_list; 361 cctx->ntbl = sizeof(ssl_option_list) / sizeof(ssl_flag_tbl); 362 return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); 363 } 364 365 static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) 366 { 367 int rv = 1; 368 if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) 369 return -2; 370 if (cctx->ctx) 371 rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value); 372 if (cctx->ssl) 373 rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM); 374 return rv > 0; 375 } 376 377 static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value) 378 { 379 int rv = 1; 380 if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) 381 return -2; 382 if (cctx->ctx) 383 rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM); 384 if (cctx->ssl) 385 rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM); 386 return rv > 0; 387 } 388 389 static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value) 390 { 391 int rv = 1; 392 if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) 393 return -2; 394 if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) 395 return -2; 396 if (cctx->ctx) 397 rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value); 398 return rv > 0; 399 } 400 401 #ifndef OPENSSL_NO_DH 402 static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) 403 { 404 int rv = 0; 405 DH *dh = NULL; 406 BIO *in = NULL; 407 if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) 408 return -2; 409 if (cctx->ctx || cctx->ssl) { 410 in = BIO_new(BIO_s_file_internal()); 411 if (!in) 412 goto end; 413 if (BIO_read_filename(in, value) <= 0) 414 goto end; 415 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); 416 if (!dh) 417 goto end; 418 } else 419 return 1; 420 if (cctx->ctx) 421 rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh); 422 if (cctx->ssl) 423 rv = SSL_set_tmp_dh(cctx->ssl, dh); 424 end: 425 if (dh) 426 DH_free(dh); 427 if (in) 428 BIO_free(in); 429 return rv > 0; 430 } 431 #endif 432 typedef struct { 433 int (*cmd) (SSL_CONF_CTX *cctx, const char *value); 434 const char *str_file; 435 const char *str_cmdline; 436 unsigned int value_type; 437 } ssl_conf_cmd_tbl; 438 439 /* Table of supported parameters */ 440 441 #define SSL_CONF_CMD(name, cmdopt, type) \ 442 {cmd_##name, #name, cmdopt, type} 443 444 #define SSL_CONF_CMD_STRING(name, cmdopt) \ 445 SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING) 446 447 static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { 448 SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"), 449 SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"), 450 SSL_CONF_CMD_STRING(Curves, "curves"), 451 #ifndef OPENSSL_NO_ECDH 452 SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"), 453 #endif 454 SSL_CONF_CMD_STRING(CipherString, "cipher"), 455 SSL_CONF_CMD_STRING(Protocol, NULL), 456 SSL_CONF_CMD_STRING(Options, NULL), 457 SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE), 458 SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE), 459 SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE), 460 #ifndef OPENSSL_NO_DH 461 SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE) 462 #endif 463 }; 464 465 static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) 466 { 467 if (!pcmd || !*pcmd) 468 return 0; 469 /* If a prefix is set, check and skip */ 470 if (cctx->prefix) { 471 if (strlen(*pcmd) <= cctx->prefixlen) 472 return 0; 473 if (cctx->flags & SSL_CONF_FLAG_CMDLINE && 474 strncmp(*pcmd, cctx->prefix, cctx->prefixlen)) 475 return 0; 476 if (cctx->flags & SSL_CONF_FLAG_FILE && 477 strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen)) 478 return 0; 479 *pcmd += cctx->prefixlen; 480 } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { 481 if (**pcmd != '-' || !(*pcmd)[1]) 482 return 0; 483 *pcmd += 1; 484 } 485 return 1; 486 } 487 488 static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, 489 const char *cmd) 490 { 491 const ssl_conf_cmd_tbl *t; 492 size_t i; 493 if (cmd == NULL) 494 return NULL; 495 496 /* Look for matching parameter name in table */ 497 for (i = 0, t = ssl_conf_cmds; 498 i < sizeof(ssl_conf_cmds) / sizeof(ssl_conf_cmd_tbl); i++, t++) { 499 if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { 500 if (t->str_cmdline && !strcmp(t->str_cmdline, cmd)) 501 return t; 502 } 503 if (cctx->flags & SSL_CONF_FLAG_FILE) { 504 if (t->str_file && !strcasecmp(t->str_file, cmd)) 505 return t; 506 } 507 } 508 return NULL; 509 } 510 511 int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) 512 { 513 const ssl_conf_cmd_tbl *runcmd; 514 if (cmd == NULL) { 515 SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME); 516 return 0; 517 } 518 519 if (!ssl_conf_cmd_skip_prefix(cctx, &cmd)) 520 return -2; 521 522 runcmd = ssl_conf_cmd_lookup(cctx, cmd); 523 524 if (runcmd) { 525 int rv; 526 if (value == NULL) 527 return -3; 528 rv = runcmd->cmd(cctx, value); 529 if (rv > 0) 530 return 2; 531 if (rv == -2) 532 return -2; 533 if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { 534 SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE); 535 ERR_add_error_data(4, "cmd=", cmd, ", value=", value); 536 } 537 return 0; 538 } 539 540 if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { 541 if (ctrl_str_option(cctx, cmd)) 542 return 1; 543 } 544 545 if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { 546 SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME); 547 ERR_add_error_data(2, "cmd=", cmd); 548 } 549 550 return -2; 551 } 552 553 int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv) 554 { 555 int rv; 556 const char *arg = NULL, *argn; 557 if (pargc && *pargc == 0) 558 return 0; 559 if (!pargc || *pargc > 0) 560 arg = **pargv; 561 if (arg == NULL) 562 return 0; 563 if (!pargc || *pargc > 1) 564 argn = (*pargv)[1]; 565 else 566 argn = NULL; 567 cctx->flags &= ~SSL_CONF_FLAG_FILE; 568 cctx->flags |= SSL_CONF_FLAG_CMDLINE; 569 rv = SSL_CONF_cmd(cctx, arg, argn); 570 if (rv > 0) { 571 /* Success: update pargc, pargv */ 572 (*pargv) += rv; 573 if (pargc) 574 (*pargc) -= rv; 575 return rv; 576 } 577 /* Unknown switch: indicate no arguments processed */ 578 if (rv == -2) 579 return 0; 580 /* Some error occurred processing command, return fatal error */ 581 if (rv == 0) 582 return -1; 583 return rv; 584 } 585 586 int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd) 587 { 588 if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) { 589 const ssl_conf_cmd_tbl *runcmd; 590 runcmd = ssl_conf_cmd_lookup(cctx, cmd); 591 if (runcmd) 592 return runcmd->value_type; 593 } 594 return SSL_CONF_TYPE_UNKNOWN; 595 } 596 597 SSL_CONF_CTX *SSL_CONF_CTX_new(void) 598 { 599 SSL_CONF_CTX *ret; 600 ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX)); 601 if (ret) { 602 ret->flags = 0; 603 ret->prefix = NULL; 604 ret->prefixlen = 0; 605 ret->ssl = NULL; 606 ret->ctx = NULL; 607 ret->poptions = NULL; 608 ret->pcert_flags = NULL; 609 ret->tbl = NULL; 610 ret->ntbl = 0; 611 } 612 return ret; 613 } 614 615 int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx) 616 { 617 return 1; 618 } 619 620 void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx) 621 { 622 if (cctx) { 623 if (cctx->prefix) 624 OPENSSL_free(cctx->prefix); 625 OPENSSL_free(cctx); 626 } 627 } 628 629 unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags) 630 { 631 cctx->flags |= flags; 632 return cctx->flags; 633 } 634 635 unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags) 636 { 637 cctx->flags &= ~flags; 638 return cctx->flags; 639 } 640 641 int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre) 642 { 643 char *tmp = NULL; 644 if (pre) { 645 tmp = BUF_strdup(pre); 646 if (tmp == NULL) 647 return 0; 648 } 649 if (cctx->prefix) 650 OPENSSL_free(cctx->prefix); 651 cctx->prefix = tmp; 652 if (tmp) 653 cctx->prefixlen = strlen(tmp); 654 else 655 cctx->prefixlen = 0; 656 return 1; 657 } 658 659 void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl) 660 { 661 cctx->ssl = ssl; 662 cctx->ctx = NULL; 663 if (ssl) { 664 cctx->poptions = &ssl->options; 665 cctx->pcert_flags = &ssl->cert->cert_flags; 666 } else { 667 cctx->poptions = NULL; 668 cctx->pcert_flags = NULL; 669 } 670 } 671 672 void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx) 673 { 674 cctx->ctx = ctx; 675 cctx->ssl = NULL; 676 if (ctx) { 677 cctx->poptions = &ctx->options; 678 cctx->pcert_flags = &ctx->cert->cert_flags; 679 } else { 680 cctx->poptions = NULL; 681 cctx->pcert_flags = NULL; 682 } 683 } 684