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