1 /* $OpenBSD: apps.c,v 1.62 2022/01/10 12:17:49 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 return set_multi_opts(flags, arg, ex_tbl); 937 } 938 939 int 940 set_ext_copy(int *copy_type, const char *arg) 941 { 942 if (!strcasecmp(arg, "none")) 943 *copy_type = EXT_COPY_NONE; 944 else if (!strcasecmp(arg, "copy")) 945 *copy_type = EXT_COPY_ADD; 946 else if (!strcasecmp(arg, "copyall")) 947 *copy_type = EXT_COPY_ALL; 948 else 949 return 0; 950 return 1; 951 } 952 953 int 954 copy_extensions(X509 *x, X509_REQ *req, int copy_type) 955 { 956 STACK_OF(X509_EXTENSION) *exts = NULL; 957 X509_EXTENSION *ext, *tmpext; 958 ASN1_OBJECT *obj; 959 int i, idx, ret = 0; 960 961 if (!x || !req || (copy_type == EXT_COPY_NONE)) 962 return 1; 963 exts = X509_REQ_get_extensions(req); 964 965 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 966 ext = sk_X509_EXTENSION_value(exts, i); 967 obj = X509_EXTENSION_get_object(ext); 968 idx = X509_get_ext_by_OBJ(x, obj, -1); 969 /* Does extension exist? */ 970 if (idx != -1) { 971 /* If normal copy don't override existing extension */ 972 if (copy_type == EXT_COPY_ADD) 973 continue; 974 /* Delete all extensions of same type */ 975 do { 976 tmpext = X509_get_ext(x, idx); 977 X509_delete_ext(x, idx); 978 X509_EXTENSION_free(tmpext); 979 idx = X509_get_ext_by_OBJ(x, obj, -1); 980 } while (idx != -1); 981 } 982 if (!X509_add_ext(x, ext, -1)) 983 goto end; 984 } 985 986 ret = 1; 987 988 end: 989 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); 990 991 return ret; 992 } 993 994 static int 995 set_multi_opts(unsigned long *flags, const char *arg, 996 const NAME_EX_TBL *in_tbl) 997 { 998 STACK_OF(CONF_VALUE) *vals; 999 CONF_VALUE *val; 1000 int i, ret = 1; 1001 1002 if (!arg) 1003 return 0; 1004 vals = X509V3_parse_list(arg); 1005 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { 1006 val = sk_CONF_VALUE_value(vals, i); 1007 if (!set_table_opts(flags, val->name, in_tbl)) 1008 ret = 0; 1009 } 1010 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 1011 return ret; 1012 } 1013 1014 static int 1015 set_table_opts(unsigned long *flags, const char *arg, 1016 const NAME_EX_TBL *in_tbl) 1017 { 1018 char c; 1019 const NAME_EX_TBL *ptbl; 1020 1021 c = arg[0]; 1022 if (c == '-') { 1023 c = 0; 1024 arg++; 1025 } else if (c == '+') { 1026 c = 1; 1027 arg++; 1028 } else 1029 c = 1; 1030 1031 for (ptbl = in_tbl; ptbl->name; ptbl++) { 1032 if (!strcasecmp(arg, ptbl->name)) { 1033 *flags &= ~ptbl->mask; 1034 if (c) 1035 *flags |= ptbl->flag; 1036 else 1037 *flags &= ~ptbl->flag; 1038 return 1; 1039 } 1040 } 1041 return 0; 1042 } 1043 1044 void 1045 print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags) 1046 { 1047 char *buf; 1048 char mline = 0; 1049 int indent = 0; 1050 1051 if (title) 1052 BIO_puts(out, title); 1053 if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { 1054 mline = 1; 1055 indent = 4; 1056 } 1057 if (lflags == XN_FLAG_COMPAT) { 1058 buf = X509_NAME_oneline(nm, 0, 0); 1059 BIO_puts(out, buf); 1060 BIO_puts(out, "\n"); 1061 free(buf); 1062 } else { 1063 if (mline) 1064 BIO_puts(out, "\n"); 1065 X509_NAME_print_ex(out, nm, indent, lflags); 1066 BIO_puts(out, "\n"); 1067 } 1068 } 1069 1070 X509_STORE * 1071 setup_verify(BIO *bp, char *CAfile, char *CApath) 1072 { 1073 X509_STORE *store; 1074 X509_LOOKUP *lookup; 1075 1076 if (!(store = X509_STORE_new())) 1077 goto end; 1078 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); 1079 if (lookup == NULL) 1080 goto end; 1081 if (CAfile) { 1082 if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { 1083 BIO_printf(bp, "Error loading file %s\n", CAfile); 1084 goto end; 1085 } 1086 } else 1087 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); 1088 1089 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); 1090 if (lookup == NULL) 1091 goto end; 1092 if (CApath) { 1093 if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { 1094 BIO_printf(bp, "Error loading directory %s\n", CApath); 1095 goto end; 1096 } 1097 } else 1098 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); 1099 1100 ERR_clear_error(); 1101 return store; 1102 1103 end: 1104 X509_STORE_free(store); 1105 return NULL; 1106 } 1107 1108 int 1109 load_config(BIO *err, CONF *cnf) 1110 { 1111 static int load_config_called = 0; 1112 1113 if (load_config_called) 1114 return 1; 1115 load_config_called = 1; 1116 if (cnf == NULL) 1117 cnf = config; 1118 if (cnf == NULL) 1119 return 1; 1120 1121 OPENSSL_load_builtin_modules(); 1122 1123 if (CONF_modules_load(cnf, NULL, 0) <= 0) { 1124 BIO_printf(err, "Error configuring OpenSSL\n"); 1125 ERR_print_errors(err); 1126 return 0; 1127 } 1128 return 1; 1129 } 1130 1131 char * 1132 make_config_name() 1133 { 1134 const char *t = X509_get_default_cert_area(); 1135 char *p; 1136 1137 if (asprintf(&p, "%s/openssl.cnf", t) == -1) 1138 return NULL; 1139 return p; 1140 } 1141 1142 static unsigned long 1143 index_serial_hash(const OPENSSL_CSTRING *a) 1144 { 1145 const char *n; 1146 1147 n = a[DB_serial]; 1148 while (*n == '0') 1149 n++; 1150 return (lh_strhash(n)); 1151 } 1152 1153 static int 1154 index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) 1155 { 1156 const char *aa, *bb; 1157 1158 for (aa = a[DB_serial]; *aa == '0'; aa++) 1159 ; 1160 for (bb = b[DB_serial]; *bb == '0'; bb++) 1161 ; 1162 return (strcmp(aa, bb)); 1163 } 1164 1165 static int 1166 index_name_qual(char **a) 1167 { 1168 return (a[0][0] == 'V'); 1169 } 1170 1171 static unsigned long 1172 index_name_hash(const OPENSSL_CSTRING *a) 1173 { 1174 return (lh_strhash(a[DB_name])); 1175 } 1176 1177 int 1178 index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) 1179 { 1180 return (strcmp(a[DB_name], b[DB_name])); 1181 } 1182 1183 static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) 1184 static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING) 1185 static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) 1186 static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) 1187 1188 BIGNUM * 1189 load_serial(char *serialfile, int create, ASN1_INTEGER **retai) 1190 { 1191 BIO *in = NULL; 1192 BIGNUM *ret = NULL; 1193 char buf[1024]; 1194 ASN1_INTEGER *ai = NULL; 1195 1196 ai = ASN1_INTEGER_new(); 1197 if (ai == NULL) 1198 goto err; 1199 1200 if ((in = BIO_new(BIO_s_file())) == NULL) { 1201 ERR_print_errors(bio_err); 1202 goto err; 1203 } 1204 if (BIO_read_filename(in, serialfile) <= 0) { 1205 if (!create) { 1206 perror(serialfile); 1207 goto err; 1208 } else { 1209 ret = BN_new(); 1210 if (ret == NULL || !rand_serial(ret, ai)) 1211 BIO_printf(bio_err, "Out of memory\n"); 1212 } 1213 } else { 1214 if (!a2i_ASN1_INTEGER(in, ai, buf, sizeof buf)) { 1215 BIO_printf(bio_err, "unable to load number from %s\n", 1216 serialfile); 1217 goto err; 1218 } 1219 ret = ASN1_INTEGER_to_BN(ai, NULL); 1220 if (ret == NULL) { 1221 BIO_printf(bio_err, 1222 "error converting number from bin to BIGNUM\n"); 1223 goto err; 1224 } 1225 } 1226 1227 if (ret && retai) { 1228 *retai = ai; 1229 ai = NULL; 1230 } 1231 1232 err: 1233 BIO_free(in); 1234 ASN1_INTEGER_free(ai); 1235 return (ret); 1236 } 1237 1238 int 1239 save_serial(char *serialfile, char *suffix, BIGNUM *serial, 1240 ASN1_INTEGER **retai) 1241 { 1242 char serialpath[PATH_MAX]; 1243 BIO *out = NULL; 1244 int ret = 0, n; 1245 ASN1_INTEGER *ai = NULL; 1246 1247 if (suffix == NULL) 1248 n = strlcpy(serialpath, serialfile, sizeof serialpath); 1249 else 1250 n = snprintf(serialpath, sizeof serialpath, "%s.%s", 1251 serialfile, suffix); 1252 if (n < 0 || n >= sizeof(serialpath)) { 1253 BIO_printf(bio_err, "serial too long\n"); 1254 goto err; 1255 } 1256 out = BIO_new(BIO_s_file()); 1257 if (out == NULL) { 1258 ERR_print_errors(bio_err); 1259 goto err; 1260 } 1261 if (BIO_write_filename(out, serialpath) <= 0) { 1262 perror(serialfile); 1263 goto err; 1264 } 1265 if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) { 1266 BIO_printf(bio_err, 1267 "error converting serial to ASN.1 format\n"); 1268 goto err; 1269 } 1270 i2a_ASN1_INTEGER(out, ai); 1271 BIO_puts(out, "\n"); 1272 ret = 1; 1273 if (retai) { 1274 *retai = ai; 1275 ai = NULL; 1276 } 1277 1278 err: 1279 BIO_free_all(out); 1280 ASN1_INTEGER_free(ai); 1281 return (ret); 1282 } 1283 1284 int 1285 rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) 1286 { 1287 char opath[PATH_MAX], npath[PATH_MAX]; 1288 1289 if (snprintf(npath, sizeof npath, "%s.%s", serialfile, 1290 new_suffix) >= sizeof npath) { 1291 BIO_printf(bio_err, "file name too long\n"); 1292 goto err; 1293 } 1294 1295 if (snprintf(opath, sizeof opath, "%s.%s", serialfile, 1296 old_suffix) >= sizeof opath) { 1297 BIO_printf(bio_err, "file name too long\n"); 1298 goto err; 1299 } 1300 1301 if (rename(serialfile, opath) == -1 && 1302 errno != ENOENT && errno != ENOTDIR) { 1303 BIO_printf(bio_err, "unable to rename %s to %s\n", 1304 serialfile, opath); 1305 perror("reason"); 1306 goto err; 1307 } 1308 1309 1310 if (rename(npath, serialfile) == -1) { 1311 BIO_printf(bio_err, "unable to rename %s to %s\n", 1312 npath, serialfile); 1313 perror("reason"); 1314 if (rename(opath, serialfile) == -1) { 1315 BIO_printf(bio_err, "unable to rename %s to %s\n", 1316 opath, serialfile); 1317 perror("reason"); 1318 } 1319 goto err; 1320 } 1321 return 1; 1322 1323 err: 1324 return 0; 1325 } 1326 1327 int 1328 rand_serial(BIGNUM *b, ASN1_INTEGER *ai) 1329 { 1330 BIGNUM *btmp; 1331 int ret = 0; 1332 1333 if (b) 1334 btmp = b; 1335 else 1336 btmp = BN_new(); 1337 1338 if (!btmp) 1339 return 0; 1340 1341 if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) 1342 goto error; 1343 if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) 1344 goto error; 1345 1346 ret = 1; 1347 1348 error: 1349 if (b != btmp) 1350 BN_free(btmp); 1351 1352 return ret; 1353 } 1354 1355 CA_DB * 1356 load_index(char *dbfile, DB_ATTR *db_attr) 1357 { 1358 CA_DB *retdb = NULL; 1359 TXT_DB *tmpdb = NULL; 1360 BIO *in = BIO_new(BIO_s_file()); 1361 CONF *dbattr_conf = NULL; 1362 char attrpath[PATH_MAX]; 1363 long errorline = -1; 1364 1365 if (in == NULL) { 1366 ERR_print_errors(bio_err); 1367 goto err; 1368 } 1369 if (BIO_read_filename(in, dbfile) <= 0) { 1370 perror(dbfile); 1371 BIO_printf(bio_err, "unable to open '%s'\n", dbfile); 1372 goto err; 1373 } 1374 if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) 1375 goto err; 1376 1377 if (snprintf(attrpath, sizeof attrpath, "%s.attr", dbfile) 1378 >= sizeof attrpath) { 1379 BIO_printf(bio_err, "attr filename too long\n"); 1380 goto err; 1381 } 1382 1383 dbattr_conf = NCONF_new(NULL); 1384 if (NCONF_load(dbattr_conf, attrpath, &errorline) <= 0) { 1385 if (errorline > 0) { 1386 BIO_printf(bio_err, 1387 "error on line %ld of db attribute file '%s'\n", 1388 errorline, attrpath); 1389 goto err; 1390 } else { 1391 NCONF_free(dbattr_conf); 1392 dbattr_conf = NULL; 1393 } 1394 } 1395 if ((retdb = malloc(sizeof(CA_DB))) == NULL) { 1396 fprintf(stderr, "Out of memory\n"); 1397 goto err; 1398 } 1399 retdb->db = tmpdb; 1400 tmpdb = NULL; 1401 if (db_attr) 1402 retdb->attributes = *db_attr; 1403 else { 1404 retdb->attributes.unique_subject = 1; 1405 } 1406 1407 if (dbattr_conf) { 1408 char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject"); 1409 if (p) { 1410 retdb->attributes.unique_subject = parse_yesno(p, 1); 1411 } 1412 } 1413 1414 err: 1415 NCONF_free(dbattr_conf); 1416 TXT_DB_free(tmpdb); 1417 BIO_free_all(in); 1418 return retdb; 1419 } 1420 1421 int 1422 index_index(CA_DB *db) 1423 { 1424 if (!TXT_DB_create_index(db->db, DB_serial, NULL, 1425 LHASH_HASH_FN(index_serial), LHASH_COMP_FN(index_serial))) { 1426 BIO_printf(bio_err, 1427 "error creating serial number index:(%ld,%ld,%ld)\n", 1428 db->db->error, db->db->arg1, db->db->arg2); 1429 return 0; 1430 } 1431 if (db->attributes.unique_subject && 1432 !TXT_DB_create_index(db->db, DB_name, index_name_qual, 1433 LHASH_HASH_FN(index_name), LHASH_COMP_FN(index_name))) { 1434 BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n", 1435 db->db->error, db->db->arg1, db->db->arg2); 1436 return 0; 1437 } 1438 return 1; 1439 } 1440 1441 int 1442 save_index(const char *file, const char *suffix, CA_DB *db) 1443 { 1444 char attrpath[PATH_MAX], dbfile[PATH_MAX]; 1445 BIO *out = BIO_new(BIO_s_file()); 1446 int j; 1447 1448 if (out == NULL) { 1449 ERR_print_errors(bio_err); 1450 goto err; 1451 } 1452 if (snprintf(attrpath, sizeof attrpath, "%s.attr.%s", 1453 file, suffix) >= sizeof attrpath) { 1454 BIO_printf(bio_err, "file name too long\n"); 1455 goto err; 1456 } 1457 if (snprintf(dbfile, sizeof dbfile, "%s.%s", 1458 file, suffix) >= sizeof dbfile) { 1459 BIO_printf(bio_err, "file name too long\n"); 1460 goto err; 1461 } 1462 1463 if (BIO_write_filename(out, dbfile) <= 0) { 1464 perror(dbfile); 1465 BIO_printf(bio_err, "unable to open '%s'\n", dbfile); 1466 goto err; 1467 } 1468 j = TXT_DB_write(out, db->db); 1469 if (j <= 0) 1470 goto err; 1471 1472 BIO_free(out); 1473 1474 out = BIO_new(BIO_s_file()); 1475 1476 if (BIO_write_filename(out, attrpath) <= 0) { 1477 perror(attrpath); 1478 BIO_printf(bio_err, "unable to open '%s'\n", attrpath); 1479 goto err; 1480 } 1481 BIO_printf(out, "unique_subject = %s\n", 1482 db->attributes.unique_subject ? "yes" : "no"); 1483 BIO_free(out); 1484 1485 return 1; 1486 1487 err: 1488 return 0; 1489 } 1490 1491 int 1492 rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix) 1493 { 1494 char attrpath[PATH_MAX], nattrpath[PATH_MAX], oattrpath[PATH_MAX]; 1495 char dbpath[PATH_MAX], odbpath[PATH_MAX]; 1496 1497 if (snprintf(attrpath, sizeof attrpath, "%s.attr", 1498 dbfile) >= sizeof attrpath) { 1499 BIO_printf(bio_err, "file name too long\n"); 1500 goto err; 1501 } 1502 if (snprintf(nattrpath, sizeof nattrpath, "%s.attr.%s", 1503 dbfile, new_suffix) >= sizeof nattrpath) { 1504 BIO_printf(bio_err, "file name too long\n"); 1505 goto err; 1506 } 1507 if (snprintf(oattrpath, sizeof oattrpath, "%s.attr.%s", 1508 dbfile, old_suffix) >= sizeof oattrpath) { 1509 BIO_printf(bio_err, "file name too long\n"); 1510 goto err; 1511 } 1512 if (snprintf(dbpath, sizeof dbpath, "%s.%s", 1513 dbfile, new_suffix) >= sizeof dbpath) { 1514 BIO_printf(bio_err, "file name too long\n"); 1515 goto err; 1516 } 1517 if (snprintf(odbpath, sizeof odbpath, "%s.%s", 1518 dbfile, old_suffix) >= sizeof odbpath) { 1519 BIO_printf(bio_err, "file name too long\n"); 1520 goto err; 1521 } 1522 1523 if (rename(dbfile, odbpath) == -1 && errno != ENOENT && errno != ENOTDIR) { 1524 BIO_printf(bio_err, "unable to rename %s to %s\n", 1525 dbfile, odbpath); 1526 perror("reason"); 1527 goto err; 1528 } 1529 1530 if (rename(dbpath, dbfile) == -1) { 1531 BIO_printf(bio_err, "unable to rename %s to %s\n", 1532 dbpath, dbfile); 1533 perror("reason"); 1534 if (rename(odbpath, dbfile) == -1) { 1535 BIO_printf(bio_err, "unable to rename %s to %s\n", 1536 odbpath, dbfile); 1537 perror("reason"); 1538 } 1539 goto err; 1540 } 1541 1542 if (rename(attrpath, oattrpath) == -1 && errno != ENOENT && errno != ENOTDIR) { 1543 BIO_printf(bio_err, "unable to rename %s to %s\n", 1544 attrpath, oattrpath); 1545 perror("reason"); 1546 if (rename(dbfile, dbpath) == -1) { 1547 BIO_printf(bio_err, "unable to rename %s to %s\n", 1548 dbfile, dbpath); 1549 perror("reason"); 1550 } 1551 if (rename(odbpath, dbfile) == -1) { 1552 BIO_printf(bio_err, "unable to rename %s to %s\n", 1553 odbpath, dbfile); 1554 perror("reason"); 1555 } 1556 goto err; 1557 } 1558 1559 if (rename(nattrpath, attrpath) == -1) { 1560 BIO_printf(bio_err, "unable to rename %s to %s\n", 1561 nattrpath, attrpath); 1562 perror("reason"); 1563 if (rename(oattrpath, attrpath) == -1) { 1564 BIO_printf(bio_err, "unable to rename %s to %s\n", 1565 oattrpath, attrpath); 1566 perror("reason"); 1567 } 1568 if (rename(dbfile, dbpath) == -1) { 1569 BIO_printf(bio_err, "unable to rename %s to %s\n", 1570 dbfile, dbpath); 1571 perror("reason"); 1572 } 1573 if (rename(odbpath, dbfile) == -1) { 1574 BIO_printf(bio_err, "unable to rename %s to %s\n", 1575 odbpath, dbfile); 1576 perror("reason"); 1577 } 1578 goto err; 1579 } 1580 return 1; 1581 1582 err: 1583 return 0; 1584 } 1585 1586 void 1587 free_index(CA_DB *db) 1588 { 1589 if (db) { 1590 TXT_DB_free(db->db); 1591 free(db); 1592 } 1593 } 1594 1595 int 1596 parse_yesno(const char *str, int def) 1597 { 1598 int ret = def; 1599 1600 if (str) { 1601 switch (*str) { 1602 case 'f': /* false */ 1603 case 'F': /* FALSE */ 1604 case 'n': /* no */ 1605 case 'N': /* NO */ 1606 case '0': /* 0 */ 1607 ret = 0; 1608 break; 1609 case 't': /* true */ 1610 case 'T': /* TRUE */ 1611 case 'y': /* yes */ 1612 case 'Y': /* YES */ 1613 case '1': /* 1 */ 1614 ret = 1; 1615 break; 1616 default: 1617 ret = def; 1618 break; 1619 } 1620 } 1621 return ret; 1622 } 1623 1624 /* 1625 * subject is expected to be in the format /type0=value0/type1=value1/type2=... 1626 * where characters may be escaped by \ 1627 */ 1628 X509_NAME * 1629 parse_name(char *subject, long chtype, int multirdn) 1630 { 1631 X509_NAME *name = NULL; 1632 size_t buflen, max_ne; 1633 char **ne_types, **ne_values; 1634 char *buf, *bp, *sp; 1635 int i, nid, ne_num = 0; 1636 int *mval; 1637 1638 /* 1639 * Buffer to copy the types and values into. Due to escaping the 1640 * copy can only become shorter. 1641 */ 1642 buflen = strlen(subject) + 1; 1643 buf = malloc(buflen); 1644 1645 /* Maximum number of name elements. */ 1646 max_ne = buflen / 2 + 1; 1647 ne_types = reallocarray(NULL, max_ne, sizeof(char *)); 1648 ne_values = reallocarray(NULL, max_ne, sizeof(char *)); 1649 mval = reallocarray(NULL, max_ne, sizeof(int)); 1650 1651 if (buf == NULL || ne_types == NULL || ne_values == NULL || 1652 mval == NULL) { 1653 BIO_printf(bio_err, "malloc error\n"); 1654 goto error; 1655 } 1656 1657 bp = buf; 1658 sp = subject; 1659 1660 if (*subject != '/') { 1661 BIO_printf(bio_err, "Subject does not start with '/'.\n"); 1662 goto error; 1663 } 1664 1665 /* Skip leading '/'. */ 1666 sp++; 1667 1668 /* No multivalued RDN by default. */ 1669 mval[ne_num] = 0; 1670 1671 while (*sp) { 1672 /* Collect type. */ 1673 ne_types[ne_num] = bp; 1674 while (*sp) { 1675 /* is there anything to escape in the type...? */ 1676 if (*sp == '\\') { 1677 if (*++sp) 1678 *bp++ = *sp++; 1679 else { 1680 BIO_printf(bio_err, "escape character " 1681 "at end of string\n"); 1682 goto error; 1683 } 1684 } else if (*sp == '=') { 1685 sp++; 1686 *bp++ = '\0'; 1687 break; 1688 } else 1689 *bp++ = *sp++; 1690 } 1691 if (!*sp) { 1692 BIO_printf(bio_err, "end of string encountered while " 1693 "processing type of subject name element #%d\n", 1694 ne_num); 1695 goto error; 1696 } 1697 ne_values[ne_num] = bp; 1698 while (*sp) { 1699 if (*sp == '\\') { 1700 if (*++sp) 1701 *bp++ = *sp++; 1702 else { 1703 BIO_printf(bio_err, "escape character " 1704 "at end of string\n"); 1705 goto error; 1706 } 1707 } else if (*sp == '/') { 1708 sp++; 1709 /* no multivalued RDN by default */ 1710 mval[ne_num + 1] = 0; 1711 break; 1712 } else if (*sp == '+' && multirdn) { 1713 /* a not escaped + signals a multivalued RDN */ 1714 sp++; 1715 mval[ne_num + 1] = -1; 1716 break; 1717 } else 1718 *bp++ = *sp++; 1719 } 1720 *bp++ = '\0'; 1721 ne_num++; 1722 } 1723 1724 if ((name = X509_NAME_new()) == NULL) 1725 goto error; 1726 1727 for (i = 0; i < ne_num; i++) { 1728 if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) { 1729 BIO_printf(bio_err, 1730 "Subject Attribute %s has no known NID, skipped\n", 1731 ne_types[i]); 1732 continue; 1733 } 1734 if (!*ne_values[i]) { 1735 BIO_printf(bio_err, "No value provided for Subject " 1736 "Attribute %s, skipped\n", ne_types[i]); 1737 continue; 1738 } 1739 if (!X509_NAME_add_entry_by_NID(name, nid, chtype, 1740 (unsigned char *) ne_values[i], -1, -1, mval[i])) 1741 goto error; 1742 } 1743 goto done; 1744 1745 error: 1746 X509_NAME_free(name); 1747 name = NULL; 1748 1749 done: 1750 free(ne_values); 1751 free(ne_types); 1752 free(mval); 1753 free(buf); 1754 1755 return name; 1756 } 1757 1758 int 1759 args_verify(char ***pargs, int *pargc, int *badarg, BIO *err, 1760 X509_VERIFY_PARAM **pm) 1761 { 1762 ASN1_OBJECT *otmp = NULL; 1763 unsigned long flags = 0; 1764 int i; 1765 int purpose = 0, depth = -1; 1766 char **oldargs = *pargs; 1767 char *arg = **pargs, *argn = (*pargs)[1]; 1768 time_t at_time = 0; 1769 const char *errstr = NULL; 1770 1771 if (!strcmp(arg, "-policy")) { 1772 if (!argn) 1773 *badarg = 1; 1774 else { 1775 otmp = OBJ_txt2obj(argn, 0); 1776 if (!otmp) { 1777 BIO_printf(err, "Invalid Policy \"%s\"\n", 1778 argn); 1779 *badarg = 1; 1780 } 1781 } 1782 (*pargs)++; 1783 } else if (strcmp(arg, "-purpose") == 0) { 1784 X509_PURPOSE *xptmp; 1785 if (!argn) 1786 *badarg = 1; 1787 else { 1788 i = X509_PURPOSE_get_by_sname(argn); 1789 if (i < 0) { 1790 BIO_printf(err, "unrecognized purpose\n"); 1791 *badarg = 1; 1792 } else { 1793 xptmp = X509_PURPOSE_get0(i); 1794 purpose = X509_PURPOSE_get_id(xptmp); 1795 } 1796 } 1797 (*pargs)++; 1798 } else if (strcmp(arg, "-verify_depth") == 0) { 1799 if (!argn) 1800 *badarg = 1; 1801 else { 1802 depth = strtonum(argn, 1, INT_MAX, &errstr); 1803 if (errstr) { 1804 BIO_printf(err, "invalid depth %s: %s\n", 1805 argn, errstr); 1806 *badarg = 1; 1807 } 1808 } 1809 (*pargs)++; 1810 } else if (strcmp(arg, "-attime") == 0) { 1811 if (!argn) 1812 *badarg = 1; 1813 else { 1814 long long timestamp; 1815 /* 1816 * interpret the -attime argument as seconds since 1817 * Epoch 1818 */ 1819 if (sscanf(argn, "%lli", ×tamp) != 1) { 1820 BIO_printf(bio_err, 1821 "Error parsing timestamp %s\n", 1822 argn); 1823 *badarg = 1; 1824 } 1825 /* XXX 2038 truncation */ 1826 at_time = (time_t) timestamp; 1827 } 1828 (*pargs)++; 1829 } else if (!strcmp(arg, "-ignore_critical")) 1830 flags |= X509_V_FLAG_IGNORE_CRITICAL; 1831 else if (!strcmp(arg, "-issuer_checks")) 1832 flags |= X509_V_FLAG_CB_ISSUER_CHECK; 1833 else if (!strcmp(arg, "-crl_check")) 1834 flags |= X509_V_FLAG_CRL_CHECK; 1835 else if (!strcmp(arg, "-crl_check_all")) 1836 flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL; 1837 else if (!strcmp(arg, "-policy_check")) 1838 flags |= X509_V_FLAG_POLICY_CHECK; 1839 else if (!strcmp(arg, "-explicit_policy")) 1840 flags |= X509_V_FLAG_EXPLICIT_POLICY; 1841 else if (!strcmp(arg, "-legacy_verify")) 1842 flags |= X509_V_FLAG_LEGACY_VERIFY; 1843 else if (!strcmp(arg, "-inhibit_any")) 1844 flags |= X509_V_FLAG_INHIBIT_ANY; 1845 else if (!strcmp(arg, "-inhibit_map")) 1846 flags |= X509_V_FLAG_INHIBIT_MAP; 1847 else if (!strcmp(arg, "-x509_strict")) 1848 flags |= X509_V_FLAG_X509_STRICT; 1849 else if (!strcmp(arg, "-extended_crl")) 1850 flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; 1851 else if (!strcmp(arg, "-use_deltas")) 1852 flags |= X509_V_FLAG_USE_DELTAS; 1853 else if (!strcmp(arg, "-policy_print")) 1854 flags |= X509_V_FLAG_NOTIFY_POLICY; 1855 else if (!strcmp(arg, "-check_ss_sig")) 1856 flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; 1857 else 1858 return 0; 1859 1860 if (*badarg) { 1861 X509_VERIFY_PARAM_free(*pm); 1862 *pm = NULL; 1863 goto end; 1864 } 1865 if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) { 1866 *badarg = 1; 1867 goto end; 1868 } 1869 if (otmp) { 1870 X509_VERIFY_PARAM_add0_policy(*pm, otmp); 1871 otmp = NULL; 1872 } 1873 if (flags) 1874 X509_VERIFY_PARAM_set_flags(*pm, flags); 1875 1876 if (purpose) 1877 X509_VERIFY_PARAM_set_purpose(*pm, purpose); 1878 1879 if (depth >= 0) 1880 X509_VERIFY_PARAM_set_depth(*pm, depth); 1881 1882 if (at_time) 1883 X509_VERIFY_PARAM_set_time(*pm, at_time); 1884 1885 end: 1886 (*pargs)++; 1887 1888 if (pargc) 1889 *pargc -= *pargs - oldargs; 1890 1891 ASN1_OBJECT_free(otmp); 1892 return 1; 1893 } 1894 1895 /* Read whole contents of a BIO into an allocated memory buffer and 1896 * return it. 1897 */ 1898 1899 int 1900 bio_to_mem(unsigned char **out, int maxlen, BIO *in) 1901 { 1902 BIO *mem; 1903 int len, ret; 1904 unsigned char tbuf[1024]; 1905 1906 mem = BIO_new(BIO_s_mem()); 1907 if (!mem) 1908 return -1; 1909 for (;;) { 1910 if ((maxlen != -1) && maxlen < 1024) 1911 len = maxlen; 1912 else 1913 len = 1024; 1914 len = BIO_read(in, tbuf, len); 1915 if (len <= 0) 1916 break; 1917 if (BIO_write(mem, tbuf, len) != len) { 1918 BIO_free(mem); 1919 return -1; 1920 } 1921 maxlen -= len; 1922 1923 if (maxlen == 0) 1924 break; 1925 } 1926 ret = BIO_get_mem_data(mem, (char **) out); 1927 BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY); 1928 BIO_free(mem); 1929 return ret; 1930 } 1931 1932 int 1933 pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value) 1934 { 1935 int rv; 1936 char *stmp, *vtmp = NULL; 1937 1938 if (value == NULL) 1939 return -1; 1940 stmp = strdup(value); 1941 if (!stmp) 1942 return -1; 1943 vtmp = strchr(stmp, ':'); 1944 if (vtmp) { 1945 *vtmp = 0; 1946 vtmp++; 1947 } 1948 rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); 1949 free(stmp); 1950 1951 return rv; 1952 } 1953 1954 static void 1955 nodes_print(BIO *out, const char *name, STACK_OF(X509_POLICY_NODE) *nodes) 1956 { 1957 X509_POLICY_NODE *node; 1958 int i; 1959 1960 BIO_printf(out, "%s Policies:", name); 1961 if (nodes) { 1962 BIO_puts(out, "\n"); 1963 for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { 1964 node = sk_X509_POLICY_NODE_value(nodes, i); 1965 X509_POLICY_NODE_print(out, node, 2); 1966 } 1967 } else 1968 BIO_puts(out, " <empty>\n"); 1969 } 1970 1971 void 1972 policies_print(BIO *out, X509_STORE_CTX *ctx) 1973 { 1974 X509_POLICY_TREE *tree; 1975 int explicit_policy; 1976 int free_out = 0; 1977 1978 if (out == NULL) { 1979 out = BIO_new_fp(stderr, BIO_NOCLOSE); 1980 free_out = 1; 1981 } 1982 tree = X509_STORE_CTX_get0_policy_tree(ctx); 1983 explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); 1984 1985 BIO_printf(out, "Require explicit Policy: %s\n", 1986 explicit_policy ? "True" : "False"); 1987 1988 nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree)); 1989 nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree)); 1990 1991 if (free_out) 1992 BIO_free(out); 1993 } 1994 1995 /* 1996 * next_protos_parse parses a comma separated list of strings into a string 1997 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. 1998 * outlen: (output) set to the length of the resulting buffer on success. 1999 * err: (maybe NULL) on failure, an error message line is written to this BIO. 2000 * in: a NUL termianted string like "abc,def,ghi" 2001 * 2002 * returns: a malloced buffer or NULL on failure. 2003 */ 2004 unsigned char * 2005 next_protos_parse(unsigned short *outlen, const char *in) 2006 { 2007 size_t len; 2008 unsigned char *out; 2009 size_t i, start = 0; 2010 2011 len = strlen(in); 2012 if (len >= 65535) 2013 return NULL; 2014 2015 out = malloc(strlen(in) + 1); 2016 if (!out) 2017 return NULL; 2018 2019 for (i = 0; i <= len; ++i) { 2020 if (i == len || in[i] == ',') { 2021 if (i - start > 255) { 2022 free(out); 2023 return NULL; 2024 } 2025 out[start] = i - start; 2026 start = i + 1; 2027 } else 2028 out[i + 1] = in[i]; 2029 } 2030 2031 *outlen = len + 1; 2032 return out; 2033 } 2034 2035 int 2036 app_isdir(const char *name) 2037 { 2038 struct stat st; 2039 2040 if (stat(name, &st) == 0) 2041 return S_ISDIR(st.st_mode); 2042 return -1; 2043 } 2044 2045 #define OPTION_WIDTH 18 2046 2047 void 2048 options_usage(const struct option *opts) 2049 { 2050 const char *p, *q; 2051 char optstr[32]; 2052 int i; 2053 2054 for (i = 0; opts[i].name != NULL; i++) { 2055 if (opts[i].desc == NULL) 2056 continue; 2057 2058 snprintf(optstr, sizeof(optstr), "-%s %s", opts[i].name, 2059 (opts[i].argname != NULL) ? opts[i].argname : ""); 2060 fprintf(stderr, " %-*s", OPTION_WIDTH, optstr); 2061 if (strlen(optstr) > OPTION_WIDTH) 2062 fprintf(stderr, "\n %-*s", OPTION_WIDTH, ""); 2063 2064 p = opts[i].desc; 2065 while ((q = strchr(p, '\n')) != NULL) { 2066 fprintf(stderr, " %.*s", (int)(q - p), p); 2067 fprintf(stderr, "\n %-*s", OPTION_WIDTH, ""); 2068 p = q + 1; 2069 } 2070 fprintf(stderr, " %s\n", p); 2071 } 2072 } 2073 2074 int 2075 options_parse(int argc, char **argv, const struct option *opts, char **unnamed, 2076 int *argsused) 2077 { 2078 const char *errstr; 2079 const struct option *opt; 2080 long long val; 2081 char *arg, *p; 2082 int fmt, used; 2083 int ord = 0; 2084 int i, j; 2085 2086 if (unnamed != NULL) 2087 *unnamed = NULL; 2088 2089 for (i = 1; i < argc; i++) { 2090 p = arg = argv[i]; 2091 2092 /* Single unnamed argument (without leading hyphen). */ 2093 if (*p++ != '-') { 2094 if (argsused != NULL) 2095 goto done; 2096 if (unnamed == NULL) 2097 goto unknown; 2098 if (*unnamed != NULL) 2099 goto toomany; 2100 *unnamed = arg; 2101 continue; 2102 } 2103 2104 /* End of named options (single hyphen). */ 2105 if (*p == '\0') { 2106 if (++i >= argc) 2107 goto done; 2108 if (argsused != NULL) 2109 goto done; 2110 if (unnamed != NULL && i == argc - 1) { 2111 if (*unnamed != NULL) 2112 goto toomany; 2113 *unnamed = argv[i]; 2114 continue; 2115 } 2116 goto unknown; 2117 } 2118 2119 /* See if there is a matching option... */ 2120 for (j = 0; opts[j].name != NULL; j++) { 2121 if (strcmp(p, opts[j].name) == 0) 2122 break; 2123 } 2124 opt = &opts[j]; 2125 if (opt->name == NULL && opt->type == 0) 2126 goto unknown; 2127 2128 if (opt->type == OPTION_ARG || 2129 opt->type == OPTION_ARG_FORMAT || 2130 opt->type == OPTION_ARG_FUNC || 2131 opt->type == OPTION_ARG_INT || 2132 opt->type == OPTION_ARG_LONG || 2133 opt->type == OPTION_ARG_TIME) { 2134 if (++i >= argc) { 2135 fprintf(stderr, "missing %s argument for -%s\n", 2136 opt->argname, opt->name); 2137 return (1); 2138 } 2139 } 2140 2141 switch (opt->type) { 2142 case OPTION_ARG: 2143 *opt->opt.arg = argv[i]; 2144 break; 2145 2146 case OPTION_ARGV_FUNC: 2147 if (opt->opt.argvfunc(argc - i, &argv[i], &used) != 0) 2148 return (1); 2149 i += used - 1; 2150 break; 2151 2152 case OPTION_ARG_FORMAT: 2153 fmt = str2fmt(argv[i]); 2154 if (fmt == FORMAT_UNDEF) { 2155 fprintf(stderr, "unknown %s '%s' for -%s\n", 2156 opt->argname, argv[i], opt->name); 2157 return (1); 2158 } 2159 *opt->opt.value = fmt; 2160 break; 2161 2162 case OPTION_ARG_FUNC: 2163 if (opt->opt.argfunc(argv[i]) != 0) 2164 return (1); 2165 break; 2166 2167 case OPTION_ARG_INT: 2168 val = strtonum(argv[i], 0, INT_MAX, &errstr); 2169 if (errstr != NULL) { 2170 fprintf(stderr, "%s %s argument for -%s\n", 2171 errstr, opt->argname, opt->name); 2172 return (1); 2173 } 2174 *opt->opt.value = (int)val; 2175 break; 2176 2177 case OPTION_ARG_LONG: 2178 val = strtonum(argv[i], 0, LONG_MAX, &errstr); 2179 if (errstr != NULL) { 2180 fprintf(stderr, "%s %s argument for -%s\n", 2181 errstr, opt->argname, opt->name); 2182 return (1); 2183 } 2184 *opt->opt.lvalue = (long)val; 2185 break; 2186 2187 case OPTION_ARG_TIME: 2188 val = strtonum(argv[i], 0, LLONG_MAX, &errstr); 2189 if (errstr != NULL) { 2190 fprintf(stderr, "%s %s argument for -%s\n", 2191 errstr, opt->argname, opt->name); 2192 return (1); 2193 } 2194 *opt->opt.tvalue = val; 2195 break; 2196 2197 case OPTION_DISCARD: 2198 break; 2199 2200 case OPTION_FUNC: 2201 if (opt->opt.func() != 0) 2202 return (1); 2203 break; 2204 2205 case OPTION_FLAG: 2206 *opt->opt.flag = 1; 2207 break; 2208 2209 case OPTION_FLAG_ORD: 2210 *opt->opt.flag = ++ord; 2211 break; 2212 2213 case OPTION_VALUE: 2214 *opt->opt.value = opt->value; 2215 break; 2216 2217 case OPTION_VALUE_AND: 2218 *opt->opt.value &= opt->value; 2219 break; 2220 2221 case OPTION_VALUE_OR: 2222 *opt->opt.value |= opt->value; 2223 break; 2224 2225 case OPTION_UL_VALUE_OR: 2226 *opt->opt.ulvalue |= opt->ulvalue; 2227 break; 2228 2229 case OPTION_ORDER: 2230 *opt->opt.order = ++(*opt->order); 2231 break; 2232 2233 default: 2234 fprintf(stderr, "option %s - unknown type %i\n", 2235 opt->name, opt->type); 2236 return (1); 2237 } 2238 } 2239 2240 done: 2241 if (argsused != NULL) 2242 *argsused = i; 2243 2244 return (0); 2245 2246 toomany: 2247 fprintf(stderr, "too many arguments\n"); 2248 return (1); 2249 2250 unknown: 2251 fprintf(stderr, "unknown option '%s'\n", arg); 2252 return (1); 2253 } 2254 2255 void 2256 show_cipher(const OBJ_NAME *name, void *arg) 2257 { 2258 int *n = arg; 2259 2260 if (!islower((unsigned char)*name->name)) 2261 return; 2262 2263 fprintf(stderr, " -%-24s%s", name->name, (++*n % 3 != 0 ? "" : "\n")); 2264 } 2265 2266 int 2267 pkey_check(BIO *out, EVP_PKEY *pkey, int (check_fn)(EVP_PKEY_CTX *), 2268 const char *desc) 2269 { 2270 EVP_PKEY_CTX *ctx; 2271 2272 if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { 2273 ERR_print_errors(bio_err); 2274 return 0; 2275 } 2276 2277 if (check_fn(ctx) == 1) { 2278 BIO_printf(out, "%s valid\n", desc); 2279 } else { 2280 unsigned long err; 2281 2282 BIO_printf(out, "%s invalid\n", desc); 2283 2284 while ((err = ERR_get_error()) != 0) 2285 BIO_printf(out, "Detailed error: %s\n", 2286 ERR_reason_error_string(err)); 2287 } 2288 2289 EVP_PKEY_CTX_free(ctx); 2290 2291 return 1; 2292 } 2293