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