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