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