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