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