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