00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 #include <stdio.h>
00113 #include <stdlib.h>
00114 #include <string.h>
00115 #include <sys/types.h>
00116 #include <sys/stat.h>
00117 #include <ctype.h>
00118 #include <openssl/err.h>
00119 #include <openssl/x509.h>
00120 #include <openssl/x509v3.h>
00121 #include <openssl/pem.h>
00122 #include <openssl/pkcs12.h>
00123 #include <openssl/ui.h>
00124 #include <openssl/safestack.h>
00125 #ifndef OPENSSL_NO_ENGINE
00126 #include <openssl/engine.h>
00127 #endif
00128 #ifndef OPENSSL_NO_RSA
00129 #include <openssl/rsa.h>
00130 #endif
00131 #include <openssl/bn.h>
00132
00133 #define NON_MAIN
00134 #include "apps.h"
00135 #undef NON_MAIN
00136
00137 typedef struct {
00138 const char *name;
00139 unsigned long flag;
00140 unsigned long mask;
00141 } NAME_EX_TBL;
00142
00143 static UI_METHOD *ui_method = NULL;
00144
00145 static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
00146 static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
00147
00148 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
00149
00150 static EVP_PKEY *
00151 load_netscape_key(BIO *err, BIO *key, const char *file,
00152 const char *key_descrip, int format);
00153 #endif
00154
00155 int app_init(long mesgwin);
00156 #ifdef undef
00157 int args_from_file(char *file, int *argc, char **argv[])
00158 {
00159 FILE *fp;
00160 int num,i;
00161 unsigned int len;
00162 static char *buf=NULL;
00163 static char **arg=NULL;
00164 char *p;
00165 struct stat stbuf;
00166
00167 if (stat(file,&stbuf) < 0) return(0);
00168
00169 fp=fopen(file,"r");
00170 if (fp == NULL)
00171 return(0);
00172
00173 *argc=0;
00174 *argv=NULL;
00175
00176 len=(unsigned int)stbuf.st_size;
00177 if (buf != NULL) OPENSSL_free(buf);
00178 buf=(char *)OPENSSL_malloc(len+1);
00179 if (buf == NULL) return(0);
00180
00181 len=fread(buf,1,len,fp);
00182 if (len <= 1) return(0);
00183 buf[len]='\0';
00184
00185 i=0;
00186 for (p=buf; *p; p++)
00187 if (*p == '\n') i++;
00188 if (arg != NULL) OPENSSL_free(arg);
00189 arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2));
00190
00191 *argv=arg;
00192 num=0;
00193 p=buf;
00194 for (;;)
00195 {
00196 if (!*p) break;
00197 if (*p == '#')
00198 {
00199 while (*p && (*p != '\n')) p++;
00200 continue;
00201 }
00202
00203 *(arg++)=p;
00204 num++;
00205 while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
00206 p++;
00207 if (!*p) break;
00208 if (*p == '\n')
00209 {
00210 *(p++)='\0';
00211 continue;
00212 }
00213
00214 p++;
00215 while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
00216 p++;
00217 if (!*p) break;
00218 if (*p == '\n')
00219 {
00220 p++;
00221 continue;
00222 }
00223 *(arg++)=p++;
00224 num++;
00225 while (*p && (*p != '\n')) p++;
00226 if (!*p) break;
00227
00228 *(p++)='\0';
00229 }
00230 *argc=num;
00231 return(1);
00232 }
00233 #endif
00234
00235 int str2fmt(char *s)
00236 {
00237 if ((*s == 'D') || (*s == 'd'))
00238 return(FORMAT_ASN1);
00239 else if ((*s == 'T') || (*s == 't'))
00240 return(FORMAT_TEXT);
00241 else if ((*s == 'P') || (*s == 'p'))
00242 return(FORMAT_PEM);
00243 else if ((*s == 'N') || (*s == 'n'))
00244 return(FORMAT_NETSCAPE);
00245 else if ((*s == 'S') || (*s == 's'))
00246 return(FORMAT_SMIME);
00247 else if ((*s == '1')
00248 || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
00249 || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
00250 return(FORMAT_PKCS12);
00251 else if ((*s == 'E') || (*s == 'e'))
00252 return(FORMAT_ENGINE);
00253 else
00254 return(FORMAT_UNDEF);
00255 }
00256
00257 #if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
00258 void program_name(char *in, char *out, int size)
00259 {
00260 int i,n;
00261 char *p=NULL;
00262
00263 n=strlen(in);
00264
00265 for (i=n-1; i>0; i--)
00266 {
00267 if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':'))
00268 {
00269 p= &(in[i+1]);
00270 break;
00271 }
00272 }
00273 if (p == NULL)
00274 p=in;
00275 n=strlen(p);
00276
00277 #if defined(OPENSSL_SYS_NETWARE)
00278
00279 if ((n > 4) && (p[n-4] == '.') &&
00280 ((p[n-3] == 'n') || (p[n-3] == 'N')) &&
00281 ((p[n-2] == 'l') || (p[n-2] == 'L')) &&
00282 ((p[n-1] == 'm') || (p[n-1] == 'M')))
00283 n-=4;
00284 #else
00285
00286 if ((n > 4) && (p[n-4] == '.') &&
00287 ((p[n-3] == 'e') || (p[n-3] == 'E')) &&
00288 ((p[n-2] == 'x') || (p[n-2] == 'X')) &&
00289 ((p[n-1] == 'e') || (p[n-1] == 'E')))
00290 n-=4;
00291 #endif
00292
00293 if (n > size-1)
00294 n=size-1;
00295
00296 for (i=0; i<n; i++)
00297 {
00298 if ((p[i] >= 'A') && (p[i] <= 'Z'))
00299 out[i]=p[i]-'A'+'a';
00300 else
00301 out[i]=p[i];
00302 }
00303 out[n]='\0';
00304 }
00305 #else
00306 #ifdef OPENSSL_SYS_VMS
00307 void program_name(char *in, char *out, int size)
00308 {
00309 char *p=in, *q;
00310 char *chars=":]>";
00311
00312 while(*chars != '\0')
00313 {
00314 q=strrchr(p,*chars);
00315 if (q > p)
00316 p = q + 1;
00317 chars++;
00318 }
00319
00320 q=strrchr(p,'.');
00321 if (q == NULL)
00322 q = p + strlen(p);
00323 strncpy(out,p,size-1);
00324 if (q-p >= size)
00325 {
00326 out[size-1]='\0';
00327 }
00328 else
00329 {
00330 out[q-p]='\0';
00331 }
00332 }
00333 #else
00334 void program_name(char *in, char *out, int size)
00335 {
00336 char *p;
00337
00338 p=strrchr(in,'/');
00339 if (p != NULL)
00340 p++;
00341 else
00342 p=in;
00343 BUF_strlcpy(out,p,size);
00344 }
00345 #endif
00346 #endif
00347
00348 int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
00349 {
00350 int num,len,i;
00351 char *p;
00352
00353 *argc=0;
00354 *argv=NULL;
00355
00356 len=strlen(buf);
00357 i=0;
00358 if (arg->count == 0)
00359 {
00360 arg->count=20;
00361 arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count);
00362 }
00363 for (i=0; i<arg->count; i++)
00364 arg->data[i]=NULL;
00365
00366 num=0;
00367 p=buf;
00368 for (;;)
00369 {
00370
00371 if (!*p) break;
00372 while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
00373 p++;
00374 if (!*p) break;
00375
00376
00377 if (num >= arg->count)
00378 {
00379 char **tmp_p;
00380 int tlen = arg->count + 20;
00381 tmp_p = (char **)OPENSSL_realloc(arg->data,
00382 sizeof(char *)*tlen);
00383 if (tmp_p == NULL)
00384 return 0;
00385 arg->data = tmp_p;
00386 arg->count = tlen;
00387
00388 for (i = num; i < arg->count; i++)
00389 arg->data[i] = NULL;
00390 }
00391 arg->data[num++]=p;
00392
00393
00394 if ((*p == '\'') || (*p == '\"'))
00395 {
00396 i= *(p++);
00397 arg->data[num-1]++;
00398 while (*p && (*p != i))
00399 p++;
00400 *p='\0';
00401 }
00402 else
00403 {
00404 while (*p && ((*p != ' ') &&
00405 (*p != '\t') && (*p != '\n')))
00406 p++;
00407
00408 if (*p == '\0')
00409 p--;
00410 else
00411 *p='\0';
00412 }
00413 p++;
00414 }
00415 *argc=num;
00416 *argv=arg->data;
00417 return(1);
00418 }
00419
00420 #ifndef APP_INIT
00421 int app_init(long mesgwin)
00422 {
00423 return(1);
00424 }
00425 #endif
00426
00427
00428 int dump_cert_text (BIO *out, X509 *x)
00429 {
00430 char *p;
00431
00432 p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0);
00433 BIO_puts(out,"subject=");
00434 BIO_puts(out,p);
00435 OPENSSL_free(p);
00436
00437 p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0);
00438 BIO_puts(out,"\nissuer=");
00439 BIO_puts(out,p);
00440 BIO_puts(out,"\n");
00441 OPENSSL_free(p);
00442
00443 return 0;
00444 }
00445
00446 static int ui_open(UI *ui)
00447 {
00448 return UI_method_get_opener(UI_OpenSSL())(ui);
00449 }
00450 static int ui_read(UI *ui, UI_STRING *uis)
00451 {
00452 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
00453 && UI_get0_user_data(ui))
00454 {
00455 switch(UI_get_string_type(uis))
00456 {
00457 case UIT_PROMPT:
00458 case UIT_VERIFY:
00459 {
00460 const char *password =
00461 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
00462 if (password && password[0] != '\0')
00463 {
00464 UI_set_result(ui, uis, password);
00465 return 1;
00466 }
00467 }
00468 default:
00469 break;
00470 }
00471 }
00472 return UI_method_get_reader(UI_OpenSSL())(ui, uis);
00473 }
00474 static int ui_write(UI *ui, UI_STRING *uis)
00475 {
00476 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
00477 && UI_get0_user_data(ui))
00478 {
00479 switch(UI_get_string_type(uis))
00480 {
00481 case UIT_PROMPT:
00482 case UIT_VERIFY:
00483 {
00484 const char *password =
00485 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
00486 if (password && password[0] != '\0')
00487 return 1;
00488 }
00489 default:
00490 break;
00491 }
00492 }
00493 return UI_method_get_writer(UI_OpenSSL())(ui, uis);
00494 }
00495 static int ui_close(UI *ui)
00496 {
00497 return UI_method_get_closer(UI_OpenSSL())(ui);
00498 }
00499 int setup_ui_method(void)
00500 {
00501 ui_method = UI_create_method("OpenSSL application user interface");
00502 UI_method_set_opener(ui_method, ui_open);
00503 UI_method_set_reader(ui_method, ui_read);
00504 UI_method_set_writer(ui_method, ui_write);
00505 UI_method_set_closer(ui_method, ui_close);
00506 return 0;
00507 }
00508 void destroy_ui_method(void)
00509 {
00510 if(ui_method)
00511 {
00512 UI_destroy_method(ui_method);
00513 ui_method = NULL;
00514 }
00515 }
00516 int password_callback(char *buf, int bufsiz, int verify,
00517 PW_CB_DATA *cb_tmp)
00518 {
00519 UI *ui = NULL;
00520 int res = 0;
00521 const char *prompt_info = NULL;
00522 const char *password = NULL;
00523 PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
00524
00525 if (cb_data)
00526 {
00527 if (cb_data->password)
00528 password = cb_data->password;
00529 if (cb_data->prompt_info)
00530 prompt_info = cb_data->prompt_info;
00531 }
00532
00533 if (password)
00534 {
00535 res = strlen(password);
00536 if (res > bufsiz)
00537 res = bufsiz;
00538 memcpy(buf, password, res);
00539 return res;
00540 }
00541
00542 ui = UI_new_method(ui_method);
00543 if (ui)
00544 {
00545 int ok = 0;
00546 char *buff = NULL;
00547 int ui_flags = 0;
00548 char *prompt = NULL;
00549
00550 prompt = UI_construct_prompt(ui, "pass phrase",
00551 prompt_info);
00552
00553 ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
00554 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
00555
00556 if (ok >= 0)
00557 ok = UI_add_input_string(ui,prompt,ui_flags,buf,
00558 PW_MIN_LENGTH,BUFSIZ-1);
00559 if (ok >= 0 && verify)
00560 {
00561 buff = (char *)OPENSSL_malloc(bufsiz);
00562 ok = UI_add_verify_string(ui,prompt,ui_flags,buff,
00563 PW_MIN_LENGTH,BUFSIZ-1, buf);
00564 }
00565 if (ok >= 0)
00566 do
00567 {
00568 ok = UI_process(ui);
00569 }
00570 while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
00571
00572 if (buff)
00573 {
00574 OPENSSL_cleanse(buff,(unsigned int)bufsiz);
00575 OPENSSL_free(buff);
00576 }
00577
00578 if (ok >= 0)
00579 res = strlen(buf);
00580 if (ok == -1)
00581 {
00582 BIO_printf(bio_err, "User interface error\n");
00583 ERR_print_errors(bio_err);
00584 OPENSSL_cleanse(buf,(unsigned int)bufsiz);
00585 res = 0;
00586 }
00587 if (ok == -2)
00588 {
00589 BIO_printf(bio_err,"aborted!\n");
00590 OPENSSL_cleanse(buf,(unsigned int)bufsiz);
00591 res = 0;
00592 }
00593 UI_free(ui);
00594 OPENSSL_free(prompt);
00595 }
00596 return res;
00597 }
00598
00599 static char *app_get_pass(BIO *err, char *arg, int keepbio);
00600
00601 int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
00602 {
00603 int same;
00604 if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0;
00605 else same = 1;
00606 if(arg1) {
00607 *pass1 = app_get_pass(err, arg1, same);
00608 if(!*pass1) return 0;
00609 } else if(pass1) *pass1 = NULL;
00610 if(arg2) {
00611 *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
00612 if(!*pass2) return 0;
00613 } else if(pass2) *pass2 = NULL;
00614 return 1;
00615 }
00616
00617 static char *app_get_pass(BIO *err, char *arg, int keepbio)
00618 {
00619 char *tmp, tpass[APP_PASS_LEN];
00620 static BIO *pwdbio = NULL;
00621 int i;
00622 if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5);
00623 if(!strncmp(arg, "env:", 4)) {
00624 tmp = getenv(arg + 4);
00625 if(!tmp) {
00626 BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
00627 return NULL;
00628 }
00629 return BUF_strdup(tmp);
00630 }
00631 if(!keepbio || !pwdbio) {
00632 if(!strncmp(arg, "file:", 5)) {
00633 pwdbio = BIO_new_file(arg + 5, "r");
00634 if(!pwdbio) {
00635 BIO_printf(err, "Can't open file %s\n", arg + 5);
00636 return NULL;
00637 }
00638 } else if(!strncmp(arg, "fd:", 3)) {
00639 BIO *btmp;
00640 i = atoi(arg + 3);
00641 if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
00642 if((i < 0) || !pwdbio) {
00643 BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
00644 return NULL;
00645 }
00646
00647 btmp = BIO_new(BIO_f_buffer());
00648 pwdbio = BIO_push(btmp, pwdbio);
00649 } else if(!strcmp(arg, "stdin")) {
00650 pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
00651 if(!pwdbio) {
00652 BIO_printf(err, "Can't open BIO for stdin\n");
00653 return NULL;
00654 }
00655 } else {
00656 BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
00657 return NULL;
00658 }
00659 }
00660 i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
00661 if(keepbio != 1) {
00662 BIO_free_all(pwdbio);
00663 pwdbio = NULL;
00664 }
00665 if(i <= 0) {
00666 BIO_printf(err, "Error reading password from BIO\n");
00667 return NULL;
00668 }
00669 tmp = strchr(tpass, '\n');
00670 if(tmp) *tmp = 0;
00671 return BUF_strdup(tpass);
00672 }
00673
00674 int add_oid_section(BIO *err, CONF *conf)
00675 {
00676 char *p;
00677 STACK_OF(CONF_VALUE) *sktmp;
00678 CONF_VALUE *cnf;
00679 int i;
00680 if(!(p=NCONF_get_string(conf,NULL,"oid_section")))
00681 {
00682 ERR_clear_error();
00683 return 1;
00684 }
00685 if(!(sktmp = NCONF_get_section(conf, p))) {
00686 BIO_printf(err, "problem loading oid section %s\n", p);
00687 return 0;
00688 }
00689 for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
00690 cnf = sk_CONF_VALUE_value(sktmp, i);
00691 if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
00692 BIO_printf(err, "problem creating object %s=%s\n",
00693 cnf->name, cnf->value);
00694 return 0;
00695 }
00696 }
00697 return 1;
00698 }
00699
00700 static int load_pkcs12(BIO *err, BIO *in, const char *desc,
00701 pem_password_cb *pem_cb, void *cb_data,
00702 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
00703 {
00704 const char *pass;
00705 char tpass[PEM_BUFSIZE];
00706 int len, ret = 0;
00707 PKCS12 *p12;
00708 p12 = d2i_PKCS12_bio(in, NULL);
00709 if (p12 == NULL)
00710 {
00711 BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
00712 goto die;
00713 }
00714
00715 if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
00716 pass = "";
00717 else
00718 {
00719 if (!pem_cb)
00720 pem_cb = (pem_password_cb *)password_callback;
00721 len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
00722 if (len < 0)
00723 {
00724 BIO_printf(err, "Passpharse callback error for %s\n",
00725 desc);
00726 goto die;
00727 }
00728 if (len < PEM_BUFSIZE)
00729 tpass[len] = 0;
00730 if (!PKCS12_verify_mac(p12, tpass, len))
00731 {
00732 BIO_printf(err,
00733 "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);
00734 goto die;
00735 }
00736 pass = tpass;
00737 }
00738 ret = PKCS12_parse(p12, pass, pkey, cert, ca);
00739 die:
00740 if (p12)
00741 PKCS12_free(p12);
00742 return ret;
00743 }
00744
00745 X509 *load_cert(BIO *err, const char *file, int format,
00746 const char *pass, ENGINE *e, const char *cert_descrip)
00747 {
00748 ASN1_HEADER *ah=NULL;
00749 BUF_MEM *buf=NULL;
00750 X509 *x=NULL;
00751 BIO *cert;
00752
00753 if ((cert=BIO_new(BIO_s_file())) == NULL)
00754 {
00755 ERR_print_errors(err);
00756 goto end;
00757 }
00758
00759 if (file == NULL)
00760 {
00761 setvbuf(stdin, NULL, _IONBF, 0);
00762 BIO_set_fp(cert,stdin,BIO_NOCLOSE);
00763 }
00764 else
00765 {
00766 if (BIO_read_filename(cert,file) <= 0)
00767 {
00768 BIO_printf(err, "Error opening %s %s\n",
00769 cert_descrip, file);
00770 ERR_print_errors(err);
00771 goto end;
00772 }
00773 }
00774
00775 if (format == FORMAT_ASN1)
00776 x=d2i_X509_bio(cert,NULL);
00777 else if (format == FORMAT_NETSCAPE)
00778 {
00779 const unsigned char *p,*op;
00780 int size=0,i;
00781
00782
00783
00784
00785 buf=BUF_MEM_new();
00786 for (;;)
00787 {
00788 if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
00789 goto end;
00790 i=BIO_read(cert,&(buf->data[size]),1024*10);
00791 size+=i;
00792 if (i == 0) break;
00793 if (i < 0)
00794 {
00795 perror("reading certificate");
00796 goto end;
00797 }
00798 }
00799 p=(unsigned char *)buf->data;
00800 op=p;
00801
00802
00803 if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
00804 goto end;
00805 if ((ah->header == NULL) || (ah->header->data == NULL) ||
00806 (strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data,
00807 ah->header->length) != 0))
00808 {
00809 BIO_printf(err,"Error reading header on certificate\n");
00810 goto end;
00811 }
00812
00813 p=op;
00814 ah->meth=X509_asn1_meth();
00815 if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
00816 goto end;
00817 x=(X509 *)ah->data;
00818 ah->data=NULL;
00819 }
00820 else if (format == FORMAT_PEM)
00821 x=PEM_read_bio_X509_AUX(cert,NULL,
00822 (pem_password_cb *)password_callback, NULL);
00823 else if (format == FORMAT_PKCS12)
00824 {
00825 if (!load_pkcs12(err, cert,cert_descrip, NULL, NULL,
00826 NULL, &x, NULL))
00827 goto end;
00828 }
00829 else {
00830 BIO_printf(err,"bad input format specified for %s\n",
00831 cert_descrip);
00832 goto end;
00833 }
00834 end:
00835 if (x == NULL)
00836 {
00837 BIO_printf(err,"unable to load certificate\n");
00838 ERR_print_errors(err);
00839 }
00840 if (ah != NULL) ASN1_HEADER_free(ah);
00841 if (cert != NULL) BIO_free(cert);
00842 if (buf != NULL) BUF_MEM_free(buf);
00843 return(x);
00844 }
00845
00846 EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
00847 const char *pass, ENGINE *e, const char *key_descrip)
00848 {
00849 BIO *key=NULL;
00850 EVP_PKEY *pkey=NULL;
00851 PW_CB_DATA cb_data;
00852
00853 cb_data.password = pass;
00854 cb_data.prompt_info = file;
00855
00856 if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
00857 {
00858 BIO_printf(err,"no keyfile specified\n");
00859 goto end;
00860 }
00861 #ifndef OPENSSL_NO_ENGINE
00862 if (format == FORMAT_ENGINE)
00863 {
00864 if (!e)
00865 BIO_printf(bio_err,"no engine specified\n");
00866 else
00867 pkey = ENGINE_load_private_key(e, file,
00868 ui_method, &cb_data);
00869 goto end;
00870 }
00871 #endif
00872 key=BIO_new(BIO_s_file());
00873 if (key == NULL)
00874 {
00875 ERR_print_errors(err);
00876 goto end;
00877 }
00878 if (file == NULL && maybe_stdin)
00879 {
00880 setvbuf(stdin, NULL, _IONBF, 0);
00881 BIO_set_fp(key,stdin,BIO_NOCLOSE);
00882 }
00883 else
00884 if (BIO_read_filename(key,file) <= 0)
00885 {
00886 BIO_printf(err, "Error opening %s %s\n",
00887 key_descrip, file);
00888 ERR_print_errors(err);
00889 goto end;
00890 }
00891 if (format == FORMAT_ASN1)
00892 {
00893 pkey=d2i_PrivateKey_bio(key, NULL);
00894 }
00895 else if (format == FORMAT_PEM)
00896 {
00897 pkey=PEM_read_bio_PrivateKey(key,NULL,
00898 (pem_password_cb *)password_callback, &cb_data);
00899 }
00900 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
00901 else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
00902 pkey = load_netscape_key(err, key, file, key_descrip, format);
00903 #endif
00904 else if (format == FORMAT_PKCS12)
00905 {
00906 if (!load_pkcs12(err, key, key_descrip,
00907 (pem_password_cb *)password_callback, &cb_data,
00908 &pkey, NULL, NULL))
00909 goto end;
00910 }
00911 else
00912 {
00913 BIO_printf(err,"bad input format specified for key file\n");
00914 goto end;
00915 }
00916 end:
00917 if (key != NULL) BIO_free(key);
00918 if (pkey == NULL)
00919 BIO_printf(err,"unable to load %s\n", key_descrip);
00920 return(pkey);
00921 }
00922
00923 EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
00924 const char *pass, ENGINE *e, const char *key_descrip)
00925 {
00926 BIO *key=NULL;
00927 EVP_PKEY *pkey=NULL;
00928 PW_CB_DATA cb_data;
00929
00930 cb_data.password = pass;
00931 cb_data.prompt_info = file;
00932
00933 if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
00934 {
00935 BIO_printf(err,"no keyfile specified\n");
00936 goto end;
00937 }
00938 #ifndef OPENSSL_NO_ENGINE
00939 if (format == FORMAT_ENGINE)
00940 {
00941 if (!e)
00942 BIO_printf(bio_err,"no engine specified\n");
00943 else
00944 pkey = ENGINE_load_public_key(e, file,
00945 ui_method, &cb_data);
00946 goto end;
00947 }
00948 #endif
00949 key=BIO_new(BIO_s_file());
00950 if (key == NULL)
00951 {
00952 ERR_print_errors(err);
00953 goto end;
00954 }
00955 if (file == NULL && maybe_stdin)
00956 {
00957 setvbuf(stdin, NULL, _IONBF, 0);
00958 BIO_set_fp(key,stdin,BIO_NOCLOSE);
00959 }
00960 else
00961 if (BIO_read_filename(key,file) <= 0)
00962 {
00963 BIO_printf(err, "Error opening %s %s\n",
00964 key_descrip, file);
00965 ERR_print_errors(err);
00966 goto end;
00967 }
00968 if (format == FORMAT_ASN1)
00969 {
00970 pkey=d2i_PUBKEY_bio(key, NULL);
00971 }
00972 else if (format == FORMAT_PEM)
00973 {
00974 pkey=PEM_read_bio_PUBKEY(key,NULL,
00975 (pem_password_cb *)password_callback, &cb_data);
00976 }
00977 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
00978 else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
00979 pkey = load_netscape_key(err, key, file, key_descrip, format);
00980 #endif
00981 else
00982 {
00983 BIO_printf(err,"bad input format specified for key file\n");
00984 goto end;
00985 }
00986 end:
00987 if (key != NULL) BIO_free(key);
00988 if (pkey == NULL)
00989 BIO_printf(err,"unable to load %s\n", key_descrip);
00990 return(pkey);
00991 }
00992
00993 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
00994 static EVP_PKEY *
00995 load_netscape_key(BIO *err, BIO *key, const char *file,
00996 const char *key_descrip, int format)
00997 {
00998 EVP_PKEY *pkey;
00999 BUF_MEM *buf;
01000 RSA *rsa;
01001 const unsigned char *p;
01002 int size, i;
01003
01004 buf=BUF_MEM_new();
01005 pkey = EVP_PKEY_new();
01006 size = 0;
01007 if (buf == NULL || pkey == NULL)
01008 goto error;
01009 for (;;)
01010 {
01011 if (!BUF_MEM_grow_clean(buf,size+1024*10))
01012 goto error;
01013 i = BIO_read(key, &(buf->data[size]), 1024*10);
01014 size += i;
01015 if (i == 0)
01016 break;
01017 if (i < 0)
01018 {
01019 BIO_printf(err, "Error reading %s %s",
01020 key_descrip, file);
01021 goto error;
01022 }
01023 }
01024 p=(unsigned char *)buf->data;
01025 rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL,
01026 (format == FORMAT_IISSGC ? 1 : 0));
01027 if (rsa == NULL)
01028 goto error;
01029 BUF_MEM_free(buf);
01030 EVP_PKEY_set1_RSA(pkey, rsa);
01031 return pkey;
01032 error:
01033 BUF_MEM_free(buf);
01034 EVP_PKEY_free(pkey);
01035 return NULL;
01036 }
01037 #endif
01038
01039 STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
01040 const char *pass, ENGINE *e, const char *cert_descrip)
01041 {
01042 BIO *certs;
01043 int i;
01044 STACK_OF(X509) *othercerts = NULL;
01045 STACK_OF(X509_INFO) *allcerts = NULL;
01046 X509_INFO *xi;
01047 PW_CB_DATA cb_data;
01048
01049 cb_data.password = pass;
01050 cb_data.prompt_info = file;
01051
01052 if((certs = BIO_new(BIO_s_file())) == NULL)
01053 {
01054 ERR_print_errors(err);
01055 goto end;
01056 }
01057
01058 if (file == NULL)
01059 BIO_set_fp(certs,stdin,BIO_NOCLOSE);
01060 else
01061 {
01062 if (BIO_read_filename(certs,file) <= 0)
01063 {
01064 BIO_printf(err, "Error opening %s %s\n",
01065 cert_descrip, file);
01066 ERR_print_errors(err);
01067 goto end;
01068 }
01069 }
01070
01071 if (format == FORMAT_PEM)
01072 {
01073 othercerts = sk_X509_new_null();
01074 if(!othercerts)
01075 {
01076 sk_X509_free(othercerts);
01077 othercerts = NULL;
01078 goto end;
01079 }
01080 allcerts = PEM_X509_INFO_read_bio(certs, NULL,
01081 (pem_password_cb *)password_callback, &cb_data);
01082 for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
01083 {
01084 xi = sk_X509_INFO_value (allcerts, i);
01085 if (xi->x509)
01086 {
01087 sk_X509_push(othercerts, xi->x509);
01088 xi->x509 = NULL;
01089 }
01090 }
01091 goto end;
01092 }
01093 else {
01094 BIO_printf(err,"bad input format specified for %s\n",
01095 cert_descrip);
01096 goto end;
01097 }
01098 end:
01099 if (othercerts == NULL)
01100 {
01101 BIO_printf(err,"unable to load certificates\n");
01102 ERR_print_errors(err);
01103 }
01104 if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
01105 if (certs != NULL) BIO_free(certs);
01106 return(othercerts);
01107 }
01108
01109
01110 #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
01111
01112 #define X509V3_EXT_DEFAULT 0
01113
01114 #define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
01115
01116 #define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
01117
01118 #define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
01119
01120 #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
01121 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
01122
01123 int set_cert_ex(unsigned long *flags, const char *arg)
01124 {
01125 static const NAME_EX_TBL cert_tbl[] = {
01126 { "compatible", X509_FLAG_COMPAT, 0xffffffffl},
01127 { "ca_default", X509_FLAG_CA, 0xffffffffl},
01128 { "no_header", X509_FLAG_NO_HEADER, 0},
01129 { "no_version", X509_FLAG_NO_VERSION, 0},
01130 { "no_serial", X509_FLAG_NO_SERIAL, 0},
01131 { "no_signame", X509_FLAG_NO_SIGNAME, 0},
01132 { "no_validity", X509_FLAG_NO_VALIDITY, 0},
01133 { "no_subject", X509_FLAG_NO_SUBJECT, 0},
01134 { "no_issuer", X509_FLAG_NO_ISSUER, 0},
01135 { "no_pubkey", X509_FLAG_NO_PUBKEY, 0},
01136 { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
01137 { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
01138 { "no_aux", X509_FLAG_NO_AUX, 0},
01139 { "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
01140 { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
01141 { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
01142 { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
01143 { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
01144 { NULL, 0, 0}
01145 };
01146 return set_multi_opts(flags, arg, cert_tbl);
01147 }
01148
01149 int set_name_ex(unsigned long *flags, const char *arg)
01150 {
01151 static const NAME_EX_TBL ex_tbl[] = {
01152 { "esc_2253", ASN1_STRFLGS_ESC_2253, 0},
01153 { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
01154 { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
01155 { "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
01156 { "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
01157 { "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
01158 { "show_type", ASN1_STRFLGS_SHOW_TYPE, 0},