1 /* $OpenBSD: apps.c,v 1.56 2020/10/14 07:20:09 tb Exp $ */ 2 /* 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 18 * All rights reserved. 19 * 20 * This package is an SSL implementation written 21 * by Eric Young (eay@cryptsoft.com). 22 * The implementation was written so as to conform with Netscapes SSL. 23 * 24 * This library is free for commercial and non-commercial use as long as 25 * the following conditions are aheared to. The following conditions 26 * apply to all code found in this distribution, be it the RC4, RSA, 27 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 28 * included with this distribution is covered by the same copyright terms 29 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 30 * 31 * Copyright remains Eric Young's, and as such any Copyright notices in 32 * the code are not to be removed. 33 * If this package is used in a product, Eric Young should be given attribution 34 * as the author of the parts of the library used. 35 * This can be in the form of a textual message at program startup or 36 * in documentation (online or textual) provided with the package. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * "This product includes cryptographic software written by 49 * Eric Young (eay@cryptsoft.com)" 50 * The word 'cryptographic' can be left out if the rouines from the library 51 * being used are not cryptographic related :-). 52 * 4. If you include any Windows specific code (or a derivative thereof) from 53 * the apps directory (application code) you must include an acknowledgement: 54 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 55 * 56 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 * 68 * The licence and distribution terms for any publically available version or 69 * derivative of this code cannot be changed. i.e. this code cannot simply be 70 * copied and put under another distribution licence 71 * [including the GNU Public Licence.] 72 */ 73 /* ==================================================================== 74 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 75 * 76 * Redistribution and use in source and binary forms, with or without 77 * modification, are permitted provided that the following conditions 78 * are met: 79 * 80 * 1. Redistributions of source code must retain the above copyright 81 * notice, this list of conditions and the following disclaimer. 82 * 83 * 2. Redistributions in binary form must reproduce the above copyright 84 * notice, this list of conditions and the following disclaimer in 85 * the documentation and/or other materials provided with the 86 * distribution. 87 * 88 * 3. All advertising materials mentioning features or use of this 89 * software must display the following acknowledgment: 90 * "This product includes software developed by the OpenSSL Project 91 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 92 * 93 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 94 * endorse or promote products derived from this software without 95 * prior written permission. For written permission, please contact 96 * openssl-core@openssl.org. 97 * 98 * 5. Products derived from this software may not be called "OpenSSL" 99 * nor may "OpenSSL" appear in their names without prior written 100 * permission of the OpenSSL Project. 101 * 102 * 6. Redistributions of any form whatsoever must retain the following 103 * acknowledgment: 104 * "This product includes software developed by the OpenSSL Project 105 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 106 * 107 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 108 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 109 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 110 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 111 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 112 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 113 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 114 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 115 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 116 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 117 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 118 * OF THE POSSIBILITY OF SUCH DAMAGE. 119 * ==================================================================== 120 * 121 * This product includes cryptographic software written by Eric Young 122 * (eay@cryptsoft.com). This product includes software written by Tim 123 * Hudson (tjh@cryptsoft.com). 124 * 125 */ 126 127 #include <sys/types.h> 128 #include <sys/stat.h> 129 130 #include <ctype.h> 131 #include <errno.h> 132 #include <stdio.h> 133 #include <stdlib.h> 134 #include <limits.h> 135 #include <string.h> 136 #include <unistd.h> 137 138 #include "apps.h" 139 140 #include <openssl/bn.h> 141 #include <openssl/err.h> 142 #include <openssl/pem.h> 143 #include <openssl/pkcs12.h> 144 #include <openssl/safestack.h> 145 #include <openssl/x509.h> 146 #include <openssl/x509v3.h> 147 148 #include <openssl/rsa.h> 149 150 typedef struct { 151 const char *name; 152 unsigned long flag; 153 unsigned long mask; 154 } NAME_EX_TBL; 155 156 UI_METHOD *ui_method = NULL; 157 158 static int set_table_opts(unsigned long *flags, const char *arg, 159 const NAME_EX_TBL *in_tbl); 160 static int set_multi_opts(unsigned long *flags, const char *arg, 161 const NAME_EX_TBL *in_tbl); 162 163 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 164 /* Looks like this stuff is worth moving into separate function */ 165 static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file, 166 const char *key_descrip, int format); 167 #endif 168 169 int 170 str2fmt(char *s) 171 { 172 if (s == NULL) 173 return FORMAT_UNDEF; 174 if ((*s == 'D') || (*s == 'd')) 175 return (FORMAT_ASN1); 176 else if ((*s == 'T') || (*s == 't')) 177 return (FORMAT_TEXT); 178 else if ((*s == 'N') || (*s == 'n')) 179 return (FORMAT_NETSCAPE); 180 else if ((*s == 'S') || (*s == 's')) 181 return (FORMAT_SMIME); 182 else if ((*s == 'M') || (*s == 'm')) 183 return (FORMAT_MSBLOB); 184 else if ((*s == '1') || 185 (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0) || 186 (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0)) 187 return (FORMAT_PKCS12); 188 else if ((*s == 'P') || (*s == 'p')) { 189 if (s[1] == 'V' || s[1] == 'v') 190 return FORMAT_PVK; 191 else 192 return (FORMAT_PEM); 193 } else 194 return (FORMAT_UNDEF); 195 } 196 197 void 198 program_name(char *in, char *out, int size) 199 { 200 char *p; 201 202 p = strrchr(in, '/'); 203 if (p != NULL) 204 p++; 205 else 206 p = in; 207 strlcpy(out, p, size); 208 } 209 210 int 211 chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]) 212 { 213 int num, i; 214 char *p; 215 216 *argc = 0; 217 *argv = NULL; 218 219 if (arg->count == 0) { 220 arg->count = 20; 221 arg->data = reallocarray(NULL, arg->count, sizeof(char *)); 222 if (arg->data == NULL) 223 return 0; 224 } 225 for (i = 0; i < arg->count; i++) 226 arg->data[i] = NULL; 227 228 num = 0; 229 p = buf; 230 for (;;) { 231 /* first scan over white space */ 232 if (!*p) 233 break; 234 while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) 235 p++; 236 if (!*p) 237 break; 238 239 /* The start of something good :-) */ 240 if (num >= arg->count) { 241 char **tmp_p; 242 int tlen = arg->count + 20; 243 tmp_p = reallocarray(arg->data, tlen, sizeof(char *)); 244 if (tmp_p == NULL) 245 return 0; 246 arg->data = tmp_p; 247 arg->count = tlen; 248 /* initialize newly allocated data */ 249 for (i = num; i < arg->count; i++) 250 arg->data[i] = NULL; 251 } 252 arg->data[num++] = p; 253 254 /* now look for the end of this */ 255 if ((*p == '\'') || (*p == '\"')) { /* scan for closing 256 * quote */ 257 i = *(p++); 258 arg->data[num - 1]++; /* jump over quote */ 259 while (*p && (*p != i)) 260 p++; 261 *p = '\0'; 262 } else { 263 while (*p && ((*p != ' ') && 264 (*p != '\t') && (*p != '\n'))) 265 p++; 266 267 if (*p == '\0') 268 p--; 269 else 270 *p = '\0'; 271 } 272 p++; 273 } 274 *argc = num; 275 *argv = arg->data; 276 return (1); 277 } 278 279 int 280 dump_cert_text(BIO *out, X509 *x) 281 { 282 char *p; 283 284 p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0); 285 BIO_puts(out, "subject="); 286 BIO_puts(out, p); 287 free(p); 288 289 p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0); 290 BIO_puts(out, "\nissuer="); 291 BIO_puts(out, p); 292 BIO_puts(out, "\n"); 293 free(p); 294 295 return 0; 296 } 297 298 int 299 ui_open(UI *ui) 300 { 301 return UI_method_get_opener(UI_OpenSSL()) (ui); 302 } 303 304 int 305 ui_read(UI *ui, UI_STRING *uis) 306 { 307 const char *password; 308 int string_type; 309 310 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD && 311 UI_get0_user_data(ui)) { 312 string_type = UI_get_string_type(uis); 313 if (string_type == UIT_PROMPT || string_type == UIT_VERIFY) { 314 password = 315 ((PW_CB_DATA *)UI_get0_user_data(ui))->password; 316 if (password && password[0] != '\0') { 317 UI_set_result(ui, uis, password); 318 return 1; 319 } 320 } 321 } 322 return UI_method_get_reader(UI_OpenSSL()) (ui, uis); 323 } 324 325 int 326 ui_write(UI *ui, UI_STRING *uis) 327 { 328 const char *password; 329 int string_type; 330 331 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD && 332 UI_get0_user_data(ui)) { 333 string_type = UI_get_string_type(uis); 334 if (string_type == UIT_PROMPT || string_type == UIT_VERIFY) { 335 password = 336 ((PW_CB_DATA *)UI_get0_user_data(ui))->password; 337 if (password && password[0] != '\0') 338 return 1; 339 } 340 } 341 return UI_method_get_writer(UI_OpenSSL()) (ui, uis); 342 } 343 344 int 345 ui_close(UI *ui) 346 { 347 return UI_method_get_closer(UI_OpenSSL()) (ui); 348 } 349 350 int 351 password_callback(char *buf, int bufsiz, int verify, void *arg) 352 { 353 PW_CB_DATA *cb_tmp = arg; 354 UI *ui = NULL; 355 int res = 0; 356 const char *prompt_info = NULL; 357 const char *password = NULL; 358 PW_CB_DATA *cb_data = (PW_CB_DATA *) cb_tmp; 359 360 if (cb_data) { 361 if (cb_data->password) 362 password = cb_data->password; 363 if (cb_data->prompt_info) 364 prompt_info = cb_data->prompt_info; 365 } 366 if (password) { 367 res = strlen(password); 368 if (res > bufsiz) 369 res = bufsiz; 370 memcpy(buf, password, res); 371 return res; 372 } 373 ui = UI_new_method(ui_method); 374 if (ui) { 375 int ok = 0; 376 char *buff = NULL; 377 int ui_flags = 0; 378 char *prompt = NULL; 379 380 prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); 381 382 ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; 383 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); 384 385 if (ok >= 0) 386 ok = UI_add_input_string(ui, prompt, ui_flags, buf, 387 PW_MIN_LENGTH, bufsiz - 1); 388 if (ok >= 0 && verify) { 389 buff = malloc(bufsiz); 390 ok = UI_add_verify_string(ui, prompt, ui_flags, buff, 391 PW_MIN_LENGTH, bufsiz - 1, buf); 392 } 393 if (ok >= 0) 394 do { 395 ok = UI_process(ui); 396 } while (ok < 0 && 397 UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); 398 399 freezero(buff, (unsigned int) bufsiz); 400 if (ok >= 0) 401 res = strlen(buf); 402 if (ok == -1) { 403 BIO_printf(bio_err, "User interface error\n"); 404 ERR_print_errors(bio_err); 405 explicit_bzero(buf, (unsigned int) bufsiz); 406 res = 0; 407 } 408 if (ok == -2) { 409 BIO_printf(bio_err, "aborted!\n"); 410 explicit_bzero(buf, (unsigned int) bufsiz); 411 res = 0; 412 } 413 UI_free(ui); 414 free(prompt); 415 } 416 return res; 417 } 418 419 static char *app_get_pass(BIO *err, char *arg, int keepbio); 420 421 int 422 app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) 423 { 424 int same; 425 426 if (!arg2 || !arg1 || strcmp(arg1, arg2)) 427 same = 0; 428 else 429 same = 1; 430 if (arg1) { 431 *pass1 = app_get_pass(err, arg1, same); 432 if (!*pass1) 433 return 0; 434 } else if (pass1) 435 *pass1 = NULL; 436 if (arg2) { 437 *pass2 = app_get_pass(err, arg2, same ? 2 : 0); 438 if (!*pass2) 439 return 0; 440 } else if (pass2) 441 *pass2 = NULL; 442 return 1; 443 } 444 445 static char * 446 app_get_pass(BIO *err, char *arg, int keepbio) 447 { 448 char *tmp, tpass[APP_PASS_LEN]; 449 static BIO *pwdbio = NULL; 450 const char *errstr = NULL; 451 int i; 452 453 if (!strncmp(arg, "pass:", 5)) 454 return strdup(arg + 5); 455 if (!strncmp(arg, "env:", 4)) { 456 tmp = getenv(arg + 4); 457 if (!tmp) { 458 BIO_printf(err, "Can't read environment variable %s\n", 459 arg + 4); 460 return NULL; 461 } 462 return strdup(tmp); 463 } 464 if (!keepbio || !pwdbio) { 465 if (!strncmp(arg, "file:", 5)) { 466 pwdbio = BIO_new_file(arg + 5, "r"); 467 if (!pwdbio) { 468 BIO_printf(err, "Can't open file %s\n", 469 arg + 5); 470 return NULL; 471 } 472 } else if (!strncmp(arg, "fd:", 3)) { 473 BIO *btmp; 474 i = strtonum(arg + 3, 0, INT_MAX, &errstr); 475 if (errstr) { 476 BIO_printf(err, 477 "Invalid file descriptor %s: %s\n", 478 arg, errstr); 479 return NULL; 480 } 481 pwdbio = BIO_new_fd(i, BIO_NOCLOSE); 482 if (!pwdbio) { 483 BIO_printf(err, 484 "Can't access file descriptor %s\n", 485 arg + 3); 486 return NULL; 487 } 488 /* 489 * Can't do BIO_gets on an fd BIO so add a buffering 490 * BIO 491 */ 492 btmp = BIO_new(BIO_f_buffer()); 493 pwdbio = BIO_push(btmp, pwdbio); 494 } else if (!strcmp(arg, "stdin")) { 495 pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE); 496 if (!pwdbio) { 497 BIO_printf(err, "Can't open BIO for stdin\n"); 498 return NULL; 499 } 500 } else { 501 BIO_printf(err, "Invalid password argument \"%s\"\n", 502 arg); 503 return NULL; 504 } 505 } 506 i = BIO_gets(pwdbio, tpass, APP_PASS_LEN); 507 if (keepbio != 1) { 508 BIO_free_all(pwdbio); 509 pwdbio = NULL; 510 } 511 if (i <= 0) { 512 BIO_printf(err, "Error reading password from BIO\n"); 513 return NULL; 514 } 515 tmp = strchr(tpass, '\n'); 516 if (tmp) 517 *tmp = 0; 518 return strdup(tpass); 519 } 520 521 int 522 add_oid_section(BIO *err, CONF *conf) 523 { 524 char *p; 525 STACK_OF(CONF_VALUE) *sktmp; 526 CONF_VALUE *cnf; 527 int i; 528 529 if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) { 530 ERR_clear_error(); 531 return 1; 532 } 533 if (!(sktmp = NCONF_get_section(conf, p))) { 534 BIO_printf(err, "problem loading oid section %s\n", p); 535 return 0; 536 } 537 for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { 538 cnf = sk_CONF_VALUE_value(sktmp, i); 539 if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) { 540 BIO_printf(err, "problem creating object %s=%s\n", 541 cnf->name, cnf->value); 542 return 0; 543 } 544 } 545 return 1; 546 } 547 548 static int 549 load_pkcs12(BIO *err, BIO *in, const char *desc, pem_password_cb *pem_cb, 550 void *cb_data, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) 551 { 552 const char *pass; 553 char tpass[PEM_BUFSIZE]; 554 int len, ret = 0; 555 PKCS12 *p12; 556 557 p12 = d2i_PKCS12_bio(in, NULL); 558 if (p12 == NULL) { 559 BIO_printf(err, "Error loading PKCS12 file for %s\n", desc); 560 goto die; 561 } 562 /* See if an empty password will do */ 563 if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) 564 pass = ""; 565 else { 566 if (!pem_cb) 567 pem_cb = password_callback; 568 len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); 569 if (len < 0) { 570 BIO_printf(err, "Passpharse callback error for %s\n", 571 desc); 572 goto die; 573 } 574 if (len < PEM_BUFSIZE) 575 tpass[len] = 0; 576 if (!PKCS12_verify_mac(p12, tpass, len)) { 577 BIO_printf(err, 578 "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc); 579 goto die; 580 } 581 pass = tpass; 582 } 583 ret = PKCS12_parse(p12, pass, pkey, cert, ca); 584 585 die: 586 PKCS12_free(p12); 587 return ret; 588 } 589 590 X509 * 591 load_cert(BIO *err, const char *file, int format, const char *pass, 592 const char *cert_descrip) 593 { 594 X509 *x = NULL; 595 BIO *cert; 596 597 if ((cert = BIO_new(BIO_s_file())) == NULL) { 598 ERR_print_errors(err); 599 goto end; 600 } 601 if (file == NULL) { 602 setvbuf(stdin, NULL, _IONBF, 0); 603 BIO_set_fp(cert, stdin, BIO_NOCLOSE); 604 } else { 605 if (BIO_read_filename(cert, file) <= 0) { 606 BIO_printf(err, "Error opening %s %s\n", 607 cert_descrip, file); 608 ERR_print_errors(err); 609 goto end; 610 } 611 } 612 613 if (format == FORMAT_ASN1) 614 x = d2i_X509_bio(cert, NULL); 615 else if (format == FORMAT_NETSCAPE) { 616 NETSCAPE_X509 *nx; 617 nx = ASN1_item_d2i_bio(&NETSCAPE_X509_it, 618 cert, NULL); 619 if (nx == NULL) 620 goto end; 621 622 if ((strncmp(NETSCAPE_CERT_HDR, (char *) nx->header->data, 623 nx->header->length) != 0)) { 624 NETSCAPE_X509_free(nx); 625 BIO_printf(err, 626 "Error reading header on certificate\n"); 627 goto end; 628 } 629 x = nx->cert; 630 nx->cert = NULL; 631 NETSCAPE_X509_free(nx); 632 } else if (format == FORMAT_PEM) 633 x = PEM_read_bio_X509_AUX(cert, NULL, password_callback, NULL); 634 else if (format == FORMAT_PKCS12) { 635 if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL, 636 NULL, &x, NULL)) 637 goto end; 638 } else { 639 BIO_printf(err, "bad input format specified for %s\n", 640 cert_descrip); 641 goto end; 642 } 643 644 end: 645 if (x == NULL) { 646 BIO_printf(err, "unable to load certificate\n"); 647 ERR_print_errors(err); 648 } 649 BIO_free(cert); 650 return (x); 651 } 652 653 EVP_PKEY * 654 load_key(BIO *err, const char *file, int format, int maybe_stdin, 655 const char *pass, const char *key_descrip) 656 { 657 BIO *key = NULL; 658 EVP_PKEY *pkey = NULL; 659 PW_CB_DATA cb_data; 660 661 cb_data.password = pass; 662 cb_data.prompt_info = file; 663 664 if (file == NULL && (!maybe_stdin)) { 665 BIO_printf(err, "no keyfile specified\n"); 666 goto end; 667 } 668 key = BIO_new(BIO_s_file()); 669 if (key == NULL) { 670 ERR_print_errors(err); 671 goto end; 672 } 673 if (file == NULL && maybe_stdin) { 674 setvbuf(stdin, NULL, _IONBF, 0); 675 BIO_set_fp(key, stdin, BIO_NOCLOSE); 676 } else if (BIO_read_filename(key, file) <= 0) { 677 BIO_printf(err, "Error opening %s %s\n", 678 key_descrip, file); 679 ERR_print_errors(err); 680 goto end; 681 } 682 if (format == FORMAT_ASN1) { 683 pkey = d2i_PrivateKey_bio(key, NULL); 684 } else if (format == FORMAT_PEM) { 685 pkey = PEM_read_bio_PrivateKey(key, NULL, password_callback, &cb_data); 686 } 687 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 688 else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) 689 pkey = load_netscape_key(err, key, file, key_descrip, format); 690 #endif 691 else if (format == FORMAT_PKCS12) { 692 if (!load_pkcs12(err, key, key_descrip, password_callback, &cb_data, 693 &pkey, NULL, NULL)) 694 goto end; 695 } 696 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4) 697 else if (format == FORMAT_MSBLOB) 698 pkey = b2i_PrivateKey_bio(key); 699 else if (format == FORMAT_PVK) 700 pkey = b2i_PVK_bio(key, password_callback, 701 &cb_data); 702 #endif 703 else { 704 BIO_printf(err, "bad input format specified for key file\n"); 705 goto end; 706 } 707 end: 708 BIO_free(key); 709 if (pkey == NULL) { 710 BIO_printf(err, "unable to load %s\n", key_descrip); 711 ERR_print_errors(err); 712 } 713 return (pkey); 714 } 715 716 EVP_PKEY * 717 load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, 718 const char *pass, const char *key_descrip) 719 { 720 BIO *key = NULL; 721 EVP_PKEY *pkey = NULL; 722 PW_CB_DATA cb_data; 723 724 cb_data.password = pass; 725 cb_data.prompt_info = file; 726 727 if (file == NULL && !maybe_stdin) { 728 BIO_printf(err, "no keyfile specified\n"); 729 goto end; 730 } 731 key = BIO_new(BIO_s_file()); 732 if (key == NULL) { 733 ERR_print_errors(err); 734 goto end; 735 } 736 if (file == NULL && maybe_stdin) { 737 setvbuf(stdin, NULL, _IONBF, 0); 738 BIO_set_fp(key, stdin, BIO_NOCLOSE); 739 } else if (BIO_read_filename(key, file) <= 0) { 740 BIO_printf(err, "Error opening %s %s\n", key_descrip, file); 741 ERR_print_errors(err); 742 goto end; 743 } 744 if (format == FORMAT_ASN1) { 745 pkey = d2i_PUBKEY_bio(key, NULL); 746 } 747 else if (format == FORMAT_ASN1RSA) { 748 RSA *rsa; 749 rsa = d2i_RSAPublicKey_bio(key, NULL); 750 if (rsa) { 751 pkey = EVP_PKEY_new(); 752 if (pkey) 753 EVP_PKEY_set1_RSA(pkey, rsa); 754 RSA_free(rsa); 755 } else 756 pkey = NULL; 757 } else if (format == FORMAT_PEMRSA) { 758 RSA *rsa; 759 rsa = PEM_read_bio_RSAPublicKey(key, NULL, password_callback, &cb_data); 760 if (rsa) { 761 pkey = EVP_PKEY_new(); 762 if (pkey) 763 EVP_PKEY_set1_RSA(pkey, rsa); 764 RSA_free(rsa); 765 } else 766 pkey = NULL; 767 } 768 else if (format == FORMAT_PEM) { 769 pkey = PEM_read_bio_PUBKEY(key, NULL, password_callback, &cb_data); 770 } 771 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 772 else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) 773 pkey = load_netscape_key(err, key, file, key_descrip, format); 774 #endif 775 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) 776 else if (format == FORMAT_MSBLOB) 777 pkey = b2i_PublicKey_bio(key); 778 #endif 779 else { 780 BIO_printf(err, "bad input format specified for key file\n"); 781 goto end; 782 } 783 784 end: 785 BIO_free(key); 786 if (pkey == NULL) 787 BIO_printf(err, "unable to load %s\n", key_descrip); 788 return (pkey); 789 } 790 791 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 792 static EVP_PKEY * 793 load_netscape_key(BIO *err, BIO *key, const char *file, 794 const char *key_descrip, int format) 795 { 796 EVP_PKEY *pkey; 797 BUF_MEM *buf; 798 RSA *rsa; 799 const unsigned char *p; 800 int size, i; 801 802 buf = BUF_MEM_new(); 803 pkey = EVP_PKEY_new(); 804 size = 0; 805 if (buf == NULL || pkey == NULL) 806 goto error; 807 for (;;) { 808 if (!BUF_MEM_grow_clean(buf, size + 1024 * 10)) 809 goto error; 810 i = BIO_read(key, &(buf->data[size]), 1024 * 10); 811 size += i; 812 if (i == 0) 813 break; 814 if (i < 0) { 815 BIO_printf(err, "Error reading %s %s", 816 key_descrip, file); 817 goto error; 818 } 819 } 820 p = (unsigned char *) buf->data; 821 rsa = d2i_RSA_NET(NULL, &p, (long) size, NULL, 822 (format == FORMAT_IISSGC ? 1 : 0)); 823 if (rsa == NULL) 824 goto error; 825 BUF_MEM_free(buf); 826 EVP_PKEY_set1_RSA(pkey, rsa); 827 return pkey; 828 829 error: 830 BUF_MEM_free(buf); 831 EVP_PKEY_free(pkey); 832 return NULL; 833 } 834 #endif /* ndef OPENSSL_NO_RC4 */ 835 836 static int 837 load_certs_crls(BIO *err, const char *file, int format, const char *pass, 838 const char *desc, STACK_OF(X509) **pcerts, 839 STACK_OF(X509_CRL) **pcrls) 840 { 841 int i; 842 BIO *bio; 843 STACK_OF(X509_INFO) *xis = NULL; 844 X509_INFO *xi; 845 PW_CB_DATA cb_data; 846 int rv = 0; 847 848 cb_data.password = pass; 849 cb_data.prompt_info = file; 850 851 if (format != FORMAT_PEM) { 852 BIO_printf(err, "bad input format specified for %s\n", desc); 853 return 0; 854 } 855 if (file == NULL) 856 bio = BIO_new_fp(stdin, BIO_NOCLOSE); 857 else 858 bio = BIO_new_file(file, "r"); 859 860 if (bio == NULL) { 861 BIO_printf(err, "Error opening %s %s\n", 862 desc, file ? file : "stdin"); 863 ERR_print_errors(err); 864 return 0; 865 } 866 xis = PEM_X509_INFO_read_bio(bio, NULL, password_callback, &cb_data); 867 868 BIO_free(bio); 869 870 if (pcerts) { 871 *pcerts = sk_X509_new_null(); 872 if (!*pcerts) 873 goto end; 874 } 875 if (pcrls) { 876 *pcrls = sk_X509_CRL_new_null(); 877 if (!*pcrls) 878 goto end; 879 } 880 for (i = 0; i < sk_X509_INFO_num(xis); i++) { 881 xi = sk_X509_INFO_value(xis, i); 882 if (xi->x509 && pcerts) { 883 if (!sk_X509_push(*pcerts, xi->x509)) 884 goto end; 885 xi->x509 = NULL; 886 } 887 if (xi->crl && pcrls) { 888 if (!sk_X509_CRL_push(*pcrls, xi->crl)) 889 goto end; 890 xi->crl = NULL; 891 } 892 } 893 894 if (pcerts && sk_X509_num(*pcerts) > 0) 895 rv = 1; 896 897 if (pcrls && sk_X509_CRL_num(*pcrls) > 0) 898 rv = 1; 899 900 end: 901 sk_X509_INFO_pop_free(xis, X509_INFO_free); 902 903 if (rv == 0) { 904 if (pcerts) { 905 sk_X509_pop_free(*pcerts, X509_free); 906 *pcerts = NULL; 907 } 908 if (pcrls) { 909 sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); 910 *pcrls = NULL; 911 } 912 BIO_printf(err, "unable to load %s\n", 913 pcerts ? "certificates" : "CRLs"); 914 ERR_print_errors(err); 915 } 916 return rv; 917 } 918 919 STACK_OF(X509) * 920 load_certs(BIO *err, const char *file, int format, const char *pass, 921 const char *desc) 922 { 923 STACK_OF(X509) *certs; 924 925 if (!load_certs_crls(err, file, format, pass, desc, &certs, NULL)) 926 return NULL; 927 return certs; 928 } 929 930 STACK_OF(X509_CRL) * 931 load_crls(BIO *err, const char *file, int format, const char *pass, 932 const char *desc) 933 { 934 STACK_OF(X509_CRL) *crls; 935 936 if (!load_certs_crls(err, file, format, pass, desc, NULL, &crls)) 937 return NULL; 938 return crls; 939 } 940 941 #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) 942 /* Return error for unknown extensions */ 943 #define X509V3_EXT_DEFAULT 0 944 /* Print error for unknown extensions */ 945 #define X509V3_EXT_ERROR_UNKNOWN (1L << 16) 946 /* ASN1 parse unknown extensions */ 947 #define X509V3_EXT_PARSE_UNKNOWN (2L << 16) 948 /* BIO_dump unknown extensions */ 949 #define X509V3_EXT_DUMP_UNKNOWN (3L << 16) 950 951 #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \ 952 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) 953 954 int 955 set_cert_ex(unsigned long *flags, const char *arg) 956 { 957 static const NAME_EX_TBL cert_tbl[] = { 958 {"compatible", X509_FLAG_COMPAT, 0xffffffffl}, 959 {"ca_default", X509_FLAG_CA, 0xffffffffl}, 960 {"no_header", X509_FLAG_NO_HEADER, 0}, 961 {"no_version", X509_FLAG_NO_VERSION, 0}, 962 {"no_serial", X509_FLAG_NO_SERIAL, 0}, 963 {"no_signame", X509_FLAG_NO_SIGNAME, 0}, 964 {"no_validity", X509_FLAG_NO_VALIDITY, 0}, 965 {"no_subject", X509_FLAG_NO_SUBJECT, 0}, 966 {"no_issuer", X509_FLAG_NO_ISSUER, 0}, 967 {"no_pubkey", X509_FLAG_NO_PUBKEY, 0}, 968 {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0}, 969 {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0}, 970 {"no_aux", X509_FLAG_NO_AUX, 0}, 971 {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0}, 972 {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK}, 973 {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 974 {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 975 {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 976 {NULL, 0, 0} 977 }; 978 return set_multi_opts(flags, arg, cert_tbl); 979 } 980 981 int 982 set_name_ex(unsigned long *flags, const char *arg) 983 { 984 static const NAME_EX_TBL ex_tbl[] = { 985 {"esc_2253", ASN1_STRFLGS_ESC_2253, 0}, 986 {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0}, 987 {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0}, 988 {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0}, 989 {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0}, 990 {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0}, 991 {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0}, 992 {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0}, 993 {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0}, 994 {"dump_der", ASN1_STRFLGS_DUMP_DER, 0}, 995 {"compat", XN_FLAG_COMPAT, 0xffffffffL}, 996 {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK}, 997 {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK}, 998 {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK}, 999 {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK}, 1000 {"dn_rev", XN_FLAG_DN_REV, 0}, 1001 {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK}, 1002 {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK}, 1003 {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK}, 1004 {"align", XN_FLAG_FN_ALIGN, 0}, 1005 {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK}, 1006 {"space_eq", XN_FLAG_SPC_EQ, 0}, 1007 {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0}, 1008 {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL}, 1009 {"oneline", XN_FLAG_ONELINE, 0xffffffffL}, 1010 {"multiline", XN_FLAG_MULTILINE, 0xffffffffL}, 1011 {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL}, 1012 {NULL, 0, 0} 1013 }; 1014 return set_multi_opts(flags, arg, ex_tbl); 1015 } 1016 1017 int 1018 set_ext_copy(int *copy_type, const char *arg) 1019 { 1020 if (!strcasecmp(arg, "none")) 1021 *copy_type = EXT_COPY_NONE; 1022 else if (!strcasecmp(arg, "copy")) 1023 *copy_type = EXT_COPY_ADD; 1024 else if (!strcasecmp(arg, "copyall")) 1025 *copy_type = EXT_COPY_ALL; 1026 else 1027 return 0; 1028 return 1; 1029 } 1030 1031 int 1032 copy_extensions(X509 *x, X509_REQ *req, int copy_type) 1033 { 1034 STACK_OF(X509_EXTENSION) *exts = NULL; 1035 X509_EXTENSION *ext, *tmpext; 1036 ASN1_OBJECT *obj; 1037 int i, idx, ret = 0; 1038 1039 if (!x || !req || (copy_type == EXT_COPY_NONE)) 1040 return 1; 1041 exts = X509_REQ_get_extensions(req); 1042 1043 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 1044 ext = sk_X509_EXTENSION_value(exts, i); 1045 obj = X509_EXTENSION_get_object(ext); 1046 idx = X509_get_ext_by_OBJ(x, obj, -1); 1047 /* Does extension exist? */ 1048 if (idx != -1) { 1049 /* If normal copy don't override existing extension */ 1050 if (copy_type == EXT_COPY_ADD) 1051 continue; 1052 /* Delete all extensions of same type */ 1053 do { 1054 tmpext = X509_get_ext(x, idx); 1055 X509_delete_ext(x, idx); 1056 X509_EXTENSION_free(tmpext); 1057 idx = X509_get_ext_by_OBJ(x, obj, -1); 1058 } while (idx != -1); 1059 } 1060 if (!X509_add_ext(x, ext, -1)) 1061 goto end; 1062 } 1063 1064 ret = 1; 1065 1066 end: 1067 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); 1068 1069 return ret; 1070 } 1071 1072 static int 1073 set_multi_opts(unsigned long *flags, const char *arg, 1074 const NAME_EX_TBL *in_tbl) 1075 { 1076 STACK_OF(CONF_VALUE) *vals; 1077 CONF_VALUE *val; 1078 int i, ret = 1; 1079 1080 if (!arg) 1081 return 0; 1082 vals = X509V3_parse_list(arg); 1083 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { 1084 val = sk_CONF_VALUE_value(vals, i); 1085 if (!set_table_opts(flags, val->name, in_tbl)) 1086 ret = 0; 1087 } 1088 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 1089 return ret; 1090 } 1091 1092 static int 1093 set_table_opts(unsigned long *flags, const char *arg, 1094 const NAME_EX_TBL *in_tbl) 1095 { 1096 char c; 1097 const NAME_EX_TBL *ptbl; 1098 1099 c = arg[0]; 1100 if (c == '-') { 1101 c = 0; 1102 arg++; 1103 } else if (c == '+') { 1104 c = 1; 1105 arg++; 1106 } else 1107 c = 1; 1108 1109 for (ptbl = in_tbl; ptbl->name; ptbl++) { 1110 if (!strcasecmp(arg, ptbl->name)) { 1111 *flags &= ~ptbl->mask; 1112 if (c) 1113 *flags |= ptbl->flag; 1114 else 1115 *flags &= ~ptbl->flag; 1116 return 1; 1117 } 1118 } 1119 return 0; 1120 } 1121 1122 void 1123 print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags) 1124 { 1125 char *buf; 1126 char mline = 0; 1127 int indent = 0; 1128 1129 if (title) 1130 BIO_puts(out, title); 1131 if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { 1132 mline = 1; 1133 indent = 4; 1134 } 1135 if (lflags == XN_FLAG_COMPAT) { 1136 buf = X509_NAME_oneline(nm, 0, 0); 1137 BIO_puts(out, buf); 1138 BIO_puts(out, "\n"); 1139 free(buf); 1140 } else { 1141 if (mline) 1142 BIO_puts(out, "\n"); 1143 X509_NAME_print_ex(out, nm, indent, lflags); 1144 BIO_puts(out, "\n"); 1145 } 1146 } 1147 1148 X509_STORE * 1149 setup_verify(BIO *bp, char *CAfile, char *CApath) 1150 { 1151 X509_STORE *store; 1152 X509_LOOKUP *lookup; 1153 1154 if (!(store = X509_STORE_new())) 1155 goto end; 1156 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); 1157 if (lookup == NULL) 1158 goto end; 1159 if (CAfile) { 1160 if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { 1161 BIO_printf(bp, "Error loading file %s\n", CAfile); 1162 goto end; 1163 } 1164 } else 1165 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); 1166 1167 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); 1168 if (lookup == NULL) 1169 goto end; 1170 if (CApath) { 1171 if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { 1172 BIO_printf(bp, "Error loading directory %s\n", CApath); 1173 goto end; 1174 } 1175 } else 1176 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); 1177 1178 ERR_clear_error(); 1179 return store; 1180 1181 end: 1182 X509_STORE_free(store); 1183 return NULL; 1184 } 1185 1186 int 1187 load_config(BIO *err, CONF *cnf) 1188 { 1189 static int load_config_called = 0; 1190 1191 if (load_config_called) 1192 return 1; 1193 load_config_called = 1; 1194 if (cnf == NULL) 1195 cnf = config; 1196 if (cnf == NULL) 1197 return 1; 1198 1199 OPENSSL_load_builtin_modules(); 1200 1201 if (CONF_modules_load(cnf, NULL, 0) <= 0) { 1202 BIO_printf(err, "Error configuring OpenSSL\n"); 1203 ERR_print_errors(err); 1204 return 0; 1205 } 1206 return 1; 1207 } 1208 1209 char * 1210 make_config_name() 1211 { 1212 const char *t = X509_get_default_cert_area(); 1213 char *p; 1214 1215 if (asprintf(&p, "%s/openssl.cnf", t) == -1) 1216 return NULL; 1217 return p; 1218 } 1219 1220 static unsigned long 1221 index_serial_hash(const OPENSSL_CSTRING *a) 1222 { 1223 const char *n; 1224 1225 n = a[DB_serial]; 1226 while (*n == '0') 1227 n++; 1228 return (lh_strhash(n)); 1229 } 1230 1231 static int 1232 index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) 1233 { 1234 const char *aa, *bb; 1235 1236 for (aa = a[DB_serial]; *aa == '0'; aa++) 1237 ; 1238 for (bb = b[DB_serial]; *bb == '0'; bb++) 1239 ; 1240 return (strcmp(aa, bb)); 1241 } 1242 1243 static int 1244 index_name_qual(char **a) 1245 { 1246 return (a[0][0] == 'V'); 1247 } 1248 1249 static unsigned long 1250 index_name_hash(const OPENSSL_CSTRING *a) 1251 { 1252 return (lh_strhash(a[DB_name])); 1253 } 1254 1255 int 1256 index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) 1257 { 1258 return (strcmp(a[DB_name], b[DB_name])); 1259 } 1260 1261 static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) 1262 static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING) 1263 static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) 1264 static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) 1265 1266 BIGNUM * 1267 load_serial(char *serialfile, int create, ASN1_INTEGER **retai) 1268 { 1269 BIO *in = NULL; 1270 BIGNUM *ret = NULL; 1271 char buf[1024]; 1272 ASN1_INTEGER *ai = NULL; 1273 1274 ai = ASN1_INTEGER_new(); 1275 if (ai == NULL) 1276 goto err; 1277 1278 if ((in = BIO_new(BIO_s_file())) == NULL) { 1279 ERR_print_errors(bio_err); 1280 goto err; 1281 } 1282 if (BIO_read_filename(in, serialfile) <= 0) { 1283 if (!create) { 1284 perror(serialfile); 1285 goto err; 1286 } else { 1287 ret = BN_new(); 1288 if (ret == NULL || !rand_serial(ret, ai)) 1289 BIO_printf(bio_err, "Out of memory\n"); 1290 } 1291 } else { 1292 if (!a2i_ASN1_INTEGER(in, ai, buf, sizeof buf)) { 1293 BIO_printf(bio_err, "unable to load number from %s\n", 1294 serialfile); 1295 goto err; 1296 } 1297 ret = ASN1_INTEGER_to_BN(ai, NULL); 1298 if (ret == NULL) { 1299 BIO_printf(bio_err, 1300 "error converting number from bin to BIGNUM\n"); 1301 goto err; 1302 } 1303 } 1304 1305 if (ret && retai) { 1306 *retai = ai; 1307 ai = NULL; 1308 } 1309 1310 err: 1311 BIO_free(in); 1312 ASN1_INTEGER_free(ai); 1313 return (ret); 1314 } 1315 1316 int 1317 save_serial(char *serialfile, char *suffix, BIGNUM *serial, 1318 ASN1_INTEGER **retai) 1319 { 1320 char serialpath[PATH_MAX]; 1321 BIO *out = NULL; 1322 int ret = 0, n; 1323 ASN1_INTEGER *ai = NULL; 1324 1325 if (suffix == NULL) 1326 n = strlcpy(serialpath, serialfile, sizeof serialpath); 1327 else 1328 n = snprintf(serialpath, sizeof serialpath, "%s.%s", 1329 serialfile, suffix); 1330 if (n < 0 || n >= sizeof(serialpath)) { 1331 BIO_printf(bio_err, "serial too long\n"); 1332 goto err; 1333 } 1334 out = BIO_new(BIO_s_file()); 1335 if (out == NULL) { 1336 ERR_print_errors(bio_err); 1337 goto err; 1338 } 1339 if (BIO_write_filename(out, serialpath) <= 0) { 1340 perror(serialfile); 1341 goto err; 1342 } 1343 if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) { 1344 BIO_printf(bio_err, 1345 "error converting serial to ASN.1 format\n"); 1346 goto err; 1347 } 1348 i2a_ASN1_INTEGER(out, ai); 1349 BIO_puts(out, "\n"); 1350 ret = 1; 1351 if (retai) { 1352 *retai = ai; 1353 ai = NULL; 1354 } 1355 1356 err: 1357 BIO_free_all(out); 1358 ASN1_INTEGER_free(ai); 1359 return (ret); 1360 } 1361 1362 int 1363 rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) 1364 { 1365 char opath[PATH_MAX], npath[PATH_MAX]; 1366 1367 if (snprintf(npath, sizeof npath, "%s.%s", serialfile, 1368 new_suffix) >= sizeof npath) { 1369 BIO_printf(bio_err, "file name too long\n"); 1370 goto err; 1371 } 1372 1373 if (snprintf(opath, sizeof opath, "%s.%s", serialfile, 1374 old_suffix) >= sizeof opath) { 1375 BIO_printf(bio_err, "file name too long\n"); 1376 goto err; 1377 } 1378 1379 if (rename(serialfile, opath) == -1 && 1380 errno != ENOENT && errno != ENOTDIR) { 1381 BIO_printf(bio_err, "unable to rename %s to %s\n", 1382 serialfile, opath); 1383 perror("reason"); 1384 goto err; 1385 } 1386 1387 1388 if (rename(npath, serialfile) == -1) { 1389 BIO_printf(bio_err, "unable to rename %s to %s\n", 1390 npath, serialfile); 1391 perror("reason"); 1392 if (rename(opath, serialfile) == -1) { 1393 BIO_printf(bio_err, "unable to rename %s to %s\n", 1394 opath, serialfile); 1395 perror("reason"); 1396 } 1397 goto err; 1398 } 1399 return 1; 1400 1401 err: 1402 return 0; 1403 } 1404 1405 int 1406 rand_serial(BIGNUM *b, ASN1_INTEGER *ai) 1407 { 1408 BIGNUM *btmp; 1409 int ret = 0; 1410 1411 if (b) 1412 btmp = b; 1413 else 1414 btmp = BN_new(); 1415 1416 if (!btmp) 1417 return 0; 1418 1419 if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) 1420 goto error; 1421 if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) 1422 goto error; 1423 1424 ret = 1; 1425 1426 error: 1427 if (b != btmp) 1428 BN_free(btmp); 1429 1430 return ret; 1431 } 1432 1433 CA_DB * 1434 load_index(char *dbfile, DB_ATTR *db_attr) 1435 { 1436 CA_DB *retdb = NULL; 1437 TXT_DB *tmpdb = NULL; 1438 BIO *in = BIO_new(BIO_s_file()); 1439 CONF *dbattr_conf = NULL; 1440 char attrpath[PATH_MAX]; 1441 long errorline = -1; 1442 1443 if (in == NULL) { 1444 ERR_print_errors(bio_err); 1445 goto err; 1446 } 1447 if (BIO_read_filename(in, dbfile) <= 0) { 1448 perror(dbfile); 1449 BIO_printf(bio_err, "unable to open '%s'\n", dbfile); 1450 goto err; 1451 } 1452 if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) 1453 goto err; 1454 1455 if (snprintf(attrpath, sizeof attrpath, "%s.attr", dbfile) 1456 >= sizeof attrpath) { 1457 BIO_printf(bio_err, "attr filename too long\n"); 1458 goto err; 1459 } 1460 1461 dbattr_conf = NCONF_new(NULL); 1462 if (NCONF_load(dbattr_conf, attrpath, &errorline) <= 0) { 1463 if (errorline > 0) { 1464 BIO_printf(bio_err, 1465 "error on line %ld of db attribute file '%s'\n", 1466 errorline, attrpath); 1467 goto err; 1468 } else { 1469 NCONF_free(dbattr_conf); 1470 dbattr_conf = NULL; 1471 } 1472 } 1473 if ((retdb = malloc(sizeof(CA_DB))) == NULL) { 1474 fprintf(stderr, "Out of memory\n"); 1475 goto err; 1476 } 1477 retdb->db = tmpdb; 1478 tmpdb = NULL; 1479 if (db_attr) 1480 retdb->attributes = *db_attr; 1481 else { 1482 retdb->attributes.unique_subject = 1; 1483 } 1484 1485 if (dbattr_conf) { 1486 char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject"); 1487 if (p) { 1488 retdb->attributes.unique_subject = parse_yesno(p, 1); 1489 } 1490 } 1491 1492 err: 1493 NCONF_free(dbattr_conf); 1494 TXT_DB_free(tmpdb); 1495 BIO_free_all(in); 1496 return retdb; 1497 } 1498 1499 int 1500 index_index(CA_DB *db) 1501 { 1502 if (!TXT_DB_create_index(db->db, DB_serial, NULL, 1503 LHASH_HASH_FN(index_serial), LHASH_COMP_FN(index_serial))) { 1504 BIO_printf(bio_err, 1505 "error creating serial number index:(%ld,%ld,%ld)\n", 1506 db->db->error, db->db->arg1, db->db->arg2); 1507 return 0; 1508 } 1509 if (db->attributes.unique_subject && 1510 !TXT_DB_create_index(db->db, DB_name, index_name_qual, 1511 LHASH_HASH_FN(index_name), LHASH_COMP_FN(index_name))) { 1512 BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n", 1513 db->db->error, db->db->arg1, db->db->arg2); 1514 return 0; 1515 } 1516 return 1; 1517 } 1518 1519 int 1520 save_index(const char *file, const char *suffix, CA_DB *db) 1521 { 1522 char attrpath[PATH_MAX], dbfile[PATH_MAX]; 1523 BIO *out = BIO_new(BIO_s_file()); 1524 int j; 1525 1526 if (out == NULL) { 1527 ERR_print_errors(bio_err); 1528 goto err; 1529 } 1530 if (snprintf(attrpath, sizeof attrpath, "%s.attr.%s", 1531 file, suffix) >= sizeof attrpath) { 1532 BIO_printf(bio_err, "file name too long\n"); 1533 goto err; 1534 } 1535 if (snprintf(dbfile, sizeof dbfile, "%s.%s", 1536 file, suffix) >= sizeof dbfile) { 1537 BIO_printf(bio_err, "file name too long\n"); 1538 goto err; 1539 } 1540 1541 if (BIO_write_filename(out, dbfile) <= 0) { 1542 perror(dbfile); 1543 BIO_printf(bio_err, "unable to open '%s'\n", dbfile); 1544 goto err; 1545 } 1546 j = TXT_DB_write(out, db->db); 1547 if (j <= 0) 1548 goto err; 1549 1550 BIO_free(out); 1551 1552 out = BIO_new(BIO_s_file()); 1553 1554 if (BIO_write_filename(out, attrpath) <= 0) { 1555 perror(attrpath); 1556 BIO_printf(bio_err, "unable to open '%s'\n", attrpath); 1557 goto err; 1558 } 1559 BIO_printf(out, "unique_subject = %s\n", 1560 db->attributes.unique_subject ? "yes" : "no"); 1561 BIO_free(out); 1562 1563 return 1; 1564 1565 err: 1566 return 0; 1567 } 1568 1569 int 1570 rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix) 1571 { 1572 char attrpath[PATH_MAX], nattrpath[PATH_MAX], oattrpath[PATH_MAX]; 1573 char dbpath[PATH_MAX], odbpath[PATH_MAX]; 1574 1575 if (snprintf(attrpath, sizeof attrpath, "%s.attr", 1576 dbfile) >= sizeof attrpath) { 1577 BIO_printf(bio_err, "file name too long\n"); 1578 goto err; 1579 } 1580 if (snprintf(nattrpath, sizeof nattrpath, "%s.attr.%s", 1581 dbfile, new_suffix) >= sizeof nattrpath) { 1582 BIO_printf(bio_err, "file name too long\n"); 1583 goto err; 1584 } 1585 if (snprintf(oattrpath, sizeof oattrpath, "%s.attr.%s", 1586 dbfile, old_suffix) >= sizeof oattrpath) { 1587 BIO_printf(bio_err, "file name too long\n"); 1588 goto err; 1589 } 1590 if (snprintf(dbpath, sizeof dbpath, "%s.%s", 1591 dbfile, new_suffix) >= sizeof dbpath) { 1592 BIO_printf(bio_err, "file name too long\n"); 1593 goto err; 1594 } 1595 if (snprintf(odbpath, sizeof odbpath, "%s.%s", 1596 dbfile, old_suffix) >= sizeof odbpath) { 1597 BIO_printf(bio_err, "file name too long\n"); 1598 goto err; 1599 } 1600 1601 if (rename(dbfile, odbpath) == -1 && errno != ENOENT && errno != ENOTDIR) { 1602 BIO_printf(bio_err, "unable to rename %s to %s\n", 1603 dbfile, odbpath); 1604 perror("reason"); 1605 goto err; 1606 } 1607 1608 if (rename(dbpath, dbfile) == -1) { 1609 BIO_printf(bio_err, "unable to rename %s to %s\n", 1610 dbpath, dbfile); 1611 perror("reason"); 1612 if (rename(odbpath, dbfile) == -1) { 1613 BIO_printf(bio_err, "unable to rename %s to %s\n", 1614 odbpath, dbfile); 1615 perror("reason"); 1616 } 1617 goto err; 1618 } 1619 1620 if (rename(attrpath, oattrpath) == -1 && errno != ENOENT && errno != ENOTDIR) { 1621 BIO_printf(bio_err, "unable to rename %s to %s\n", 1622 attrpath, oattrpath); 1623 perror("reason"); 1624 if (rename(dbfile, dbpath) == -1) { 1625 BIO_printf(bio_err, "unable to rename %s to %s\n", 1626 dbfile, dbpath); 1627 perror("reason"); 1628 } 1629 if (rename(odbpath, dbfile) == -1) { 1630 BIO_printf(bio_err, "unable to rename %s to %s\n", 1631 odbpath, dbfile); 1632 perror("reason"); 1633 } 1634 goto err; 1635 } 1636 1637 if (rename(nattrpath, attrpath) == -1) { 1638 BIO_printf(bio_err, "unable to rename %s to %s\n", 1639 nattrpath, attrpath); 1640 perror("reason"); 1641 if (rename(oattrpath, attrpath) == -1) { 1642 BIO_printf(bio_err, "unable to rename %s to %s\n", 1643 oattrpath, attrpath); 1644 perror("reason"); 1645 } 1646 if (rename(dbfile, dbpath) == -1) { 1647 BIO_printf(bio_err, "unable to rename %s to %s\n", 1648 dbfile, dbpath); 1649 perror("reason"); 1650 } 1651 if (rename(odbpath, dbfile) == -1) { 1652 BIO_printf(bio_err, "unable to rename %s to %s\n", 1653 odbpath, dbfile); 1654 perror("reason"); 1655 } 1656 goto err; 1657 } 1658 return 1; 1659 1660 err: 1661 return 0; 1662 } 1663 1664 void 1665 free_index(CA_DB *db) 1666 { 1667 if (db) { 1668 TXT_DB_free(db->db); 1669 free(db); 1670 } 1671 } 1672 1673 int 1674 parse_yesno(const char *str, int def) 1675 { 1676 int ret = def; 1677 1678 if (str) { 1679 switch (*str) { 1680 case 'f': /* false */ 1681 case 'F': /* FALSE */ 1682 case 'n': /* no */ 1683 case 'N': /* NO */ 1684 case '0': /* 0 */ 1685 ret = 0; 1686 break; 1687 case 't': /* true */ 1688 case 'T': /* TRUE */ 1689 case 'y': /* yes */ 1690 case 'Y': /* YES */ 1691 case '1': /* 1 */ 1692 ret = 1; 1693 break; 1694 default: 1695 ret = def; 1696 break; 1697 } 1698 } 1699 return ret; 1700 } 1701 1702 /* 1703 * subject is expected to be in the format /type0=value0/type1=value1/type2=... 1704 * where characters may be escaped by \ 1705 */ 1706 X509_NAME * 1707 parse_name(char *subject, long chtype, int multirdn) 1708 { 1709 X509_NAME *name = NULL; 1710 size_t buflen, max_ne; 1711 char **ne_types, **ne_values; 1712 char *buf, *bp, *sp; 1713 int i, nid, ne_num = 0; 1714 int *mval; 1715 1716 /* 1717 * Buffer to copy the types and values into. Due to escaping the 1718 * copy can only become shorter. 1719 */ 1720 buflen = strlen(subject) + 1; 1721 buf = malloc(buflen); 1722 1723 /* Maximum number of name elements. */ 1724 max_ne = buflen / 2 + 1; 1725 ne_types = reallocarray(NULL, max_ne, sizeof(char *)); 1726 ne_values = reallocarray(NULL, max_ne, sizeof(char *)); 1727 mval = reallocarray(NULL, max_ne, sizeof(int)); 1728 1729 if (buf == NULL || ne_types == NULL || ne_values == NULL || 1730 mval == NULL) { 1731 BIO_printf(bio_err, "malloc error\n"); 1732 goto error; 1733 } 1734 1735 bp = buf; 1736 sp = subject; 1737 1738 if (*subject != '/') { 1739 BIO_printf(bio_err, "Subject does not start with '/'.\n"); 1740 goto error; 1741 } 1742 1743 /* Skip leading '/'. */ 1744 sp++; 1745 1746 /* No multivalued RDN by default. */ 1747 mval[ne_num] = 0; 1748 1749 while (*sp) { 1750 /* Collect type. */ 1751 ne_types[ne_num] = bp; 1752 while (*sp) { 1753 /* is there anything to escape in the type...? */ 1754 if (*sp == '\\') { 1755 if (*++sp) 1756 *bp++ = *sp++; 1757 else { 1758 BIO_printf(bio_err, "escape character " 1759 "at end of string\n"); 1760 goto error; 1761 } 1762 } else if (*sp == '=') { 1763 sp++; 1764 *bp++ = '\0'; 1765 break; 1766 } else 1767 *bp++ = *sp++; 1768 } 1769 if (!*sp) { 1770 BIO_printf(bio_err, "end of string encountered while " 1771 "processing type of subject name element #%d\n", 1772 ne_num); 1773 goto error; 1774 } 1775 ne_values[ne_num] = bp; 1776 while (*sp) { 1777 if (*sp == '\\') { 1778 if (*++sp) 1779 *bp++ = *sp++; 1780 else { 1781 BIO_printf(bio_err, "escape character " 1782 "at end of string\n"); 1783 goto error; 1784 } 1785 } else if (*sp == '/') { 1786 sp++; 1787 /* no multivalued RDN by default */ 1788 mval[ne_num + 1] = 0; 1789 break; 1790 } else if (*sp == '+' && multirdn) { 1791 /* a not escaped + signals a multivalued RDN */ 1792 sp++; 1793 mval[ne_num + 1] = -1; 1794 break; 1795 } else 1796 *bp++ = *sp++; 1797 } 1798 *bp++ = '\0'; 1799 ne_num++; 1800 } 1801 1802 if ((name = X509_NAME_new()) == NULL) 1803 goto error; 1804 1805 for (i = 0; i < ne_num; i++) { 1806 if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) { 1807 BIO_printf(bio_err, 1808 "Subject Attribute %s has no known NID, skipped\n", 1809 ne_types[i]); 1810 continue; 1811 } 1812 if (!*ne_values[i]) { 1813 BIO_printf(bio_err, "No value provided for Subject " 1814 "Attribute %s, skipped\n", ne_types[i]); 1815 continue; 1816 } 1817 if (!X509_NAME_add_entry_by_NID(name, nid, chtype, 1818 (unsigned char *) ne_values[i], -1, -1, mval[i])) 1819 goto error; 1820 } 1821 goto done; 1822 1823 error: 1824 X509_NAME_free(name); 1825 name = NULL; 1826 1827 done: 1828 free(ne_values); 1829 free(ne_types); 1830 free(mval); 1831 free(buf); 1832 1833 return name; 1834 } 1835 1836 int 1837 args_verify(char ***pargs, int *pargc, int *badarg, BIO *err, 1838 X509_VERIFY_PARAM **pm) 1839 { 1840 ASN1_OBJECT *otmp = NULL; 1841 unsigned long flags = 0; 1842 int i; 1843 int purpose = 0, depth = -1; 1844 char **oldargs = *pargs; 1845 char *arg = **pargs, *argn = (*pargs)[1]; 1846 time_t at_time = 0; 1847 const char *errstr = NULL; 1848 1849 if (!strcmp(arg, "-policy")) { 1850 if (!argn) 1851 *badarg = 1; 1852 else { 1853 otmp = OBJ_txt2obj(argn, 0); 1854 if (!otmp) { 1855 BIO_printf(err, "Invalid Policy \"%s\"\n", 1856 argn); 1857 *badarg = 1; 1858 } 1859 } 1860 (*pargs)++; 1861 } else if (strcmp(arg, "-purpose") == 0) { 1862 X509_PURPOSE *xptmp; 1863 if (!argn) 1864 *badarg = 1; 1865 else { 1866 i = X509_PURPOSE_get_by_sname(argn); 1867 if (i < 0) { 1868 BIO_printf(err, "unrecognized purpose\n"); 1869 *badarg = 1; 1870 } else { 1871 xptmp = X509_PURPOSE_get0(i); 1872 purpose = X509_PURPOSE_get_id(xptmp); 1873 } 1874 } 1875 (*pargs)++; 1876 } else if (strcmp(arg, "-verify_depth") == 0) { 1877 if (!argn) 1878 *badarg = 1; 1879 else { 1880 depth = strtonum(argn, 1, INT_MAX, &errstr); 1881 if (errstr) { 1882 BIO_printf(err, "invalid depth %s: %s\n", 1883 argn, errstr); 1884 *badarg = 1; 1885 } 1886 } 1887 (*pargs)++; 1888 } else if (strcmp(arg, "-attime") == 0) { 1889 if (!argn) 1890 *badarg = 1; 1891 else { 1892 long long timestamp; 1893 /* 1894 * interpret the -attime argument as seconds since 1895 * Epoch 1896 */ 1897 if (sscanf(argn, "%lli", ×tamp) != 1) { 1898 BIO_printf(bio_err, 1899 "Error parsing timestamp %s\n", 1900 argn); 1901 *badarg = 1; 1902 } 1903 /* XXX 2038 truncation */ 1904 at_time = (time_t) timestamp; 1905 } 1906 (*pargs)++; 1907 } else if (!strcmp(arg, "-ignore_critical")) 1908 flags |= X509_V_FLAG_IGNORE_CRITICAL; 1909 else if (!strcmp(arg, "-issuer_checks")) 1910 flags |= X509_V_FLAG_CB_ISSUER_CHECK; 1911 else if (!strcmp(arg, "-crl_check")) 1912 flags |= X509_V_FLAG_CRL_CHECK; 1913 else if (!strcmp(arg, "-crl_check_all")) 1914 flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL; 1915 else if (!strcmp(arg, "-policy_check")) 1916 flags |= X509_V_FLAG_POLICY_CHECK; 1917 else if (!strcmp(arg, "-explicit_policy")) 1918 flags |= X509_V_FLAG_EXPLICIT_POLICY; 1919 else if (!strcmp(arg, "-inhibit_any")) 1920 flags |= X509_V_FLAG_INHIBIT_ANY; 1921 else if (!strcmp(arg, "-inhibit_map")) 1922 flags |= X509_V_FLAG_INHIBIT_MAP; 1923 else if (!strcmp(arg, "-x509_strict")) 1924 flags |= X509_V_FLAG_X509_STRICT; 1925 else if (!strcmp(arg, "-extended_crl")) 1926 flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; 1927 else if (!strcmp(arg, "-use_deltas")) 1928 flags |= X509_V_FLAG_USE_DELTAS; 1929 else if (!strcmp(arg, "-policy_print")) 1930 flags |= X509_V_FLAG_NOTIFY_POLICY; 1931 else if (!strcmp(arg, "-check_ss_sig")) 1932 flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; 1933 else 1934 return 0; 1935 1936 if (*badarg) { 1937 X509_VERIFY_PARAM_free(*pm); 1938 *pm = NULL; 1939 goto end; 1940 } 1941 if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) { 1942 *badarg = 1; 1943 goto end; 1944 } 1945 if (otmp) { 1946 X509_VERIFY_PARAM_add0_policy(*pm, otmp); 1947 otmp = NULL; 1948 } 1949 if (flags) 1950 X509_VERIFY_PARAM_set_flags(*pm, flags); 1951 1952 if (purpose) 1953 X509_VERIFY_PARAM_set_purpose(*pm, purpose); 1954 1955 if (depth >= 0) 1956 X509_VERIFY_PARAM_set_depth(*pm, depth); 1957 1958 if (at_time) 1959 X509_VERIFY_PARAM_set_time(*pm, at_time); 1960 1961 end: 1962 (*pargs)++; 1963 1964 if (pargc) 1965 *pargc -= *pargs - oldargs; 1966 1967 ASN1_OBJECT_free(otmp); 1968 return 1; 1969 } 1970 1971 /* Read whole contents of a BIO into an allocated memory buffer and 1972 * return it. 1973 */ 1974 1975 int 1976 bio_to_mem(unsigned char **out, int maxlen, BIO *in) 1977 { 1978 BIO *mem; 1979 int len, ret; 1980 unsigned char tbuf[1024]; 1981 1982 mem = BIO_new(BIO_s_mem()); 1983 if (!mem) 1984 return -1; 1985 for (;;) { 1986 if ((maxlen != -1) && maxlen < 1024) 1987 len = maxlen; 1988 else 1989 len = 1024; 1990 len = BIO_read(in, tbuf, len); 1991 if (len <= 0) 1992 break; 1993 if (BIO_write(mem, tbuf, len) != len) { 1994 BIO_free(mem); 1995 return -1; 1996 } 1997 maxlen -= len; 1998 1999 if (maxlen == 0) 2000 break; 2001 } 2002 ret = BIO_get_mem_data(mem, (char **) out); 2003 BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY); 2004 BIO_free(mem); 2005 return ret; 2006 } 2007 2008 int 2009 pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value) 2010 { 2011 int rv; 2012 char *stmp, *vtmp = NULL; 2013 2014 if (value == NULL) 2015 return -1; 2016 stmp = strdup(value); 2017 if (!stmp) 2018 return -1; 2019 vtmp = strchr(stmp, ':'); 2020 if (vtmp) { 2021 *vtmp = 0; 2022 vtmp++; 2023 } 2024 rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); 2025 free(stmp); 2026 2027 return rv; 2028 } 2029 2030 static void 2031 nodes_print(BIO *out, const char *name, STACK_OF(X509_POLICY_NODE) *nodes) 2032 { 2033 X509_POLICY_NODE *node; 2034 int i; 2035 2036 BIO_printf(out, "%s Policies:", name); 2037 if (nodes) { 2038 BIO_puts(out, "\n"); 2039 for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { 2040 node = sk_X509_POLICY_NODE_value(nodes, i); 2041 X509_POLICY_NODE_print(out, node, 2); 2042 } 2043 } else 2044 BIO_puts(out, " <empty>\n"); 2045 } 2046 2047 void 2048 policies_print(BIO *out, X509_STORE_CTX *ctx) 2049 { 2050 X509_POLICY_TREE *tree; 2051 int explicit_policy; 2052 int free_out = 0; 2053 2054 if (out == NULL) { 2055 out = BIO_new_fp(stderr, BIO_NOCLOSE); 2056 free_out = 1; 2057 } 2058 tree = X509_STORE_CTX_get0_policy_tree(ctx); 2059 explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); 2060 2061 BIO_printf(out, "Require explicit Policy: %s\n", 2062 explicit_policy ? "True" : "False"); 2063 2064 nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree)); 2065 nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree)); 2066 2067 if (free_out) 2068 BIO_free(out); 2069 } 2070 2071 /* 2072 * next_protos_parse parses a comma separated list of strings into a string 2073 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. 2074 * outlen: (output) set to the length of the resulting buffer on success. 2075 * err: (maybe NULL) on failure, an error message line is written to this BIO. 2076 * in: a NUL termianted string like "abc,def,ghi" 2077 * 2078 * returns: a malloced buffer or NULL on failure. 2079 */ 2080 unsigned char * 2081 next_protos_parse(unsigned short *outlen, const char *in) 2082 { 2083 size_t len; 2084 unsigned char *out; 2085 size_t i, start = 0; 2086 2087 len = strlen(in); 2088 if (len >= 65535) 2089 return NULL; 2090 2091 out = malloc(strlen(in) + 1); 2092 if (!out) 2093 return NULL; 2094 2095 for (i = 0; i <= len; ++i) { 2096 if (i == len || in[i] == ',') { 2097 if (i - start > 255) { 2098 free(out); 2099 return NULL; 2100 } 2101 out[start] = i - start; 2102 start = i + 1; 2103 } else 2104 out[i + 1] = in[i]; 2105 } 2106 2107 *outlen = len + 1; 2108 return out; 2109 } 2110 2111 int 2112 app_isdir(const char *name) 2113 { 2114 struct stat st; 2115 2116 if (stat(name, &st) == 0) 2117 return S_ISDIR(st.st_mode); 2118 return -1; 2119 } 2120 2121 #define OPTION_WIDTH 18 2122 2123 void 2124 options_usage(const struct option *opts) 2125 { 2126 const char *p, *q; 2127 char optstr[32]; 2128 int i; 2129 2130 for (i = 0; opts[i].name != NULL; i++) { 2131 if (opts[i].desc == NULL) 2132 continue; 2133 2134 snprintf(optstr, sizeof(optstr), "-%s %s", opts[i].name, 2135 (opts[i].argname != NULL) ? opts[i].argname : ""); 2136 fprintf(stderr, " %-*s", OPTION_WIDTH, optstr); 2137 if (strlen(optstr) > OPTION_WIDTH) 2138 fprintf(stderr, "\n %-*s", OPTION_WIDTH, ""); 2139 2140 p = opts[i].desc; 2141 while ((q = strchr(p, '\n')) != NULL) { 2142 fprintf(stderr, " %.*s", (int)(q - p), p); 2143 fprintf(stderr, "\n %-*s", OPTION_WIDTH, ""); 2144 p = q + 1; 2145 } 2146 fprintf(stderr, " %s\n", p); 2147 } 2148 } 2149 2150 int 2151 options_parse(int argc, char **argv, const struct option *opts, char **unnamed, 2152 int *argsused) 2153 { 2154 const char *errstr; 2155 const struct option *opt; 2156 long long val; 2157 char *arg, *p; 2158 int fmt, used; 2159 int ord = 0; 2160 int i, j; 2161 2162 if (unnamed != NULL) 2163 *unnamed = NULL; 2164 2165 for (i = 1; i < argc; i++) { 2166 p = arg = argv[i]; 2167 2168 /* Single unnamed argument (without leading hyphen). */ 2169 if (*p++ != '-') { 2170 if (argsused != NULL) 2171 goto done; 2172 if (unnamed == NULL) 2173 goto unknown; 2174 if (*unnamed != NULL) 2175 goto toomany; 2176 *unnamed = arg; 2177 continue; 2178 } 2179 2180 /* End of named options (single hyphen). */ 2181 if (*p == '\0') { 2182 if (++i >= argc) 2183 goto done; 2184 if (argsused != NULL) 2185 goto done; 2186 if (unnamed != NULL && i == argc - 1) { 2187 if (*unnamed != NULL) 2188 goto toomany; 2189 *unnamed = argv[i]; 2190 continue; 2191 } 2192 goto unknown; 2193 } 2194 2195 /* See if there is a matching option... */ 2196 for (j = 0; opts[j].name != NULL; j++) { 2197 if (strcmp(p, opts[j].name) == 0) 2198 break; 2199 } 2200 opt = &opts[j]; 2201 if (opt->name == NULL && opt->type == 0) 2202 goto unknown; 2203 2204 if (opt->type == OPTION_ARG || 2205 opt->type == OPTION_ARG_FORMAT || 2206 opt->type == OPTION_ARG_FUNC || 2207 opt->type == OPTION_ARG_INT || 2208 opt->type == OPTION_ARG_LONG || 2209 opt->type == OPTION_ARG_TIME) { 2210 if (++i >= argc) { 2211 fprintf(stderr, "missing %s argument for -%s\n", 2212 opt->argname, opt->name); 2213 return (1); 2214 } 2215 } 2216 2217 switch (opt->type) { 2218 case OPTION_ARG: 2219 *opt->opt.arg = argv[i]; 2220 break; 2221 2222 case OPTION_ARGV_FUNC: 2223 if (opt->opt.argvfunc(argc - i, &argv[i], &used) != 0) 2224 return (1); 2225 i += used - 1; 2226 break; 2227 2228 case OPTION_ARG_FORMAT: 2229 fmt = str2fmt(argv[i]); 2230 if (fmt == FORMAT_UNDEF) { 2231 fprintf(stderr, "unknown %s '%s' for -%s\n", 2232 opt->argname, argv[i], opt->name); 2233 return (1); 2234 } 2235 *opt->opt.value = fmt; 2236 break; 2237 2238 case OPTION_ARG_FUNC: 2239 if (opt->opt.argfunc(argv[i]) != 0) 2240 return (1); 2241 break; 2242 2243 case OPTION_ARG_INT: 2244 val = strtonum(argv[i], 0, INT_MAX, &errstr); 2245 if (errstr != NULL) { 2246 fprintf(stderr, "%s %s argument for -%s\n", 2247 errstr, opt->argname, opt->name); 2248 return (1); 2249 } 2250 *opt->opt.value = (int)val; 2251 break; 2252 2253 case OPTION_ARG_LONG: 2254 val = strtonum(argv[i], 0, LONG_MAX, &errstr); 2255 if (errstr != NULL) { 2256 fprintf(stderr, "%s %s argument for -%s\n", 2257 errstr, opt->argname, opt->name); 2258 return (1); 2259 } 2260 *opt->opt.lvalue = (long)val; 2261 break; 2262 2263 case OPTION_ARG_TIME: 2264 val = strtonum(argv[i], 0, LLONG_MAX, &errstr); 2265 if (errstr != NULL) { 2266 fprintf(stderr, "%s %s argument for -%s\n", 2267 errstr, opt->argname, opt->name); 2268 return (1); 2269 } 2270 *opt->opt.tvalue = val; 2271 break; 2272 2273 case OPTION_DISCARD: 2274 break; 2275 2276 case OPTION_FUNC: 2277 if (opt->opt.func() != 0) 2278 return (1); 2279 break; 2280 2281 case OPTION_FLAG: 2282 *opt->opt.flag = 1; 2283 break; 2284 2285 case OPTION_FLAG_ORD: 2286 *opt->opt.flag = ++ord; 2287 break; 2288 2289 case OPTION_VALUE: 2290 *opt->opt.value = opt->value; 2291 break; 2292 2293 case OPTION_VALUE_AND: 2294 *opt->opt.value &= opt->value; 2295 break; 2296 2297 case OPTION_VALUE_OR: 2298 *opt->opt.value |= opt->value; 2299 break; 2300 2301 case OPTION_UL_VALUE_OR: 2302 *opt->opt.ulvalue |= opt->ulvalue; 2303 break; 2304 2305 default: 2306 fprintf(stderr, "option %s - unknown type %i\n", 2307 opt->name, opt->type); 2308 return (1); 2309 } 2310 } 2311 2312 done: 2313 if (argsused != NULL) 2314 *argsused = i; 2315 2316 return (0); 2317 2318 toomany: 2319 fprintf(stderr, "too many arguments\n"); 2320 return (1); 2321 2322 unknown: 2323 fprintf(stderr, "unknown option '%s'\n", arg); 2324 return (1); 2325 } 2326 2327 void 2328 show_cipher(const OBJ_NAME *name, void *arg) 2329 { 2330 int *n = arg; 2331 2332 if (!islower((unsigned char)*name->name)) 2333 return; 2334 2335 fprintf(stderr, " -%-24s%s", name->name, (++*n % 3 != 0 ? "" : "\n")); 2336 } 2337 2338