1 /* apps/apps.c */ 2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 (at) 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 (at) cryptsoft.com). This product includes software written by Tim 108 * Hudson (tjh (at) 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 <assert.h> 119 #include <openssl/err.h> 120 #include <openssl/x509.h> 121 #include <openssl/x509v3.h> 122 #include <openssl/pem.h> 123 #include <openssl/pkcs12.h> 124 #include <openssl/ui.h> 125 #include <openssl/safestack.h> 126 #ifndef OPENSSL_NO_ENGINE 127 #include <openssl/engine.h> 128 #endif 129 #ifndef OPENSSL_NO_RSA 130 #include <openssl/rsa.h> 131 #endif 132 #include <openssl/bn.h> 133 #ifndef OPENSSL_NO_JPAKE 134 #include <openssl/jpake.h> 135 #endif 136 137 #define NON_MAIN 138 #include "apps.h" 139 #undef NON_MAIN 140 141 typedef struct { 142 const char *name; 143 unsigned long flag; 144 unsigned long mask; 145 } NAME_EX_TBL; 146 147 static UI_METHOD *ui_method = NULL; 148 149 static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); 150 static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); 151 152 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 153 /* Looks like this stuff is worth moving into separate function */ 154 static EVP_PKEY * 155 load_netscape_key(BIO *err, BIO *key, const char *file, 156 const char *key_descrip, int format); 157 #endif 158 159 int app_init(long mesgwin); 160 #ifdef undef /* never finished - probably never will be :-) */ 161 int args_from_file(char *file, int *argc, char **argv[]) 162 { 163 FILE *fp; 164 int num,i; 165 unsigned int len; 166 static char *buf=NULL; 167 static char **arg=NULL; 168 char *p; 169 struct stat stbuf; 170 171 if (stat(file,&stbuf) < 0) return(0); 172 173 fp=fopen(file,"r"); 174 if (fp == NULL) 175 return(0); 176 177 *argc=0; 178 *argv=NULL; 179 180 len=(unsigned int)stbuf.st_size; 181 if (buf != NULL) OPENSSL_free(buf); 182 buf=(char *)OPENSSL_malloc(len+1); 183 if (buf == NULL) return(0); 184 185 len=fread(buf,1,len,fp); 186 if (len <= 1) return(0); 187 buf[len]='\0'; 188 189 i=0; 190 for (p=buf; *p; p++) 191 if (*p == '\n') i++; 192 if (arg != NULL) OPENSSL_free(arg); 193 arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2)); 194 195 *argv=arg; 196 num=0; 197 p=buf; 198 for (;;) 199 { 200 if (!*p) break; 201 if (*p == '#') /* comment line */ 202 { 203 while (*p && (*p != '\n')) p++; 204 continue; 205 } 206 /* else we have a line */ 207 *(arg++)=p; 208 num++; 209 while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n'))) 210 p++; 211 if (!*p) break; 212 if (*p == '\n') 213 { 214 *(p++)='\0'; 215 continue; 216 } 217 /* else it is a tab or space */ 218 p++; 219 while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) 220 p++; 221 if (!*p) break; 222 if (*p == '\n') 223 { 224 p++; 225 continue; 226 } 227 *(arg++)=p++; 228 num++; 229 while (*p && (*p != '\n')) p++; 230 if (!*p) break; 231 /* else *p == '\n' */ 232 *(p++)='\0'; 233 } 234 *argc=num; 235 return(1); 236 } 237 #endif 238 239 int str2fmt(char *s) 240 { 241 if ((*s == 'D') || (*s == 'd')) 242 return(FORMAT_ASN1); 243 else if ((*s == 'T') || (*s == 't')) 244 return(FORMAT_TEXT); 245 else if ((*s == 'P') || (*s == 'p')) 246 return(FORMAT_PEM); 247 else if ((*s == 'N') || (*s == 'n')) 248 return(FORMAT_NETSCAPE); 249 else if ((*s == 'S') || (*s == 's')) 250 return(FORMAT_SMIME); 251 else if ((*s == '1') 252 || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0) 253 || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0)) 254 return(FORMAT_PKCS12); 255 else if ((*s == 'E') || (*s == 'e')) 256 return(FORMAT_ENGINE); 257 else 258 return(FORMAT_UNDEF); 259 } 260 261 #if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE) 262 void program_name(char *in, char *out, int size) 263 { 264 int i,n; 265 char *p=NULL; 266 267 n=strlen(in); 268 /* find the last '/', '\' or ':' */ 269 for (i=n-1; i>0; i--) 270 { 271 if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':')) 272 { 273 p= &(in[i+1]); 274 break; 275 } 276 } 277 if (p == NULL) 278 p=in; 279 n=strlen(p); 280 281 #if defined(OPENSSL_SYS_NETWARE) 282 /* strip off trailing .nlm if present. */ 283 if ((n > 4) && (p[n-4] == '.') && 284 ((p[n-3] == 'n') || (p[n-3] == 'N')) && 285 ((p[n-2] == 'l') || (p[n-2] == 'L')) && 286 ((p[n-1] == 'm') || (p[n-1] == 'M'))) 287 n-=4; 288 #else 289 /* strip off trailing .exe if present. */ 290 if ((n > 4) && (p[n-4] == '.') && 291 ((p[n-3] == 'e') || (p[n-3] == 'E')) && 292 ((p[n-2] == 'x') || (p[n-2] == 'X')) && 293 ((p[n-1] == 'e') || (p[n-1] == 'E'))) 294 n-=4; 295 #endif 296 297 if (n > size-1) 298 n=size-1; 299 300 for (i=0; i<n; i++) 301 { 302 if ((p[i] >= 'A') && (p[i] <= 'Z')) 303 out[i]=p[i]-'A'+'a'; 304 else 305 out[i]=p[i]; 306 } 307 out[n]='\0'; 308 } 309 #else 310 #ifdef OPENSSL_SYS_VMS 311 void program_name(char *in, char *out, int size) 312 { 313 char *p=in, *q; 314 char *chars=":]>"; 315 316 while(*chars != '\0') 317 { 318 q=strrchr(p,*chars); 319 if (q > p) 320 p = q + 1; 321 chars++; 322 } 323 324 q=strrchr(p,'.'); 325 if (q == NULL) 326 q = p + strlen(p); 327 strncpy(out,p,size-1); 328 if (q-p >= size) 329 { 330 out[size-1]='\0'; 331 } 332 else 333 { 334 out[q-p]='\0'; 335 } 336 } 337 #else 338 void program_name(char *in, char *out, int size) 339 { 340 char *p; 341 342 p=strrchr(in,'/'); 343 if (p != NULL) 344 p++; 345 else 346 p=in; 347 BUF_strlcpy(out,p,size); 348 } 349 #endif 350 #endif 351 352 int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]) 353 { 354 int num,len,i; 355 char *p; 356 357 *argc=0; 358 *argv=NULL; 359 360 len=strlen(buf); 361 i=0; 362 if (arg->count == 0) 363 { 364 arg->count=20; 365 arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count); 366 } 367 for (i=0; i<arg->count; i++) 368 arg->data[i]=NULL; 369 370 num=0; 371 p=buf; 372 for (;;) 373 { 374 /* first scan over white space */ 375 if (!*p) break; 376 while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) 377 p++; 378 if (!*p) break; 379 380 /* The start of something good :-) */ 381 if (num >= arg->count) 382 { 383 char **tmp_p; 384 int tlen = arg->count + 20; 385 tmp_p = (char **)OPENSSL_realloc(arg->data, 386 sizeof(char *)*tlen); 387 if (tmp_p == NULL) 388 return 0; 389 arg->data = tmp_p; 390 arg->count = tlen; 391 /* initialize newly allocated data */ 392 for (i = num; i < arg->count; i++) 393 arg->data[i] = NULL; 394 } 395 arg->data[num++]=p; 396 397 /* now look for the end of this */ 398 if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */ 399 { 400 i= *(p++); 401 arg->data[num-1]++; /* jump over quote */ 402 while (*p && (*p != i)) 403 p++; 404 *p='\0'; 405 } 406 else 407 { 408 while (*p && ((*p != ' ') && 409 (*p != '\t') && (*p != '\n'))) 410 p++; 411 412 if (*p == '\0') 413 p--; 414 else 415 *p='\0'; 416 } 417 p++; 418 } 419 *argc=num; 420 *argv=arg->data; 421 return(1); 422 } 423 424 #ifndef APP_INIT 425 int app_init(long mesgwin) 426 { 427 return(1); 428 } 429 #endif 430 431 432 int dump_cert_text (BIO *out, X509 *x) 433 { 434 char *p; 435 436 p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0); 437 BIO_puts(out,"subject="); 438 BIO_puts(out,p); 439 OPENSSL_free(p); 440 441 p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0); 442 BIO_puts(out,"\nissuer="); 443 BIO_puts(out,p); 444 BIO_puts(out,"\n"); 445 OPENSSL_free(p); 446 447 return 0; 448 } 449 450 static int ui_open(UI *ui) 451 { 452 return UI_method_get_opener(UI_OpenSSL())(ui); 453 } 454 static int ui_read(UI *ui, UI_STRING *uis) 455 { 456 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD 457 && UI_get0_user_data(ui)) 458 { 459 switch(UI_get_string_type(uis)) 460 { 461 case UIT_PROMPT: 462 case UIT_VERIFY: 463 { 464 const char *password = 465 ((PW_CB_DATA *)UI_get0_user_data(ui))->password; 466 if (password && password[0] != '\0') 467 { 468 UI_set_result(ui, uis, password); 469 return 1; 470 } 471 } 472 default: 473 break; 474 } 475 } 476 return UI_method_get_reader(UI_OpenSSL())(ui, uis); 477 } 478 static int ui_write(UI *ui, UI_STRING *uis) 479 { 480 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD 481 && UI_get0_user_data(ui)) 482 { 483 switch(UI_get_string_type(uis)) 484 { 485 case UIT_PROMPT: 486 case UIT_VERIFY: 487 { 488 const char *password = 489 ((PW_CB_DATA *)UI_get0_user_data(ui))->password; 490 if (password && password[0] != '\0') 491 return 1; 492 } 493 default: 494 break; 495 } 496 } 497 return UI_method_get_writer(UI_OpenSSL())(ui, uis); 498 } 499 static int ui_close(UI *ui) 500 { 501 return UI_method_get_closer(UI_OpenSSL())(ui); 502 } 503 int setup_ui_method(void) 504 { 505 ui_method = UI_create_method("OpenSSL application user interface"); 506 UI_method_set_opener(ui_method, ui_open); 507 UI_method_set_reader(ui_method, ui_read); 508 UI_method_set_writer(ui_method, ui_write); 509 UI_method_set_closer(ui_method, ui_close); 510 return 0; 511 } 512 void destroy_ui_method(void) 513 { 514 if(ui_method) 515 { 516 UI_destroy_method(ui_method); 517 ui_method = NULL; 518 } 519 } 520 int password_callback(char *buf, int bufsiz, int verify, 521 PW_CB_DATA *cb_tmp) 522 { 523 UI *ui = NULL; 524 int res = 0; 525 const char *prompt_info = NULL; 526 const char *password = NULL; 527 PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp; 528 529 if (cb_data) 530 { 531 if (cb_data->password) 532 password = cb_data->password; 533 if (cb_data->prompt_info) 534 prompt_info = cb_data->prompt_info; 535 } 536 537 if (password) 538 { 539 res = strlen(password); 540 if (res > bufsiz) 541 res = bufsiz; 542 memcpy(buf, password, res); 543 return res; 544 } 545 546 ui = UI_new_method(ui_method); 547 if (ui) 548 { 549 int ok = 0; 550 char *buff = NULL; 551 int ui_flags = 0; 552 char *prompt = NULL; 553 554 prompt = UI_construct_prompt(ui, "pass phrase", 555 prompt_info); 556 557 ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; 558 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); 559 560 if (ok >= 0) 561 ok = UI_add_input_string(ui,prompt,ui_flags,buf, 562 PW_MIN_LENGTH,BUFSIZ-1); 563 if (ok >= 0 && verify) 564 { 565 buff = (char *)OPENSSL_malloc(bufsiz); 566 ok = UI_add_verify_string(ui,prompt,ui_flags,buff, 567 PW_MIN_LENGTH,BUFSIZ-1, buf); 568 } 569 if (ok >= 0) 570 do 571 { 572 ok = UI_process(ui); 573 } 574 while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); 575 576 if (buff) 577 { 578 OPENSSL_cleanse(buff,(unsigned int)bufsiz); 579 OPENSSL_free(buff); 580 } 581 582 if (ok >= 0) 583 res = strlen(buf); 584 if (ok == -1) 585 { 586 BIO_printf(bio_err, "User interface error\n"); 587 ERR_print_errors(bio_err); 588 OPENSSL_cleanse(buf,(unsigned int)bufsiz); 589 res = 0; 590 } 591 if (ok == -2) 592 { 593 BIO_printf(bio_err,"aborted!\n"); 594 OPENSSL_cleanse(buf,(unsigned int)bufsiz); 595 res = 0; 596 } 597 UI_free(ui); 598 OPENSSL_free(prompt); 599 } 600 return res; 601 } 602 603 static char *app_get_pass(BIO *err, char *arg, int keepbio); 604 605 int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) 606 { 607 int same; 608 if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0; 609 else same = 1; 610 if(arg1) { 611 *pass1 = app_get_pass(err, arg1, same); 612 if(!*pass1) return 0; 613 } else if(pass1) *pass1 = NULL; 614 if(arg2) { 615 *pass2 = app_get_pass(err, arg2, same ? 2 : 0); 616 if(!*pass2) return 0; 617 } else if(pass2) *pass2 = NULL; 618 return 1; 619 } 620 621 static char *app_get_pass(BIO *err, char *arg, int keepbio) 622 { 623 char *tmp, tpass[APP_PASS_LEN]; 624 static BIO *pwdbio = NULL; 625 int i; 626 if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5); 627 if(!strncmp(arg, "env:", 4)) { 628 tmp = getenv(arg + 4); 629 if(!tmp) { 630 BIO_printf(err, "Can't read environment variable %s\n", arg + 4); 631 return NULL; 632 } 633 return BUF_strdup(tmp); 634 } 635 if(!keepbio || !pwdbio) { 636 if(!strncmp(arg, "file:", 5)) { 637 pwdbio = BIO_new_file(arg + 5, "r"); 638 if(!pwdbio) { 639 BIO_printf(err, "Can't open file %s\n", arg + 5); 640 return NULL; 641 } 642 } else if(!strncmp(arg, "fd:", 3)) { 643 BIO *btmp; 644 i = atoi(arg + 3); 645 if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE); 646 if((i < 0) || !pwdbio) { 647 BIO_printf(err, "Can't access file descriptor %s\n", arg + 3); 648 return NULL; 649 } 650 /* Can't do BIO_gets on an fd BIO so add a buffering BIO */ 651 btmp = BIO_new(BIO_f_buffer()); 652 pwdbio = BIO_push(btmp, pwdbio); 653 } else if(!strcmp(arg, "stdin")) { 654 pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE); 655 if(!pwdbio) { 656 BIO_printf(err, "Can't open BIO for stdin\n"); 657 return NULL; 658 } 659 } else { 660 BIO_printf(err, "Invalid password argument \"%s\"\n", arg); 661 return NULL; 662 } 663 } 664 i = BIO_gets(pwdbio, tpass, APP_PASS_LEN); 665 if(keepbio != 1) { 666 BIO_free_all(pwdbio); 667 pwdbio = NULL; 668 } 669 if(i <= 0) { 670 BIO_printf(err, "Error reading password from BIO\n"); 671 return NULL; 672 } 673 tmp = strchr(tpass, '\n'); 674 if(tmp) *tmp = 0; 675 return BUF_strdup(tpass); 676 } 677 678 int add_oid_section(BIO *err, CONF *conf) 679 { 680 char *p; 681 STACK_OF(CONF_VALUE) *sktmp; 682 CONF_VALUE *cnf; 683 int i; 684 if(!(p=NCONF_get_string(conf,NULL,"oid_section"))) 685 { 686 ERR_clear_error(); 687 return 1; 688 } 689 if(!(sktmp = NCONF_get_section(conf, p))) { 690 BIO_printf(err, "problem loading oid section %s\n", p); 691 return 0; 692 } 693 for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { 694 cnf = sk_CONF_VALUE_value(sktmp, i); 695 if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) { 696 BIO_printf(err, "problem creating object %s=%s\n", 697 cnf->name, cnf->value); 698 return 0; 699 } 700 } 701 return 1; 702 } 703 704 static int load_pkcs12(BIO *err, BIO *in, const char *desc, 705 pem_password_cb *pem_cb, void *cb_data, 706 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) 707 { 708 const char *pass; 709 char tpass[PEM_BUFSIZE]; 710 int len, ret = 0; 711 PKCS12 *p12; 712 p12 = d2i_PKCS12_bio(in, NULL); 713 if (p12 == NULL) 714 { 715 BIO_printf(err, "Error loading PKCS12 file for %s\n", desc); 716 goto die; 717 } 718 /* See if an empty password will do */ 719 if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) 720 pass = ""; 721 else 722 { 723 if (!pem_cb) 724 pem_cb = (pem_password_cb *)password_callback; 725 len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); 726 if (len < 0) 727 { 728 BIO_printf(err, "Passpharse callback error for %s\n", 729 desc); 730 goto die; 731 } 732 if (len < PEM_BUFSIZE) 733 tpass[len] = 0; 734 if (!PKCS12_verify_mac(p12, tpass, len)) 735 { 736 BIO_printf(err, 737 "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc); 738 goto die; 739 } 740 pass = tpass; 741 } 742 ret = PKCS12_parse(p12, pass, pkey, cert, ca); 743 die: 744 if (p12) 745 PKCS12_free(p12); 746 return ret; 747 } 748 749 X509 *load_cert(BIO *err, const char *file, int format, 750 const char *pass, ENGINE *e, const char *cert_descrip) 751 { 752 ASN1_HEADER *ah=NULL; 753 BUF_MEM *buf=NULL; 754 X509 *x=NULL; 755 BIO *cert; 756 757 if ((cert=BIO_new(BIO_s_file())) == NULL) 758 { 759 ERR_print_errors(err); 760 goto end; 761 } 762 763 if (file == NULL) 764 { 765 setvbuf(stdin, NULL, _IONBF, 0); 766 BIO_set_fp(cert,stdin,BIO_NOCLOSE); 767 } 768 else 769 { 770 if (BIO_read_filename(cert,file) <= 0) 771 { 772 BIO_printf(err, "Error opening %s %s\n", 773 cert_descrip, file); 774 ERR_print_errors(err); 775 goto end; 776 } 777 } 778 779 if (format == FORMAT_ASN1) 780 x=d2i_X509_bio(cert,NULL); 781 else if (format == FORMAT_NETSCAPE) 782 { 783 const unsigned char *p,*op; 784 int size=0,i; 785 786 /* We sort of have to do it this way because it is sort of nice 787 * to read the header first and check it, then 788 * try to read the certificate */ 789 buf=BUF_MEM_new(); 790 for (;;) 791 { 792 if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10))) 793 goto end; 794 i=BIO_read(cert,&(buf->data[size]),1024*10); 795 size+=i; 796 if (i == 0) break; 797 if (i < 0) 798 { 799 perror("reading certificate"); 800 goto end; 801 } 802 } 803 p=(unsigned char *)buf->data; 804 op=p; 805 806 /* First load the header */ 807 if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL) 808 goto end; 809 if ((ah->header == NULL) || (ah->header->data == NULL) || 810 (strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data, 811 ah->header->length) != 0)) 812 { 813 BIO_printf(err,"Error reading header on certificate\n"); 814 goto end; 815 } 816 /* header is ok, so now read the object */ 817 p=op; 818 ah->meth=X509_asn1_meth(); 819 if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL) 820 goto end; 821 x=(X509 *)ah->data; 822 ah->data=NULL; 823 } 824 else if (format == FORMAT_PEM) 825 x=PEM_read_bio_X509_AUX(cert,NULL, 826 (pem_password_cb *)password_callback, NULL); 827 else if (format == FORMAT_PKCS12) 828 { 829 if (!load_pkcs12(err, cert,cert_descrip, NULL, NULL, 830 NULL, &x, NULL)) 831 goto end; 832 } 833 else { 834 BIO_printf(err,"bad input format specified for %s\n", 835 cert_descrip); 836 goto end; 837 } 838 end: 839 if (x == NULL) 840 { 841 BIO_printf(err,"unable to load certificate\n"); 842 ERR_print_errors(err); 843 } 844 if (ah != NULL) ASN1_HEADER_free(ah); 845 if (cert != NULL) BIO_free(cert); 846 if (buf != NULL) BUF_MEM_free(buf); 847 return(x); 848 } 849 850 EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, 851 const char *pass, ENGINE *e, const char *key_descrip) 852 { 853 BIO *key=NULL; 854 EVP_PKEY *pkey=NULL; 855 PW_CB_DATA cb_data; 856 857 cb_data.password = pass; 858 cb_data.prompt_info = file; 859 860 if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) 861 { 862 BIO_printf(err,"no keyfile specified\n"); 863 goto end; 864 } 865 #ifndef OPENSSL_NO_ENGINE 866 if (format == FORMAT_ENGINE) 867 { 868 if (!e) 869 BIO_printf(bio_err,"no engine specified\n"); 870 else 871 pkey = ENGINE_load_private_key(e, file, 872 ui_method, &cb_data); 873 goto end; 874 } 875 #endif 876 key=BIO_new(BIO_s_file()); 877 if (key == NULL) 878 { 879 ERR_print_errors(err); 880 goto end; 881 } 882 if (file == NULL && maybe_stdin) 883 { 884 setvbuf(stdin, NULL, _IONBF, 0); 885 BIO_set_fp(key,stdin,BIO_NOCLOSE); 886 } 887 else 888 if (BIO_read_filename(key,file) <= 0) 889 { 890 BIO_printf(err, "Error opening %s %s\n", 891 key_descrip, file); 892 ERR_print_errors(err); 893 goto end; 894 } 895 if (format == FORMAT_ASN1) 896 { 897 pkey=d2i_PrivateKey_bio(key, NULL); 898 } 899 else if (format == FORMAT_PEM) 900 { 901 pkey=PEM_read_bio_PrivateKey(key,NULL, 902 (pem_password_cb *)password_callback, &cb_data); 903 } 904 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 905 else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) 906 pkey = load_netscape_key(err, key, file, key_descrip, format); 907 #endif 908 else if (format == FORMAT_PKCS12) 909 { 910 if (!load_pkcs12(err, key, key_descrip, 911 (pem_password_cb *)password_callback, &cb_data, 912 &pkey, NULL, NULL)) 913 goto end; 914 } 915 else 916 { 917 BIO_printf(err,"bad input format specified for key file\n"); 918 goto end; 919 } 920 end: 921 if (key != NULL) BIO_free(key); 922 if (pkey == NULL) 923 BIO_printf(err,"unable to load %s\n", key_descrip); 924 return(pkey); 925 } 926 927 EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, 928 const char *pass, ENGINE *e, const char *key_descrip) 929 { 930 BIO *key=NULL; 931 EVP_PKEY *pkey=NULL; 932 PW_CB_DATA cb_data; 933 934 cb_data.password = pass; 935 cb_data.prompt_info = file; 936 937 if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) 938 { 939 BIO_printf(err,"no keyfile specified\n"); 940 goto end; 941 } 942 #ifndef OPENSSL_NO_ENGINE 943 if (format == FORMAT_ENGINE) 944 { 945 if (!e) 946 BIO_printf(bio_err,"no engine specified\n"); 947 else 948 pkey = ENGINE_load_public_key(e, file, 949 ui_method, &cb_data); 950 goto end; 951 } 952 #endif 953 key=BIO_new(BIO_s_file()); 954 if (key == NULL) 955 { 956 ERR_print_errors(err); 957 goto end; 958 } 959 if (file == NULL && maybe_stdin) 960 { 961 setvbuf(stdin, NULL, _IONBF, 0); 962 BIO_set_fp(key,stdin,BIO_NOCLOSE); 963 } 964 else 965 if (BIO_read_filename(key,file) <= 0) 966 { 967 BIO_printf(err, "Error opening %s %s\n", 968 key_descrip, file); 969 ERR_print_errors(err); 970 goto end; 971 } 972 if (format == FORMAT_ASN1) 973 { 974 pkey=d2i_PUBKEY_bio(key, NULL); 975 } 976 else if (format == FORMAT_PEM) 977 { 978 pkey=PEM_read_bio_PUBKEY(key,NULL, 979 (pem_password_cb *)password_callback, &cb_data); 980 } 981 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 982 else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) 983 pkey = load_netscape_key(err, key, file, key_descrip, format); 984 #endif 985 else 986 { 987 BIO_printf(err,"bad input format specified for key file\n"); 988 goto end; 989 } 990 end: 991 if (key != NULL) BIO_free(key); 992 if (pkey == NULL) 993 BIO_printf(err,"unable to load %s\n", key_descrip); 994 return(pkey); 995 } 996 997 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) 998 static EVP_PKEY * 999 load_netscape_key(BIO *err, BIO *key, const char *file, 1000 const char *key_descrip, int format) 1001 { 1002 EVP_PKEY *pkey; 1003 BUF_MEM *buf; 1004 RSA *rsa; 1005 const unsigned char *p; 1006 int size, i; 1007 1008 buf=BUF_MEM_new(); 1009 pkey = EVP_PKEY_new(); 1010 size = 0; 1011 if (buf == NULL || pkey == NULL) 1012 goto error; 1013 for (;;) 1014 { 1015 if (!BUF_MEM_grow_clean(buf,size+1024*10)) 1016 goto error; 1017 i = BIO_read(key, &(buf->data[size]), 1024*10); 1018 size += i; 1019 if (i == 0) 1020 break; 1021 if (i < 0) 1022 { 1023 BIO_printf(err, "Error reading %s %s", 1024 key_descrip, file); 1025 goto error; 1026 } 1027 } 1028 p=(unsigned char *)buf->data; 1029 rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL, 1030 (format == FORMAT_IISSGC ? 1 : 0)); 1031 if (rsa == NULL) 1032 goto error; 1033 BUF_MEM_free(buf); 1034 EVP_PKEY_set1_RSA(pkey, rsa); 1035 return pkey; 1036 error: 1037 BUF_MEM_free(buf); 1038 EVP_PKEY_free(pkey); 1039 return NULL; 1040 } 1041 #endif /* ndef OPENSSL_NO_RC4 */ 1042 1043 STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, 1044 const char *pass, ENGINE *e, const char *cert_descrip) 1045 { 1046 BIO *certs; 1047 int i; 1048 STACK_OF(X509) *othercerts = NULL; 1049 STACK_OF(X509_INFO) *allcerts = NULL; 1050 X509_INFO *xi; 1051 PW_CB_DATA cb_data; 1052 1053 cb_data.password = pass; 1054 cb_data.prompt_info = file; 1055 1056 if((certs = BIO_new(BIO_s_file())) == NULL) 1057 { 1058 ERR_print_errors(err); 1059 goto end; 1060 } 1061 1062 if (file == NULL) 1063 BIO_set_fp(certs,stdin,BIO_NOCLOSE); 1064 else 1065 { 1066 if (BIO_read_filename(certs,file) <= 0) 1067 { 1068 BIO_printf(err, "Error opening %s %s\n", 1069 cert_descrip, file); 1070 ERR_print_errors(err); 1071 goto end; 1072 } 1073 } 1074 1075 if (format == FORMAT_PEM) 1076 { 1077 othercerts = sk_X509_new_null(); 1078 if(!othercerts) 1079 { 1080 sk_X509_free(othercerts); 1081 othercerts = NULL; 1082 goto end; 1083 } 1084 allcerts = PEM_X509_INFO_read_bio(certs, NULL, 1085 (pem_password_cb *)password_callback, &cb_data); 1086 for(i = 0; i < sk_X509_INFO_num(allcerts); i++) 1087 { 1088 xi = sk_X509_INFO_value (allcerts, i); 1089 if (xi->x509) 1090 { 1091 sk_X509_push(othercerts, xi->x509); 1092 xi->x509 = NULL; 1093 } 1094 } 1095 goto end; 1096 } 1097 else { 1098 BIO_printf(err,"bad input format specified for %s\n", 1099 cert_descrip); 1100 goto end; 1101 } 1102 end: 1103 if (othercerts == NULL) 1104 { 1105 BIO_printf(err,"unable to load certificates\n"); 1106 ERR_print_errors(err); 1107 } 1108 if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free); 1109 if (certs != NULL) BIO_free(certs); 1110 return(othercerts); 1111 } 1112 1113 1114 #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) 1115 /* Return error for unknown extensions */ 1116 #define X509V3_EXT_DEFAULT 0 1117 /* Print error for unknown extensions */ 1118 #define X509V3_EXT_ERROR_UNKNOWN (1L << 16) 1119 /* ASN1 parse unknown extensions */ 1120 #define X509V3_EXT_PARSE_UNKNOWN (2L << 16) 1121 /* BIO_dump unknown extensions */ 1122 #define X509V3_EXT_DUMP_UNKNOWN (3L << 16) 1123 1124 #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \ 1125 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) 1126 1127 int set_cert_ex(unsigned long *flags, const char *arg) 1128 { 1129 static const NAME_EX_TBL cert_tbl[] = { 1130 { "compatible", X509_FLAG_COMPAT, 0xffffffffl}, 1131 { "ca_default", X509_FLAG_CA, 0xffffffffl}, 1132 { "no_header", X509_FLAG_NO_HEADER, 0}, 1133 { "no_version", X509_FLAG_NO_VERSION, 0}, 1134 { "no_serial", X509_FLAG_NO_SERIAL, 0}, 1135 { "no_signame", X509_FLAG_NO_SIGNAME, 0}, 1136 { "no_validity", X509_FLAG_NO_VALIDITY, 0}, 1137 { "no_subject", X509_FLAG_NO_SUBJECT, 0}, 1138 { "no_issuer", X509_FLAG_NO_ISSUER, 0}, 1139 { "no_pubkey", X509_FLAG_NO_PUBKEY, 0}, 1140 { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0}, 1141 { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0}, 1142 { "no_aux", X509_FLAG_NO_AUX, 0}, 1143 { "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0}, 1144 { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK}, 1145 { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1146 { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1147 { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, 1148 { NULL, 0, 0} 1149 }; 1150 return set_multi_opts(flags, arg, cert_tbl); 1151 } 1152 1153 int set_name_ex(unsigned long *flags, const char *arg) 1154 { 1155 static const NAME_EX_TBL ex_tbl[] = { 1156 { "esc_2253", ASN1_STRFLGS_ESC_2253, 0}, 1157 { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0}, 1158 { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0}, 1159 { "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0}, 1160 { "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0}, 1161 { "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0}, 1162 { "show_type", ASN1_STRFLGS_SHOW_TYPE, 0}, 1163 { "dump_all", ASN1_STRFLGS_DUMP_ALL, 0}, 1164 { "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0}, 1165 { "dump_der", ASN1_STRFLGS_DUMP_DER, 0}, 1166 { "compat", XN_FLAG_COMPAT, 0xffffffffL}, 1167 { "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK}, 1168 { "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK}, 1169 { "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK}, 1170 { "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK}, 1171 { "dn_rev", XN_FLAG_DN_REV, 0}, 1172 { "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK}, 1173 { "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK}, 1174 { "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK}, 1175 { "align", XN_FLAG_FN_ALIGN, 0}, 1176 { "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK}, 1177 { "space_eq", XN_FLAG_SPC_EQ, 0}, 1178 { "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0}, 1179 { "RFC2253", XN_FLAG_RFC2253, 0xffffffffL}, 1180 { "oneline", XN_FLAG_ONELINE, 0xffffffffL}, 1181 { "multiline", XN_FLAG_MULTILINE, 0xffffffffL}, 1182 { "ca_default", XN_FLAG_MULTILINE, 0xffffffffL}, 1183 { NULL, 0, 0} 1184 }; 1185 return set_multi_opts(flags, arg, ex_tbl); 1186 } 1187 1188 int set_ext_copy(int *copy_type, const char *arg) 1189 { 1190 if (!strcasecmp(arg, "none")) 1191 *copy_type = EXT_COPY_NONE; 1192 else if (!strcasecmp(arg, "copy")) 1193 *copy_type = EXT_COPY_ADD; 1194 else if (!strcasecmp(arg, "copyall")) 1195 *copy_type = EXT_COPY_ALL; 1196 else 1197 return 0; 1198 return 1; 1199 } 1200 1201 int copy_extensions(X509 *x, X509_REQ *req, int copy_type) 1202 { 1203 STACK_OF(X509_EXTENSION) *exts = NULL; 1204 X509_EXTENSION *ext, *tmpext; 1205 ASN1_OBJECT *obj; 1206 int i, idx, ret = 0; 1207 if (!x || !req || (copy_type == EXT_COPY_NONE)) 1208 return 1; 1209 exts = X509_REQ_get_extensions(req); 1210 1211 for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 1212 ext = sk_X509_EXTENSION_value(exts, i); 1213 obj = X509_EXTENSION_get_object(ext); 1214 idx = X509_get_ext_by_OBJ(x, obj, -1); 1215 /* Does extension exist? */ 1216 if (idx != -1) { 1217 /* If normal copy don't override existing extension */ 1218 if (copy_type == EXT_COPY_ADD) 1219 continue; 1220 /* Delete all extensions of same type */ 1221 do { 1222 tmpext = X509_get_ext(x, idx); 1223 X509_delete_ext(x, idx); 1224 X509_EXTENSION_free(tmpext); 1225 idx = X509_get_ext_by_OBJ(x, obj, -1); 1226 } while (idx != -1); 1227 } 1228 if (!X509_add_ext(x, ext, -1)) 1229 goto end; 1230 } 1231 1232 ret = 1; 1233 1234 end: 1235 1236 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); 1237 1238 return ret; 1239 } 1240 1241 1242 1243 1244 static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl) 1245 { 1246 STACK_OF(CONF_VALUE) *vals; 1247 CONF_VALUE *val; 1248 int i, ret = 1; 1249 if(!arg) return 0; 1250 vals = X509V3_parse_list(arg); 1251 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { 1252 val = sk_CONF_VALUE_value(vals, i); 1253 if (!set_table_opts(flags, val->name, in_tbl)) 1254 ret = 0; 1255 } 1256 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 1257 return ret; 1258 } 1259 1260 static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl) 1261 { 1262 char c; 1263 const NAME_EX_TBL *ptbl; 1264 c = arg[0]; 1265 1266 if(c == '-') { 1267 c = 0; 1268 arg++; 1269 } else if (c == '+') { 1270 c = 1; 1271 arg++; 1272 } else c = 1; 1273 1274 for(ptbl = in_tbl; ptbl->name; ptbl++) { 1275 if(!strcasecmp(arg, ptbl->name)) { 1276 *flags &= ~ptbl->mask; 1277 if(c) *flags |= ptbl->flag; 1278 else *flags &= ~ptbl->flag; 1279 return 1; 1280 } 1281 } 1282 return 0; 1283 } 1284 1285 void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags) 1286 { 1287 char *buf; 1288 char mline = 0; 1289 int indent = 0; 1290 1291 if(title) BIO_puts(out, title); 1292 if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { 1293 mline = 1; 1294 indent = 4; 1295 } 1296 if(lflags == XN_FLAG_COMPAT) { 1297 buf = X509_NAME_oneline(nm, 0, 0); 1298 BIO_puts(out, buf); 1299 BIO_puts(out, "\n"); 1300 OPENSSL_free(buf); 1301 } else { 1302 if(mline) BIO_puts(out, "\n"); 1303 X509_NAME_print_ex(out, nm, indent, lflags); 1304 BIO_puts(out, "\n"); 1305 } 1306 } 1307 1308 X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath) 1309 { 1310 X509_STORE *store; 1311 X509_LOOKUP *lookup; 1312 if(!(store = X509_STORE_new())) goto end; 1313 lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file()); 1314 if (lookup == NULL) goto end; 1315 if (CAfile) { 1316 if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) { 1317 BIO_printf(bp, "Error loading file %s\n", CAfile); 1318 goto end; 1319 } 1320 } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); 1321 1322 lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir()); 1323 if (lookup == NULL) goto end; 1324 if (CApath) { 1325 if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) { 1326 BIO_printf(bp, "Error loading directory %s\n", CApath); 1327 goto end; 1328 } 1329 } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); 1330 1331 ERR_clear_error(); 1332 return store; 1333 end: 1334 X509_STORE_free(store); 1335 return NULL; 1336 } 1337 1338 #ifndef OPENSSL_NO_ENGINE 1339 /* Try to load an engine in a shareable library */ 1340 static ENGINE *try_load_engine(BIO *err, const char *engine, int debug) 1341 { 1342 ENGINE *e = ENGINE_by_id("dynamic"); 1343 if (e) 1344 { 1345 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) 1346 || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) 1347 { 1348 ENGINE_free(e); 1349 e = NULL; 1350 } 1351 } 1352 return e; 1353 } 1354 1355 ENGINE *setup_engine(BIO *err, const char *engine, int debug) 1356 { 1357 ENGINE *e = NULL; 1358 1359 if (engine) 1360 { 1361 if(strcmp(engine, "auto") == 0) 1362 { 1363 BIO_printf(err,"enabling auto ENGINE support\n"); 1364 ENGINE_register_all_complete(); 1365 return NULL; 1366 } 1367 if((e = ENGINE_by_id(engine)) == NULL 1368 && (e = try_load_engine(err, engine, debug)) == NULL) 1369 { 1370 BIO_printf(err,"invalid engine \"%s\"\n", engine); 1371 ERR_print_errors(err); 1372 return NULL; 1373 } 1374 if (debug) 1375 { 1376 ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 1377 0, err, 0); 1378 } 1379 ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1); 1380 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) 1381 { 1382 BIO_printf(err,"can't use that engine\n"); 1383 ERR_print_errors(err); 1384 ENGINE_free(e); 1385 return NULL; 1386 } 1387 1388 BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e)); 1389 1390 /* Free our "structural" reference. */ 1391 ENGINE_free(e); 1392 } 1393 return e; 1394 } 1395 #endif 1396 1397 int load_config(BIO *err, CONF *cnf) 1398 { 1399 if (!cnf) 1400 cnf = config; 1401 if (!cnf) 1402 return 1; 1403 1404 OPENSSL_load_builtin_modules(); 1405 1406 if (CONF_modules_load(cnf, NULL, 0) <= 0) 1407 { 1408 BIO_printf(err, "Error configuring OpenSSL\n"); 1409 ERR_print_errors(err); 1410 return 0; 1411 } 1412 return 1; 1413 } 1414 1415 char *make_config_name() 1416 { 1417 const char *t=X509_get_default_cert_area(); 1418 size_t len; 1419 char *p; 1420 1421 len=strlen(t)+strlen(OPENSSL_CONF)+2; 1422 p=OPENSSL_malloc(len); 1423 BUF_strlcpy(p,t,len); 1424 #ifndef OPENSSL_SYS_VMS 1425 BUF_strlcat(p,"/",len); 1426 #endif 1427 BUF_strlcat(p,OPENSSL_CONF,len); 1428 1429 return p; 1430 } 1431 1432 static unsigned long index_serial_hash(const char **a) 1433 { 1434 const char *n; 1435 1436 n=a[DB_serial]; 1437 while (*n == '0') n++; 1438 return(lh_strhash(n)); 1439 } 1440 1441 static int index_serial_cmp(const char **a, const char **b) 1442 { 1443 const char *aa,*bb; 1444 1445 for (aa=a[DB_serial]; *aa == '0'; aa++); 1446 for (bb=b[DB_serial]; *bb == '0'; bb++); 1447 return(strcmp(aa,bb)); 1448 } 1449 1450 static int index_name_qual(char **a) 1451 { return(a[0][0] == 'V'); } 1452 1453 static unsigned long index_name_hash(const char **a) 1454 { return(lh_strhash(a[DB_name])); } 1455 1456 int index_name_cmp(const char **a, const char **b) 1457 { return(strcmp(a[DB_name], 1458 b[DB_name])); } 1459 1460 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **) 1461 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **) 1462 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **) 1463 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **) 1464 1465 #undef BSIZE 1466 #define BSIZE 256 1467 1468 BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai) 1469 { 1470 BIO *in=NULL; 1471 BIGNUM *ret=NULL; 1472 MS_STATIC char buf[1024]; 1473 ASN1_INTEGER *ai=NULL; 1474 1475 ai=ASN1_INTEGER_new(); 1476 if (ai == NULL) goto err; 1477 1478 if ((in=BIO_new(BIO_s_file())) == NULL) 1479 { 1480 ERR_print_errors(bio_err); 1481 goto err; 1482 } 1483 1484 if (BIO_read_filename(in,serialfile) <= 0) 1485 { 1486 if (!create) 1487 { 1488 perror(serialfile); 1489 goto err; 1490 } 1491 else 1492 { 1493 ret=BN_new(); 1494 if (ret == NULL || !rand_serial(ret, ai)) 1495 BIO_printf(bio_err, "Out of memory\n"); 1496 } 1497 } 1498 else 1499 { 1500 if (!a2i_ASN1_INTEGER(in,ai,buf,1024)) 1501 { 1502 BIO_printf(bio_err,"unable to load number from %s\n", 1503 serialfile); 1504 goto err; 1505 } 1506 ret=ASN1_INTEGER_to_BN(ai,NULL); 1507 if (ret == NULL) 1508 { 1509 BIO_printf(bio_err,"error converting number from bin to BIGNUM\n"); 1510 goto err; 1511 } 1512 } 1513 1514 if (ret && retai) 1515 { 1516 *retai = ai; 1517 ai = NULL; 1518 } 1519 err: 1520 if (in != NULL) BIO_free(in); 1521 if (ai != NULL) ASN1_INTEGER_free(ai); 1522 return(ret); 1523 } 1524 1525 int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai) 1526 { 1527 char buf[1][BSIZE]; 1528 BIO *out = NULL; 1529 int ret=0; 1530 ASN1_INTEGER *ai=NULL; 1531 int j; 1532 1533 if (suffix == NULL) 1534 j = strlen(serialfile); 1535 else 1536 j = strlen(serialfile) + strlen(suffix) + 1; 1537 if (j >= BSIZE) 1538 { 1539 BIO_printf(bio_err,"file name too long\n"); 1540 goto err; 1541 } 1542 1543 if (suffix == NULL) 1544 BUF_strlcpy(buf[0], serialfile, BSIZE); 1545 else 1546 { 1547 #ifndef OPENSSL_SYS_VMS 1548 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix); 1549 #else 1550 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix); 1551 #endif 1552 } 1553 #ifdef RL_DEBUG 1554 BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); 1555 #endif 1556 out=BIO_new(BIO_s_file()); 1557 if (out == NULL) 1558 { 1559 ERR_print_errors(bio_err); 1560 goto err; 1561 } 1562 if (BIO_write_filename(out,buf[0]) <= 0) 1563 { 1564 perror(serialfile); 1565 goto err; 1566 } 1567 1568 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL) 1569 { 1570 BIO_printf(bio_err,"error converting serial to ASN.1 format\n"); 1571 goto err; 1572 } 1573 i2a_ASN1_INTEGER(out,ai); 1574 BIO_puts(out,"\n"); 1575 ret=1; 1576 if (retai) 1577 { 1578 *retai = ai; 1579 ai = NULL; 1580 } 1581 err: 1582 if (out != NULL) BIO_free_all(out); 1583 if (ai != NULL) ASN1_INTEGER_free(ai); 1584 return(ret); 1585 } 1586 1587 int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) 1588 { 1589 char buf[5][BSIZE]; 1590 int i,j; 1591 struct stat sb; 1592 1593 i = strlen(serialfile) + strlen(old_suffix); 1594 j = strlen(serialfile) + strlen(new_suffix); 1595 if (i > j) j = i; 1596 if (j + 1 >= BSIZE) 1597 { 1598 BIO_printf(bio_err,"file name too long\n"); 1599 goto err; 1600 } 1601 1602 #ifndef OPENSSL_SYS_VMS 1603 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", 1604 serialfile, new_suffix); 1605 #else 1606 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", 1607 serialfile, new_suffix); 1608 #endif 1609 #ifndef OPENSSL_SYS_VMS 1610 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", 1611 serialfile, old_suffix); 1612 #else 1613 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", 1614 serialfile, old_suffix); 1615 #endif 1616 if (stat(serialfile,&sb) < 0) 1617 { 1618 if (errno != ENOENT 1619 #ifdef ENOTDIR 1620 && errno != ENOTDIR 1621 #endif 1622 ) 1623 goto err; 1624 } 1625 else 1626 { 1627 #ifdef RL_DEBUG 1628 BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1629 serialfile, buf[1]); 1630 #endif 1631 if (rename(serialfile,buf[1]) < 0) 1632 { 1633 BIO_printf(bio_err, 1634 "unable to rename %s to %s\n", 1635 serialfile, buf[1]); 1636 perror("reason"); 1637 goto err; 1638 } 1639 } 1640 #ifdef RL_DEBUG 1641 BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1642 buf[0],serialfile); 1643 #endif 1644 if (rename(buf[0],serialfile) < 0) 1645 { 1646 BIO_printf(bio_err, 1647 "unable to rename %s to %s\n", 1648 buf[0],serialfile); 1649 perror("reason"); 1650 rename(buf[1],serialfile); 1651 goto err; 1652 } 1653 return 1; 1654 err: 1655 return 0; 1656 } 1657 1658 int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) 1659 { 1660 BIGNUM *btmp; 1661 int ret = 0; 1662 if (b) 1663 btmp = b; 1664 else 1665 btmp = BN_new(); 1666 1667 if (!btmp) 1668 return 0; 1669 1670 if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) 1671 goto error; 1672 if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) 1673 goto error; 1674 1675 ret = 1; 1676 1677 error: 1678 1679 if (!b) 1680 BN_free(btmp); 1681 1682 return ret; 1683 } 1684 1685 CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) 1686 { 1687 CA_DB *retdb = NULL; 1688 TXT_DB *tmpdb = NULL; 1689 BIO *in = BIO_new(BIO_s_file()); 1690 CONF *dbattr_conf = NULL; 1691 char buf[1][BSIZE]; 1692 long errorline= -1; 1693 1694 if (in == NULL) 1695 { 1696 ERR_print_errors(bio_err); 1697 goto err; 1698 } 1699 if (BIO_read_filename(in,dbfile) <= 0) 1700 { 1701 perror(dbfile); 1702 BIO_printf(bio_err,"unable to open '%s'\n",dbfile); 1703 goto err; 1704 } 1705 if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL) 1706 { 1707 if (tmpdb != NULL) TXT_DB_free(tmpdb); 1708 goto err; 1709 } 1710 1711 #ifndef OPENSSL_SYS_VMS 1712 BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile); 1713 #else 1714 BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile); 1715 #endif 1716 dbattr_conf = NCONF_new(NULL); 1717 if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0) 1718 { 1719 if (errorline > 0) 1720 { 1721 BIO_printf(bio_err, 1722 "error on line %ld of db attribute file '%s'\n" 1723 ,errorline,buf[0]); 1724 goto err; 1725 } 1726 else 1727 { 1728 NCONF_free(dbattr_conf); 1729 dbattr_conf = NULL; 1730 } 1731 } 1732 1733 if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL) 1734 { 1735 fprintf(stderr, "Out of memory\n"); 1736 goto err; 1737 } 1738 1739 retdb->db = tmpdb; 1740 tmpdb = NULL; 1741 if (db_attr) 1742 retdb->attributes = *db_attr; 1743 else 1744 { 1745 retdb->attributes.unique_subject = 1; 1746 } 1747 1748 if (dbattr_conf) 1749 { 1750 char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject"); 1751 if (p) 1752 { 1753 #ifdef RL_DEBUG 1754 BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p); 1755 #endif 1756 retdb->attributes.unique_subject = parse_yesno(p,1); 1757 } 1758 } 1759 1760 err: 1761 if (dbattr_conf) NCONF_free(dbattr_conf); 1762 if (tmpdb) TXT_DB_free(tmpdb); 1763 if (in) BIO_free_all(in); 1764 return retdb; 1765 } 1766 1767 int index_index(CA_DB *db) 1768 { 1769 if (!TXT_DB_create_index(db->db, DB_serial, NULL, 1770 LHASH_HASH_FN(index_serial_hash), 1771 LHASH_COMP_FN(index_serial_cmp))) 1772 { 1773 BIO_printf(bio_err, 1774 "error creating serial number index:(%ld,%ld,%ld)\n", 1775 db->db->error,db->db->arg1,db->db->arg2); 1776 return 0; 1777 } 1778 1779 if (db->attributes.unique_subject 1780 && !TXT_DB_create_index(db->db, DB_name, index_name_qual, 1781 LHASH_HASH_FN(index_name_hash), 1782 LHASH_COMP_FN(index_name_cmp))) 1783 { 1784 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n", 1785 db->db->error,db->db->arg1,db->db->arg2); 1786 return 0; 1787 } 1788 return 1; 1789 } 1790 1791 int save_index(const char *dbfile, const char *suffix, CA_DB *db) 1792 { 1793 char buf[3][BSIZE]; 1794 BIO *out = BIO_new(BIO_s_file()); 1795 int j; 1796 1797 if (out == NULL) 1798 { 1799 ERR_print_errors(bio_err); 1800 goto err; 1801 } 1802 1803 j = strlen(dbfile) + strlen(suffix); 1804 if (j + 6 >= BSIZE) 1805 { 1806 BIO_printf(bio_err,"file name too long\n"); 1807 goto err; 1808 } 1809 1810 #ifndef OPENSSL_SYS_VMS 1811 j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile); 1812 #else 1813 j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile); 1814 #endif 1815 #ifndef OPENSSL_SYS_VMS 1816 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix); 1817 #else 1818 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix); 1819 #endif 1820 #ifndef OPENSSL_SYS_VMS 1821 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix); 1822 #else 1823 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix); 1824 #endif 1825 #ifdef RL_DEBUG 1826 BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); 1827 #endif 1828 if (BIO_write_filename(out,buf[0]) <= 0) 1829 { 1830 perror(dbfile); 1831 BIO_printf(bio_err,"unable to open '%s'\n", dbfile); 1832 goto err; 1833 } 1834 j=TXT_DB_write(out,db->db); 1835 if (j <= 0) goto err; 1836 1837 BIO_free(out); 1838 1839 out = BIO_new(BIO_s_file()); 1840 #ifdef RL_DEBUG 1841 BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]); 1842 #endif 1843 if (BIO_write_filename(out,buf[1]) <= 0) 1844 { 1845 perror(buf[2]); 1846 BIO_printf(bio_err,"unable to open '%s'\n", buf[2]); 1847 goto err; 1848 } 1849 BIO_printf(out,"unique_subject = %s\n", 1850 db->attributes.unique_subject ? "yes" : "no"); 1851 BIO_free(out); 1852 1853 return 1; 1854 err: 1855 return 0; 1856 } 1857 1858 int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix) 1859 { 1860 char buf[5][BSIZE]; 1861 int i,j; 1862 struct stat sb; 1863 1864 i = strlen(dbfile) + strlen(old_suffix); 1865 j = strlen(dbfile) + strlen(new_suffix); 1866 if (i > j) j = i; 1867 if (j + 6 >= BSIZE) 1868 { 1869 BIO_printf(bio_err,"file name too long\n"); 1870 goto err; 1871 } 1872 1873 #ifndef OPENSSL_SYS_VMS 1874 j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile); 1875 #else 1876 j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile); 1877 #endif 1878 #ifndef OPENSSL_SYS_VMS 1879 j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", 1880 dbfile, new_suffix); 1881 #else 1882 j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", 1883 dbfile, new_suffix); 1884 #endif 1885 #ifndef OPENSSL_SYS_VMS 1886 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", 1887 dbfile, new_suffix); 1888 #else 1889 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", 1890 dbfile, new_suffix); 1891 #endif 1892 #ifndef OPENSSL_SYS_VMS 1893 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", 1894 dbfile, old_suffix); 1895 #else 1896 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", 1897 dbfile, old_suffix); 1898 #endif 1899 #ifndef OPENSSL_SYS_VMS 1900 j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", 1901 dbfile, old_suffix); 1902 #else 1903 j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", 1904 dbfile, old_suffix); 1905 #endif 1906 if (stat(dbfile,&sb) < 0) 1907 { 1908 if (errno != ENOENT 1909 #ifdef ENOTDIR 1910 && errno != ENOTDIR 1911 #endif 1912 ) 1913 goto err; 1914 } 1915 else 1916 { 1917 #ifdef RL_DEBUG 1918 BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1919 dbfile, buf[1]); 1920 #endif 1921 if (rename(dbfile,buf[1]) < 0) 1922 { 1923 BIO_printf(bio_err, 1924 "unable to rename %s to %s\n", 1925 dbfile, buf[1]); 1926 perror("reason"); 1927 goto err; 1928 } 1929 } 1930 #ifdef RL_DEBUG 1931 BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1932 buf[0],dbfile); 1933 #endif 1934 if (rename(buf[0],dbfile) < 0) 1935 { 1936 BIO_printf(bio_err, 1937 "unable to rename %s to %s\n", 1938 buf[0],dbfile); 1939 perror("reason"); 1940 rename(buf[1],dbfile); 1941 goto err; 1942 } 1943 if (stat(buf[4],&sb) < 0) 1944 { 1945 if (errno != ENOENT 1946 #ifdef ENOTDIR 1947 && errno != ENOTDIR 1948 #endif 1949 ) 1950 goto err; 1951 } 1952 else 1953 { 1954 #ifdef RL_DEBUG 1955 BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1956 buf[4],buf[3]); 1957 #endif 1958 if (rename(buf[4],buf[3]) < 0) 1959 { 1960 BIO_printf(bio_err, 1961 "unable to rename %s to %s\n", 1962 buf[4], buf[3]); 1963 perror("reason"); 1964 rename(dbfile,buf[0]); 1965 rename(buf[1],dbfile); 1966 goto err; 1967 } 1968 } 1969 #ifdef RL_DEBUG 1970 BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", 1971 buf[2],buf[4]); 1972 #endif 1973 if (rename(buf[2],buf[4]) < 0) 1974 { 1975 BIO_printf(bio_err, 1976 "unable to rename %s to %s\n", 1977 buf[2],buf[4]); 1978 perror("reason"); 1979 rename(buf[3],buf[4]); 1980 rename(dbfile,buf[0]); 1981 rename(buf[1],dbfile); 1982 goto err; 1983 } 1984 return 1; 1985 err: 1986 return 0; 1987 } 1988 1989 void free_index(CA_DB *db) 1990 { 1991 if (db) 1992 { 1993 if (db->db) TXT_DB_free(db->db); 1994 OPENSSL_free(db); 1995 } 1996 } 1997 1998 int parse_yesno(const char *str, int def) 1999 { 2000 int ret = def; 2001 if (str) 2002 { 2003 switch (*str) 2004 { 2005 case 'f': /* false */ 2006 case 'F': /* FALSE */ 2007 case 'n': /* no */ 2008 case 'N': /* NO */ 2009 case '0': /* 0 */ 2010 ret = 0; 2011 break; 2012 case 't': /* true */ 2013 case 'T': /* TRUE */ 2014 case 'y': /* yes */ 2015 case 'Y': /* YES */ 2016 case '1': /* 1 */ 2017 ret = 1; 2018 break; 2019 default: 2020 ret = def; 2021 break; 2022 } 2023 } 2024 return ret; 2025 } 2026 2027 /* 2028 * subject is expected to be in the format /type0=value0/type1=value1/type2=... 2029 * where characters may be escaped by \ 2030 */ 2031 X509_NAME *parse_name(char *subject, long chtype, int multirdn) 2032 { 2033 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */ 2034 char *buf = OPENSSL_malloc(buflen); 2035 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */ 2036 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *)); 2037 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *)); 2038 int *mval = OPENSSL_malloc (max_ne * sizeof (int)); 2039 2040 char *sp = subject, *bp = buf; 2041 int i, ne_num = 0; 2042 2043 X509_NAME *n = NULL; 2044 int nid; 2045 2046 if (!buf || !ne_types || !ne_values) 2047 { 2048 BIO_printf(bio_err, "malloc error\n"); 2049 goto error; 2050 } 2051 2052 if (*subject != '/') 2053 { 2054 BIO_printf(bio_err, "Subject does not start with '/'.\n"); 2055 goto error; 2056 } 2057 sp++; /* skip leading / */ 2058 2059 /* no multivalued RDN by default */ 2060 mval[ne_num] = 0; 2061 2062 while (*sp) 2063 { 2064 /* collect type */ 2065 ne_types[ne_num] = bp; 2066 while (*sp) 2067 { 2068 if (*sp == '\\') /* is there anything to escape in the type...? */ 2069 { 2070 if (*++sp) 2071 *bp++ = *sp++; 2072 else 2073 { 2074 BIO_printf(bio_err, "escape character at end of string\n"); 2075 goto error; 2076 } 2077 } 2078 else if (*sp == '=') 2079 { 2080 sp++; 2081 *bp++ = '\0'; 2082 break; 2083 } 2084 else 2085 *bp++ = *sp++; 2086 } 2087 if (!*sp) 2088 { 2089 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num); 2090 goto error; 2091 } 2092 ne_values[ne_num] = bp; 2093 while (*sp) 2094 { 2095 if (*sp == '\\') 2096 { 2097 if (*++sp) 2098 *bp++ = *sp++; 2099 else 2100 { 2101 BIO_printf(bio_err, "escape character at end of string\n"); 2102 goto error; 2103 } 2104 } 2105 else if (*sp == '/') 2106 { 2107 sp++; 2108 /* no multivalued RDN by default */ 2109 mval[ne_num+1] = 0; 2110 break; 2111 } 2112 else if (*sp == '+' && multirdn) 2113 { 2114 /* a not escaped + signals a mutlivalued RDN */ 2115 sp++; 2116 mval[ne_num+1] = -1; 2117 break; 2118 } 2119 else 2120 *bp++ = *sp++; 2121 } 2122 *bp++ = '\0'; 2123 ne_num++; 2124 } 2125 2126 if (!(n = X509_NAME_new())) 2127 goto error; 2128 2129 for (i = 0; i < ne_num; i++) 2130 { 2131 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef) 2132 { 2133 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]); 2134 continue; 2135 } 2136 2137 if (!*ne_values[i]) 2138 { 2139 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]); 2140 continue; 2141 } 2142 2143 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i])) 2144 goto error; 2145 } 2146 2147 OPENSSL_free(ne_values); 2148 OPENSSL_free(ne_types); 2149 OPENSSL_free(buf); 2150 return n; 2151 2152 error: 2153 X509_NAME_free(n); 2154 if (ne_values) 2155 OPENSSL_free(ne_values); 2156 if (ne_types) 2157 OPENSSL_free(ne_types); 2158 if (buf) 2159 OPENSSL_free(buf); 2160 return NULL; 2161 } 2162 2163 /* This code MUST COME AFTER anything that uses rename() */ 2164 #ifdef OPENSSL_SYS_WIN32 2165 int WIN32_rename(const char *from, const char *to) 2166 { 2167 #ifndef OPENSSL_SYS_WINCE 2168 /* Windows rename gives an error if 'to' exists, so delete it 2169 * first and ignore file not found errror 2170 */ 2171 if((remove(to) != 0) && (errno != ENOENT)) 2172 return -1; 2173 #undef rename 2174 return rename(from, to); 2175 #else 2176 /* convert strings to UNICODE */ 2177 { 2178 BOOL result = FALSE; 2179 WCHAR* wfrom; 2180 WCHAR* wto; 2181 int i; 2182 wfrom = malloc((strlen(from)+1)*2); 2183 wto = malloc((strlen(to)+1)*2); 2184 if (wfrom != NULL && wto != NULL) 2185 { 2186 for (i=0; i<(int)strlen(from)+1; i++) 2187 wfrom[i] = (short)from[i]; 2188 for (i=0; i<(int)strlen(to)+1; i++) 2189 wto[i] = (short)to[i]; 2190 result = MoveFile(wfrom, wto); 2191 } 2192 if (wfrom != NULL) 2193 free(wfrom); 2194 if (wto != NULL) 2195 free(wto); 2196 return result; 2197 } 2198 #endif 2199 } 2200 #endif 2201 2202 int args_verify(char ***pargs, int *pargc, 2203 int *badarg, BIO *err, X509_VERIFY_PARAM **pm) 2204 { 2205 ASN1_OBJECT *otmp = NULL; 2206 unsigned long flags = 0; 2207 int i; 2208 int purpose = 0; 2209 char **oldargs = *pargs; 2210 char *arg = **pargs, *argn = (*pargs)[1]; 2211 if (!strcmp(arg, "-policy")) 2212 { 2213 if (!argn) 2214 *badarg = 1; 2215 else 2216 { 2217 otmp = OBJ_txt2obj(argn, 0); 2218 if (!otmp) 2219 { 2220 BIO_printf(err, "Invalid Policy \"%s\"\n", 2221 argn); 2222 *badarg = 1; 2223 } 2224 } 2225 (*pargs)++; 2226 } 2227 else if (strcmp(arg,"-purpose") == 0) 2228 { 2229 X509_PURPOSE *xptmp; 2230 if (!argn) 2231 *badarg = 1; 2232 else 2233 { 2234 i = X509_PURPOSE_get_by_sname(argn); 2235 if(i < 0) 2236 { 2237 BIO_printf(err, "unrecognized purpose\n"); 2238 *badarg = 1; 2239 } 2240 else 2241 { 2242 xptmp = X509_PURPOSE_get0(i); 2243 purpose = X509_PURPOSE_get_id(xptmp); 2244 } 2245 } 2246 (*pargs)++; 2247 } 2248 else if (!strcmp(arg, "-ignore_critical")) 2249 flags |= X509_V_FLAG_IGNORE_CRITICAL; 2250 else if (!strcmp(arg, "-issuer_checks")) 2251 flags |= X509_V_FLAG_CB_ISSUER_CHECK; 2252 else if (!strcmp(arg, "-crl_check")) 2253 flags |= X509_V_FLAG_CRL_CHECK; 2254 else if (!strcmp(arg, "-crl_check_all")) 2255 flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; 2256 else if (!strcmp(arg, "-policy_check")) 2257 flags |= X509_V_FLAG_POLICY_CHECK; 2258 else if (!strcmp(arg, "-explicit_policy")) 2259 flags |= X509_V_FLAG_EXPLICIT_POLICY; 2260 else if (!strcmp(arg, "-x509_strict")) 2261 flags |= X509_V_FLAG_X509_STRICT; 2262 else if (!strcmp(arg, "-policy_print")) 2263 flags |= X509_V_FLAG_NOTIFY_POLICY; 2264 else if (!strcmp(arg, "-check_ss_sig")) 2265 flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; 2266 else 2267 return 0; 2268 2269 if (*badarg) 2270 { 2271 if (*pm) 2272 X509_VERIFY_PARAM_free(*pm); 2273 *pm = NULL; 2274 goto end; 2275 } 2276 2277 if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) 2278 { 2279 *badarg = 1; 2280 goto end; 2281 } 2282 2283 if (otmp) 2284 X509_VERIFY_PARAM_add0_policy(*pm, otmp); 2285 if (flags) 2286 X509_VERIFY_PARAM_set_flags(*pm, flags); 2287 2288 if (purpose) 2289 X509_VERIFY_PARAM_set_purpose(*pm, purpose); 2290 2291 end: 2292 2293 (*pargs)++; 2294 2295 if (pargc) 2296 *pargc -= *pargs - oldargs; 2297 2298 return 1; 2299 2300 } 2301 2302 static void nodes_print(BIO *out, const char *name, 2303 STACK_OF(X509_POLICY_NODE) *nodes) 2304 { 2305 X509_POLICY_NODE *node; 2306 int i; 2307 BIO_printf(out, "%s Policies:", name); 2308 if (nodes) 2309 { 2310 BIO_puts(out, "\n"); 2311 for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) 2312 { 2313 node = sk_X509_POLICY_NODE_value(nodes, i); 2314 X509_POLICY_NODE_print(out, node, 2); 2315 } 2316 } 2317 else 2318 BIO_puts(out, " <empty>\n"); 2319 } 2320 2321 void policies_print(BIO *out, X509_STORE_CTX *ctx) 2322 { 2323 X509_POLICY_TREE *tree; 2324 int explicit_policy; 2325 int free_out = 0; 2326 if (out == NULL) 2327 { 2328 out = BIO_new_fp(stderr, BIO_NOCLOSE); 2329 free_out = 1; 2330 } 2331 tree = X509_STORE_CTX_get0_policy_tree(ctx); 2332 explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); 2333 2334 BIO_printf(out, "Require explicit Policy: %s\n", 2335 explicit_policy ? "True" : "False"); 2336 2337 nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree)); 2338 nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree)); 2339 if (free_out) 2340 BIO_free(out); 2341 } 2342 2343 #ifndef OPENSSL_NO_JPAKE 2344 2345 static JPAKE_CTX *jpake_init(const char *us, const char *them, 2346 const char *secret) 2347 { 2348 BIGNUM *p = NULL; 2349 BIGNUM *g = NULL; 2350 BIGNUM *q = NULL; 2351 BIGNUM *bnsecret = BN_new(); 2352 JPAKE_CTX *ctx; 2353 2354 /* Use a safe prime for p (that we found earlier) */ 2355 BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F"); 2356 g = BN_new(); 2357 BN_set_word(g, 2); 2358 q = BN_new(); 2359 BN_rshift1(q, p); 2360 2361 BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret); 2362 2363 ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret); 2364 BN_free(bnsecret); 2365 BN_free(q); 2366 BN_free(g); 2367 BN_free(p); 2368 2369 return ctx; 2370 } 2371 2372 static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p) 2373 { 2374 BN_print(conn, p->gx); 2375 BIO_puts(conn, "\n"); 2376 BN_print(conn, p->zkpx.gr); 2377 BIO_puts(conn, "\n"); 2378 BN_print(conn, p->zkpx.b); 2379 BIO_puts(conn, "\n"); 2380 } 2381 2382 static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx) 2383 { 2384 JPAKE_STEP1 s1; 2385 2386 JPAKE_STEP1_init(&s1); 2387 JPAKE_STEP1_generate(&s1, ctx); 2388 jpake_send_part(bconn, &s1.p1); 2389 jpake_send_part(bconn, &s1.p2); 2390 (void)BIO_flush(bconn); 2391 JPAKE_STEP1_release(&s1); 2392 } 2393 2394 static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx) 2395 { 2396 JPAKE_STEP2 s2; 2397 2398 JPAKE_STEP2_init(&s2); 2399 JPAKE_STEP2_generate(&s2, ctx); 2400 jpake_send_part(bconn, &s2); 2401 (void)BIO_flush(bconn); 2402 JPAKE_STEP2_release(&s2); 2403 } 2404 2405 static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx) 2406 { 2407 JPAKE_STEP3A s3a; 2408 2409 JPAKE_STEP3A_init(&s3a); 2410 JPAKE_STEP3A_generate(&s3a, ctx); 2411 BIO_write(bconn, s3a.hhk, sizeof s3a.hhk); 2412 (void)BIO_flush(bconn); 2413 JPAKE_STEP3A_release(&s3a); 2414 } 2415 2416 static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx) 2417 { 2418 JPAKE_STEP3B s3b; 2419 2420 JPAKE_STEP3B_init(&s3b); 2421 JPAKE_STEP3B_generate(&s3b, ctx); 2422 BIO_write(bconn, s3b.hk, sizeof s3b.hk); 2423 (void)BIO_flush(bconn); 2424 JPAKE_STEP3B_release(&s3b); 2425 } 2426 2427 static void readbn(BIGNUM **bn, BIO *bconn) 2428 { 2429 char buf[10240]; 2430 int l; 2431 2432 l = BIO_gets(bconn, buf, sizeof buf); 2433 assert(l > 0); 2434 assert(buf[l-1] == '\n'); 2435 buf[l-1] = '\0'; 2436 BN_hex2bn(bn, buf); 2437 } 2438 2439 static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn) 2440 { 2441 readbn(&p->gx, bconn); 2442 readbn(&p->zkpx.gr, bconn); 2443 readbn(&p->zkpx.b, bconn); 2444 } 2445 2446 static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn) 2447 { 2448 JPAKE_STEP1 s1; 2449 2450 JPAKE_STEP1_init(&s1); 2451 jpake_receive_part(&s1.p1, bconn); 2452 jpake_receive_part(&s1.p2, bconn); 2453 if(!JPAKE_STEP1_process(ctx, &s1)) 2454 { 2455 ERR_print_errors(bio_err); 2456 exit(1); 2457 } 2458 JPAKE_STEP1_release(&s1); 2459 } 2460 2461 static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn) 2462 { 2463 JPAKE_STEP2 s2; 2464 2465 JPAKE_STEP2_init(&s2); 2466 jpake_receive_part(&s2, bconn); 2467 if(!JPAKE_STEP2_process(ctx, &s2)) 2468 { 2469 ERR_print_errors(bio_err); 2470 exit(1); 2471 } 2472 JPAKE_STEP2_release(&s2); 2473 } 2474 2475 static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn) 2476 { 2477 JPAKE_STEP3A s3a; 2478 int l; 2479 2480 JPAKE_STEP3A_init(&s3a); 2481 l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk); 2482 assert(l == sizeof s3a.hhk); 2483 if(!JPAKE_STEP3A_process(ctx, &s3a)) 2484 { 2485 ERR_print_errors(bio_err); 2486 exit(1); 2487 } 2488 JPAKE_STEP3A_release(&s3a); 2489 } 2490 2491 static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn) 2492 { 2493 JPAKE_STEP3B s3b; 2494 int l; 2495 2496 JPAKE_STEP3B_init(&s3b); 2497 l = BIO_read(bconn, s3b.hk, sizeof s3b.hk); 2498 assert(l == sizeof s3b.hk); 2499 if(!JPAKE_STEP3B_process(ctx, &s3b)) 2500 { 2501 ERR_print_errors(bio_err); 2502 exit(1); 2503 } 2504 JPAKE_STEP3B_release(&s3b); 2505 } 2506 2507 void jpake_client_auth(BIO *out, BIO *conn, const char *secret) 2508 { 2509 JPAKE_CTX *ctx; 2510 BIO *bconn; 2511 2512 BIO_puts(out, "Authenticating with JPAKE\n"); 2513 2514 ctx = jpake_init("client", "server", secret); 2515 2516 bconn = BIO_new(BIO_f_buffer()); 2517 BIO_push(bconn, conn); 2518 2519 jpake_send_step1(bconn, ctx); 2520 jpake_receive_step1(ctx, bconn); 2521 jpake_send_step2(bconn, ctx); 2522 jpake_receive_step2(ctx, bconn); 2523 jpake_send_step3a(bconn, ctx); 2524 jpake_receive_step3b(ctx, bconn); 2525 2526 /* 2527 * The problem is that you must use the derived key in the 2528 * session key or you are subject to man-in-the-middle 2529 * attacks. 2530 */ 2531 BIO_puts(out, "JPAKE authentication succeeded (N.B. This version can" 2532 " be MitMed. See the version in HEAD for how to do it" 2533 " properly)\n"); 2534 2535 BIO_pop(bconn); 2536 BIO_free(bconn); 2537 } 2538 2539 void jpake_server_auth(BIO *out, BIO *conn, const char *secret) 2540 { 2541 JPAKE_CTX *ctx; 2542 BIO *bconn; 2543 2544 BIO_puts(out, "Authenticating with JPAKE\n"); 2545 2546 ctx = jpake_init("server", "client", secret); 2547 2548 bconn = BIO_new(BIO_f_buffer()); 2549 BIO_push(bconn, conn); 2550 2551 jpake_receive_step1(ctx, bconn); 2552 jpake_send_step1(bconn, ctx); 2553 jpake_receive_step2(ctx, bconn); 2554 jpake_send_step2(bconn, ctx); 2555 jpake_receive_step3a(ctx, bconn); 2556 jpake_send_step3b(bconn, ctx); 2557 2558 /* 2559 * The problem is that you must use the derived key in the 2560 * session key or you are subject to man-in-the-middle 2561 * attacks. 2562 */ 2563 BIO_puts(out, "JPAKE authentication succeeded (N.B. This version can" 2564 " be MitMed. See the version in HEAD for how to do it" 2565 " properly)\n"); 2566 2567 BIO_pop(bconn); 2568 BIO_free(bconn); 2569 } 2570 2571 #endif 2572