apps.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. /* apps/apps.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include <string.h>
  61. #include <sys/types.h>
  62. #include <sys/stat.h>
  63. #define NON_MAIN
  64. #include "apps.h"
  65. #undef NON_MAIN
  66. #include <openssl/err.h>
  67. #include <openssl/x509.h>
  68. #include <openssl/pem.h>
  69. #include <openssl/pkcs12.h>
  70. #include <openssl/safestack.h>
  71. #ifdef OPENSSL_SYS_WINDOWS
  72. # include "bss_file.c"
  73. #endif
  74. typedef struct {
  75. char *name;
  76. unsigned long flag;
  77. unsigned long mask;
  78. } NAME_EX_TBL;
  79. static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
  80. int app_init(long mesgwin);
  81. #ifdef undef /* never finished - probably never will be :-) */
  82. int args_from_file(char *file, int *argc, char **argv[])
  83. {
  84. FILE *fp;
  85. int num,i;
  86. unsigned int len;
  87. static char *buf=NULL;
  88. static char **arg=NULL;
  89. char *p;
  90. struct stat stbuf;
  91. if (stat(file,&stbuf) < 0) return(0);
  92. fp=fopen(file,"r");
  93. if (fp == NULL)
  94. return(0);
  95. *argc=0;
  96. *argv=NULL;
  97. len=(unsigned int)stbuf.st_size;
  98. if (buf != NULL) OPENSSL_free(buf);
  99. buf=(char *)OPENSSL_malloc(len+1);
  100. if (buf == NULL) return(0);
  101. len=fread(buf,1,len,fp);
  102. if (len <= 1) return(0);
  103. buf[len]='\0';
  104. i=0;
  105. for (p=buf; *p; p++)
  106. if (*p == '\n') i++;
  107. if (arg != NULL) OPENSSL_free(arg);
  108. arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2));
  109. *argv=arg;
  110. num=0;
  111. p=buf;
  112. for (;;)
  113. {
  114. if (!*p) break;
  115. if (*p == '#') /* comment line */
  116. {
  117. while (*p && (*p != '\n')) p++;
  118. continue;
  119. }
  120. /* else we have a line */
  121. *(arg++)=p;
  122. num++;
  123. while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
  124. p++;
  125. if (!*p) break;
  126. if (*p == '\n')
  127. {
  128. *(p++)='\0';
  129. continue;
  130. }
  131. /* else it is a tab or space */
  132. p++;
  133. while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
  134. p++;
  135. if (!*p) break;
  136. if (*p == '\n')
  137. {
  138. p++;
  139. continue;
  140. }
  141. *(arg++)=p++;
  142. num++;
  143. while (*p && (*p != '\n')) p++;
  144. if (!*p) break;
  145. /* else *p == '\n' */
  146. *(p++)='\0';
  147. }
  148. *argc=num;
  149. return(1);
  150. }
  151. #endif
  152. int str2fmt(char *s)
  153. {
  154. if ((*s == 'D') || (*s == 'd'))
  155. return(FORMAT_ASN1);
  156. else if ((*s == 'T') || (*s == 't'))
  157. return(FORMAT_TEXT);
  158. else if ((*s == 'P') || (*s == 'p'))
  159. return(FORMAT_PEM);
  160. else if ((*s == 'N') || (*s == 'n'))
  161. return(FORMAT_NETSCAPE);
  162. else if ((*s == 'S') || (*s == 's'))
  163. return(FORMAT_SMIME);
  164. else if ((*s == '1')
  165. || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
  166. || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
  167. return(FORMAT_PKCS12);
  168. else if ((*s == 'E') || (*s == 'e'))
  169. return(FORMAT_ENGINE);
  170. else
  171. return(FORMAT_UNDEF);
  172. }
  173. #if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
  174. void program_name(char *in, char *out, int size)
  175. {
  176. int i,n;
  177. char *p=NULL;
  178. n=strlen(in);
  179. /* find the last '/', '\' or ':' */
  180. for (i=n-1; i>0; i--)
  181. {
  182. if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':'))
  183. {
  184. p= &(in[i+1]);
  185. break;
  186. }
  187. }
  188. if (p == NULL)
  189. p=in;
  190. n=strlen(p);
  191. /* strip off trailing .exe if present. */
  192. if ((n > 4) && (p[n-4] == '.') &&
  193. ((p[n-3] == 'e') || (p[n-3] == 'E')) &&
  194. ((p[n-2] == 'x') || (p[n-2] == 'X')) &&
  195. ((p[n-1] == 'e') || (p[n-1] == 'E')))
  196. n-=4;
  197. if (n > size-1)
  198. n=size-1;
  199. for (i=0; i<n; i++)
  200. {
  201. if ((p[i] >= 'A') && (p[i] <= 'Z'))
  202. out[i]=p[i]-'A'+'a';
  203. else
  204. out[i]=p[i];
  205. }
  206. out[n]='\0';
  207. }
  208. #else
  209. #ifdef OPENSSL_SYS_VMS
  210. void program_name(char *in, char *out, int size)
  211. {
  212. char *p=in, *q;
  213. char *chars=":]>";
  214. while(*chars != '\0')
  215. {
  216. q=strrchr(p,*chars);
  217. if (q > p)
  218. p = q + 1;
  219. chars++;
  220. }
  221. q=strrchr(p,'.');
  222. if (q == NULL)
  223. q = in+size;
  224. strncpy(out,p,q-p);
  225. out[q-p]='\0';
  226. }
  227. #else
  228. void program_name(char *in, char *out, int size)
  229. {
  230. char *p;
  231. p=strrchr(in,'/');
  232. if (p != NULL)
  233. p++;
  234. else
  235. p=in;
  236. strncpy(out,p,size-1);
  237. out[size-1]='\0';
  238. }
  239. #endif
  240. #endif
  241. #ifdef OPENSSL_SYS_WIN32
  242. int WIN32_rename(char *from, char *to)
  243. {
  244. #ifdef OPENSSL_SYS_WINNT
  245. int ret;
  246. /* Note: MoveFileEx() doesn't work under Win95, Win98 */
  247. ret=MoveFileEx(from,to,MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED);
  248. return(ret?0:-1);
  249. #else
  250. unlink(to);
  251. return MoveFile(from, to);
  252. #endif
  253. }
  254. #endif
  255. int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
  256. {
  257. int num,len,i;
  258. char *p;
  259. *argc=0;
  260. *argv=NULL;
  261. len=strlen(buf);
  262. i=0;
  263. if (arg->count == 0)
  264. {
  265. arg->count=20;
  266. arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count);
  267. }
  268. for (i=0; i<arg->count; i++)
  269. arg->data[i]=NULL;
  270. num=0;
  271. p=buf;
  272. for (;;)
  273. {
  274. /* first scan over white space */
  275. if (!*p) break;
  276. while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
  277. p++;
  278. if (!*p) break;
  279. /* The start of something good :-) */
  280. if (num >= arg->count)
  281. {
  282. arg->count+=20;
  283. arg->data=(char **)OPENSSL_realloc(arg->data,
  284. sizeof(char *)*arg->count);
  285. if (argc == 0) return(0);
  286. }
  287. arg->data[num++]=p;
  288. /* now look for the end of this */
  289. if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */
  290. {
  291. i= *(p++);
  292. arg->data[num-1]++; /* jump over quote */
  293. while (*p && (*p != i))
  294. p++;
  295. *p='\0';
  296. }
  297. else
  298. {
  299. while (*p && ((*p != ' ') &&
  300. (*p != '\t') && (*p != '\n')))
  301. p++;
  302. if (*p == '\0')
  303. p--;
  304. else
  305. *p='\0';
  306. }
  307. p++;
  308. }
  309. *argc=num;
  310. *argv=arg->data;
  311. return(1);
  312. }
  313. #ifndef APP_INIT
  314. int app_init(long mesgwin)
  315. {
  316. return(1);
  317. }
  318. #endif
  319. int dump_cert_text (BIO *out, X509 *x)
  320. {
  321. char buf[256];
  322. X509_NAME_oneline(X509_get_subject_name(x),buf,256);
  323. BIO_puts(out,"subject=");
  324. BIO_puts(out,buf);
  325. X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
  326. BIO_puts(out,"\nissuer= ");
  327. BIO_puts(out,buf);
  328. BIO_puts(out,"\n");
  329. return 0;
  330. }
  331. static char *app_get_pass(BIO *err, char *arg, int keepbio);
  332. int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
  333. {
  334. int same;
  335. if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0;
  336. else same = 1;
  337. if(arg1) {
  338. *pass1 = app_get_pass(err, arg1, same);
  339. if(!*pass1) return 0;
  340. } else if(pass1) *pass1 = NULL;
  341. if(arg2) {
  342. *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
  343. if(!*pass2) return 0;
  344. } else if(pass2) *pass2 = NULL;
  345. return 1;
  346. }
  347. static char *app_get_pass(BIO *err, char *arg, int keepbio)
  348. {
  349. char *tmp, tpass[APP_PASS_LEN];
  350. static BIO *pwdbio = NULL;
  351. int i;
  352. if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5);
  353. if(!strncmp(arg, "env:", 4)) {
  354. tmp = getenv(arg + 4);
  355. if(!tmp) {
  356. BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
  357. return NULL;
  358. }
  359. return BUF_strdup(tmp);
  360. }
  361. if(!keepbio || !pwdbio) {
  362. if(!strncmp(arg, "file:", 5)) {
  363. pwdbio = BIO_new_file(arg + 5, "r");
  364. if(!pwdbio) {
  365. BIO_printf(err, "Can't open file %s\n", arg + 5);
  366. return NULL;
  367. }
  368. } else if(!strncmp(arg, "fd:", 3)) {
  369. BIO *btmp;
  370. i = atoi(arg + 3);
  371. if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
  372. if((i < 0) || !pwdbio) {
  373. BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
  374. return NULL;
  375. }
  376. /* Can't do BIO_gets on an fd BIO so add a buffering BIO */
  377. btmp = BIO_new(BIO_f_buffer());
  378. pwdbio = BIO_push(btmp, pwdbio);
  379. } else if(!strcmp(arg, "stdin")) {
  380. pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
  381. if(!pwdbio) {
  382. BIO_printf(err, "Can't open BIO for stdin\n");
  383. return NULL;
  384. }
  385. } else {
  386. BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
  387. return NULL;
  388. }
  389. }
  390. i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
  391. if(keepbio != 1) {
  392. BIO_free_all(pwdbio);
  393. pwdbio = NULL;
  394. }
  395. if(i <= 0) {
  396. BIO_printf(err, "Error reading password from BIO\n");
  397. return NULL;
  398. }
  399. tmp = strchr(tpass, '\n');
  400. if(tmp) *tmp = 0;
  401. return BUF_strdup(tpass);
  402. }
  403. int add_oid_section(BIO *err, LHASH *conf)
  404. {
  405. char *p;
  406. STACK_OF(CONF_VALUE) *sktmp;
  407. CONF_VALUE *cnf;
  408. int i;
  409. if(!(p=CONF_get_string(conf,NULL,"oid_section")))
  410. {
  411. ERR_clear_error();
  412. return 1;
  413. }
  414. if(!(sktmp = CONF_get_section(conf, p))) {
  415. BIO_printf(err, "problem loading oid section %s\n", p);
  416. return 0;
  417. }
  418. for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
  419. cnf = sk_CONF_VALUE_value(sktmp, i);
  420. if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
  421. BIO_printf(err, "problem creating object %s=%s\n",
  422. cnf->name, cnf->value);
  423. return 0;
  424. }
  425. }
  426. return 1;
  427. }
  428. X509 *load_cert(BIO *err, char *file, int format)
  429. {
  430. ASN1_HEADER *ah=NULL;
  431. BUF_MEM *buf=NULL;
  432. X509 *x=NULL;
  433. BIO *cert;
  434. if ((cert=BIO_new(BIO_s_file())) == NULL)
  435. {
  436. ERR_print_errors(err);
  437. goto end;
  438. }
  439. if (file == NULL)
  440. {
  441. setvbuf(stdin, NULL, _IONBF, 0);
  442. BIO_set_fp(cert,stdin,BIO_NOCLOSE);
  443. }
  444. else
  445. {
  446. if (BIO_read_filename(cert,file) <= 0)
  447. {
  448. perror(file);
  449. goto end;
  450. }
  451. }
  452. if (format == FORMAT_ASN1)
  453. x=d2i_X509_bio(cert,NULL);
  454. else if (format == FORMAT_NETSCAPE)
  455. {
  456. unsigned char *p,*op;
  457. int size=0,i;
  458. /* We sort of have to do it this way because it is sort of nice
  459. * to read the header first and check it, then
  460. * try to read the certificate */
  461. buf=BUF_MEM_new();
  462. for (;;)
  463. {
  464. if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
  465. goto end;
  466. i=BIO_read(cert,&(buf->data[size]),1024*10);
  467. size+=i;
  468. if (i == 0) break;
  469. if (i < 0)
  470. {
  471. perror("reading certificate");
  472. goto end;
  473. }
  474. }
  475. p=(unsigned char *)buf->data;
  476. op=p;
  477. /* First load the header */
  478. if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
  479. goto end;
  480. if ((ah->header == NULL) || (ah->header->data == NULL) ||
  481. (strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data,
  482. ah->header->length) != 0))
  483. {
  484. BIO_printf(err,"Error reading header on certificate\n");
  485. goto end;
  486. }
  487. /* header is ok, so now read the object */
  488. p=op;
  489. ah->meth=X509_asn1_meth();
  490. if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
  491. goto end;
  492. x=(X509 *)ah->data;
  493. ah->data=NULL;
  494. }
  495. else if (format == FORMAT_PEM)
  496. x=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL);
  497. else if (format == FORMAT_PKCS12)
  498. {
  499. PKCS12 *p12 = d2i_PKCS12_bio(cert, NULL);
  500. PKCS12_parse(p12, NULL, NULL, &x, NULL);
  501. PKCS12_free(p12);
  502. p12 = NULL;
  503. }
  504. else {
  505. BIO_printf(err,"bad input format specified for input cert\n");
  506. goto end;
  507. }
  508. end:
  509. if (x == NULL)
  510. {
  511. BIO_printf(err,"unable to load certificate\n");
  512. ERR_print_errors(err);
  513. }
  514. if (ah != NULL) ASN1_HEADER_free(ah);
  515. if (cert != NULL) BIO_free(cert);
  516. if (buf != NULL) BUF_MEM_free(buf);
  517. return(x);
  518. }
  519. EVP_PKEY *load_key(BIO *err, char *file, int format, char *pass, ENGINE *e)
  520. {
  521. BIO *key=NULL;
  522. EVP_PKEY *pkey=NULL;
  523. if (file == NULL)
  524. {
  525. BIO_printf(err,"no keyfile specified\n");
  526. goto end;
  527. }
  528. if (format == FORMAT_ENGINE)
  529. {
  530. if (!e)
  531. BIO_printf(bio_err,"no engine specified\n");
  532. else
  533. pkey = ENGINE_load_private_key(e, file, pass);
  534. goto end;
  535. }
  536. key=BIO_new(BIO_s_file());
  537. if (key == NULL)
  538. {
  539. ERR_print_errors(err);
  540. goto end;
  541. }
  542. if (BIO_read_filename(key,file) <= 0)
  543. {
  544. perror(file);
  545. goto end;
  546. }
  547. if (format == FORMAT_ASN1)
  548. {
  549. pkey=d2i_PrivateKey_bio(key, NULL);
  550. }
  551. else if (format == FORMAT_PEM)
  552. {
  553. pkey=PEM_read_bio_PrivateKey(key,NULL,NULL,pass);
  554. }
  555. else if (format == FORMAT_PKCS12)
  556. {
  557. PKCS12 *p12 = d2i_PKCS12_bio(key, NULL);
  558. PKCS12_parse(p12, pass, &pkey, NULL, NULL);
  559. PKCS12_free(p12);
  560. p12 = NULL;
  561. }
  562. else
  563. {
  564. BIO_printf(err,"bad input format specified for key\n");
  565. goto end;
  566. }
  567. end:
  568. if (key != NULL) BIO_free(key);
  569. if (pkey == NULL)
  570. BIO_printf(err,"unable to load Private Key\n");
  571. return(pkey);
  572. }
  573. EVP_PKEY *load_pubkey(BIO *err, char *file, int format, ENGINE *e)
  574. {
  575. BIO *key=NULL;
  576. EVP_PKEY *pkey=NULL;
  577. if (file == NULL)
  578. {
  579. BIO_printf(err,"no keyfile specified\n");
  580. goto end;
  581. }
  582. if (format == FORMAT_ENGINE)
  583. {
  584. if (!e)
  585. BIO_printf(bio_err,"no engine specified\n");
  586. else
  587. pkey = ENGINE_load_public_key(e, file, NULL);
  588. goto end;
  589. }
  590. key=BIO_new(BIO_s_file());
  591. if (key == NULL)
  592. {
  593. ERR_print_errors(err);
  594. goto end;
  595. }
  596. if (BIO_read_filename(key,file) <= 0)
  597. {
  598. perror(file);
  599. goto end;
  600. }
  601. if (format == FORMAT_ASN1)
  602. {
  603. pkey=d2i_PUBKEY_bio(key, NULL);
  604. }
  605. else if (format == FORMAT_PEM)
  606. {
  607. pkey=PEM_read_bio_PUBKEY(key,NULL,NULL,NULL);
  608. }
  609. else
  610. {
  611. BIO_printf(err,"bad input format specified for key\n");
  612. goto end;
  613. }
  614. end:
  615. if (key != NULL) BIO_free(key);
  616. if (pkey == NULL)
  617. BIO_printf(err,"unable to load Public Key\n");
  618. return(pkey);
  619. }
  620. STACK_OF(X509) *load_certs(BIO *err, char *file, int format)
  621. {
  622. BIO *certs;
  623. int i;
  624. STACK_OF(X509) *othercerts = NULL;
  625. STACK_OF(X509_INFO) *allcerts = NULL;
  626. X509_INFO *xi;
  627. if((certs = BIO_new(BIO_s_file())) == NULL)
  628. {
  629. ERR_print_errors(err);
  630. goto end;
  631. }
  632. if (file == NULL)
  633. BIO_set_fp(certs,stdin,BIO_NOCLOSE);
  634. else
  635. {
  636. if (BIO_read_filename(certs,file) <= 0)
  637. {
  638. perror(file);
  639. goto end;
  640. }
  641. }
  642. if (format == FORMAT_PEM)
  643. {
  644. othercerts = sk_X509_new_null();
  645. if(!othercerts)
  646. {
  647. sk_X509_free(othercerts);
  648. othercerts = NULL;
  649. goto end;
  650. }
  651. allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
  652. for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
  653. {
  654. xi = sk_X509_INFO_value (allcerts, i);
  655. if (xi->x509)
  656. {
  657. sk_X509_push(othercerts, xi->x509);
  658. xi->x509 = NULL;
  659. }
  660. }
  661. goto end;
  662. }
  663. else {
  664. BIO_printf(err,"bad input format specified for input cert\n");
  665. goto end;
  666. }
  667. end:
  668. if (othercerts == NULL)
  669. {
  670. BIO_printf(err,"unable to load certificates\n");
  671. ERR_print_errors(err);
  672. }
  673. if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
  674. if (certs != NULL) BIO_free(certs);
  675. return(othercerts);
  676. }
  677. #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
  678. /* Return error for unknown extensions */
  679. #define X509V3_EXT_DEFAULT 0
  680. /* Print error for unknown extensions */
  681. #define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
  682. /* ASN1 parse unknown extensions */
  683. #define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
  684. /* BIO_dump unknown extensions */
  685. #define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
  686. int set_cert_ex(unsigned long *flags, const char *arg)
  687. {
  688. static const NAME_EX_TBL cert_tbl[] = {
  689. { "compatible", X509_FLAG_COMPAT, 0xffffffffl},
  690. { "no_header", X509_FLAG_NO_HEADER, 0},
  691. { "no_version", X509_FLAG_NO_VERSION, 0},
  692. { "no_serial", X509_FLAG_NO_SERIAL, 0},
  693. { "no_signame", X509_FLAG_NO_SIGNAME, 0},
  694. { "no_validity", X509_FLAG_NO_VALIDITY, 0},
  695. { "no_subject", X509_FLAG_NO_SUBJECT, 0},
  696. { "no_pubkey", X509_FLAG_NO_PUBKEY, 0},
  697. { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
  698. { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
  699. { "no_aux", X509_FLAG_NO_AUX, 0},
  700. { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
  701. { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
  702. { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
  703. { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
  704. { NULL, 0, 0}
  705. };
  706. return set_table_opts(flags, arg, cert_tbl);
  707. }
  708. int set_name_ex(unsigned long *flags, const char *arg)
  709. {
  710. static const NAME_EX_TBL ex_tbl[] = {
  711. { "esc_2253", ASN1_STRFLGS_ESC_2253, 0},
  712. { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
  713. { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
  714. { "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
  715. { "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
  716. { "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
  717. { "show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
  718. { "dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
  719. { "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
  720. { "dump_der", ASN1_STRFLGS_DUMP_DER, 0},
  721. { "compat", XN_FLAG_COMPAT, 0xffffffffL},
  722. { "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
  723. { "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
  724. { "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
  725. { "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
  726. { "dn_rev", XN_FLAG_DN_REV, 0},
  727. { "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
  728. { "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
  729. { "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
  730. { "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
  731. { "space_eq", XN_FLAG_SPC_EQ, 0},
  732. { "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
  733. { "RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
  734. { "oneline", XN_FLAG_ONELINE, 0xffffffffL},
  735. { "multiline", XN_FLAG_MULTILINE, 0xffffffffL},
  736. { NULL, 0, 0}
  737. };
  738. return set_table_opts(flags, arg, ex_tbl);
  739. }
  740. static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
  741. {
  742. char c;
  743. const NAME_EX_TBL *ptbl;
  744. c = arg[0];
  745. if(c == '-') {
  746. c = 0;
  747. arg++;
  748. } else if (c == '+') {
  749. c = 1;
  750. arg++;
  751. } else c = 1;
  752. for(ptbl = in_tbl; ptbl->name; ptbl++) {
  753. if(!strcasecmp(arg, ptbl->name)) {
  754. *flags &= ~ptbl->mask;
  755. if(c) *flags |= ptbl->flag;
  756. else *flags &= ~ptbl->flag;
  757. return 1;
  758. }
  759. }
  760. return 0;
  761. }
  762. void print_name(BIO *out, char *title, X509_NAME *nm, unsigned long lflags)
  763. {
  764. char buf[256];
  765. char mline = 0;
  766. int indent = 0;
  767. if(title) BIO_puts(out, title);
  768. if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
  769. mline = 1;
  770. indent = 4;
  771. }
  772. if(lflags == XN_FLAG_COMPAT) {
  773. X509_NAME_oneline(nm,buf,256);
  774. BIO_puts(out,buf);
  775. BIO_puts(out, "\n");
  776. } else {
  777. if(mline) BIO_puts(out, "\n");
  778. X509_NAME_print_ex(out, nm, indent, lflags);
  779. BIO_puts(out, "\n");
  780. }
  781. }
  782. X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
  783. {
  784. X509_STORE *store;
  785. X509_LOOKUP *lookup;
  786. if(!(store = X509_STORE_new())) goto end;
  787. lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
  788. if (lookup == NULL) goto end;
  789. if (CAfile) {
  790. if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) {
  791. BIO_printf(bp, "Error loading file %s\n", CAfile);
  792. goto end;
  793. }
  794. } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
  795. lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
  796. if (lookup == NULL) goto end;
  797. if (CApath) {
  798. if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) {
  799. BIO_printf(bp, "Error loading directory %s\n", CApath);
  800. goto end;
  801. }
  802. } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
  803. ERR_clear_error();
  804. return store;
  805. end:
  806. X509_STORE_free(store);
  807. return NULL;
  808. }