apps.c revision 279264
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#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
113#define _POSIX_C_SOURCE 2	/* On VMS, you need to define this to get
114				   the declaration of fileno().  The value
115				   2 is to make sure no function defined
116				   in POSIX-2 is left undefined. */
117#endif
118#include <stdio.h>
119#include <stdlib.h>
120#include <string.h>
121#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB)
122#include <strings.h>
123#endif
124#include <sys/types.h>
125#include <ctype.h>
126#include <errno.h>
127#include <assert.h>
128#include <openssl/err.h>
129#include <openssl/x509.h>
130#include <openssl/x509v3.h>
131#include <openssl/pem.h>
132#include <openssl/pkcs12.h>
133#include <openssl/ui.h>
134#include <openssl/safestack.h>
135#ifndef OPENSSL_NO_ENGINE
136#include <openssl/engine.h>
137#endif
138#ifndef OPENSSL_NO_RSA
139#include <openssl/rsa.h>
140#endif
141#include <openssl/bn.h>
142#ifndef OPENSSL_NO_JPAKE
143#include <openssl/jpake.h>
144#endif
145
146#define NON_MAIN
147#include "apps.h"
148#undef NON_MAIN
149
150#ifdef _WIN32
151static int WIN32_rename(const char *from, const char *to);
152#define rename(from,to) WIN32_rename((from),(to))
153#endif
154
155typedef struct {
156	const char *name;
157	unsigned long flag;
158	unsigned long mask;
159} NAME_EX_TBL;
160
161static UI_METHOD *ui_method = NULL;
162
163static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
164static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
165
166#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
167/* Looks like this stuff is worth moving into separate function */
168static EVP_PKEY *
169load_netscape_key(BIO *err, BIO *key, const char *file,
170		const char *key_descrip, int format);
171#endif
172
173int app_init(long mesgwin);
174#ifdef undef /* never finished - probably never will be :-) */
175int args_from_file(char *file, int *argc, char **argv[])
176	{
177	FILE *fp;
178	int num,i;
179	unsigned int len;
180	static char *buf=NULL;
181	static char **arg=NULL;
182	char *p;
183
184	fp=fopen(file,"r");
185	if (fp == NULL)
186		return(0);
187
188	if (fseek(fp,0,SEEK_END)==0)
189		len=ftell(fp), rewind(fp);
190	else	len=-1;
191	if (len<=0)
192		{
193		fclose(fp);
194		return(0);
195		}
196
197	*argc=0;
198	*argv=NULL;
199
200	if (buf != NULL) OPENSSL_free(buf);
201	buf=(char *)OPENSSL_malloc(len+1);
202	if (buf == NULL) return(0);
203
204	len=fread(buf,1,len,fp);
205	if (len <= 1) return(0);
206	buf[len]='\0';
207
208	i=0;
209	for (p=buf; *p; p++)
210		if (*p == '\n') i++;
211	if (arg != NULL) OPENSSL_free(arg);
212	arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2));
213
214	*argv=arg;
215	num=0;
216	p=buf;
217	for (;;)
218		{
219		if (!*p) break;
220		if (*p == '#') /* comment line */
221			{
222			while (*p && (*p != '\n')) p++;
223			continue;
224			}
225		/* else we have a line */
226		*(arg++)=p;
227		num++;
228		while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
229			p++;
230		if (!*p) break;
231		if (*p == '\n')
232			{
233			*(p++)='\0';
234			continue;
235			}
236		/* else it is a tab or space */
237		p++;
238		while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
239			p++;
240		if (!*p) break;
241		if (*p == '\n')
242			{
243			p++;
244			continue;
245			}
246		*(arg++)=p++;
247		num++;
248		while (*p && (*p != '\n')) p++;
249		if (!*p) break;
250		/* else *p == '\n' */
251		*(p++)='\0';
252		}
253	*argc=num;
254	return(1);
255	}
256#endif
257
258int str2fmt(char *s)
259	{
260	if (s == NULL)
261		return FORMAT_UNDEF;
262	if 	((*s == 'D') || (*s == 'd'))
263		return(FORMAT_ASN1);
264	else if ((*s == 'T') || (*s == 't'))
265		return(FORMAT_TEXT);
266  	else if ((*s == 'N') || (*s == 'n'))
267  		return(FORMAT_NETSCAPE);
268  	else if ((*s == 'S') || (*s == 's'))
269  		return(FORMAT_SMIME);
270 	else if ((*s == 'M') || (*s == 'm'))
271 		return(FORMAT_MSBLOB);
272	else if ((*s == '1')
273		|| (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
274		|| (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
275		return(FORMAT_PKCS12);
276	else if ((*s == 'E') || (*s == 'e'))
277		return(FORMAT_ENGINE);
278	else if ((*s == 'P') || (*s == 'p'))
279 		{
280 		if (s[1] == 'V' || s[1] == 'v')
281 			return FORMAT_PVK;
282 		else
283  			return(FORMAT_PEM);
284 		}
285	else
286		return(FORMAT_UNDEF);
287	}
288
289#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
290void program_name(char *in, char *out, int size)
291	{
292	int i,n;
293	char *p=NULL;
294
295	n=strlen(in);
296	/* find the last '/', '\' or ':' */
297	for (i=n-1; i>0; i--)
298		{
299		if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':'))
300			{
301			p= &(in[i+1]);
302			break;
303			}
304		}
305	if (p == NULL)
306		p=in;
307	n=strlen(p);
308
309#if defined(OPENSSL_SYS_NETWARE)
310   /* strip off trailing .nlm if present. */
311   if ((n > 4) && (p[n-4] == '.') &&
312      ((p[n-3] == 'n') || (p[n-3] == 'N')) &&
313      ((p[n-2] == 'l') || (p[n-2] == 'L')) &&
314      ((p[n-1] == 'm') || (p[n-1] == 'M')))
315      n-=4;
316#else
317	/* strip off trailing .exe if present. */
318	if ((n > 4) && (p[n-4] == '.') &&
319		((p[n-3] == 'e') || (p[n-3] == 'E')) &&
320		((p[n-2] == 'x') || (p[n-2] == 'X')) &&
321		((p[n-1] == 'e') || (p[n-1] == 'E')))
322		n-=4;
323#endif
324
325	if (n > size-1)
326		n=size-1;
327
328	for (i=0; i<n; i++)
329		{
330		if ((p[i] >= 'A') && (p[i] <= 'Z'))
331			out[i]=p[i]-'A'+'a';
332		else
333			out[i]=p[i];
334		}
335	out[n]='\0';
336	}
337#else
338#ifdef OPENSSL_SYS_VMS
339void program_name(char *in, char *out, int size)
340	{
341	char *p=in, *q;
342	char *chars=":]>";
343
344	while(*chars != '\0')
345		{
346		q=strrchr(p,*chars);
347		if (q > p)
348			p = q + 1;
349		chars++;
350		}
351
352	q=strrchr(p,'.');
353	if (q == NULL)
354		q = p + strlen(p);
355	strncpy(out,p,size-1);
356	if (q-p >= size)
357		{
358		out[size-1]='\0';
359		}
360	else
361		{
362		out[q-p]='\0';
363		}
364	}
365#else
366void program_name(char *in, char *out, int size)
367	{
368	char *p;
369
370	p=strrchr(in,'/');
371	if (p != NULL)
372		p++;
373	else
374		p=in;
375	BUF_strlcpy(out,p,size);
376	}
377#endif
378#endif
379
380int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
381	{
382	int num,i;
383	char *p;
384
385	*argc=0;
386	*argv=NULL;
387
388	i=0;
389	if (arg->count == 0)
390		{
391		arg->count=20;
392		arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count);
393		if (arg->data == NULL)
394			return 0;
395		}
396	for (i=0; i<arg->count; i++)
397		arg->data[i]=NULL;
398
399	num=0;
400	p=buf;
401	for (;;)
402		{
403		/* first scan over white space */
404		if (!*p) break;
405		while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
406			p++;
407		if (!*p) break;
408
409		/* The start of something good :-) */
410		if (num >= arg->count)
411			{
412			char **tmp_p;
413			int tlen = arg->count + 20;
414			tmp_p = (char **)OPENSSL_realloc(arg->data,
415				sizeof(char *)*tlen);
416			if (tmp_p == NULL)
417				return 0;
418			arg->data  = tmp_p;
419			arg->count = tlen;
420			/* initialize newly allocated data */
421			for (i = num; i < arg->count; i++)
422				arg->data[i] = NULL;
423			}
424		arg->data[num++]=p;
425
426		/* now look for the end of this */
427		if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */
428			{
429			i= *(p++);
430			arg->data[num-1]++; /* jump over quote */
431			while (*p && (*p != i))
432				p++;
433			*p='\0';
434			}
435		else
436			{
437			while (*p && ((*p != ' ') &&
438				(*p != '\t') && (*p != '\n')))
439				p++;
440
441			if (*p == '\0')
442				p--;
443			else
444				*p='\0';
445			}
446		p++;
447		}
448	*argc=num;
449	*argv=arg->data;
450	return(1);
451	}
452
453#ifndef APP_INIT
454int app_init(long mesgwin)
455	{
456	return(1);
457	}
458#endif
459
460
461int dump_cert_text (BIO *out, X509 *x)
462{
463	char *p;
464
465	p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0);
466	BIO_puts(out,"subject=");
467	BIO_puts(out,p);
468	OPENSSL_free(p);
469
470	p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0);
471	BIO_puts(out,"\nissuer=");
472	BIO_puts(out,p);
473	BIO_puts(out,"\n");
474	OPENSSL_free(p);
475
476	return 0;
477}
478
479static int ui_open(UI *ui)
480	{
481	return UI_method_get_opener(UI_OpenSSL())(ui);
482	}
483static int ui_read(UI *ui, UI_STRING *uis)
484	{
485	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
486		&& UI_get0_user_data(ui))
487		{
488		switch(UI_get_string_type(uis))
489			{
490		case UIT_PROMPT:
491		case UIT_VERIFY:
492			{
493			const char *password =
494				((PW_CB_DATA *)UI_get0_user_data(ui))->password;
495			if (password && password[0] != '\0')
496				{
497				UI_set_result(ui, uis, password);
498				return 1;
499				}
500			}
501		default:
502			break;
503			}
504		}
505	return UI_method_get_reader(UI_OpenSSL())(ui, uis);
506	}
507static int ui_write(UI *ui, UI_STRING *uis)
508	{
509	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
510		&& UI_get0_user_data(ui))
511		{
512		switch(UI_get_string_type(uis))
513			{
514		case UIT_PROMPT:
515		case UIT_VERIFY:
516			{
517			const char *password =
518				((PW_CB_DATA *)UI_get0_user_data(ui))->password;
519			if (password && password[0] != '\0')
520				return 1;
521			}
522		default:
523			break;
524			}
525		}
526	return UI_method_get_writer(UI_OpenSSL())(ui, uis);
527	}
528static int ui_close(UI *ui)
529	{
530	return UI_method_get_closer(UI_OpenSSL())(ui);
531	}
532int setup_ui_method(void)
533	{
534	ui_method = UI_create_method("OpenSSL application user interface");
535	UI_method_set_opener(ui_method, ui_open);
536	UI_method_set_reader(ui_method, ui_read);
537	UI_method_set_writer(ui_method, ui_write);
538	UI_method_set_closer(ui_method, ui_close);
539	return 0;
540	}
541void destroy_ui_method(void)
542	{
543	if(ui_method)
544		{
545		UI_destroy_method(ui_method);
546		ui_method = NULL;
547		}
548	}
549int password_callback(char *buf, int bufsiz, int verify,
550	PW_CB_DATA *cb_tmp)
551	{
552	UI *ui = NULL;
553	int res = 0;
554	const char *prompt_info = NULL;
555	const char *password = NULL;
556	PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
557
558	if (cb_data)
559		{
560		if (cb_data->password)
561			password = cb_data->password;
562		if (cb_data->prompt_info)
563			prompt_info = cb_data->prompt_info;
564		}
565
566	if (password)
567		{
568		res = strlen(password);
569		if (res > bufsiz)
570			res = bufsiz;
571		memcpy(buf, password, res);
572		return res;
573		}
574
575	ui = UI_new_method(ui_method);
576	if (ui)
577		{
578		int ok = 0;
579		char *buff = NULL;
580		int ui_flags = 0;
581		char *prompt = NULL;
582
583		prompt = UI_construct_prompt(ui, "pass phrase",
584			prompt_info);
585
586		ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
587		UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
588
589		if (ok >= 0)
590			ok = UI_add_input_string(ui,prompt,ui_flags,buf,
591				PW_MIN_LENGTH,bufsiz-1);
592		if (ok >= 0 && verify)
593			{
594			buff = (char *)OPENSSL_malloc(bufsiz);
595			ok = UI_add_verify_string(ui,prompt,ui_flags,buff,
596				PW_MIN_LENGTH,bufsiz-1, buf);
597			}
598		if (ok >= 0)
599			do
600				{
601				ok = UI_process(ui);
602				}
603			while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
604
605		if (buff)
606			{
607			OPENSSL_cleanse(buff,(unsigned int)bufsiz);
608			OPENSSL_free(buff);
609			}
610
611		if (ok >= 0)
612			res = strlen(buf);
613		if (ok == -1)
614			{
615			BIO_printf(bio_err, "User interface error\n");
616			ERR_print_errors(bio_err);
617			OPENSSL_cleanse(buf,(unsigned int)bufsiz);
618			res = 0;
619			}
620		if (ok == -2)
621			{
622			BIO_printf(bio_err,"aborted!\n");
623			OPENSSL_cleanse(buf,(unsigned int)bufsiz);
624			res = 0;
625			}
626		UI_free(ui);
627		OPENSSL_free(prompt);
628		}
629	return res;
630	}
631
632static char *app_get_pass(BIO *err, char *arg, int keepbio);
633
634int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
635{
636	int same;
637	if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0;
638	else same = 1;
639	if(arg1) {
640		*pass1 = app_get_pass(err, arg1, same);
641		if(!*pass1) return 0;
642	} else if(pass1) *pass1 = NULL;
643	if(arg2) {
644		*pass2 = app_get_pass(err, arg2, same ? 2 : 0);
645		if(!*pass2) return 0;
646	} else if(pass2) *pass2 = NULL;
647	return 1;
648}
649
650static char *app_get_pass(BIO *err, char *arg, int keepbio)
651{
652	char *tmp, tpass[APP_PASS_LEN];
653	static BIO *pwdbio = NULL;
654	int i;
655	if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5);
656	if(!strncmp(arg, "env:", 4)) {
657		tmp = getenv(arg + 4);
658		if(!tmp) {
659			BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
660			return NULL;
661		}
662		return BUF_strdup(tmp);
663	}
664	if(!keepbio || !pwdbio) {
665		if(!strncmp(arg, "file:", 5)) {
666			pwdbio = BIO_new_file(arg + 5, "r");
667			if(!pwdbio) {
668				BIO_printf(err, "Can't open file %s\n", arg + 5);
669				return NULL;
670			}
671#if !defined(_WIN32)
672		/*
673		 * Under _WIN32, which covers even Win64 and CE, file
674		 * descriptors referenced by BIO_s_fd are not inherited
675		 * by child process and therefore below is not an option.
676		 * It could have been an option if bss_fd.c was operating
677		 * on real Windows descriptors, such as those obtained
678		 * with CreateFile.
679		 */
680		} else if(!strncmp(arg, "fd:", 3)) {
681			BIO *btmp;
682			i = atoi(arg + 3);
683			if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
684			if((i < 0) || !pwdbio) {
685				BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
686				return NULL;
687			}
688			/* Can't do BIO_gets on an fd BIO so add a buffering BIO */
689			btmp = BIO_new(BIO_f_buffer());
690			pwdbio = BIO_push(btmp, pwdbio);
691#endif
692		} else if(!strcmp(arg, "stdin")) {
693			pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
694			if(!pwdbio) {
695				BIO_printf(err, "Can't open BIO for stdin\n");
696				return NULL;
697			}
698		} else {
699			BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
700			return NULL;
701		}
702	}
703	i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
704	if(keepbio != 1) {
705		BIO_free_all(pwdbio);
706		pwdbio = NULL;
707	}
708	if(i <= 0) {
709		BIO_printf(err, "Error reading password from BIO\n");
710		return NULL;
711	}
712	tmp = strchr(tpass, '\n');
713	if(tmp) *tmp = 0;
714	return BUF_strdup(tpass);
715}
716
717int add_oid_section(BIO *err, CONF *conf)
718{
719	char *p;
720	STACK_OF(CONF_VALUE) *sktmp;
721	CONF_VALUE *cnf;
722	int i;
723	if(!(p=NCONF_get_string(conf,NULL,"oid_section")))
724		{
725		ERR_clear_error();
726		return 1;
727		}
728	if(!(sktmp = NCONF_get_section(conf, p))) {
729		BIO_printf(err, "problem loading oid section %s\n", p);
730		return 0;
731	}
732	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
733		cnf = sk_CONF_VALUE_value(sktmp, i);
734		if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
735			BIO_printf(err, "problem creating object %s=%s\n",
736							 cnf->name, cnf->value);
737			return 0;
738		}
739	}
740	return 1;
741}
742
743static int load_pkcs12(BIO *err, BIO *in, const char *desc,
744		pem_password_cb *pem_cb,  void *cb_data,
745		EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
746	{
747 	const char *pass;
748	char tpass[PEM_BUFSIZE];
749	int len, ret = 0;
750	PKCS12 *p12;
751	p12 = d2i_PKCS12_bio(in, NULL);
752	if (p12 == NULL)
753		{
754		BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
755		goto die;
756		}
757	/* See if an empty password will do */
758	if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
759		pass = "";
760	else
761		{
762		if (!pem_cb)
763			pem_cb = (pem_password_cb *)password_callback;
764		len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
765		if (len < 0)
766			{
767			BIO_printf(err, "Passpharse callback error for %s\n",
768					desc);
769			goto die;
770			}
771		if (len < PEM_BUFSIZE)
772			tpass[len] = 0;
773		if (!PKCS12_verify_mac(p12, tpass, len))
774			{
775			BIO_printf(err,
776	"Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);
777			goto die;
778			}
779		pass = tpass;
780		}
781	ret = PKCS12_parse(p12, pass, pkey, cert, ca);
782	die:
783	if (p12)
784		PKCS12_free(p12);
785	return ret;
786	}
787
788X509 *load_cert(BIO *err, const char *file, int format,
789	const char *pass, ENGINE *e, const char *cert_descrip)
790	{
791	X509 *x=NULL;
792	BIO *cert;
793
794	if ((cert=BIO_new(BIO_s_file())) == NULL)
795		{
796		ERR_print_errors(err);
797		goto end;
798		}
799
800	if (file == NULL)
801		{
802#ifdef _IONBF
803# ifndef OPENSSL_NO_SETVBUF_IONBF
804		setvbuf(stdin, NULL, _IONBF, 0);
805# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
806#endif
807		BIO_set_fp(cert,stdin,BIO_NOCLOSE);
808		}
809	else
810		{
811		if (BIO_read_filename(cert,file) <= 0)
812			{
813			BIO_printf(err, "Error opening %s %s\n",
814				cert_descrip, file);
815			ERR_print_errors(err);
816			goto end;
817			}
818		}
819
820	if 	(format == FORMAT_ASN1)
821		x=d2i_X509_bio(cert,NULL);
822	else if (format == FORMAT_NETSCAPE)
823		{
824		NETSCAPE_X509 *nx;
825		nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL);
826		if (nx == NULL)
827				goto end;
828
829		if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data,
830			nx->header->length) != 0))
831			{
832			NETSCAPE_X509_free(nx);
833			BIO_printf(err,"Error reading header on certificate\n");
834			goto end;
835			}
836		x=nx->cert;
837		nx->cert = NULL;
838		NETSCAPE_X509_free(nx);
839		}
840	else if (format == FORMAT_PEM)
841		x=PEM_read_bio_X509_AUX(cert,NULL,
842			(pem_password_cb *)password_callback, NULL);
843	else if (format == FORMAT_PKCS12)
844		{
845		if (!load_pkcs12(err, cert,cert_descrip, NULL, NULL,
846					NULL, &x, NULL))
847			goto end;
848		}
849	else	{
850		BIO_printf(err,"bad input format specified for %s\n",
851			cert_descrip);
852		goto end;
853		}
854end:
855	if (x == NULL)
856		{
857		BIO_printf(err,"unable to load certificate\n");
858		ERR_print_errors(err);
859		}
860	if (cert != NULL) BIO_free(cert);
861	return(x);
862	}
863
864EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
865	const char *pass, ENGINE *e, const char *key_descrip)
866	{
867	BIO *key=NULL;
868	EVP_PKEY *pkey=NULL;
869	PW_CB_DATA cb_data;
870
871	cb_data.password = pass;
872	cb_data.prompt_info = file;
873
874	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
875		{
876		BIO_printf(err,"no keyfile specified\n");
877		goto end;
878		}
879#ifndef OPENSSL_NO_ENGINE
880	if (format == FORMAT_ENGINE)
881		{
882		if (!e)
883			BIO_printf(err,"no engine specified\n");
884		else
885			{
886			pkey = ENGINE_load_private_key(e, file,
887				ui_method, &cb_data);
888			if (!pkey)
889				{
890				BIO_printf(err,"cannot load %s from engine\n",key_descrip);
891				ERR_print_errors(err);
892				}
893			}
894		goto end;
895		}
896#endif
897	key=BIO_new(BIO_s_file());
898	if (key == NULL)
899		{
900		ERR_print_errors(err);
901		goto end;
902		}
903	if (file == NULL && maybe_stdin)
904		{
905#ifdef _IONBF
906# ifndef OPENSSL_NO_SETVBUF_IONBF
907		setvbuf(stdin, NULL, _IONBF, 0);
908# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
909#endif
910		BIO_set_fp(key,stdin,BIO_NOCLOSE);
911		}
912	else
913		if (BIO_read_filename(key,file) <= 0)
914			{
915			BIO_printf(err, "Error opening %s %s\n",
916				key_descrip, file);
917			ERR_print_errors(err);
918			goto end;
919			}
920	if (format == FORMAT_ASN1)
921		{
922		pkey=d2i_PrivateKey_bio(key, NULL);
923		}
924	else if (format == FORMAT_PEM)
925		{
926		pkey=PEM_read_bio_PrivateKey(key,NULL,
927			(pem_password_cb *)password_callback, &cb_data);
928		}
929#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
930	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
931		pkey = load_netscape_key(err, key, file, key_descrip, format);
932#endif
933	else if (format == FORMAT_PKCS12)
934		{
935		if (!load_pkcs12(err, key, key_descrip,
936				(pem_password_cb *)password_callback, &cb_data,
937				&pkey, NULL, NULL))
938			goto end;
939		}
940#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
941	else if (format == FORMAT_MSBLOB)
942		pkey = b2i_PrivateKey_bio(key);
943	else if (format == FORMAT_PVK)
944		pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
945								&cb_data);
946#endif
947	else
948		{
949		BIO_printf(err,"bad input format specified for key file\n");
950		goto end;
951		}
952 end:
953	if (key != NULL) BIO_free(key);
954	if (pkey == NULL)
955		{
956		BIO_printf(err,"unable to load %s\n", key_descrip);
957		ERR_print_errors(err);
958		}
959	return(pkey);
960	}
961
962EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
963	const char *pass, ENGINE *e, const char *key_descrip)
964	{
965	BIO *key=NULL;
966	EVP_PKEY *pkey=NULL;
967	PW_CB_DATA cb_data;
968
969	cb_data.password = pass;
970	cb_data.prompt_info = file;
971
972	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
973		{
974		BIO_printf(err,"no keyfile specified\n");
975		goto end;
976		}
977#ifndef OPENSSL_NO_ENGINE
978	if (format == FORMAT_ENGINE)
979		{
980		if (!e)
981			BIO_printf(bio_err,"no engine specified\n");
982		else
983			pkey = ENGINE_load_public_key(e, file,
984				ui_method, &cb_data);
985		goto end;
986		}
987#endif
988	key=BIO_new(BIO_s_file());
989	if (key == NULL)
990		{
991		ERR_print_errors(err);
992		goto end;
993		}
994	if (file == NULL && maybe_stdin)
995		{
996#ifdef _IONBF
997# ifndef OPENSSL_NO_SETVBUF_IONBF
998		setvbuf(stdin, NULL, _IONBF, 0);
999# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
1000#endif
1001		BIO_set_fp(key,stdin,BIO_NOCLOSE);
1002		}
1003	else
1004		if (BIO_read_filename(key,file) <= 0)
1005			{
1006			BIO_printf(err, "Error opening %s %s\n",
1007				key_descrip, file);
1008			ERR_print_errors(err);
1009			goto end;
1010		}
1011	if (format == FORMAT_ASN1)
1012		{
1013		pkey=d2i_PUBKEY_bio(key, NULL);
1014		}
1015#ifndef OPENSSL_NO_RSA
1016	else if (format == FORMAT_ASN1RSA)
1017		{
1018		RSA *rsa;
1019		rsa = d2i_RSAPublicKey_bio(key, NULL);
1020		if (rsa)
1021			{
1022			pkey = EVP_PKEY_new();
1023			if (pkey)
1024				EVP_PKEY_set1_RSA(pkey, rsa);
1025			RSA_free(rsa);
1026			}
1027		else
1028			pkey = NULL;
1029		}
1030	else if (format == FORMAT_PEMRSA)
1031		{
1032		RSA *rsa;
1033		rsa = PEM_read_bio_RSAPublicKey(key, NULL,
1034			(pem_password_cb *)password_callback, &cb_data);
1035		if (rsa)
1036			{
1037			pkey = EVP_PKEY_new();
1038			if (pkey)
1039				EVP_PKEY_set1_RSA(pkey, rsa);
1040			RSA_free(rsa);
1041			}
1042		else
1043			pkey = NULL;
1044		}
1045#endif
1046	else if (format == FORMAT_PEM)
1047		{
1048		pkey=PEM_read_bio_PUBKEY(key,NULL,
1049			(pem_password_cb *)password_callback, &cb_data);
1050		}
1051#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
1052	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
1053		pkey = load_netscape_key(err, key, file, key_descrip, format);
1054#endif
1055#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
1056	else if (format == FORMAT_MSBLOB)
1057		pkey = b2i_PublicKey_bio(key);
1058#endif
1059	else
1060		{
1061		BIO_printf(err,"bad input format specified for key file\n");
1062		goto end;
1063		}
1064 end:
1065	if (key != NULL) BIO_free(key);
1066	if (pkey == NULL)
1067		BIO_printf(err,"unable to load %s\n", key_descrip);
1068	return(pkey);
1069	}
1070
1071#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
1072static EVP_PKEY *
1073load_netscape_key(BIO *err, BIO *key, const char *file,
1074		const char *key_descrip, int format)
1075	{
1076	EVP_PKEY *pkey;
1077	BUF_MEM *buf;
1078	RSA	*rsa;
1079	const unsigned char *p;
1080	int size, i;
1081
1082	buf=BUF_MEM_new();
1083	pkey = EVP_PKEY_new();
1084	size = 0;
1085	if (buf == NULL || pkey == NULL)
1086		goto error;
1087	for (;;)
1088		{
1089		if (!BUF_MEM_grow_clean(buf,size+1024*10))
1090			goto error;
1091		i = BIO_read(key, &(buf->data[size]), 1024*10);
1092		size += i;
1093		if (i == 0)
1094			break;
1095		if (i < 0)
1096			{
1097				BIO_printf(err, "Error reading %s %s",
1098					key_descrip, file);
1099				goto error;
1100			}
1101		}
1102	p=(unsigned char *)buf->data;
1103	rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL,
1104		(format == FORMAT_IISSGC ? 1 : 0));
1105	if (rsa == NULL)
1106		goto error;
1107	BUF_MEM_free(buf);
1108	EVP_PKEY_set1_RSA(pkey, rsa);
1109	return pkey;
1110error:
1111	BUF_MEM_free(buf);
1112	EVP_PKEY_free(pkey);
1113	return NULL;
1114	}
1115#endif /* ndef OPENSSL_NO_RC4 */
1116
1117static int load_certs_crls(BIO *err, const char *file, int format,
1118	const char *pass, ENGINE *e, const char *desc,
1119	STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls)
1120	{
1121	int i;
1122	BIO *bio;
1123	STACK_OF(X509_INFO) *xis = NULL;
1124	X509_INFO *xi;
1125	PW_CB_DATA cb_data;
1126	int rv = 0;
1127
1128	cb_data.password = pass;
1129	cb_data.prompt_info = file;
1130
1131	if (format != FORMAT_PEM)
1132		{
1133		BIO_printf(err,"bad input format specified for %s\n", desc);
1134		return 0;
1135		}
1136
1137	if (file == NULL)
1138		bio = BIO_new_fp(stdin,BIO_NOCLOSE);
1139	else
1140		bio = BIO_new_file(file, "r");
1141
1142	if (bio == NULL)
1143		{
1144		BIO_printf(err, "Error opening %s %s\n",
1145				desc, file ? file : "stdin");
1146		ERR_print_errors(err);
1147		return 0;
1148		}
1149
1150	xis = PEM_X509_INFO_read_bio(bio, NULL,
1151				(pem_password_cb *)password_callback, &cb_data);
1152
1153	BIO_free(bio);
1154
1155	if (pcerts)
1156		{
1157		*pcerts = sk_X509_new_null();
1158		if (!*pcerts)
1159			goto end;
1160		}
1161
1162	if (pcrls)
1163		{
1164		*pcrls = sk_X509_CRL_new_null();
1165		if (!*pcrls)
1166			goto end;
1167		}
1168
1169	for(i = 0; i < sk_X509_INFO_num(xis); i++)
1170		{
1171		xi = sk_X509_INFO_value (xis, i);
1172		if (xi->x509 && pcerts)
1173			{
1174			if (!sk_X509_push(*pcerts, xi->x509))
1175				goto end;
1176			xi->x509 = NULL;
1177			}
1178		if (xi->crl && pcrls)
1179			{
1180			if (!sk_X509_CRL_push(*pcrls, xi->crl))
1181				goto end;
1182			xi->crl = NULL;
1183			}
1184		}
1185
1186	if (pcerts && sk_X509_num(*pcerts) > 0)
1187		rv = 1;
1188
1189	if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
1190		rv = 1;
1191
1192	end:
1193
1194	if (xis)
1195		sk_X509_INFO_pop_free(xis, X509_INFO_free);
1196
1197	if (rv == 0)
1198		{
1199		if (pcerts)
1200			{
1201			sk_X509_pop_free(*pcerts, X509_free);
1202			*pcerts = NULL;
1203			}
1204		if (pcrls)
1205			{
1206			sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
1207			*pcrls = NULL;
1208			}
1209		BIO_printf(err,"unable to load %s\n",
1210				pcerts ? "certificates" : "CRLs");
1211		ERR_print_errors(err);
1212		}
1213	return rv;
1214	}
1215
1216STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
1217	const char *pass, ENGINE *e, const char *desc)
1218	{
1219	STACK_OF(X509) *certs;
1220	if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL))
1221		return NULL;
1222	return certs;
1223	}
1224
1225STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
1226	const char *pass, ENGINE *e, const char *desc)
1227	{
1228	STACK_OF(X509_CRL) *crls;
1229	if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls))
1230		return NULL;
1231	return crls;
1232	}
1233
1234#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
1235/* Return error for unknown extensions */
1236#define X509V3_EXT_DEFAULT		0
1237/* Print error for unknown extensions */
1238#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
1239/* ASN1 parse unknown extensions */
1240#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
1241/* BIO_dump unknown extensions */
1242#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
1243
1244#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
1245			 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
1246
1247int set_cert_ex(unsigned long *flags, const char *arg)
1248{
1249	static const NAME_EX_TBL cert_tbl[] = {
1250		{ "compatible", X509_FLAG_COMPAT, 0xffffffffl},
1251		{ "ca_default", X509_FLAG_CA, 0xffffffffl},
1252		{ "no_header", X509_FLAG_NO_HEADER, 0},
1253		{ "no_version", X509_FLAG_NO_VERSION, 0},
1254		{ "no_serial", X509_FLAG_NO_SERIAL, 0},
1255		{ "no_signame", X509_FLAG_NO_SIGNAME, 0},
1256		{ "no_validity", X509_FLAG_NO_VALIDITY, 0},
1257		{ "no_subject", X509_FLAG_NO_SUBJECT, 0},
1258		{ "no_issuer", X509_FLAG_NO_ISSUER, 0},
1259		{ "no_pubkey", X509_FLAG_NO_PUBKEY, 0},
1260		{ "no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
1261		{ "no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
1262		{ "no_aux", X509_FLAG_NO_AUX, 0},
1263		{ "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
1264		{ "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
1265		{ "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1266		{ "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1267		{ "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1268		{ NULL, 0, 0}
1269	};
1270	return set_multi_opts(flags, arg, cert_tbl);
1271}
1272
1273int set_name_ex(unsigned long *flags, const char *arg)
1274{
1275	static const NAME_EX_TBL ex_tbl[] = {
1276		{ "esc_2253", ASN1_STRFLGS_ESC_2253, 0},
1277		{ "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
1278		{ "esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
1279		{ "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
1280		{ "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
1281		{ "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
1282		{ "show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
1283		{ "dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
1284		{ "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
1285		{ "dump_der", ASN1_STRFLGS_DUMP_DER, 0},
1286		{ "compat", XN_FLAG_COMPAT, 0xffffffffL},
1287		{ "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
1288		{ "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
1289		{ "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
1290		{ "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
1291		{ "dn_rev", XN_FLAG_DN_REV, 0},
1292		{ "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
1293		{ "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
1294		{ "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
1295		{ "align", XN_FLAG_FN_ALIGN, 0},
1296		{ "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
1297		{ "space_eq", XN_FLAG_SPC_EQ, 0},
1298		{ "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
1299		{ "RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
1300		{ "oneline", XN_FLAG_ONELINE, 0xffffffffL},
1301		{ "multiline", XN_FLAG_MULTILINE, 0xffffffffL},
1302		{ "ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
1303		{ NULL, 0, 0}
1304	};
1305	return set_multi_opts(flags, arg, ex_tbl);
1306}
1307
1308int set_ext_copy(int *copy_type, const char *arg)
1309{
1310	if (!strcasecmp(arg, "none"))
1311		*copy_type = EXT_COPY_NONE;
1312	else if (!strcasecmp(arg, "copy"))
1313		*copy_type = EXT_COPY_ADD;
1314	else if (!strcasecmp(arg, "copyall"))
1315		*copy_type = EXT_COPY_ALL;
1316	else
1317		return 0;
1318	return 1;
1319}
1320
1321int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
1322{
1323	STACK_OF(X509_EXTENSION) *exts = NULL;
1324	X509_EXTENSION *ext, *tmpext;
1325	ASN1_OBJECT *obj;
1326	int i, idx, ret = 0;
1327	if (!x || !req || (copy_type == EXT_COPY_NONE))
1328		return 1;
1329	exts = X509_REQ_get_extensions(req);
1330
1331	for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1332		ext = sk_X509_EXTENSION_value(exts, i);
1333		obj = X509_EXTENSION_get_object(ext);
1334		idx = X509_get_ext_by_OBJ(x, obj, -1);
1335		/* Does extension exist? */
1336		if (idx != -1) {
1337			/* If normal copy don't override existing extension */
1338			if (copy_type == EXT_COPY_ADD)
1339				continue;
1340			/* Delete all extensions of same type */
1341			do {
1342				tmpext = X509_get_ext(x, idx);
1343				X509_delete_ext(x, idx);
1344				X509_EXTENSION_free(tmpext);
1345				idx = X509_get_ext_by_OBJ(x, obj, -1);
1346			} while (idx != -1);
1347		}
1348		if (!X509_add_ext(x, ext, -1))
1349			goto end;
1350	}
1351
1352	ret = 1;
1353
1354	end:
1355
1356	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
1357
1358	return ret;
1359}
1360
1361
1362
1363
1364static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
1365{
1366	STACK_OF(CONF_VALUE) *vals;
1367	CONF_VALUE *val;
1368	int i, ret = 1;
1369	if(!arg) return 0;
1370	vals = X509V3_parse_list(arg);
1371	for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
1372		val = sk_CONF_VALUE_value(vals, i);
1373		if (!set_table_opts(flags, val->name, in_tbl))
1374			ret = 0;
1375	}
1376	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
1377	return ret;
1378}
1379
1380static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
1381{
1382	char c;
1383	const NAME_EX_TBL *ptbl;
1384	c = arg[0];
1385
1386	if(c == '-') {
1387		c = 0;
1388		arg++;
1389	} else if (c == '+') {
1390		c = 1;
1391		arg++;
1392	} else c = 1;
1393
1394	for(ptbl = in_tbl; ptbl->name; ptbl++) {
1395		if(!strcasecmp(arg, ptbl->name)) {
1396			*flags &= ~ptbl->mask;
1397			if(c) *flags |= ptbl->flag;
1398			else *flags &= ~ptbl->flag;
1399			return 1;
1400		}
1401	}
1402	return 0;
1403}
1404
1405void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
1406{
1407	char *buf;
1408	char mline = 0;
1409	int indent = 0;
1410
1411	if(title) BIO_puts(out, title);
1412	if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1413		mline = 1;
1414		indent = 4;
1415	}
1416	if(lflags == XN_FLAG_COMPAT) {
1417		buf = X509_NAME_oneline(nm, 0, 0);
1418		BIO_puts(out, buf);
1419		BIO_puts(out, "\n");
1420		OPENSSL_free(buf);
1421	} else {
1422		if(mline) BIO_puts(out, "\n");
1423		X509_NAME_print_ex(out, nm, indent, lflags);
1424		BIO_puts(out, "\n");
1425	}
1426}
1427
1428X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
1429{
1430	X509_STORE *store;
1431	X509_LOOKUP *lookup;
1432	if(!(store = X509_STORE_new())) goto end;
1433	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
1434	if (lookup == NULL) goto end;
1435	if (CAfile) {
1436		if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) {
1437			BIO_printf(bp, "Error loading file %s\n", CAfile);
1438			goto end;
1439		}
1440	} else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
1441
1442	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
1443	if (lookup == NULL) goto end;
1444	if (CApath) {
1445		if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) {
1446			BIO_printf(bp, "Error loading directory %s\n", CApath);
1447			goto end;
1448		}
1449	} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
1450
1451	ERR_clear_error();
1452	return store;
1453	end:
1454	X509_STORE_free(store);
1455	return NULL;
1456}
1457
1458#ifndef OPENSSL_NO_ENGINE
1459/* Try to load an engine in a shareable library */
1460static ENGINE *try_load_engine(BIO *err, const char *engine, int debug)
1461	{
1462	ENGINE *e = ENGINE_by_id("dynamic");
1463	if (e)
1464		{
1465		if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
1466			|| !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
1467			{
1468			ENGINE_free(e);
1469			e = NULL;
1470			}
1471		}
1472	return e;
1473	}
1474
1475ENGINE *setup_engine(BIO *err, const char *engine, int debug)
1476        {
1477        ENGINE *e = NULL;
1478
1479        if (engine)
1480                {
1481		if(strcmp(engine, "auto") == 0)
1482			{
1483			BIO_printf(err,"enabling auto ENGINE support\n");
1484			ENGINE_register_all_complete();
1485			return NULL;
1486			}
1487		if((e = ENGINE_by_id(engine)) == NULL
1488			&& (e = try_load_engine(err, engine, debug)) == NULL)
1489			{
1490			BIO_printf(err,"invalid engine \"%s\"\n", engine);
1491			ERR_print_errors(err);
1492			return NULL;
1493			}
1494		if (debug)
1495			{
1496			ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM,
1497				0, err, 0);
1498			}
1499                ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
1500		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
1501			{
1502			BIO_printf(err,"can't use that engine\n");
1503			ERR_print_errors(err);
1504			ENGINE_free(e);
1505			return NULL;
1506			}
1507
1508		BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e));
1509
1510		/* Free our "structural" reference. */
1511		ENGINE_free(e);
1512		}
1513        return e;
1514        }
1515#endif
1516
1517int load_config(BIO *err, CONF *cnf)
1518	{
1519	static int load_config_called = 0;
1520	if (load_config_called)
1521		return 1;
1522	load_config_called = 1;
1523	if (!cnf)
1524		cnf = config;
1525	if (!cnf)
1526		return 1;
1527
1528	OPENSSL_load_builtin_modules();
1529
1530	if (CONF_modules_load(cnf, NULL, 0) <= 0)
1531		{
1532		BIO_printf(err, "Error configuring OpenSSL\n");
1533		ERR_print_errors(err);
1534		return 0;
1535		}
1536	return 1;
1537	}
1538
1539char *make_config_name()
1540	{
1541	const char *t=X509_get_default_cert_area();
1542	size_t len;
1543	char *p;
1544
1545	len=strlen(t)+strlen(OPENSSL_CONF)+2;
1546	p=OPENSSL_malloc(len);
1547	if (p == NULL)
1548		return NULL;
1549	BUF_strlcpy(p,t,len);
1550#ifndef OPENSSL_SYS_VMS
1551	BUF_strlcat(p,"/",len);
1552#endif
1553	BUF_strlcat(p,OPENSSL_CONF,len);
1554
1555	return p;
1556	}
1557
1558static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
1559	{
1560	const char *n;
1561
1562	n=a[DB_serial];
1563	while (*n == '0') n++;
1564	return(lh_strhash(n));
1565	}
1566
1567static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1568	{
1569	const char *aa,*bb;
1570
1571	for (aa=a[DB_serial]; *aa == '0'; aa++);
1572	for (bb=b[DB_serial]; *bb == '0'; bb++);
1573	return(strcmp(aa,bb));
1574	}
1575
1576static int index_name_qual(char **a)
1577	{ return(a[0][0] == 'V'); }
1578
1579static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
1580	{ return(lh_strhash(a[DB_name])); }
1581
1582int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1583	{ return(strcmp(a[DB_name], b[DB_name])); }
1584
1585static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1586static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1587static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1588static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1589
1590#undef BSIZE
1591#define BSIZE 256
1592
1593BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
1594	{
1595	BIO *in=NULL;
1596	BIGNUM *ret=NULL;
1597	MS_STATIC char buf[1024];
1598	ASN1_INTEGER *ai=NULL;
1599
1600	ai=ASN1_INTEGER_new();
1601	if (ai == NULL) goto err;
1602
1603	if ((in=BIO_new(BIO_s_file())) == NULL)
1604		{
1605		ERR_print_errors(bio_err);
1606		goto err;
1607		}
1608
1609	if (BIO_read_filename(in,serialfile) <= 0)
1610		{
1611		if (!create)
1612			{
1613			perror(serialfile);
1614			goto err;
1615			}
1616		else
1617			{
1618			ret=BN_new();
1619			if (ret == NULL || !rand_serial(ret, ai))
1620				BIO_printf(bio_err, "Out of memory\n");
1621			}
1622		}
1623	else
1624		{
1625		if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1626			{
1627			BIO_printf(bio_err,"unable to load number from %s\n",
1628				serialfile);
1629			goto err;
1630			}
1631		ret=ASN1_INTEGER_to_BN(ai,NULL);
1632		if (ret == NULL)
1633			{
1634			BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
1635			goto err;
1636			}
1637		}
1638
1639	if (ret && retai)
1640		{
1641		*retai = ai;
1642		ai = NULL;
1643		}
1644 err:
1645	if (in != NULL) BIO_free(in);
1646	if (ai != NULL) ASN1_INTEGER_free(ai);
1647	return(ret);
1648	}
1649
1650int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai)
1651	{
1652	char buf[1][BSIZE];
1653	BIO *out = NULL;
1654	int ret=0;
1655	ASN1_INTEGER *ai=NULL;
1656	int j;
1657
1658	if (suffix == NULL)
1659		j = strlen(serialfile);
1660	else
1661		j = strlen(serialfile) + strlen(suffix) + 1;
1662	if (j >= BSIZE)
1663		{
1664		BIO_printf(bio_err,"file name too long\n");
1665		goto err;
1666		}
1667
1668	if (suffix == NULL)
1669		BUF_strlcpy(buf[0], serialfile, BSIZE);
1670	else
1671		{
1672#ifndef OPENSSL_SYS_VMS
1673		j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
1674#else
1675		j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
1676#endif
1677		}
1678#ifdef RL_DEBUG
1679	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
1680#endif
1681	out=BIO_new(BIO_s_file());
1682	if (out == NULL)
1683		{
1684		ERR_print_errors(bio_err);
1685		goto err;
1686		}
1687	if (BIO_write_filename(out,buf[0]) <= 0)
1688		{
1689		perror(serialfile);
1690		goto err;
1691		}
1692
1693	if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1694		{
1695		BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1696		goto err;
1697		}
1698	i2a_ASN1_INTEGER(out,ai);
1699	BIO_puts(out,"\n");
1700	ret=1;
1701	if (retai)
1702		{
1703		*retai = ai;
1704		ai = NULL;
1705		}
1706err:
1707	if (out != NULL) BIO_free_all(out);
1708	if (ai != NULL) ASN1_INTEGER_free(ai);
1709	return(ret);
1710	}
1711
1712int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
1713	{
1714	char buf[5][BSIZE];
1715	int i,j;
1716
1717	i = strlen(serialfile) + strlen(old_suffix);
1718	j = strlen(serialfile) + strlen(new_suffix);
1719	if (i > j) j = i;
1720	if (j + 1 >= BSIZE)
1721		{
1722		BIO_printf(bio_err,"file name too long\n");
1723		goto err;
1724		}
1725
1726#ifndef OPENSSL_SYS_VMS
1727	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
1728		serialfile, new_suffix);
1729#else
1730	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
1731		serialfile, new_suffix);
1732#endif
1733#ifndef OPENSSL_SYS_VMS
1734	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
1735		serialfile, old_suffix);
1736#else
1737	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
1738		serialfile, old_suffix);
1739#endif
1740#ifdef RL_DEBUG
1741	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
1742		serialfile, buf[1]);
1743#endif
1744	if (rename(serialfile,buf[1]) < 0 && errno != ENOENT
1745#ifdef ENOTDIR
1746			&& errno != ENOTDIR
1747#endif
1748	   )		{
1749			BIO_printf(bio_err,
1750				"unable to rename %s to %s\n",
1751				serialfile, buf[1]);
1752			perror("reason");
1753			goto err;
1754			}
1755#ifdef RL_DEBUG
1756	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
1757		buf[0],serialfile);
1758#endif
1759	if (rename(buf[0],serialfile) < 0)
1760		{
1761		BIO_printf(bio_err,
1762			"unable to rename %s to %s\n",
1763			buf[0],serialfile);
1764		perror("reason");
1765		rename(buf[1],serialfile);
1766		goto err;
1767		}
1768	return 1;
1769 err:
1770	return 0;
1771	}
1772
1773int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
1774	{
1775	BIGNUM *btmp;
1776	int ret = 0;
1777	if (b)
1778		btmp = b;
1779	else
1780		btmp = BN_new();
1781
1782	if (!btmp)
1783		return 0;
1784
1785	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
1786		goto error;
1787	if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1788		goto error;
1789
1790	ret = 1;
1791
1792	error:
1793
1794	if (!b)
1795		BN_free(btmp);
1796
1797	return ret;
1798	}
1799
1800CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
1801	{
1802	CA_DB *retdb = NULL;
1803	TXT_DB *tmpdb = NULL;
1804	BIO *in = BIO_new(BIO_s_file());
1805	CONF *dbattr_conf = NULL;
1806	char buf[1][BSIZE];
1807	long errorline= -1;
1808
1809	if (in == NULL)
1810		{
1811		ERR_print_errors(bio_err);
1812		goto err;
1813		}
1814	if (BIO_read_filename(in,dbfile) <= 0)
1815		{
1816		perror(dbfile);
1817		BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1818		goto err;
1819		}
1820	if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
1821		goto err;
1822
1823#ifndef OPENSSL_SYS_VMS
1824	BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
1825#else
1826	BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
1827#endif
1828	dbattr_conf = NCONF_new(NULL);
1829	if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0)
1830		{
1831		if (errorline > 0)
1832			{
1833			BIO_printf(bio_err,
1834				"error on line %ld of db attribute file '%s'\n"
1835				,errorline,buf[0]);
1836			goto err;
1837			}
1838		else
1839			{
1840			NCONF_free(dbattr_conf);
1841			dbattr_conf = NULL;
1842			}
1843		}
1844
1845	if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL)
1846		{
1847		fprintf(stderr, "Out of memory\n");
1848		goto err;
1849		}
1850
1851	retdb->db = tmpdb;
1852	tmpdb = NULL;
1853	if (db_attr)
1854		retdb->attributes = *db_attr;
1855	else
1856		{
1857		retdb->attributes.unique_subject = 1;
1858		}
1859
1860	if (dbattr_conf)
1861		{
1862		char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject");
1863		if (p)
1864			{
1865#ifdef RL_DEBUG
1866			BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
1867#endif
1868			retdb->attributes.unique_subject = parse_yesno(p,1);
1869			}
1870		}
1871
1872 err:
1873	if (dbattr_conf) NCONF_free(dbattr_conf);
1874	if (tmpdb) TXT_DB_free(tmpdb);
1875	if (in) BIO_free_all(in);
1876	return retdb;
1877	}
1878
1879int index_index(CA_DB *db)
1880	{
1881	if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1882				LHASH_HASH_FN(index_serial),
1883				LHASH_COMP_FN(index_serial)))
1884		{
1885		BIO_printf(bio_err,
1886		  "error creating serial number index:(%ld,%ld,%ld)\n",
1887		  			db->db->error,db->db->arg1,db->db->arg2);
1888			return 0;
1889		}
1890
1891	if (db->attributes.unique_subject
1892		&& !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1893			LHASH_HASH_FN(index_name),
1894			LHASH_COMP_FN(index_name)))
1895		{
1896		BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
1897			db->db->error,db->db->arg1,db->db->arg2);
1898		return 0;
1899		}
1900	return 1;
1901	}
1902
1903int save_index(const char *dbfile, const char *suffix, CA_DB *db)
1904	{
1905	char buf[3][BSIZE];
1906	BIO *out = BIO_new(BIO_s_file());
1907	int j;
1908
1909	if (out == NULL)
1910		{
1911		ERR_print_errors(bio_err);
1912		goto err;
1913		}
1914
1915	j = strlen(dbfile) + strlen(suffix);
1916	if (j + 6 >= BSIZE)
1917		{
1918		BIO_printf(bio_err,"file name too long\n");
1919		goto err;
1920		}
1921
1922#ifndef OPENSSL_SYS_VMS
1923	j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
1924#else
1925	j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
1926#endif
1927#ifndef OPENSSL_SYS_VMS
1928	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
1929#else
1930	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
1931#endif
1932#ifndef OPENSSL_SYS_VMS
1933	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
1934#else
1935	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
1936#endif
1937#ifdef RL_DEBUG
1938	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
1939#endif
1940	if (BIO_write_filename(out,buf[0]) <= 0)
1941		{
1942		perror(dbfile);
1943		BIO_printf(bio_err,"unable to open '%s'\n", dbfile);
1944		goto err;
1945		}
1946	j=TXT_DB_write(out,db->db);
1947	if (j <= 0) goto err;
1948
1949	BIO_free(out);
1950
1951	out = BIO_new(BIO_s_file());
1952#ifdef RL_DEBUG
1953	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
1954#endif
1955	if (BIO_write_filename(out,buf[1]) <= 0)
1956		{
1957		perror(buf[2]);
1958		BIO_printf(bio_err,"unable to open '%s'\n", buf[2]);
1959		goto err;
1960		}
1961	BIO_printf(out,"unique_subject = %s\n",
1962		db->attributes.unique_subject ? "yes" : "no");
1963	BIO_free(out);
1964
1965	return 1;
1966 err:
1967	return 0;
1968	}
1969
1970int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
1971	{
1972	char buf[5][BSIZE];
1973	int i,j;
1974
1975	i = strlen(dbfile) + strlen(old_suffix);
1976	j = strlen(dbfile) + strlen(new_suffix);
1977	if (i > j) j = i;
1978	if (j + 6 >= BSIZE)
1979		{
1980		BIO_printf(bio_err,"file name too long\n");
1981		goto err;
1982		}
1983
1984#ifndef OPENSSL_SYS_VMS
1985	j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
1986#else
1987	j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
1988#endif
1989#ifndef OPENSSL_SYS_VMS
1990	j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s",
1991		dbfile, new_suffix);
1992#else
1993	j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s",
1994		dbfile, new_suffix);
1995#endif
1996#ifndef OPENSSL_SYS_VMS
1997	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
1998		dbfile, new_suffix);
1999#else
2000	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
2001		dbfile, new_suffix);
2002#endif
2003#ifndef OPENSSL_SYS_VMS
2004	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
2005		dbfile, old_suffix);
2006#else
2007	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
2008		dbfile, old_suffix);
2009#endif
2010#ifndef OPENSSL_SYS_VMS
2011	j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s",
2012		dbfile, old_suffix);
2013#else
2014	j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s",
2015		dbfile, old_suffix);
2016#endif
2017#ifdef RL_DEBUG
2018	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
2019		dbfile, buf[1]);
2020#endif
2021	if (rename(dbfile,buf[1]) < 0 && errno != ENOENT
2022#ifdef ENOTDIR
2023		&& errno != ENOTDIR
2024#endif
2025	   )		{
2026			BIO_printf(bio_err,
2027				"unable to rename %s to %s\n",
2028				dbfile, buf[1]);
2029			perror("reason");
2030			goto err;
2031			}
2032#ifdef RL_DEBUG
2033	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
2034		buf[0],dbfile);
2035#endif
2036	if (rename(buf[0],dbfile) < 0)
2037		{
2038		BIO_printf(bio_err,
2039			"unable to rename %s to %s\n",
2040			buf[0],dbfile);
2041		perror("reason");
2042		rename(buf[1],dbfile);
2043		goto err;
2044		}
2045#ifdef RL_DEBUG
2046	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
2047		buf[4],buf[3]);
2048#endif
2049	if (rename(buf[4],buf[3]) < 0 && errno != ENOENT
2050#ifdef ENOTDIR
2051		&& errno != ENOTDIR
2052#endif
2053	   )		{
2054			BIO_printf(bio_err,
2055				"unable to rename %s to %s\n",
2056				buf[4], buf[3]);
2057			perror("reason");
2058			rename(dbfile,buf[0]);
2059			rename(buf[1],dbfile);
2060			goto err;
2061			}
2062#ifdef RL_DEBUG
2063	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
2064		buf[2],buf[4]);
2065#endif
2066	if (rename(buf[2],buf[4]) < 0)
2067		{
2068		BIO_printf(bio_err,
2069			"unable to rename %s to %s\n",
2070			buf[2],buf[4]);
2071		perror("reason");
2072		rename(buf[3],buf[4]);
2073		rename(dbfile,buf[0]);
2074		rename(buf[1],dbfile);
2075		goto err;
2076		}
2077	return 1;
2078 err:
2079	return 0;
2080	}
2081
2082void free_index(CA_DB *db)
2083	{
2084	if (db)
2085		{
2086		if (db->db) TXT_DB_free(db->db);
2087		OPENSSL_free(db);
2088		}
2089	}
2090
2091int parse_yesno(const char *str, int def)
2092	{
2093	int ret = def;
2094	if (str)
2095		{
2096		switch (*str)
2097			{
2098		case 'f': /* false */
2099		case 'F': /* FALSE */
2100		case 'n': /* no */
2101		case 'N': /* NO */
2102		case '0': /* 0 */
2103			ret = 0;
2104			break;
2105		case 't': /* true */
2106		case 'T': /* TRUE */
2107		case 'y': /* yes */
2108		case 'Y': /* YES */
2109		case '1': /* 1 */
2110			ret = 1;
2111			break;
2112		default:
2113			ret = def;
2114			break;
2115			}
2116		}
2117	return ret;
2118	}
2119
2120/*
2121 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2122 * where characters may be escaped by \
2123 */
2124X509_NAME *parse_name(char *subject, long chtype, int multirdn)
2125	{
2126	size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
2127	char *buf = OPENSSL_malloc(buflen);
2128	size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2129	char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
2130	char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
2131	int *mval = OPENSSL_malloc (max_ne * sizeof (int));
2132
2133	char *sp = subject, *bp = buf;
2134	int i, ne_num = 0;
2135
2136	X509_NAME *n = NULL;
2137	int nid;
2138
2139	if (!buf || !ne_types || !ne_values || !mval)
2140		{
2141		BIO_printf(bio_err, "malloc error\n");
2142		goto error;
2143		}
2144
2145	if (*subject != '/')
2146		{
2147		BIO_printf(bio_err, "Subject does not start with '/'.\n");
2148		goto error;
2149		}
2150	sp++; /* skip leading / */
2151
2152	/* no multivalued RDN by default */
2153	mval[ne_num] = 0;
2154
2155	while (*sp)
2156		{
2157		/* collect type */
2158		ne_types[ne_num] = bp;
2159		while (*sp)
2160			{
2161			if (*sp == '\\') /* is there anything to escape in the type...? */
2162				{
2163				if (*++sp)
2164					*bp++ = *sp++;
2165				else
2166					{
2167					BIO_printf(bio_err, "escape character at end of string\n");
2168					goto error;
2169					}
2170				}
2171			else if (*sp == '=')
2172				{
2173				sp++;
2174				*bp++ = '\0';
2175				break;
2176				}
2177			else
2178				*bp++ = *sp++;
2179			}
2180		if (!*sp)
2181			{
2182			BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
2183			goto error;
2184			}
2185		ne_values[ne_num] = bp;
2186		while (*sp)
2187			{
2188			if (*sp == '\\')
2189				{
2190				if (*++sp)
2191					*bp++ = *sp++;
2192				else
2193					{
2194					BIO_printf(bio_err, "escape character at end of string\n");
2195					goto error;
2196					}
2197				}
2198			else if (*sp == '/')
2199				{
2200				sp++;
2201				/* no multivalued RDN by default */
2202				mval[ne_num+1] = 0;
2203				break;
2204				}
2205			else if (*sp == '+' && multirdn)
2206				{
2207				/* a not escaped + signals a mutlivalued RDN */
2208				sp++;
2209				mval[ne_num+1] = -1;
2210				break;
2211				}
2212			else
2213				*bp++ = *sp++;
2214			}
2215		*bp++ = '\0';
2216		ne_num++;
2217		}
2218
2219	if (!(n = X509_NAME_new()))
2220		goto error;
2221
2222	for (i = 0; i < ne_num; i++)
2223		{
2224		if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
2225			{
2226			BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
2227			continue;
2228			}
2229
2230		if (!*ne_values[i])
2231			{
2232			BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
2233			continue;
2234			}
2235
2236		if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i]))
2237			goto error;
2238		}
2239
2240	OPENSSL_free(ne_values);
2241	OPENSSL_free(ne_types);
2242	OPENSSL_free(buf);
2243	OPENSSL_free(mval);
2244	return n;
2245
2246error:
2247	X509_NAME_free(n);
2248	if (ne_values)
2249		OPENSSL_free(ne_values);
2250	if (ne_types)
2251		OPENSSL_free(ne_types);
2252	if (mval)
2253		OPENSSL_free(mval);
2254	if (buf)
2255		OPENSSL_free(buf);
2256	return NULL;
2257}
2258
2259int args_verify(char ***pargs, int *pargc,
2260			int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
2261	{
2262	ASN1_OBJECT *otmp = NULL;
2263	unsigned long flags = 0;
2264	int i;
2265	int purpose = 0, depth = -1;
2266	char **oldargs = *pargs;
2267	char *arg = **pargs, *argn = (*pargs)[1];
2268	time_t at_time = 0;
2269	if (!strcmp(arg, "-policy"))
2270		{
2271		if (!argn)
2272			*badarg = 1;
2273		else
2274			{
2275			otmp = OBJ_txt2obj(argn, 0);
2276			if (!otmp)
2277				{
2278				BIO_printf(err, "Invalid Policy \"%s\"\n",
2279									argn);
2280				*badarg = 1;
2281				}
2282			}
2283		(*pargs)++;
2284		}
2285	else if (strcmp(arg,"-purpose") == 0)
2286		{
2287		X509_PURPOSE *xptmp;
2288		if (!argn)
2289			*badarg = 1;
2290		else
2291			{
2292			i = X509_PURPOSE_get_by_sname(argn);
2293			if(i < 0)
2294				{
2295				BIO_printf(err, "unrecognized purpose\n");
2296				*badarg = 1;
2297				}
2298			else
2299				{
2300				xptmp = X509_PURPOSE_get0(i);
2301				purpose = X509_PURPOSE_get_id(xptmp);
2302				}
2303			}
2304		(*pargs)++;
2305		}
2306	else if (strcmp(arg,"-verify_depth") == 0)
2307		{
2308		if (!argn)
2309			*badarg = 1;
2310		else
2311			{
2312			depth = atoi(argn);
2313			if(depth < 0)
2314				{
2315				BIO_printf(err, "invalid depth\n");
2316				*badarg = 1;
2317				}
2318			}
2319		(*pargs)++;
2320		}
2321	else if (strcmp(arg,"-attime") == 0)
2322		{
2323		if (!argn)
2324			*badarg = 1;
2325		else
2326			{
2327			long timestamp;
2328			/* interpret the -attime argument as seconds since
2329			 * Epoch */
2330			if (sscanf(argn, "%li", &timestamp) != 1)
2331				{
2332				BIO_printf(bio_err,
2333						"Error parsing timestamp %s\n",
2334					   	argn);
2335				*badarg = 1;
2336				}
2337			/* on some platforms time_t may be a float */
2338			at_time = (time_t) timestamp;
2339			}
2340		(*pargs)++;
2341		}
2342	else if (!strcmp(arg, "-ignore_critical"))
2343		flags |= X509_V_FLAG_IGNORE_CRITICAL;
2344	else if (!strcmp(arg, "-issuer_checks"))
2345		flags |= X509_V_FLAG_CB_ISSUER_CHECK;
2346	else if (!strcmp(arg, "-crl_check"))
2347		flags |=  X509_V_FLAG_CRL_CHECK;
2348	else if (!strcmp(arg, "-crl_check_all"))
2349		flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
2350	else if (!strcmp(arg, "-policy_check"))
2351		flags |= X509_V_FLAG_POLICY_CHECK;
2352	else if (!strcmp(arg, "-explicit_policy"))
2353		flags |= X509_V_FLAG_EXPLICIT_POLICY;
2354	else if (!strcmp(arg, "-inhibit_any"))
2355		flags |= X509_V_FLAG_INHIBIT_ANY;
2356	else if (!strcmp(arg, "-inhibit_map"))
2357		flags |= X509_V_FLAG_INHIBIT_MAP;
2358	else if (!strcmp(arg, "-x509_strict"))
2359		flags |= X509_V_FLAG_X509_STRICT;
2360	else if (!strcmp(arg, "-extended_crl"))
2361		flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
2362	else if (!strcmp(arg, "-use_deltas"))
2363		flags |= X509_V_FLAG_USE_DELTAS;
2364	else if (!strcmp(arg, "-policy_print"))
2365		flags |= X509_V_FLAG_NOTIFY_POLICY;
2366	else if (!strcmp(arg, "-check_ss_sig"))
2367		flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
2368	else
2369		return 0;
2370
2371	if (*badarg)
2372		{
2373		if (*pm)
2374			X509_VERIFY_PARAM_free(*pm);
2375		*pm = NULL;
2376		goto end;
2377		}
2378
2379	if (!*pm && !(*pm = X509_VERIFY_PARAM_new()))
2380		{
2381		*badarg = 1;
2382		goto end;
2383		}
2384
2385	if (otmp)
2386		X509_VERIFY_PARAM_add0_policy(*pm, otmp);
2387	if (flags)
2388		X509_VERIFY_PARAM_set_flags(*pm, flags);
2389
2390	if (purpose)
2391		X509_VERIFY_PARAM_set_purpose(*pm, purpose);
2392
2393	if (depth >= 0)
2394		X509_VERIFY_PARAM_set_depth(*pm, depth);
2395
2396	if (at_time)
2397		X509_VERIFY_PARAM_set_time(*pm, at_time);
2398
2399	end:
2400
2401	(*pargs)++;
2402
2403	if (pargc)
2404		*pargc -= *pargs - oldargs;
2405
2406	return 1;
2407
2408	}
2409
2410/* Read whole contents of a BIO into an allocated memory buffer and
2411 * return it.
2412 */
2413
2414int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
2415	{
2416	BIO *mem;
2417	int len, ret;
2418	unsigned char tbuf[1024];
2419	mem = BIO_new(BIO_s_mem());
2420	if (!mem)
2421		return -1;
2422	for(;;)
2423		{
2424		if ((maxlen != -1) && maxlen < 1024)
2425			len = maxlen;
2426		else
2427			len = 1024;
2428		len = BIO_read(in, tbuf, len);
2429		if (len <= 0)
2430			break;
2431		if (BIO_write(mem, tbuf, len) != len)
2432			{
2433			BIO_free(mem);
2434			return -1;
2435			}
2436		maxlen -= len;
2437
2438		if (maxlen == 0)
2439			break;
2440		}
2441	ret = BIO_get_mem_data(mem, (char **)out);
2442	BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
2443	BIO_free(mem);
2444	return ret;
2445	}
2446
2447int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
2448	{
2449	int rv;
2450	char *stmp, *vtmp = NULL;
2451	stmp = BUF_strdup(value);
2452	if (!stmp)
2453		return -1;
2454	vtmp = strchr(stmp, ':');
2455	if (vtmp)
2456		{
2457		*vtmp = 0;
2458		vtmp++;
2459		}
2460	rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
2461	OPENSSL_free(stmp);
2462	return rv;
2463	}
2464
2465static void nodes_print(BIO *out, const char *name,
2466	STACK_OF(X509_POLICY_NODE) *nodes)
2467	{
2468	X509_POLICY_NODE *node;
2469	int i;
2470	BIO_printf(out, "%s Policies:", name);
2471	if (nodes)
2472		{
2473		BIO_puts(out, "\n");
2474		for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++)
2475			{
2476			node = sk_X509_POLICY_NODE_value(nodes, i);
2477			X509_POLICY_NODE_print(out, node, 2);
2478			}
2479		}
2480	else
2481		BIO_puts(out, " <empty>\n");
2482	}
2483
2484void policies_print(BIO *out, X509_STORE_CTX *ctx)
2485	{
2486	X509_POLICY_TREE *tree;
2487	int explicit_policy;
2488	int free_out = 0;
2489	if (out == NULL)
2490		{
2491		out = BIO_new_fp(stderr, BIO_NOCLOSE);
2492		free_out = 1;
2493		}
2494	tree = X509_STORE_CTX_get0_policy_tree(ctx);
2495	explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
2496
2497	BIO_printf(out, "Require explicit Policy: %s\n",
2498				explicit_policy ? "True" : "False");
2499
2500	nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
2501	nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
2502	if (free_out)
2503		BIO_free(out);
2504	}
2505
2506#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
2507
2508static JPAKE_CTX *jpake_init(const char *us, const char *them,
2509							 const char *secret)
2510	{
2511	BIGNUM *p = NULL;
2512	BIGNUM *g = NULL;
2513	BIGNUM *q = NULL;
2514	BIGNUM *bnsecret = BN_new();
2515	JPAKE_CTX *ctx;
2516
2517	/* Use a safe prime for p (that we found earlier) */
2518	BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
2519	g = BN_new();
2520	BN_set_word(g, 2);
2521	q = BN_new();
2522	BN_rshift1(q, p);
2523
2524	BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret);
2525
2526	ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret);
2527	BN_free(bnsecret);
2528	BN_free(q);
2529	BN_free(g);
2530	BN_free(p);
2531
2532	return ctx;
2533	}
2534
2535static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p)
2536	{
2537	BN_print(conn, p->gx);
2538	BIO_puts(conn, "\n");
2539	BN_print(conn, p->zkpx.gr);
2540	BIO_puts(conn, "\n");
2541	BN_print(conn, p->zkpx.b);
2542	BIO_puts(conn, "\n");
2543	}
2544
2545static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx)
2546	{
2547	JPAKE_STEP1 s1;
2548
2549	JPAKE_STEP1_init(&s1);
2550	JPAKE_STEP1_generate(&s1, ctx);
2551	jpake_send_part(bconn, &s1.p1);
2552	jpake_send_part(bconn, &s1.p2);
2553	(void)BIO_flush(bconn);
2554	JPAKE_STEP1_release(&s1);
2555	}
2556
2557static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx)
2558	{
2559	JPAKE_STEP2 s2;
2560
2561	JPAKE_STEP2_init(&s2);
2562	JPAKE_STEP2_generate(&s2, ctx);
2563	jpake_send_part(bconn, &s2);
2564	(void)BIO_flush(bconn);
2565	JPAKE_STEP2_release(&s2);
2566	}
2567
2568static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx)
2569	{
2570	JPAKE_STEP3A s3a;
2571
2572	JPAKE_STEP3A_init(&s3a);
2573	JPAKE_STEP3A_generate(&s3a, ctx);
2574	BIO_write(bconn, s3a.hhk, sizeof s3a.hhk);
2575	(void)BIO_flush(bconn);
2576	JPAKE_STEP3A_release(&s3a);
2577	}
2578
2579static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx)
2580	{
2581	JPAKE_STEP3B s3b;
2582
2583	JPAKE_STEP3B_init(&s3b);
2584	JPAKE_STEP3B_generate(&s3b, ctx);
2585	BIO_write(bconn, s3b.hk, sizeof s3b.hk);
2586	(void)BIO_flush(bconn);
2587	JPAKE_STEP3B_release(&s3b);
2588	}
2589
2590static void readbn(BIGNUM **bn, BIO *bconn)
2591	{
2592	char buf[10240];
2593	int l;
2594
2595	l = BIO_gets(bconn, buf, sizeof buf);
2596	assert(l > 0);
2597	assert(buf[l-1] == '\n');
2598	buf[l-1] = '\0';
2599	BN_hex2bn(bn, buf);
2600	}
2601
2602static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn)
2603	{
2604	readbn(&p->gx, bconn);
2605	readbn(&p->zkpx.gr, bconn);
2606	readbn(&p->zkpx.b, bconn);
2607	}
2608
2609static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn)
2610	{
2611	JPAKE_STEP1 s1;
2612
2613	JPAKE_STEP1_init(&s1);
2614	jpake_receive_part(&s1.p1, bconn);
2615	jpake_receive_part(&s1.p2, bconn);
2616	if(!JPAKE_STEP1_process(ctx, &s1))
2617		{
2618		ERR_print_errors(bio_err);
2619		exit(1);
2620		}
2621	JPAKE_STEP1_release(&s1);
2622	}
2623
2624static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn)
2625	{
2626	JPAKE_STEP2 s2;
2627
2628	JPAKE_STEP2_init(&s2);
2629	jpake_receive_part(&s2, bconn);
2630	if(!JPAKE_STEP2_process(ctx, &s2))
2631		{
2632		ERR_print_errors(bio_err);
2633		exit(1);
2634		}
2635	JPAKE_STEP2_release(&s2);
2636	}
2637
2638static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn)
2639	{
2640	JPAKE_STEP3A s3a;
2641	int l;
2642
2643	JPAKE_STEP3A_init(&s3a);
2644	l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk);
2645	assert(l == sizeof s3a.hhk);
2646	if(!JPAKE_STEP3A_process(ctx, &s3a))
2647		{
2648		ERR_print_errors(bio_err);
2649		exit(1);
2650		}
2651	JPAKE_STEP3A_release(&s3a);
2652	}
2653
2654static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn)
2655	{
2656	JPAKE_STEP3B s3b;
2657	int l;
2658
2659	JPAKE_STEP3B_init(&s3b);
2660	l = BIO_read(bconn, s3b.hk, sizeof s3b.hk);
2661	assert(l == sizeof s3b.hk);
2662	if(!JPAKE_STEP3B_process(ctx, &s3b))
2663		{
2664		ERR_print_errors(bio_err);
2665		exit(1);
2666		}
2667	JPAKE_STEP3B_release(&s3b);
2668	}
2669
2670void jpake_client_auth(BIO *out, BIO *conn, const char *secret)
2671	{
2672	JPAKE_CTX *ctx;
2673	BIO *bconn;
2674
2675	BIO_puts(out, "Authenticating with JPAKE\n");
2676
2677	ctx = jpake_init("client", "server", secret);
2678
2679	bconn = BIO_new(BIO_f_buffer());
2680	BIO_push(bconn, conn);
2681
2682	jpake_send_step1(bconn, ctx);
2683	jpake_receive_step1(ctx, bconn);
2684	jpake_send_step2(bconn, ctx);
2685	jpake_receive_step2(ctx, bconn);
2686	jpake_send_step3a(bconn, ctx);
2687	jpake_receive_step3b(ctx, bconn);
2688
2689	BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
2690
2691	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
2692
2693	BIO_pop(bconn);
2694	BIO_free(bconn);
2695
2696	JPAKE_CTX_free(ctx);
2697	}
2698
2699void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
2700	{
2701	JPAKE_CTX *ctx;
2702	BIO *bconn;
2703
2704	BIO_puts(out, "Authenticating with JPAKE\n");
2705
2706	ctx = jpake_init("server", "client", secret);
2707
2708	bconn = BIO_new(BIO_f_buffer());
2709	BIO_push(bconn, conn);
2710
2711	jpake_receive_step1(ctx, bconn);
2712	jpake_send_step1(bconn, ctx);
2713	jpake_receive_step2(ctx, bconn);
2714	jpake_send_step2(bconn, ctx);
2715	jpake_receive_step3a(ctx, bconn);
2716	jpake_send_step3b(bconn, ctx);
2717
2718	BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
2719
2720	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
2721
2722	BIO_pop(bconn);
2723	BIO_free(bconn);
2724
2725	JPAKE_CTX_free(ctx);
2726	}
2727
2728#endif
2729
2730#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
2731/* next_protos_parse parses a comma separated list of strings into a string
2732 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
2733 *   outlen: (output) set to the length of the resulting buffer on success.
2734 *   err: (maybe NULL) on failure, an error message line is written to this BIO.
2735 *   in: a NUL termianted string like "abc,def,ghi"
2736 *
2737 *   returns: a malloced buffer or NULL on failure.
2738 */
2739unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
2740	{
2741	size_t len;
2742	unsigned char *out;
2743	size_t i, start = 0;
2744
2745	len = strlen(in);
2746	if (len >= 65535)
2747		return NULL;
2748
2749	out = OPENSSL_malloc(strlen(in) + 1);
2750	if (!out)
2751		return NULL;
2752
2753	for (i = 0; i <= len; ++i)
2754		{
2755		if (i == len || in[i] == ',')
2756			{
2757			if (i - start > 255)
2758				{
2759				OPENSSL_free(out);
2760				return NULL;
2761				}
2762			out[start] = i - start;
2763			start = i + 1;
2764			}
2765		else
2766			out[i+1] = in[i];
2767		}
2768
2769	*outlen = len + 1;
2770	return out;
2771	}
2772#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
2773
2774/*
2775 * Platform-specific sections
2776 */
2777#if defined(_WIN32)
2778# ifdef fileno
2779#  undef fileno
2780#  define fileno(a) (int)_fileno(a)
2781# endif
2782
2783# include <windows.h>
2784# include <tchar.h>
2785
2786static int WIN32_rename(const char *from, const char *to)
2787	{
2788	TCHAR  *tfrom=NULL,*tto;
2789	DWORD	err;
2790	int	ret=0;
2791
2792	if (sizeof(TCHAR) == 1)
2793		{
2794		tfrom = (TCHAR *)from;
2795		tto   = (TCHAR *)to;
2796		}
2797	else	/* UNICODE path */
2798		{
2799		size_t i,flen=strlen(from)+1,tlen=strlen(to)+1;
2800		tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen));
2801		if (tfrom==NULL) goto err;
2802		tto=tfrom+flen;
2803#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2804		if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen))
2805#endif
2806			for (i=0;i<flen;i++)	tfrom[i]=(TCHAR)from[i];
2807#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2808		if (!MultiByteToWideChar(CP_ACP,0,to,  tlen,(WCHAR *)tto,  tlen))
2809#endif
2810			for (i=0;i<tlen;i++)	tto[i]  =(TCHAR)to[i];
2811		}
2812
2813	if (MoveFile(tfrom,tto))	goto ok;
2814	err=GetLastError();
2815	if (err==ERROR_ALREADY_EXISTS || err==ERROR_FILE_EXISTS)
2816		{
2817		if (DeleteFile(tto) && MoveFile(tfrom,tto))
2818			goto ok;
2819		err=GetLastError();
2820		}
2821	if (err==ERROR_FILE_NOT_FOUND || err==ERROR_PATH_NOT_FOUND)
2822		errno = ENOENT;
2823	else if (err==ERROR_ACCESS_DENIED)
2824		errno = EACCES;
2825	else
2826		errno = EINVAL;	/* we could map more codes... */
2827err:
2828	ret=-1;
2829ok:
2830	if (tfrom!=NULL && tfrom!=(TCHAR *)from)	free(tfrom);
2831	return ret;
2832	}
2833#endif
2834
2835/* app_tminterval section */
2836#if defined(_WIN32)
2837double app_tminterval(int stop,int usertime)
2838	{
2839	FILETIME		now;
2840	double			ret=0;
2841	static ULARGE_INTEGER	tmstart;
2842	static int		warning=1;
2843#ifdef _WIN32_WINNT
2844	static HANDLE		proc=NULL;
2845
2846	if (proc==NULL)
2847		{
2848		if (check_winnt())
2849			proc = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,
2850						GetCurrentProcessId());
2851		if (proc==NULL) proc = (HANDLE)-1;
2852		}
2853
2854	if (usertime && proc!=(HANDLE)-1)
2855		{
2856		FILETIME junk;
2857		GetProcessTimes(proc,&junk,&junk,&junk,&now);
2858		}
2859	else
2860#endif
2861		{
2862		SYSTEMTIME systime;
2863
2864		if (usertime && warning)
2865			{
2866			BIO_printf(bio_err,"To get meaningful results, run "
2867					   "this program on idle system.\n");
2868			warning=0;
2869			}
2870		GetSystemTime(&systime);
2871		SystemTimeToFileTime(&systime,&now);
2872		}
2873
2874	if (stop==TM_START)
2875		{
2876		tmstart.u.LowPart  = now.dwLowDateTime;
2877		tmstart.u.HighPart = now.dwHighDateTime;
2878		}
2879	else	{
2880		ULARGE_INTEGER tmstop;
2881
2882		tmstop.u.LowPart   = now.dwLowDateTime;
2883		tmstop.u.HighPart  = now.dwHighDateTime;
2884
2885		ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7;
2886		}
2887
2888	return (ret);
2889	}
2890
2891#elif defined(OPENSSL_SYS_NETWARE)
2892#include <time.h>
2893
2894double app_tminterval(int stop,int usertime)
2895	{
2896	double		ret=0;
2897	static clock_t	tmstart;
2898	static int	warning=1;
2899
2900	if (usertime && warning)
2901		{
2902		BIO_printf(bio_err,"To get meaningful results, run "
2903				   "this program on idle system.\n");
2904		warning=0;
2905		}
2906
2907	if (stop==TM_START)	tmstart = clock();
2908	else			ret     = (clock()-tmstart)/(double)CLOCKS_PER_SEC;
2909
2910	return (ret);
2911	}
2912
2913#elif defined(OPENSSL_SYSTEM_VXWORKS)
2914#include <time.h>
2915
2916double app_tminterval(int stop,int usertime)
2917	{
2918	double ret=0;
2919#ifdef CLOCK_REALTIME
2920	static struct timespec	tmstart;
2921	struct timespec		now;
2922#else
2923	static unsigned long	tmstart;
2924	unsigned long		now;
2925#endif
2926	static int warning=1;
2927
2928	if (usertime && warning)
2929		{
2930		BIO_printf(bio_err,"To get meaningful results, run "
2931				   "this program on idle system.\n");
2932		warning=0;
2933		}
2934
2935#ifdef CLOCK_REALTIME
2936	clock_gettime(CLOCK_REALTIME,&now);
2937	if (stop==TM_START)	tmstart = now;
2938	else	ret = ( (now.tv_sec+now.tv_nsec*1e-9)
2939			- (tmstart.tv_sec+tmstart.tv_nsec*1e-9) );
2940#else
2941	now = tickGet();
2942	if (stop==TM_START)	tmstart = now;
2943	else			ret = (now - tmstart)/(double)sysClkRateGet();
2944#endif
2945	return (ret);
2946	}
2947
2948#elif defined(OPENSSL_SYSTEM_VMS)
2949#include <time.h>
2950#include <times.h>
2951
2952double app_tminterval(int stop,int usertime)
2953	{
2954	static clock_t	tmstart;
2955	double		ret = 0;
2956	clock_t		now;
2957#ifdef __TMS
2958	struct tms	rus;
2959
2960	now = times(&rus);
2961	if (usertime)	now = rus.tms_utime;
2962#else
2963	if (usertime)
2964		now = clock(); /* sum of user and kernel times */
2965	else	{
2966		struct timeval tv;
2967		gettimeofday(&tv,NULL);
2968		now = (clock_t)(
2969			(unsigned long long)tv.tv_sec*CLK_TCK +
2970			(unsigned long long)tv.tv_usec*(1000000/CLK_TCK)
2971			);
2972		}
2973#endif
2974	if (stop==TM_START)	tmstart = now;
2975	else			ret = (now - tmstart)/(double)(CLK_TCK);
2976
2977	return (ret);
2978	}
2979
2980#elif defined(_SC_CLK_TCK)	/* by means of unistd.h */
2981#include <sys/times.h>
2982
2983double app_tminterval(int stop,int usertime)
2984	{
2985	double		ret = 0;
2986	struct tms	rus;
2987	clock_t		now = times(&rus);
2988	static clock_t	tmstart;
2989
2990	if (usertime)		now = rus.tms_utime;
2991
2992	if (stop==TM_START)	tmstart = now;
2993	else
2994		{
2995		long int tck = sysconf(_SC_CLK_TCK);
2996		ret = (now - tmstart)/(double)tck;
2997		}
2998
2999	return (ret);
3000	}
3001
3002#else
3003#include <sys/time.h>
3004#include <sys/resource.h>
3005
3006double app_tminterval(int stop,int usertime)
3007	{
3008	double		ret = 0;
3009	struct rusage	rus;
3010	struct timeval	now;
3011	static struct timeval tmstart;
3012
3013	if (usertime)		getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime;
3014	else			gettimeofday(&now,NULL);
3015
3016	if (stop==TM_START)	tmstart = now;
3017	else			ret = ( (now.tv_sec+now.tv_usec*1e-6)
3018					- (tmstart.tv_sec+tmstart.tv_usec*1e-6) );
3019
3020	return ret;
3021	}
3022#endif
3023
3024/* app_isdir section */
3025#ifdef _WIN32
3026int app_isdir(const char *name)
3027	{
3028	HANDLE		hList;
3029	WIN32_FIND_DATA	FileData;
3030#if defined(UNICODE) || defined(_UNICODE)
3031	size_t i, len_0 = strlen(name)+1;
3032
3033	if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0]))
3034		return -1;
3035
3036#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
3037	if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0))
3038#endif
3039		for (i=0;i<len_0;i++)
3040			FileData.cFileName[i] = (WCHAR)name[i];
3041
3042	hList = FindFirstFile(FileData.cFileName,&FileData);
3043#else
3044	hList = FindFirstFile(name,&FileData);
3045#endif
3046	if (hList == INVALID_HANDLE_VALUE)	return -1;
3047	FindClose(hList);
3048	return ((FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0);
3049	}
3050#else
3051#include <sys/stat.h>
3052#ifndef S_ISDIR
3053# if defined(_S_IFMT) && defined(_S_IFDIR)
3054#  define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR)
3055# else
3056#  define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR)
3057# endif
3058#endif
3059
3060int app_isdir(const char *name)
3061	{
3062#if defined(S_ISDIR)
3063	struct stat st;
3064
3065	if (stat(name,&st)==0)	return S_ISDIR(st.st_mode);
3066	else			return -1;
3067#else
3068	return -1;
3069#endif
3070	}
3071#endif
3072
3073/* raw_read|write section */
3074#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
3075int raw_read_stdin(void *buf,int siz)
3076	{
3077	DWORD n;
3078	if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL))
3079		return (n);
3080	else	return (-1);
3081	}
3082#else
3083int raw_read_stdin(void *buf,int siz)
3084	{	return read(fileno(stdin),buf,siz);	}
3085#endif
3086
3087#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
3088int raw_write_stdout(const void *buf,int siz)
3089	{
3090	DWORD n;
3091	if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL))
3092		return (n);
3093	else	return (-1);
3094	}
3095#else
3096int raw_write_stdout(const void *buf,int siz)
3097	{	return write(fileno(stdout),buf,siz);	}
3098#endif
3099