ssl/tsrc/BC/libcrypto/topenssl/src/apps.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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 	}