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