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