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