xref: /freebsd/crypto/openssl/apps/ca.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1 /* apps/ca.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 /* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
60 
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #include <sys/types.h>
65 #include <sys/stat.h>
66 #include "apps.h"
67 #include <openssl/conf.h>
68 #include <openssl/bio.h>
69 #include <openssl/err.h>
70 #include <openssl/bn.h>
71 #include <openssl/txt_db.h>
72 #include <openssl/evp.h>
73 #include <openssl/x509.h>
74 #include <openssl/x509v3.h>
75 #include <openssl/objects.h>
76 #include <openssl/pem.h>
77 
78 #ifndef W_OK
79 #  ifdef VMS
80 #    if defined(__DECC)
81 #      include <unistd.h>
82 #    else
83 #      include <unixlib.h>
84 #    endif
85 #  else
86 #    include <sys/file.h>
87 #  endif
88 #endif
89 
90 #ifndef W_OK
91 #  define F_OK 0
92 #  define X_OK 1
93 #  define W_OK 2
94 #  define R_OK 4
95 #endif
96 
97 #undef PROG
98 #define PROG ca_main
99 
100 #define BASE_SECTION	"ca"
101 #define CONFIG_FILE "openssl.cnf"
102 
103 #define ENV_DEFAULT_CA		"default_ca"
104 
105 #define ENV_DIR			"dir"
106 #define ENV_CERTS		"certs"
107 #define ENV_CRL_DIR		"crl_dir"
108 #define ENV_CA_DB		"CA_DB"
109 #define ENV_NEW_CERTS_DIR	"new_certs_dir"
110 #define ENV_CERTIFICATE 	"certificate"
111 #define ENV_SERIAL		"serial"
112 #define ENV_CRL			"crl"
113 #define ENV_PRIVATE_KEY		"private_key"
114 #define ENV_RANDFILE		"RANDFILE"
115 #define ENV_DEFAULT_DAYS 	"default_days"
116 #define ENV_DEFAULT_STARTDATE 	"default_startdate"
117 #define ENV_DEFAULT_ENDDATE 	"default_enddate"
118 #define ENV_DEFAULT_CRL_DAYS 	"default_crl_days"
119 #define ENV_DEFAULT_CRL_HOURS 	"default_crl_hours"
120 #define ENV_DEFAULT_MD		"default_md"
121 #define ENV_PRESERVE		"preserve"
122 #define ENV_POLICY      	"policy"
123 #define ENV_EXTENSIONS      	"x509_extensions"
124 #define ENV_CRLEXT      	"crl_extensions"
125 #define ENV_MSIE_HACK		"msie_hack"
126 
127 #define ENV_DATABASE		"database"
128 
129 #define DB_type         0
130 #define DB_exp_date     1
131 #define DB_rev_date     2
132 #define DB_serial       3       /* index - unique */
133 #define DB_file         4
134 #define DB_name         5       /* index - unique for active */
135 #define DB_NUMBER       6
136 
137 #define DB_TYPE_REV	'R'
138 #define DB_TYPE_EXP	'E'
139 #define DB_TYPE_VAL	'V'
140 
141 static char *ca_usage[]={
142 "usage: ca args\n",
143 "\n",
144 " -verbose        - Talk alot while doing things\n",
145 " -config file    - A config file\n",
146 " -name arg       - The particular CA definition to use\n",
147 " -gencrl         - Generate a new CRL\n",
148 " -crldays days   - Days is when the next CRL is due\n",
149 " -crlhours hours - Hours is when the next CRL is due\n",
150 " -days arg       - number of days to certify the certificate for\n",
151 " -md arg         - md to use, one of md2, md5, sha or sha1\n",
152 " -policy arg     - The CA 'policy' to support\n",
153 " -keyfile arg    - PEM private key file\n",
154 " -key arg        - key to decode the private key if it is encrypted\n",
155 " -cert file      - The CA certificate\n",
156 " -in file        - The input PEM encoded certificate request(s)\n",
157 " -out file       - Where to put the output file(s)\n",
158 " -outdir dir     - Where to put output certificates\n",
159 " -infiles ....   - The last argument, requests to process\n",
160 " -spkac file     - File contains DN and signed public key and challenge\n",
161 " -ss_cert file   - File contains a self signed cert to sign\n",
162 " -preserveDN     - Don't re-order the DN\n",
163 " -batch          - Don't ask questions\n",
164 " -msie_hack      - msie modifications to handle all those universal strings\n",
165 " -revoke file    - Revoke a certificate (given in file)\n",
166 NULL
167 };
168 
169 #ifdef EFENCE
170 extern int EF_PROTECT_FREE;
171 extern int EF_PROTECT_BELOW;
172 extern int EF_ALIGNMENT;
173 #endif
174 
175 static int add_oid_section(LHASH *conf);
176 static void lookup_fail(char *name,char *tag);
177 static int MS_CALLBACK key_callback(char *buf,int len,int verify,void *u);
178 static unsigned long index_serial_hash(char **a);
179 static int index_serial_cmp(char **a, char **b);
180 static unsigned long index_name_hash(char **a);
181 static int index_name_qual(char **a);
182 static int index_name_cmp(char **a,char **b);
183 static BIGNUM *load_serial(char *serialfile);
184 static int save_serial(char *serialfile, BIGNUM *serial);
185 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
186 		   const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
187 		   BIGNUM *serial, char *startdate,char *enddate, int days,
188 		   int batch, char *ext_sect, LHASH *conf,int verbose);
189 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
190 			const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
191 			TXT_DB *db, BIGNUM *serial,char *startdate,
192 			char *enddate, int days, int batch, char *ext_sect,
193 			LHASH *conf,int verbose);
194 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
195 			 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
196 			 TXT_DB *db, BIGNUM *serial,char *startdate,
197 			 char *enddate, int days, char *ext_sect,LHASH *conf,
198 				int verbose);
199 static int fix_data(int nid, int *type);
200 static void write_new_certificate(BIO *bp, X509 *x, int output_der);
201 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
202 	STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
203 	char *startdate, char *enddate, int days, int batch, int verbose,
204 	X509_REQ *req, char *ext_sect, LHASH *conf);
205 static int do_revoke(X509 *x509, TXT_DB *db);
206 static int check_time_format(char *str);
207 static LHASH *conf;
208 static char *key=NULL;
209 static char *section=NULL;
210 
211 static int preserve=0;
212 static int msie_hack=0;
213 
214 int MAIN(int argc, char **argv)
215 	{
216 	int total=0;
217 	int total_done=0;
218 	int badops=0;
219 	int ret=1;
220 	int req=0;
221 	int verbose=0;
222 	int gencrl=0;
223 	int dorevoke=0;
224 	long crldays=0;
225 	long crlhours=0;
226 	long errorline= -1;
227 	char *configfile=NULL;
228 	char *md=NULL;
229 	char *policy=NULL;
230 	char *keyfile=NULL;
231 	char *certfile=NULL;
232 	char *infile=NULL;
233 	char *spkac_file=NULL;
234 	char *ss_cert_file=NULL;
235 	EVP_PKEY *pkey=NULL;
236 	int output_der = 0;
237 	char *outfile=NULL;
238 	char *outdir=NULL;
239 	char *serialfile=NULL;
240 	char *extensions=NULL;
241 	char *crl_ext=NULL;
242 	BIGNUM *serial=NULL;
243 	char *startdate=NULL;
244 	char *enddate=NULL;
245 	int days=0;
246 	int batch=0;
247 	X509 *x509=NULL;
248 	X509 *x=NULL;
249 	BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
250 	char *dbfile=NULL;
251 	TXT_DB *db=NULL;
252 	X509_CRL *crl=NULL;
253 	X509_CRL_INFO *ci=NULL;
254 	X509_REVOKED *r=NULL;
255 	char **pp,*p,*f;
256 	int i,j;
257 	long l;
258 	const EVP_MD *dgst=NULL;
259 	STACK_OF(CONF_VALUE) *attribs=NULL;
260 	STACK *cert_sk=NULL;
261 	BIO *hex=NULL;
262 #undef BSIZE
263 #define BSIZE 256
264 	MS_STATIC char buf[3][BSIZE];
265 
266 #ifdef EFENCE
267 EF_PROTECT_FREE=1;
268 EF_PROTECT_BELOW=1;
269 EF_ALIGNMENT=0;
270 #endif
271 
272 	apps_startup();
273 
274 	X509V3_add_standard_extensions();
275 
276 	preserve=0;
277 	if (bio_err == NULL)
278 		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
279 			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
280 
281 	argc--;
282 	argv++;
283 	while (argc >= 1)
284 		{
285 		if	(strcmp(*argv,"-verbose") == 0)
286 			verbose=1;
287 		else if	(strcmp(*argv,"-config") == 0)
288 			{
289 			if (--argc < 1) goto bad;
290 			configfile= *(++argv);
291 			}
292 		else if (strcmp(*argv,"-name") == 0)
293 			{
294 			if (--argc < 1) goto bad;
295 			section= *(++argv);
296 			}
297 		else if (strcmp(*argv,"-startdate") == 0)
298 			{
299 			if (--argc < 1) goto bad;
300 			startdate= *(++argv);
301 			}
302 		else if (strcmp(*argv,"-enddate") == 0)
303 			{
304 			if (--argc < 1) goto bad;
305 			enddate= *(++argv);
306 			}
307 		else if (strcmp(*argv,"-days") == 0)
308 			{
309 			if (--argc < 1) goto bad;
310 			days=atoi(*(++argv));
311 			}
312 		else if (strcmp(*argv,"-md") == 0)
313 			{
314 			if (--argc < 1) goto bad;
315 			md= *(++argv);
316 			}
317 		else if (strcmp(*argv,"-policy") == 0)
318 			{
319 			if (--argc < 1) goto bad;
320 			policy= *(++argv);
321 			}
322 		else if (strcmp(*argv,"-keyfile") == 0)
323 			{
324 			if (--argc < 1) goto bad;
325 			keyfile= *(++argv);
326 			}
327 		else if (strcmp(*argv,"-key") == 0)
328 			{
329 			if (--argc < 1) goto bad;
330 			key= *(++argv);
331 			}
332 		else if (strcmp(*argv,"-cert") == 0)
333 			{
334 			if (--argc < 1) goto bad;
335 			certfile= *(++argv);
336 			}
337 		else if (strcmp(*argv,"-in") == 0)
338 			{
339 			if (--argc < 1) goto bad;
340 			infile= *(++argv);
341 			req=1;
342 			}
343 		else if (strcmp(*argv,"-out") == 0)
344 			{
345 			if (--argc < 1) goto bad;
346 			outfile= *(++argv);
347 			}
348 		else if (strcmp(*argv,"-outdir") == 0)
349 			{
350 			if (--argc < 1) goto bad;
351 			outdir= *(++argv);
352 			}
353 		else if (strcmp(*argv,"-batch") == 0)
354 			batch=1;
355 		else if (strcmp(*argv,"-preserveDN") == 0)
356 			preserve=1;
357 		else if (strcmp(*argv,"-gencrl") == 0)
358 			gencrl=1;
359 		else if (strcmp(*argv,"-msie_hack") == 0)
360 			msie_hack=1;
361 		else if (strcmp(*argv,"-crldays") == 0)
362 			{
363 			if (--argc < 1) goto bad;
364 			crldays= atol(*(++argv));
365 			}
366 		else if (strcmp(*argv,"-crlhours") == 0)
367 			{
368 			if (--argc < 1) goto bad;
369 			crlhours= atol(*(++argv));
370 			}
371 		else if (strcmp(*argv,"-infiles") == 0)
372 			{
373 			argc--;
374 			argv++;
375 			req=1;
376 			break;
377 			}
378 		else if (strcmp(*argv, "-ss_cert") == 0)
379 			{
380 			if (--argc < 1) goto bad;
381 			ss_cert_file = *(++argv);
382 			req=1;
383 			}
384 		else if (strcmp(*argv, "-spkac") == 0)
385 			{
386 			if (--argc < 1) goto bad;
387 			spkac_file = *(++argv);
388 			req=1;
389 			}
390 		else if (strcmp(*argv,"-revoke") == 0)
391 			{
392 			if (--argc < 1) goto bad;
393 			infile= *(++argv);
394 			dorevoke=1;
395 			}
396 		else
397 			{
398 bad:
399 			BIO_printf(bio_err,"unknown option %s\n",*argv);
400 			badops=1;
401 			break;
402 			}
403 		argc--;
404 		argv++;
405 		}
406 
407 	if (badops)
408 		{
409 		for (pp=ca_usage; (*pp != NULL); pp++)
410 			BIO_printf(bio_err,*pp);
411 		goto err;
412 		}
413 
414 	ERR_load_crypto_strings();
415 
416 	/*****************************************************************/
417 	if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
418 	if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
419 	if (configfile == NULL)
420 		{
421 		/* We will just use 'buf[0]' as a temporary buffer.  */
422 #ifdef VMS
423 		strncpy(buf[0],X509_get_default_cert_area(),
424 			sizeof(buf[0])-1-sizeof(CONFIG_FILE));
425 #else
426 		strncpy(buf[0],X509_get_default_cert_area(),
427 			sizeof(buf[0])-2-sizeof(CONFIG_FILE));
428 		strcat(buf[0],"/");
429 #endif
430 		strcat(buf[0],CONFIG_FILE);
431 		configfile=buf[0];
432 		}
433 
434 	BIO_printf(bio_err,"Using configuration from %s\n",configfile);
435 	if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
436 		{
437 		if (errorline <= 0)
438 			BIO_printf(bio_err,"error loading the config file '%s'\n",
439 				configfile);
440 		else
441 			BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
442 				,errorline,configfile);
443 		goto err;
444 		}
445 
446 	/* Lets get the config section we are using */
447 	if (section == NULL)
448 		{
449 		section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
450 		if (section == NULL)
451 			{
452 			lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
453 			goto err;
454 			}
455 		}
456 
457 	if (conf != NULL)
458 		{
459 		p=CONF_get_string(conf,NULL,"oid_file");
460 		if (p != NULL)
461 			{
462 			BIO *oid_bio;
463 
464 			oid_bio=BIO_new_file(p,"r");
465 			if (oid_bio == NULL)
466 				{
467 				/*
468 				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
469 				ERR_print_errors(bio_err);
470 				*/
471 				ERR_clear_error();
472 				}
473 			else
474 				{
475 				OBJ_create_objects(oid_bio);
476 				BIO_free(oid_bio);
477 				}
478 			}
479 		}
480 		if(!add_oid_section(conf)) {
481 			ERR_print_errors(bio_err);
482 			goto err;
483 		}
484 
485 	in=BIO_new(BIO_s_file());
486 	out=BIO_new(BIO_s_file());
487 	Sout=BIO_new(BIO_s_file());
488 	Cout=BIO_new(BIO_s_file());
489 	if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
490 		{
491 		ERR_print_errors(bio_err);
492 		goto err;
493 		}
494 
495 	/*****************************************************************/
496 	/* we definitly need an public key, so lets get it */
497 
498 	if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
499 		section,ENV_PRIVATE_KEY)) == NULL))
500 		{
501 		lookup_fail(section,ENV_PRIVATE_KEY);
502 		goto err;
503 		}
504 	if (BIO_read_filename(in,keyfile) <= 0)
505 		{
506 		perror(keyfile);
507 		BIO_printf(bio_err,"trying to load CA private key\n");
508 		goto err;
509 		}
510 	if (key == NULL)
511 		pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL);
512 	else
513 		{
514 		pkey=PEM_read_bio_PrivateKey(in,NULL,key_callback,NULL);
515 		memset(key,0,strlen(key));
516 		}
517 	if (pkey == NULL)
518 		{
519 		BIO_printf(bio_err,"unable to load CA private key\n");
520 		goto err;
521 		}
522 
523 	/*****************************************************************/
524 	/* we need a certificate */
525 	if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
526 		section,ENV_CERTIFICATE)) == NULL))
527 		{
528 		lookup_fail(section,ENV_CERTIFICATE);
529 		goto err;
530 		}
531         if (BIO_read_filename(in,certfile) <= 0)
532 		{
533 		perror(certfile);
534 		BIO_printf(bio_err,"trying to load CA certificate\n");
535 		goto err;
536 		}
537 	x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
538 	if (x509 == NULL)
539 		{
540 		BIO_printf(bio_err,"unable to load CA certificate\n");
541 		goto err;
542 		}
543 
544 	if (!X509_check_private_key(x509,pkey))
545 		{
546 		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
547 		goto err;
548 		}
549 
550 	f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
551 	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
552 		preserve=1;
553 	f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
554 	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
555 		msie_hack=1;
556 
557 	/*****************************************************************/
558 	/* lookup where to write new certificates */
559 	if ((outdir == NULL) && (req))
560 		{
561 		struct stat sb;
562 
563 		if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
564 			== NULL)
565 			{
566 			BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
567 			goto err;
568 			}
569 #ifdef VMS
570 		/* For technical reasons, VMS misbehaves with X_OK */
571 		if (access(outdir,R_OK|W_OK) != 0)
572 #else
573 		if (access(outdir,R_OK|W_OK|X_OK) != 0)
574 #endif
575 			{
576 			BIO_printf(bio_err,"I am unable to acces the %s directory\n",outdir);
577 			perror(outdir);
578 			goto err;
579 			}
580 
581 		if (stat(outdir,&sb) != 0)
582 			{
583 			BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
584 			perror(outdir);
585 			goto err;
586 			}
587 		if (!(sb.st_mode & S_IFDIR))
588 			{
589 			BIO_printf(bio_err,"%s need to be a directory\n",outdir);
590 			perror(outdir);
591 			goto err;
592 			}
593 		}
594 
595 	/*****************************************************************/
596 	/* we need to load the database file */
597 	if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
598 		{
599 		lookup_fail(section,ENV_DATABASE);
600 		goto err;
601 		}
602 	if (BIO_read_filename(in,dbfile) <= 0)
603 		{
604 		perror(dbfile);
605 		BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
606 		goto err;
607 		}
608 	db=TXT_DB_read(in,DB_NUMBER);
609 	if (db == NULL) goto err;
610 
611 	/* Lets check some fields */
612 	for (i=0; i<sk_num(db->data); i++)
613 		{
614 		pp=(char **)sk_value(db->data,i);
615 		if ((pp[DB_type][0] != DB_TYPE_REV) &&
616 			(pp[DB_rev_date][0] != '\0'))
617 			{
618 			BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
619 			goto err;
620 			}
621 		if ((pp[DB_type][0] == DB_TYPE_REV) &&
622 			!check_time_format(pp[DB_rev_date]))
623 			{
624 			BIO_printf(bio_err,"entry %d: invalid revocation date\n",
625 				i+1);
626 			goto err;
627 			}
628 		if (!check_time_format(pp[DB_exp_date]))
629 			{
630 			BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
631 			goto err;
632 			}
633 		p=pp[DB_serial];
634 		j=strlen(p);
635 		if ((j&1) || (j < 2))
636 			{
637 			BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
638 			goto err;
639 			}
640 		while (*p)
641 			{
642 			if (!(	((*p >= '0') && (*p <= '9')) ||
643 				((*p >= 'A') && (*p <= 'F')) ||
644 				((*p >= 'a') && (*p <= 'f')))  )
645 				{
646 				BIO_printf(bio_err,"entry %d: bad serial number characters, char pos %ld, char is '%c'\n",i+1,(long)(p-pp[DB_serial]),*p);
647 				goto err;
648 				}
649 			p++;
650 			}
651 		}
652 	if (verbose)
653 		{
654 		BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
655 		TXT_DB_write(out,db);
656 		BIO_printf(bio_err,"%d entries loaded from the database\n",
657 			db->data->num);
658 		BIO_printf(bio_err,"generating indexs\n");
659 		}
660 
661 	if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
662 		index_serial_cmp))
663 		{
664 		BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
665 		goto err;
666 		}
667 
668 	if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
669 		index_name_cmp))
670 		{
671 		BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
672 			db->error,db->arg1,db->arg2);
673 		goto err;
674 		}
675 
676 	/*****************************************************************/
677 	if (req || gencrl)
678 		{
679 		if (outfile != NULL)
680 			{
681 
682 			if (BIO_write_filename(Sout,outfile) <= 0)
683 				{
684 				perror(outfile);
685 				goto err;
686 				}
687 			}
688 		else
689 			BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
690 		}
691 
692 	if (req)
693 		{
694 		if ((md == NULL) && ((md=CONF_get_string(conf,
695 			section,ENV_DEFAULT_MD)) == NULL))
696 			{
697 			lookup_fail(section,ENV_DEFAULT_MD);
698 			goto err;
699 			}
700 		if ((dgst=EVP_get_digestbyname(md)) == NULL)
701 			{
702 			BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
703 			goto err;
704 			}
705 		if (verbose)
706 			BIO_printf(bio_err,"message digest is %s\n",
707 				OBJ_nid2ln(dgst->type));
708 		if ((policy == NULL) && ((policy=CONF_get_string(conf,
709 			section,ENV_POLICY)) == NULL))
710 			{
711 			lookup_fail(section,ENV_POLICY);
712 			goto err;
713 			}
714 		if (verbose)
715 			BIO_printf(bio_err,"policy is %s\n",policy);
716 
717 		if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
718 			== NULL)
719 			{
720 			lookup_fail(section,ENV_SERIAL);
721 			goto err;
722 			}
723 
724 		extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
725 		if(extensions) {
726 			/* Check syntax of file */
727 			X509V3_CTX ctx;
728 			X509V3_set_ctx_test(&ctx);
729 			X509V3_set_conf_lhash(&ctx, conf);
730 			if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
731 				BIO_printf(bio_err,
732 				 "Error Loading extension section %s\n",
733 								 extensions);
734 				ret = 1;
735 				goto err;
736 			}
737 		}
738 
739 		if (startdate == NULL)
740 			{
741 			startdate=CONF_get_string(conf,section,
742 				ENV_DEFAULT_STARTDATE);
743 			}
744 		if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
745 			{
746 			BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
747 			goto err;
748 			}
749 		if (startdate == NULL) startdate="today";
750 
751 		if (enddate == NULL)
752 			{
753 			enddate=CONF_get_string(conf,section,
754 				ENV_DEFAULT_ENDDATE);
755 			}
756 		if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
757 			{
758 			BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
759 			goto err;
760 			}
761 
762 		if (days == 0)
763 			{
764 			days=(int)CONF_get_number(conf,section,
765 				ENV_DEFAULT_DAYS);
766 			}
767 		if (!enddate && (days == 0))
768 			{
769 			BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
770 			goto err;
771 			}
772 
773 		if ((serial=load_serial(serialfile)) == NULL)
774 			{
775 			BIO_printf(bio_err,"error while loading serial number\n");
776 			goto err;
777 			}
778 		if (verbose)
779 			{
780 			if ((f=BN_bn2hex(serial)) == NULL) goto err;
781 			BIO_printf(bio_err,"next serial number is %s\n",f);
782 			Free(f);
783 			}
784 
785 		if ((attribs=CONF_get_section(conf,policy)) == NULL)
786 			{
787 			BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
788 			goto err;
789 			}
790 
791 		if ((cert_sk=sk_new_null()) == NULL)
792 			{
793 			BIO_printf(bio_err,"Malloc failure\n");
794 			goto err;
795 			}
796 		if (spkac_file != NULL)
797 			{
798 			total++;
799 			j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
800 				serial,startdate,enddate, days,extensions,conf,
801 				verbose);
802 			if (j < 0) goto err;
803 			if (j > 0)
804 				{
805 				total_done++;
806 				BIO_printf(bio_err,"\n");
807 				if (!BN_add_word(serial,1)) goto err;
808 				if (!sk_push(cert_sk,(char *)x))
809 					{
810 					BIO_printf(bio_err,"Malloc failure\n");
811 					goto err;
812 					}
813 				if (outfile)
814 					{
815 					output_der = 1;
816 					batch = 1;
817 					}
818 				}
819 			}
820 		if (ss_cert_file != NULL)
821 			{
822 			total++;
823 			j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
824 				db,serial,startdate,enddate,days,batch,
825 				extensions,conf,verbose);
826 			if (j < 0) goto err;
827 			if (j > 0)
828 				{
829 				total_done++;
830 				BIO_printf(bio_err,"\n");
831 				if (!BN_add_word(serial,1)) goto err;
832 				if (!sk_push(cert_sk,(char *)x))
833 					{
834 					BIO_printf(bio_err,"Malloc failure\n");
835 					goto err;
836 					}
837 				}
838 			}
839 		if (infile != NULL)
840 			{
841 			total++;
842 			j=certify(&x,infile,pkey,x509,dgst,attribs,db,
843 				serial,startdate,enddate,days,batch,
844 				extensions,conf,verbose);
845 			if (j < 0) goto err;
846 			if (j > 0)
847 				{
848 				total_done++;
849 				BIO_printf(bio_err,"\n");
850 				if (!BN_add_word(serial,1)) goto err;
851 				if (!sk_push(cert_sk,(char *)x))
852 					{
853 					BIO_printf(bio_err,"Malloc failure\n");
854 					goto err;
855 					}
856 				}
857 			}
858 		for (i=0; i<argc; i++)
859 			{
860 			total++;
861 			j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
862 				serial,startdate,enddate,days,batch,
863 				extensions,conf,verbose);
864 			if (j < 0) goto err;
865 			if (j > 0)
866 				{
867 				total_done++;
868 				BIO_printf(bio_err,"\n");
869 				if (!BN_add_word(serial,1)) goto err;
870 				if (!sk_push(cert_sk,(char *)x))
871 					{
872 					BIO_printf(bio_err,"Malloc failure\n");
873 					goto err;
874 					}
875 				}
876 			}
877 		/* we have a stack of newly certified certificates
878 		 * and a data base and serial number that need
879 		 * updating */
880 
881 		if (sk_num(cert_sk) > 0)
882 			{
883 			if (!batch)
884 				{
885 				BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
886 				(void)BIO_flush(bio_err);
887 				buf[0][0]='\0';
888 				fgets(buf[0],10,stdin);
889 				if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
890 					{
891 					BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
892 					ret=0;
893 					goto err;
894 					}
895 				}
896 
897 			BIO_printf(bio_err,"Write out database with %d new entries\n",sk_num(cert_sk));
898 
899 			strncpy(buf[0],serialfile,BSIZE-4);
900 
901 #ifdef VMS
902 			strcat(buf[0],"-new");
903 #else
904 			strcat(buf[0],".new");
905 #endif
906 
907 			if (!save_serial(buf[0],serial)) goto err;
908 
909 			strncpy(buf[1],dbfile,BSIZE-4);
910 
911 #ifdef VMS
912 			strcat(buf[1],"-new");
913 #else
914 			strcat(buf[1],".new");
915 #endif
916 
917 			if (BIO_write_filename(out,buf[1]) <= 0)
918 				{
919 				perror(dbfile);
920 				BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
921 				goto err;
922 				}
923 			l=TXT_DB_write(out,db);
924 			if (l <= 0) goto err;
925 			}
926 
927 		if (verbose)
928 			BIO_printf(bio_err,"writing new certificates\n");
929 		for (i=0; i<sk_num(cert_sk); i++)
930 			{
931 			int k;
932 			unsigned char *n;
933 
934 			x=(X509 *)sk_value(cert_sk,i);
935 
936 			j=x->cert_info->serialNumber->length;
937 			p=(char *)x->cert_info->serialNumber->data;
938 
939 			strncpy(buf[2],outdir,BSIZE-(j*2)-6);
940 
941 #ifndef VMS
942 			strcat(buf[2],"/");
943 #endif
944 
945 			n=(unsigned char *)&(buf[2][strlen(buf[2])]);
946 			if (j > 0)
947 				{
948 				for (k=0; k<j; k++)
949 					{
950 					sprintf((char *)n,"%02X",(unsigned char)*(p++));
951 					n+=2;
952 					}
953 				}
954 			else
955 				{
956 				*(n++)='0';
957 				*(n++)='0';
958 				}
959 			*(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
960 			*n='\0';
961 			if (verbose)
962 				BIO_printf(bio_err,"writing %s\n",buf[2]);
963 
964 			if (BIO_write_filename(Cout,buf[2]) <= 0)
965 				{
966 				perror(buf[2]);
967 				goto err;
968 				}
969 			write_new_certificate(Cout,x, 0);
970 			write_new_certificate(Sout,x, output_der);
971 			}
972 
973 		if (sk_num(cert_sk))
974 			{
975 			/* Rename the database and the serial file */
976 			strncpy(buf[2],serialfile,BSIZE-4);
977 
978 #ifdef VMS
979 			strcat(buf[2],"-old");
980 #else
981 			strcat(buf[2],".old");
982 #endif
983 
984 			BIO_free(in);
985 			BIO_free(out);
986 			in=NULL;
987 			out=NULL;
988 			if (rename(serialfile,buf[2]) < 0)
989 				{
990 				BIO_printf(bio_err,"unabel to rename %s to %s\n",
991 					serialfile,buf[2]);
992 				perror("reason");
993 				goto err;
994 				}
995 			if (rename(buf[0],serialfile) < 0)
996 				{
997 				BIO_printf(bio_err,"unabel to rename %s to %s\n",
998 					buf[0],serialfile);
999 				perror("reason");
1000 				rename(buf[2],serialfile);
1001 				goto err;
1002 				}
1003 
1004 			strncpy(buf[2],dbfile,BSIZE-4);
1005 
1006 #ifdef VMS
1007 			strcat(buf[2],"-old");
1008 #else
1009 			strcat(buf[2],".old");
1010 #endif
1011 
1012 			if (rename(dbfile,buf[2]) < 0)
1013 				{
1014 				BIO_printf(bio_err,"unabel to rename %s to %s\n",
1015 					dbfile,buf[2]);
1016 				perror("reason");
1017 				goto err;
1018 				}
1019 			if (rename(buf[1],dbfile) < 0)
1020 				{
1021 				BIO_printf(bio_err,"unabel to rename %s to %s\n",
1022 					buf[1],dbfile);
1023 				perror("reason");
1024 				rename(buf[2],dbfile);
1025 				goto err;
1026 				}
1027 			BIO_printf(bio_err,"Data Base Updated\n");
1028 			}
1029 		}
1030 
1031 	/*****************************************************************/
1032 	if (gencrl)
1033 		{
1034 		crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1035 		if(crl_ext) {
1036 			/* Check syntax of file */
1037 			X509V3_CTX ctx;
1038 			X509V3_set_ctx_test(&ctx);
1039 			X509V3_set_conf_lhash(&ctx, conf);
1040 			if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1041 				BIO_printf(bio_err,
1042 				 "Error Loading CRL extension section %s\n",
1043 								 crl_ext);
1044 				ret = 1;
1045 				goto err;
1046 			}
1047 		}
1048 		if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1049 
1050 		if (!crldays && !crlhours)
1051 			{
1052 			crldays=CONF_get_number(conf,section,
1053 				ENV_DEFAULT_CRL_DAYS);
1054 			crlhours=CONF_get_number(conf,section,
1055 				ENV_DEFAULT_CRL_HOURS);
1056 			}
1057 		if ((crldays == 0) && (crlhours == 0))
1058 			{
1059 			BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1060 			goto err;
1061 			}
1062 
1063 		if (verbose) BIO_printf(bio_err,"making CRL\n");
1064 		if ((crl=X509_CRL_new()) == NULL) goto err;
1065 		ci=crl->crl;
1066 		X509_NAME_free(ci->issuer);
1067 		ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1068 		if (ci->issuer == NULL) goto err;
1069 
1070 		X509_gmtime_adj(ci->lastUpdate,0);
1071 		if (ci->nextUpdate == NULL)
1072 			ci->nextUpdate=ASN1_UTCTIME_new();
1073 		X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1074 
1075 		for (i=0; i<sk_num(db->data); i++)
1076 			{
1077 			pp=(char **)sk_value(db->data,i);
1078 			if (pp[DB_type][0] == DB_TYPE_REV)
1079 				{
1080 				if ((r=X509_REVOKED_new()) == NULL) goto err;
1081 				ASN1_STRING_set((ASN1_STRING *)
1082 					r->revocationDate,
1083 					(unsigned char *)pp[DB_rev_date],
1084 					strlen(pp[DB_rev_date]));
1085 				/* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1086 
1087 				(void)BIO_reset(hex);
1088 				if (!BIO_puts(hex,pp[DB_serial]))
1089 					goto err;
1090 				if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1091 					buf[0],BSIZE)) goto err;
1092 
1093 				sk_X509_REVOKED_push(ci->revoked,r);
1094 				}
1095 			}
1096 		/* sort the data so it will be written in serial
1097 		 * number order */
1098 		sk_X509_REVOKED_sort(ci->revoked);
1099 		for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1100 			{
1101 			r=sk_X509_REVOKED_value(ci->revoked,i);
1102 			r->sequence=i;
1103 			}
1104 
1105 		/* we now have a CRL */
1106 		if (verbose) BIO_printf(bio_err,"signing CRL\n");
1107 		if (md != NULL)
1108 			{
1109 			if ((dgst=EVP_get_digestbyname(md)) == NULL)
1110 				{
1111 				BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1112 				goto err;
1113 				}
1114 			}
1115 		else
1116 		    {
1117 #ifndef NO_DSA
1118 		    if (pkey->type == EVP_PKEY_DSA)
1119 			dgst=EVP_dss1();
1120 		    else
1121 #endif
1122 			dgst=EVP_md5();
1123 		    }
1124 
1125 		/* Add any extensions asked for */
1126 
1127 		if(crl_ext) {
1128 		    X509V3_CTX crlctx;
1129 		    if (ci->version == NULL)
1130 		    if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1131 		    ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1132 		    X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1133 		    X509V3_set_conf_lhash(&crlctx, conf);
1134 
1135 		    if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1136 						 crl_ext, crl)) goto err;
1137 		}
1138 
1139 		if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1140 
1141 		PEM_write_bio_X509_CRL(Sout,crl);
1142 		}
1143 	/*****************************************************************/
1144 	if (dorevoke)
1145 		{
1146 		in=BIO_new(BIO_s_file());
1147 		out=BIO_new(BIO_s_file());
1148 		if ((in == NULL) || (out == NULL))
1149 			{
1150 			ERR_print_errors(bio_err);
1151 			goto err;
1152 			}
1153 		if (infile == NULL)
1154 			{
1155 			BIO_printf(bio_err,"no input files\n");
1156 			goto err;
1157 			}
1158 		else
1159 			{
1160 			if (BIO_read_filename(in,infile) <= 0)
1161 				{
1162 				perror(infile);
1163 				BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1164 				goto err;
1165 				}
1166 			x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
1167 			if (x509 == NULL)
1168 				{
1169 				BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1170 				goto err;
1171 				}
1172 			j=do_revoke(x509,db);
1173 
1174 			strncpy(buf[0],dbfile,BSIZE-4);
1175 			strcat(buf[0],".new");
1176 			if (BIO_write_filename(out,buf[0]) <= 0)
1177 				{
1178 				perror(dbfile);
1179 				BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1180 				goto err;
1181 				}
1182 			j=TXT_DB_write(out,db);
1183 			if (j <= 0) goto err;
1184 			BIO_free(in);
1185 			BIO_free(out);
1186 			in=NULL;
1187 			out=NULL;
1188 			strncpy(buf[1],dbfile,BSIZE-4);
1189 			strcat(buf[1],".old");
1190 			if (rename(dbfile,buf[1]) < 0)
1191 				{
1192 				BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1193 				perror("reason");
1194 				goto err;
1195 				}
1196 			if (rename(buf[0],dbfile) < 0)
1197 				{
1198 				BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1199 				perror("reason");
1200 				rename(buf[1],dbfile);
1201 				goto err;
1202 				}
1203 			BIO_printf(bio_err,"Data Base Updated\n");
1204 			}
1205 		}
1206 	/*****************************************************************/
1207 	ret=0;
1208 err:
1209 	BIO_free(hex);
1210 	BIO_free(Cout);
1211 	BIO_free(Sout);
1212 	BIO_free(out);
1213 	BIO_free(in);
1214 
1215 	sk_pop_free(cert_sk,X509_free);
1216 
1217 	if (ret) ERR_print_errors(bio_err);
1218 	BN_free(serial);
1219 	TXT_DB_free(db);
1220 	EVP_PKEY_free(pkey);
1221 	X509_free(x509);
1222 	X509_CRL_free(crl);
1223 	CONF_free(conf);
1224 	X509V3_EXT_cleanup();
1225 	OBJ_cleanup();
1226 	EXIT(ret);
1227 	}
1228 
1229 static void lookup_fail(char *name, char *tag)
1230 	{
1231 	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1232 	}
1233 
1234 static int MS_CALLBACK key_callback(char *buf, int len, int verify, void *u)
1235 	{
1236 	int i;
1237 
1238 	if (key == NULL) return(0);
1239 	i=strlen(key);
1240 	i=(i > len)?len:i;
1241 	memcpy(buf,key,i);
1242 	return(i);
1243 	}
1244 
1245 static unsigned long index_serial_hash(char **a)
1246 	{
1247 	char *n;
1248 
1249 	n=a[DB_serial];
1250 	while (*n == '0') n++;
1251 	return(lh_strhash(n));
1252 	}
1253 
1254 static int index_serial_cmp(char **a, char **b)
1255 	{
1256 	char *aa,*bb;
1257 
1258 	for (aa=a[DB_serial]; *aa == '0'; aa++);
1259 	for (bb=b[DB_serial]; *bb == '0'; bb++);
1260 	return(strcmp(aa,bb));
1261 	}
1262 
1263 static unsigned long index_name_hash(char **a)
1264 	{ return(lh_strhash(a[DB_name])); }
1265 
1266 static int index_name_qual(char **a)
1267 	{ return(a[0][0] == 'V'); }
1268 
1269 static int index_name_cmp(char **a, char **b)
1270 	{ return(strcmp(a[DB_name],
1271 	     b[DB_name])); }
1272 
1273 static BIGNUM *load_serial(char *serialfile)
1274 	{
1275 	BIO *in=NULL;
1276 	BIGNUM *ret=NULL;
1277 	MS_STATIC char buf[1024];
1278 	ASN1_INTEGER *ai=NULL;
1279 
1280 	if ((in=BIO_new(BIO_s_file())) == NULL)
1281 		{
1282 		ERR_print_errors(bio_err);
1283 		goto err;
1284 		}
1285 
1286 	if (BIO_read_filename(in,serialfile) <= 0)
1287 		{
1288 		perror(serialfile);
1289 		goto err;
1290 		}
1291 	ai=ASN1_INTEGER_new();
1292 	if (ai == NULL) goto err;
1293 	if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1294 		{
1295 		BIO_printf(bio_err,"unable to load number from %s\n",
1296 			serialfile);
1297 		goto err;
1298 		}
1299 	ret=ASN1_INTEGER_to_BN(ai,NULL);
1300 	if (ret == NULL)
1301 		{
1302 		BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1303 		goto err;
1304 		}
1305 err:
1306 	if (in != NULL) BIO_free(in);
1307 	if (ai != NULL) ASN1_INTEGER_free(ai);
1308 	return(ret);
1309 	}
1310 
1311 static int save_serial(char *serialfile, BIGNUM *serial)
1312 	{
1313 	BIO *out;
1314 	int ret=0;
1315 	ASN1_INTEGER *ai=NULL;
1316 
1317 	out=BIO_new(BIO_s_file());
1318 	if (out == NULL)
1319 		{
1320 		ERR_print_errors(bio_err);
1321 		goto err;
1322 		}
1323 	if (BIO_write_filename(out,serialfile) <= 0)
1324 		{
1325 		perror(serialfile);
1326 		goto err;
1327 		}
1328 
1329 	if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1330 		{
1331 		BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1332 		goto err;
1333 		}
1334 	i2a_ASN1_INTEGER(out,ai);
1335 	BIO_puts(out,"\n");
1336 	ret=1;
1337 err:
1338 	if (out != NULL) BIO_free(out);
1339 	if (ai != NULL) ASN1_INTEGER_free(ai);
1340 	return(ret);
1341 	}
1342 
1343 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1344 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1345 	     BIGNUM *serial, char *startdate, char *enddate, int days,
1346 	     int batch, char *ext_sect, LHASH *lconf, int verbose)
1347 	{
1348 	X509_REQ *req=NULL;
1349 	BIO *in=NULL;
1350 	EVP_PKEY *pktmp=NULL;
1351 	int ok= -1,i;
1352 
1353 	in=BIO_new(BIO_s_file());
1354 
1355 	if (BIO_read_filename(in,infile) <= 0)
1356 		{
1357 		perror(infile);
1358 		goto err;
1359 		}
1360 	if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1361 		{
1362 		BIO_printf(bio_err,"Error reading certificate request in %s\n",
1363 			infile);
1364 		goto err;
1365 		}
1366 	if (verbose)
1367 		X509_REQ_print(bio_err,req);
1368 
1369 	BIO_printf(bio_err,"Check that the request matches the signature\n");
1370 
1371 	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1372 		{
1373 		BIO_printf(bio_err,"error unpacking public key\n");
1374 		goto err;
1375 		}
1376 	i=X509_REQ_verify(req,pktmp);
1377 	EVP_PKEY_free(pktmp);
1378 	if (i < 0)
1379 		{
1380 		ok=0;
1381 		BIO_printf(bio_err,"Signature verification problems....\n");
1382 		goto err;
1383 		}
1384 	if (i == 0)
1385 		{
1386 		ok=0;
1387 		BIO_printf(bio_err,"Signature did not match the certificate request\n");
1388 		goto err;
1389 		}
1390 	else
1391 		BIO_printf(bio_err,"Signature ok\n");
1392 
1393 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1394 		days,batch,verbose,req,ext_sect,lconf);
1395 
1396 err:
1397 	if (req != NULL) X509_REQ_free(req);
1398 	if (in != NULL) BIO_free(in);
1399 	return(ok);
1400 	}
1401 
1402 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1403 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1404 	     BIGNUM *serial, char *startdate, char *enddate, int days,
1405 	     int batch, char *ext_sect, LHASH *lconf, int verbose)
1406 	{
1407 	X509 *req=NULL;
1408 	X509_REQ *rreq=NULL;
1409 	BIO *in=NULL;
1410 	EVP_PKEY *pktmp=NULL;
1411 	int ok= -1,i;
1412 
1413 	in=BIO_new(BIO_s_file());
1414 
1415 	if (BIO_read_filename(in,infile) <= 0)
1416 		{
1417 		perror(infile);
1418 		goto err;
1419 		}
1420 	if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1421 		{
1422 		BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1423 		goto err;
1424 		}
1425 	if (verbose)
1426 		X509_print(bio_err,req);
1427 
1428 	BIO_printf(bio_err,"Check that the request matches the signature\n");
1429 
1430 	if ((pktmp=X509_get_pubkey(req)) == NULL)
1431 		{
1432 		BIO_printf(bio_err,"error unpacking public key\n");
1433 		goto err;
1434 		}
1435 	i=X509_verify(req,pktmp);
1436 	EVP_PKEY_free(pktmp);
1437 	if (i < 0)
1438 		{
1439 		ok=0;
1440 		BIO_printf(bio_err,"Signature verification problems....\n");
1441 		goto err;
1442 		}
1443 	if (i == 0)
1444 		{
1445 		ok=0;
1446 		BIO_printf(bio_err,"Signature did not match the certificate\n");
1447 		goto err;
1448 		}
1449 	else
1450 		BIO_printf(bio_err,"Signature ok\n");
1451 
1452 	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1453 		goto err;
1454 
1455 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1456 		batch,verbose,rreq,ext_sect,lconf);
1457 
1458 err:
1459 	if (rreq != NULL) X509_REQ_free(rreq);
1460 	if (req != NULL) X509_free(req);
1461 	if (in != NULL) BIO_free(in);
1462 	return(ok);
1463 	}
1464 
1465 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1466 	     STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1467 	     char *startdate, char *enddate, int days, int batch, int verbose,
1468 	     X509_REQ *req, char *ext_sect, LHASH *lconf)
1469 	{
1470 	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1471 	ASN1_UTCTIME *tm,*tmptm;
1472 	ASN1_STRING *str,*str2;
1473 	ASN1_OBJECT *obj;
1474 	X509 *ret=NULL;
1475 	X509_CINF *ci;
1476 	X509_NAME_ENTRY *ne;
1477 	X509_NAME_ENTRY *tne,*push;
1478 	EVP_PKEY *pktmp;
1479 	int ok= -1,i,j,last,nid;
1480 	char *p;
1481 	CONF_VALUE *cv;
1482 	char *row[DB_NUMBER],**rrow,**irow=NULL;
1483 	char buf[25],*pbuf;
1484 
1485 	tmptm=ASN1_UTCTIME_new();
1486 	if (tmptm == NULL)
1487 		{
1488 		BIO_printf(bio_err,"malloc error\n");
1489 		return(0);
1490 		}
1491 
1492 	for (i=0; i<DB_NUMBER; i++)
1493 		row[i]=NULL;
1494 
1495 	BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1496 	name=X509_REQ_get_subject_name(req);
1497 	for (i=0; i<X509_NAME_entry_count(name); i++)
1498 		{
1499 		ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1500 		obj=X509_NAME_ENTRY_get_object(ne);
1501 		j=i2a_ASN1_OBJECT(bio_err,obj);
1502 		str=X509_NAME_ENTRY_get_data(ne);
1503 		pbuf=buf;
1504 		for (j=22-j; j>0; j--)
1505 			*(pbuf++)=' ';
1506 		*(pbuf++)=':';
1507 		*(pbuf++)='\0';
1508 		BIO_puts(bio_err,buf);
1509 
1510 		if (msie_hack)
1511 			{
1512 			/* assume all type should be strings */
1513 			nid=OBJ_obj2nid(ne->object);
1514 
1515 			if (str->type == V_ASN1_UNIVERSALSTRING)
1516 				ASN1_UNIVERSALSTRING_to_string(str);
1517 
1518 			if ((str->type == V_ASN1_IA5STRING) &&
1519 				(nid != NID_pkcs9_emailAddress))
1520 				str->type=V_ASN1_T61STRING;
1521 
1522 			if ((nid == NID_pkcs9_emailAddress) &&
1523 				(str->type == V_ASN1_PRINTABLESTRING))
1524 				str->type=V_ASN1_IA5STRING;
1525 			}
1526 
1527 		if (str->type == V_ASN1_PRINTABLESTRING)
1528 			BIO_printf(bio_err,"PRINTABLE:'");
1529 		else if (str->type == V_ASN1_T61STRING)
1530 			BIO_printf(bio_err,"T61STRING:'");
1531 		else if (str->type == V_ASN1_IA5STRING)
1532 			BIO_printf(bio_err,"IA5STRING:'");
1533 		else if (str->type == V_ASN1_UNIVERSALSTRING)
1534 			BIO_printf(bio_err,"UNIVERSALSTRING:'");
1535 		else
1536 			BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1537 
1538 		/* check some things */
1539 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1540 			(str->type != V_ASN1_IA5STRING))
1541 			{
1542 			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1543 			goto err;
1544 			}
1545 		j=ASN1_PRINTABLE_type(str->data,str->length);
1546 		if (	((j == V_ASN1_T61STRING) &&
1547 			 (str->type != V_ASN1_T61STRING)) ||
1548 			((j == V_ASN1_IA5STRING) &&
1549 			 (str->type == V_ASN1_PRINTABLESTRING)))
1550 			{
1551 			BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1552 			goto err;
1553 			}
1554 
1555 		p=(char *)str->data;
1556 		for (j=str->length; j>0; j--)
1557 			{
1558 			if ((*p >= ' ') && (*p <= '~'))
1559 				BIO_printf(bio_err,"%c",*p);
1560 			else if (*p & 0x80)
1561 				BIO_printf(bio_err,"\\0x%02X",*p);
1562 			else if ((unsigned char)*p == 0xf7)
1563 				BIO_printf(bio_err,"^?");
1564 			else	BIO_printf(bio_err,"^%c",*p+'@');
1565 			p++;
1566 			}
1567 		BIO_printf(bio_err,"'\n");
1568 		}
1569 
1570 	/* Ok, now we check the 'policy' stuff. */
1571 	if ((subject=X509_NAME_new()) == NULL)
1572 		{
1573 		BIO_printf(bio_err,"Malloc failure\n");
1574 		goto err;
1575 		}
1576 
1577 	/* take a copy of the issuer name before we mess with it. */
1578 	CAname=X509_NAME_dup(x509->cert_info->subject);
1579 	if (CAname == NULL) goto err;
1580 	str=str2=NULL;
1581 
1582 	for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1583 		{
1584 		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1585 		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1586 			{
1587 			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1588 			goto err;
1589 			}
1590 		obj=OBJ_nid2obj(j);
1591 
1592 		last= -1;
1593 		for (;;)
1594 			{
1595 			/* lookup the object in the supplied name list */
1596 			j=X509_NAME_get_index_by_OBJ(name,obj,last);
1597 			if (j < 0)
1598 				{
1599 				if (last != -1) break;
1600 				tne=NULL;
1601 				}
1602 			else
1603 				{
1604 				tne=X509_NAME_get_entry(name,j);
1605 				}
1606 			last=j;
1607 
1608 			/* depending on the 'policy', decide what to do. */
1609 			push=NULL;
1610 			if (strcmp(cv->value,"optional") == 0)
1611 				{
1612 				if (tne != NULL)
1613 					push=tne;
1614 				}
1615 			else if (strcmp(cv->value,"supplied") == 0)
1616 				{
1617 				if (tne == NULL)
1618 					{
1619 					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1620 					goto err;
1621 					}
1622 				else
1623 					push=tne;
1624 				}
1625 			else if (strcmp(cv->value,"match") == 0)
1626 				{
1627 				int last2;
1628 
1629 				if (tne == NULL)
1630 					{
1631 					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1632 					goto err;
1633 					}
1634 
1635 				last2= -1;
1636 
1637 again2:
1638 				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1639 				if ((j < 0) && (last2 == -1))
1640 					{
1641 					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1642 					goto err;
1643 					}
1644 				if (j >= 0)
1645 					{
1646 					push=X509_NAME_get_entry(CAname,j);
1647 					str=X509_NAME_ENTRY_get_data(tne);
1648 					str2=X509_NAME_ENTRY_get_data(push);
1649 					last2=j;
1650 					if (ASN1_STRING_cmp(str,str2) != 0)
1651 						goto again2;
1652 					}
1653 				if (j < 0)
1654 					{
1655 					BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str == NULL)?"NULL":(char *)str->data),((str2 == NULL)?"NULL":(char *)str2->data));
1656 					goto err;
1657 					}
1658 				}
1659 			else
1660 				{
1661 				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1662 				goto err;
1663 				}
1664 
1665 			if (push != NULL)
1666 				{
1667 				if (!X509_NAME_add_entry(subject,push,
1668 					X509_NAME_entry_count(subject),0))
1669 					{
1670 					if (push != NULL)
1671 						X509_NAME_ENTRY_free(push);
1672 					BIO_printf(bio_err,"Malloc failure\n");
1673 					goto err;
1674 					}
1675 				}
1676 			if (j < 0) break;
1677 			}
1678 		}
1679 
1680 	if (preserve)
1681 		{
1682 		X509_NAME_free(subject);
1683 		subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1684 		if (subject == NULL) goto err;
1685 		}
1686 
1687 	if (verbose)
1688 		BIO_printf(bio_err,"The subject name apears to be ok, checking data base for clashes\n");
1689 
1690 	row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1691 	row[DB_serial]=BN_bn2hex(serial);
1692 	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1693 		{
1694 		BIO_printf(bio_err,"Malloc failure\n");
1695 		goto err;
1696 		}
1697 
1698 	rrow=TXT_DB_get_by_index(db,DB_name,row);
1699 	if (rrow != NULL)
1700 		{
1701 		BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1702 			row[DB_name]);
1703 		}
1704 	else
1705 		{
1706 		rrow=TXT_DB_get_by_index(db,DB_serial,row);
1707 		if (rrow != NULL)
1708 			{
1709 			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1710 				row[DB_serial]);
1711 			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1712 			}
1713 		}
1714 
1715 	if (rrow != NULL)
1716 		{
1717 		BIO_printf(bio_err,
1718 			"The matching entry has the following details\n");
1719 		if (rrow[DB_type][0] == 'E')
1720 			p="Expired";
1721 		else if (rrow[DB_type][0] == 'R')
1722 			p="Revoked";
1723 		else if (rrow[DB_type][0] == 'V')
1724 			p="Valid";
1725 		else
1726 			p="\ninvalid type, Data base error\n";
1727 		BIO_printf(bio_err,"Type	  :%s\n",p);;
1728 		if (rrow[DB_type][0] == 'R')
1729 			{
1730 			p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1731 			BIO_printf(bio_err,"Was revoked on:%s\n",p);
1732 			}
1733 		p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1734 		BIO_printf(bio_err,"Expires on    :%s\n",p);
1735 		p=rrow[DB_serial]; if (p == NULL) p="undef";
1736 		BIO_printf(bio_err,"Serial Number :%s\n",p);
1737 		p=rrow[DB_file]; if (p == NULL) p="undef";
1738 		BIO_printf(bio_err,"File name     :%s\n",p);
1739 		p=rrow[DB_name]; if (p == NULL) p="undef";
1740 		BIO_printf(bio_err,"Subject Name  :%s\n",p);
1741 		ok= -1; /* This is now a 'bad' error. */
1742 		goto err;
1743 		}
1744 
1745 	/* We are now totaly happy, lets make and sign the certificate */
1746 	if (verbose)
1747 		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1748 
1749 	if ((ret=X509_new()) == NULL) goto err;
1750 	ci=ret->cert_info;
1751 
1752 #ifdef X509_V3
1753 	/* Make it an X509 v3 certificate. */
1754 	if (!X509_set_version(x509,2)) goto err;
1755 #endif
1756 
1757 	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1758 		goto err;
1759 	if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1760 		goto err;
1761 
1762 	BIO_printf(bio_err,"Certificate is to be certified until ");
1763 	if (strcmp(startdate,"today") == 0)
1764 		X509_gmtime_adj(X509_get_notBefore(ret),0);
1765 	else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1766 
1767 	if (enddate == NULL)
1768 		X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1769 	else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1770 
1771 	ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1772 	if(days) BIO_printf(bio_err," (%d days)",days);
1773 	BIO_printf(bio_err, "\n");
1774 
1775 	if (!X509_set_subject_name(ret,subject)) goto err;
1776 
1777 	pktmp=X509_REQ_get_pubkey(req);
1778 	i = X509_set_pubkey(ret,pktmp);
1779 	EVP_PKEY_free(pktmp);
1780 	if (!i) goto err;
1781 
1782 	/* Lets add the extensions, if there are any */
1783 	if (ext_sect)
1784 		{
1785 		X509V3_CTX ctx;
1786 		if (ci->version == NULL)
1787 			if ((ci->version=ASN1_INTEGER_new()) == NULL)
1788 				goto err;
1789 		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1790 
1791 		/* Free the current entries if any, there should not
1792 		 * be any I belive */
1793 		if (ci->extensions != NULL)
1794 			sk_X509_EXTENSION_pop_free(ci->extensions,
1795 						   X509_EXTENSION_free);
1796 
1797 		ci->extensions = NULL;
1798 
1799 		X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1800 		X509V3_set_conf_lhash(&ctx, lconf);
1801 
1802 		if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1803 
1804 		}
1805 
1806 
1807 	if (!batch)
1808 		{
1809 		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1810 		(void)BIO_flush(bio_err);
1811 		buf[0]='\0';
1812 		fgets(buf,sizeof(buf)-1,stdin);
1813 		if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1814 			{
1815 			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1816 			ok=0;
1817 			goto err;
1818 			}
1819 		}
1820 
1821 
1822 #ifndef NO_DSA
1823 	if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1824 	pktmp=X509_get_pubkey(ret);
1825 	if (EVP_PKEY_missing_parameters(pktmp) &&
1826 		!EVP_PKEY_missing_parameters(pkey))
1827 		EVP_PKEY_copy_parameters(pktmp,pkey);
1828 	EVP_PKEY_free(pktmp);
1829 #endif
1830 
1831 	if (!X509_sign(ret,pkey,dgst))
1832 		goto err;
1833 
1834 	/* We now just add it to the database */
1835 	row[DB_type]=(char *)Malloc(2);
1836 
1837 	tm=X509_get_notAfter(ret);
1838 	row[DB_exp_date]=(char *)Malloc(tm->length+1);
1839 	memcpy(row[DB_exp_date],tm->data,tm->length);
1840 	row[DB_exp_date][tm->length]='\0';
1841 
1842 	row[DB_rev_date]=NULL;
1843 
1844 	/* row[DB_serial] done already */
1845 	row[DB_file]=(char *)Malloc(8);
1846 	/* row[DB_name] done already */
1847 
1848 	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1849 		(row[DB_file] == NULL))
1850 		{
1851 		BIO_printf(bio_err,"Malloc failure\n");
1852 		goto err;
1853 		}
1854 	strcpy(row[DB_file],"unknown");
1855 	row[DB_type][0]='V';
1856 	row[DB_type][1]='\0';
1857 
1858 	if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1859 		{
1860 		BIO_printf(bio_err,"Malloc failure\n");
1861 		goto err;
1862 		}
1863 
1864 	for (i=0; i<DB_NUMBER; i++)
1865 		{
1866 		irow[i]=row[i];
1867 		row[i]=NULL;
1868 		}
1869 	irow[DB_NUMBER]=NULL;
1870 
1871 	if (!TXT_DB_insert(db,irow))
1872 		{
1873 		BIO_printf(bio_err,"failed to update database\n");
1874 		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1875 		goto err;
1876 		}
1877 	ok=1;
1878 err:
1879 	for (i=0; i<DB_NUMBER; i++)
1880 		if (row[i] != NULL) Free(row[i]);
1881 
1882 	if (CAname != NULL)
1883 		X509_NAME_free(CAname);
1884 	if (subject != NULL)
1885 		X509_NAME_free(subject);
1886 	if (ok <= 0)
1887 		{
1888 		if (ret != NULL) X509_free(ret);
1889 		ret=NULL;
1890 		}
1891 	else
1892 		*xret=ret;
1893 	return(ok);
1894 	}
1895 
1896 static void write_new_certificate(BIO *bp, X509 *x, int output_der)
1897 	{
1898 	char *f;
1899 	char buf[256];
1900 
1901 	if (output_der)
1902 		{
1903 		(void)i2d_X509_bio(bp,x);
1904 		return;
1905 		}
1906 
1907 	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1908 	BIO_printf(bp,"issuer :%s\n",f);
1909 
1910 	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1911 	BIO_printf(bp,"subject:%s\n",f);
1912 
1913 	BIO_puts(bp,"serial :");
1914 	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1915 	BIO_puts(bp,"\n\n");
1916 	X509_print(bp,x);
1917 	BIO_puts(bp,"\n");
1918 	PEM_write_bio_X509(bp,x);
1919 	BIO_puts(bp,"\n");
1920 	}
1921 
1922 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1923 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1924 	     BIGNUM *serial, char *startdate, char *enddate, int days,
1925 	     char *ext_sect, LHASH *lconf, int verbose)
1926 	{
1927 	STACK_OF(CONF_VALUE) *sk=NULL;
1928 	LHASH *parms=NULL;
1929 	X509_REQ *req=NULL;
1930 	CONF_VALUE *cv=NULL;
1931 	NETSCAPE_SPKI *spki = NULL;
1932 	unsigned char *spki_der = NULL,*p;
1933 	X509_REQ_INFO *ri;
1934 	char *type,*buf;
1935 	EVP_PKEY *pktmp=NULL;
1936 	X509_NAME *n=NULL;
1937 	X509_NAME_ENTRY *ne=NULL;
1938 	int ok= -1,i,j;
1939 	long errline;
1940 	int nid;
1941 
1942 	/*
1943 	 * Load input file into a hash table.  (This is just an easy
1944 	 * way to read and parse the file, then put it into a convenient
1945 	 * STACK format).
1946 	 */
1947 	parms=CONF_load(NULL,infile,&errline);
1948 	if (parms == NULL)
1949 		{
1950 		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
1951 		ERR_print_errors(bio_err);
1952 		goto err;
1953 		}
1954 
1955 	sk=CONF_get_section(parms, "default");
1956 	if (sk_CONF_VALUE_num(sk) == 0)
1957 		{
1958 		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
1959 		CONF_free(parms);
1960 		goto err;
1961 		}
1962 
1963 	/*
1964 	 * Now create a dummy X509 request structure.  We don't actually
1965 	 * have an X509 request, but we have many of the components
1966 	 * (a public key, various DN components).  The idea is that we
1967 	 * put these components into the right X509 request structure
1968 	 * and we can use the same code as if you had a real X509 request.
1969 	 */
1970 	req=X509_REQ_new();
1971 	if (req == NULL)
1972 		{
1973 		ERR_print_errors(bio_err);
1974 		goto err;
1975 		}
1976 
1977 	/*
1978 	 * Build up the subject name set.
1979 	 */
1980 	ri=req->req_info;
1981 	n = ri->subject;
1982 
1983 	for (i = 0; ; i++)
1984 		{
1985 		if (sk_CONF_VALUE_num(sk) <= i) break;
1986 
1987 		cv=sk_CONF_VALUE_value(sk,i);
1988 		type=cv->name;
1989 		buf=cv->value;
1990 
1991 		if ((nid=OBJ_txt2nid(type)) == NID_undef)
1992 			{
1993 			if (strcmp(type, "SPKAC") == 0)
1994 				{
1995 				spki_der=(unsigned char *)Malloc(
1996 					strlen(cv->value)+1);
1997 				if (spki_der == NULL)
1998 					{
1999 					BIO_printf(bio_err,"Malloc failure\n");
2000 					goto err;
2001 					}
2002 				j = EVP_DecodeBlock(spki_der, (unsigned char *)cv->value,
2003 					strlen(cv->value));
2004 				if (j <= 0)
2005 					{
2006 					BIO_printf(bio_err, "Can't b64 decode SPKAC structure\n");
2007 					goto err;
2008 					}
2009 
2010 				p=spki_der;
2011 				spki = d2i_NETSCAPE_SPKI(&spki, &p, j);
2012 				Free(spki_der);
2013 				spki_der = NULL;
2014 				if (spki == NULL)
2015 					{
2016 					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2017 					ERR_print_errors(bio_err);
2018 					goto err;
2019 					}
2020 				}
2021 			continue;
2022 			}
2023 
2024 		j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2025 		if (fix_data(nid, &j) == 0)
2026 			{
2027 			BIO_printf(bio_err,
2028 				"invalid characters in string %s\n",buf);
2029 			goto err;
2030 			}
2031 
2032 		if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2033 			(unsigned char *)buf,
2034 			strlen(buf))) == NULL)
2035 			goto err;
2036 
2037 		if (!X509_NAME_add_entry(n,ne,X509_NAME_entry_count(n),0))
2038 			goto err;
2039 		}
2040 	if (spki == NULL)
2041 		{
2042 		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2043 			infile);
2044 		goto err;
2045 		}
2046 
2047 	/*
2048 	 * Now extract the key from the SPKI structure.
2049 	 */
2050 
2051 	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2052 
2053 	if ((pktmp=X509_PUBKEY_get(spki->spkac->pubkey)) == NULL)
2054 		{
2055 		BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2056 		goto err;
2057 		}
2058 
2059 	j = NETSCAPE_SPKI_verify(spki, pktmp);
2060 	if (j <= 0)
2061 		{
2062 		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2063 		goto err;
2064 		}
2065 	BIO_printf(bio_err,"Signature ok\n");
2066 
2067 	X509_REQ_set_pubkey(req,pktmp);
2068 	EVP_PKEY_free(pktmp);
2069 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2070 		   days,1,verbose,req,ext_sect,lconf);
2071 err:
2072 	if (req != NULL) X509_REQ_free(req);
2073 	if (parms != NULL) CONF_free(parms);
2074 	if (spki_der != NULL) Free(spki_der);
2075 	if (spki != NULL) NETSCAPE_SPKI_free(spki);
2076 	if (ne != NULL) X509_NAME_ENTRY_free(ne);
2077 
2078 	return(ok);
2079 	}
2080 
2081 static int fix_data(int nid, int *type)
2082 	{
2083 	if (nid == NID_pkcs9_emailAddress)
2084 		*type=V_ASN1_IA5STRING;
2085 	if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2086 		*type=V_ASN1_T61STRING;
2087 	if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2088 		*type=V_ASN1_T61STRING;
2089 	if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2090 		return(0);
2091 	if (nid == NID_pkcs9_unstructuredName)
2092 		*type=V_ASN1_IA5STRING;
2093 	return(1);
2094 	}
2095 
2096 static int check_time_format(char *str)
2097 	{
2098 	ASN1_UTCTIME tm;
2099 
2100 	tm.data=(unsigned char *)str;
2101 	tm.length=strlen(str);
2102 	tm.type=V_ASN1_UTCTIME;
2103 	return(ASN1_UTCTIME_check(&tm));
2104 	}
2105 
2106 static int add_oid_section(LHASH *hconf)
2107 {
2108 	char *p;
2109 	STACK_OF(CONF_VALUE) *sktmp;
2110 	CONF_VALUE *cnf;
2111 	int i;
2112 	if(!(p=CONF_get_string(hconf,NULL,"oid_section"))) return 1;
2113 	if(!(sktmp = CONF_get_section(hconf, p))) {
2114 		BIO_printf(bio_err, "problem loading oid section %s\n", p);
2115 		return 0;
2116 	}
2117 	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
2118 		cnf = sk_CONF_VALUE_value(sktmp, i);
2119 		if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
2120 			BIO_printf(bio_err, "problem creating object %s=%s\n",
2121 							 cnf->name, cnf->value);
2122 			return 0;
2123 		}
2124 	}
2125 	return 1;
2126 }
2127 
2128 static int do_revoke(X509 *x509, TXT_DB *db)
2129 {
2130 	ASN1_UTCTIME *tm=NULL;
2131 	char *row[DB_NUMBER],**rrow,**irow;
2132 	int ok=-1,i;
2133 
2134 	for (i=0; i<DB_NUMBER; i++)
2135 		row[i]=NULL;
2136 	row[DB_name]=X509_NAME_oneline(x509->cert_info->subject,NULL,0);
2137 	row[DB_serial]=BN_bn2hex(ASN1_INTEGER_to_BN(x509->cert_info->serialNumber,NULL));
2138 	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2139 		{
2140 		BIO_printf(bio_err,"Malloc failure\n");
2141 		goto err;
2142 		}
2143 	rrow=TXT_DB_get_by_index(db,DB_name,row);
2144 	if (rrow == NULL)
2145 		{
2146 		BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2147 
2148 		/* We now just add it to the database */
2149 		row[DB_type]=(char *)Malloc(2);
2150 
2151 		tm=X509_get_notAfter(x509);
2152 		row[DB_exp_date]=(char *)Malloc(tm->length+1);
2153 		memcpy(row[DB_exp_date],tm->data,tm->length);
2154 		row[DB_exp_date][tm->length]='\0';
2155 
2156 		row[DB_rev_date]=NULL;
2157 
2158 		/* row[DB_serial] done already */
2159 		row[DB_file]=(char *)Malloc(8);
2160 
2161 		/* row[DB_name] done already */
2162 
2163 		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2164 			(row[DB_file] == NULL))
2165 			{
2166 			BIO_printf(bio_err,"Malloc failure\n");
2167 			goto err;
2168 			}
2169 		strcpy(row[DB_file],"unknown");
2170 		row[DB_type][0]='V';
2171 		row[DB_type][1]='\0';
2172 
2173 		if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2174 			{
2175 			BIO_printf(bio_err,"Malloc failure\n");
2176 			goto err;
2177 			}
2178 
2179 		for (i=0; i<DB_NUMBER; i++)
2180 			{
2181 			irow[i]=row[i];
2182 			row[i]=NULL;
2183 			}
2184 		irow[DB_NUMBER]=NULL;
2185 
2186 		if (!TXT_DB_insert(db,irow))
2187 			{
2188 			BIO_printf(bio_err,"failed to update database\n");
2189 			BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2190 			goto err;
2191 			}
2192 
2193 		/* Revoke Certificate */
2194 		do_revoke(x509,db);
2195 
2196 		ok=1;
2197 		goto err;
2198 
2199 		}
2200 	else if (index_serial_cmp(row,rrow))
2201 		{
2202 		BIO_printf(bio_err,"ERROR:no same serial number %s\n",
2203 			   row[DB_serial]);
2204 		goto err;
2205 		}
2206 	else if (rrow[DB_type][0]=='R')
2207 		{
2208 		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2209 			   row[DB_serial]);
2210 		goto err;
2211 		}
2212 	else
2213 		{
2214 		BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2215 		tm=X509_gmtime_adj(tm,0);
2216 		rrow[DB_type][0]='R';
2217 		rrow[DB_type][1]='\0';
2218 		rrow[DB_rev_date]=(char *)Malloc(tm->length+1);
2219 		memcpy(rrow[DB_rev_date],tm->data,tm->length);
2220 		rrow[DB_rev_date][tm->length]='\0';
2221 		}
2222 	ok=1;
2223 err:
2224 	for (i=0; i<DB_NUMBER; i++)
2225 		{
2226 		if (row[i] != NULL)
2227 			Free(row[i]);
2228 		}
2229 	ASN1_UTCTIME_free(tm);
2230 	return(ok);
2231 }
2232 
2233