xref: /freebsd/crypto/openssl/apps/ca.c (revision 5521ff5a4d1929056e7ffc982fac3341ca54df7c)
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 " -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 issuer\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 			strcat(buf[0],".new");
1224 			if (BIO_write_filename(out,buf[0]) <= 0)
1225 				{
1226 				perror(dbfile);
1227 				BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1228 				goto err;
1229 				}
1230 			j=TXT_DB_write(out,db);
1231 			if (j <= 0) goto err;
1232 			strncpy(buf[1],dbfile,BSIZE-4);
1233 			strcat(buf[1],".old");
1234 			if (rename(dbfile,buf[1]) < 0)
1235 				{
1236 				BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1237 				perror("reason");
1238 				goto err;
1239 				}
1240 			if (rename(buf[0],dbfile) < 0)
1241 				{
1242 				BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1243 				perror("reason");
1244 				rename(buf[1],dbfile);
1245 				goto err;
1246 				}
1247 			BIO_printf(bio_err,"Data Base Updated\n");
1248 			}
1249 		}
1250 	/*****************************************************************/
1251 	ret=0;
1252 err:
1253 	BIO_free(hex);
1254 	BIO_free_all(Cout);
1255 	BIO_free_all(Sout);
1256 	BIO_free_all(out);
1257 	BIO_free(in);
1258 
1259 	sk_X509_pop_free(cert_sk,X509_free);
1260 
1261 	if (ret) ERR_print_errors(bio_err);
1262 	app_RAND_write_file(randfile, bio_err);
1263 	BN_free(serial);
1264 	TXT_DB_free(db);
1265 	EVP_PKEY_free(pkey);
1266 	X509_free(x509);
1267 	X509_CRL_free(crl);
1268 	CONF_free(conf);
1269 	OBJ_cleanup();
1270 	EXIT(ret);
1271 	}
1272 
1273 static void lookup_fail(char *name, char *tag)
1274 	{
1275 	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1276 	}
1277 
1278 static unsigned long index_serial_hash(char **a)
1279 	{
1280 	char *n;
1281 
1282 	n=a[DB_serial];
1283 	while (*n == '0') n++;
1284 	return(lh_strhash(n));
1285 	}
1286 
1287 static int index_serial_cmp(char **a, char **b)
1288 	{
1289 	char *aa,*bb;
1290 
1291 	for (aa=a[DB_serial]; *aa == '0'; aa++);
1292 	for (bb=b[DB_serial]; *bb == '0'; bb++);
1293 	return(strcmp(aa,bb));
1294 	}
1295 
1296 static unsigned long index_name_hash(char **a)
1297 	{ return(lh_strhash(a[DB_name])); }
1298 
1299 static int index_name_qual(char **a)
1300 	{ return(a[0][0] == 'V'); }
1301 
1302 static int index_name_cmp(char **a, char **b)
1303 	{ return(strcmp(a[DB_name],
1304 	     b[DB_name])); }
1305 
1306 static BIGNUM *load_serial(char *serialfile)
1307 	{
1308 	BIO *in=NULL;
1309 	BIGNUM *ret=NULL;
1310 	MS_STATIC char buf[1024];
1311 	ASN1_INTEGER *ai=NULL;
1312 
1313 	if ((in=BIO_new(BIO_s_file())) == NULL)
1314 		{
1315 		ERR_print_errors(bio_err);
1316 		goto err;
1317 		}
1318 
1319 	if (BIO_read_filename(in,serialfile) <= 0)
1320 		{
1321 		perror(serialfile);
1322 		goto err;
1323 		}
1324 	ai=ASN1_INTEGER_new();
1325 	if (ai == NULL) goto err;
1326 	if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1327 		{
1328 		BIO_printf(bio_err,"unable to load number from %s\n",
1329 			serialfile);
1330 		goto err;
1331 		}
1332 	ret=ASN1_INTEGER_to_BN(ai,NULL);
1333 	if (ret == NULL)
1334 		{
1335 		BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1336 		goto err;
1337 		}
1338 err:
1339 	if (in != NULL) BIO_free(in);
1340 	if (ai != NULL) ASN1_INTEGER_free(ai);
1341 	return(ret);
1342 	}
1343 
1344 static int save_serial(char *serialfile, BIGNUM *serial)
1345 	{
1346 	BIO *out;
1347 	int ret=0;
1348 	ASN1_INTEGER *ai=NULL;
1349 
1350 	out=BIO_new(BIO_s_file());
1351 	if (out == NULL)
1352 		{
1353 		ERR_print_errors(bio_err);
1354 		goto err;
1355 		}
1356 	if (BIO_write_filename(out,serialfile) <= 0)
1357 		{
1358 		perror(serialfile);
1359 		goto err;
1360 		}
1361 
1362 	if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1363 		{
1364 		BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1365 		goto err;
1366 		}
1367 	i2a_ASN1_INTEGER(out,ai);
1368 	BIO_puts(out,"\n");
1369 	ret=1;
1370 err:
1371 	if (out != NULL) BIO_free_all(out);
1372 	if (ai != NULL) ASN1_INTEGER_free(ai);
1373 	return(ret);
1374 	}
1375 
1376 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1377 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1378 	     BIGNUM *serial, char *startdate, char *enddate, int days,
1379 	     int batch, char *ext_sect, LHASH *lconf, int verbose)
1380 	{
1381 	X509_REQ *req=NULL;
1382 	BIO *in=NULL;
1383 	EVP_PKEY *pktmp=NULL;
1384 	int ok= -1,i;
1385 
1386 	in=BIO_new(BIO_s_file());
1387 
1388 	if (BIO_read_filename(in,infile) <= 0)
1389 		{
1390 		perror(infile);
1391 		goto err;
1392 		}
1393 	if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1394 		{
1395 		BIO_printf(bio_err,"Error reading certificate request in %s\n",
1396 			infile);
1397 		goto err;
1398 		}
1399 	if (verbose)
1400 		X509_REQ_print(bio_err,req);
1401 
1402 	BIO_printf(bio_err,"Check that the request matches the signature\n");
1403 
1404 	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1405 		{
1406 		BIO_printf(bio_err,"error unpacking public key\n");
1407 		goto err;
1408 		}
1409 	i=X509_REQ_verify(req,pktmp);
1410 	EVP_PKEY_free(pktmp);
1411 	if (i < 0)
1412 		{
1413 		ok=0;
1414 		BIO_printf(bio_err,"Signature verification problems....\n");
1415 		goto err;
1416 		}
1417 	if (i == 0)
1418 		{
1419 		ok=0;
1420 		BIO_printf(bio_err,"Signature did not match the certificate request\n");
1421 		goto err;
1422 		}
1423 	else
1424 		BIO_printf(bio_err,"Signature ok\n");
1425 
1426 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1427 		days,batch,verbose,req,ext_sect,lconf);
1428 
1429 err:
1430 	if (req != NULL) X509_REQ_free(req);
1431 	if (in != NULL) BIO_free(in);
1432 	return(ok);
1433 	}
1434 
1435 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1436 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1437 	     BIGNUM *serial, char *startdate, char *enddate, int days,
1438 	     int batch, char *ext_sect, LHASH *lconf, int verbose)
1439 	{
1440 	X509 *req=NULL;
1441 	X509_REQ *rreq=NULL;
1442 	BIO *in=NULL;
1443 	EVP_PKEY *pktmp=NULL;
1444 	int ok= -1,i;
1445 
1446 	in=BIO_new(BIO_s_file());
1447 
1448 	if (BIO_read_filename(in,infile) <= 0)
1449 		{
1450 		perror(infile);
1451 		goto err;
1452 		}
1453 	if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1454 		{
1455 		BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1456 		goto err;
1457 		}
1458 	if (verbose)
1459 		X509_print(bio_err,req);
1460 
1461 	BIO_printf(bio_err,"Check that the request matches the signature\n");
1462 
1463 	if ((pktmp=X509_get_pubkey(req)) == NULL)
1464 		{
1465 		BIO_printf(bio_err,"error unpacking public key\n");
1466 		goto err;
1467 		}
1468 	i=X509_verify(req,pktmp);
1469 	EVP_PKEY_free(pktmp);
1470 	if (i < 0)
1471 		{
1472 		ok=0;
1473 		BIO_printf(bio_err,"Signature verification problems....\n");
1474 		goto err;
1475 		}
1476 	if (i == 0)
1477 		{
1478 		ok=0;
1479 		BIO_printf(bio_err,"Signature did not match the certificate\n");
1480 		goto err;
1481 		}
1482 	else
1483 		BIO_printf(bio_err,"Signature ok\n");
1484 
1485 	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1486 		goto err;
1487 
1488 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1489 		batch,verbose,rreq,ext_sect,lconf);
1490 
1491 err:
1492 	if (rreq != NULL) X509_REQ_free(rreq);
1493 	if (req != NULL) X509_free(req);
1494 	if (in != NULL) BIO_free(in);
1495 	return(ok);
1496 	}
1497 
1498 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1499 	     STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1500 	     char *startdate, char *enddate, int days, int batch, int verbose,
1501 	     X509_REQ *req, char *ext_sect, LHASH *lconf)
1502 	{
1503 	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1504 	ASN1_UTCTIME *tm,*tmptm;
1505 	ASN1_STRING *str,*str2;
1506 	ASN1_OBJECT *obj;
1507 	X509 *ret=NULL;
1508 	X509_CINF *ci;
1509 	X509_NAME_ENTRY *ne;
1510 	X509_NAME_ENTRY *tne,*push;
1511 	EVP_PKEY *pktmp;
1512 	int ok= -1,i,j,last,nid;
1513 	char *p;
1514 	CONF_VALUE *cv;
1515 	char *row[DB_NUMBER],**rrow,**irow=NULL;
1516 	char buf[25],*pbuf;
1517 
1518 	tmptm=ASN1_UTCTIME_new();
1519 	if (tmptm == NULL)
1520 		{
1521 		BIO_printf(bio_err,"malloc error\n");
1522 		return(0);
1523 		}
1524 
1525 	for (i=0; i<DB_NUMBER; i++)
1526 		row[i]=NULL;
1527 
1528 	BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1529 	name=X509_REQ_get_subject_name(req);
1530 	for (i=0; i<X509_NAME_entry_count(name); i++)
1531 		{
1532 		ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1533 		obj=X509_NAME_ENTRY_get_object(ne);
1534 		j=i2a_ASN1_OBJECT(bio_err,obj);
1535 		str=X509_NAME_ENTRY_get_data(ne);
1536 		pbuf=buf;
1537 		for (j=22-j; j>0; j--)
1538 			*(pbuf++)=' ';
1539 		*(pbuf++)=':';
1540 		*(pbuf++)='\0';
1541 		BIO_puts(bio_err,buf);
1542 
1543 		if (msie_hack)
1544 			{
1545 			/* assume all type should be strings */
1546 			nid=OBJ_obj2nid(ne->object);
1547 
1548 			if (str->type == V_ASN1_UNIVERSALSTRING)
1549 				ASN1_UNIVERSALSTRING_to_string(str);
1550 
1551 			if ((str->type == V_ASN1_IA5STRING) &&
1552 				(nid != NID_pkcs9_emailAddress))
1553 				str->type=V_ASN1_T61STRING;
1554 
1555 			if ((nid == NID_pkcs9_emailAddress) &&
1556 				(str->type == V_ASN1_PRINTABLESTRING))
1557 				str->type=V_ASN1_IA5STRING;
1558 			}
1559 
1560 		if (str->type == V_ASN1_PRINTABLESTRING)
1561 			BIO_printf(bio_err,"PRINTABLE:'");
1562 		else if (str->type == V_ASN1_T61STRING)
1563 			BIO_printf(bio_err,"T61STRING:'");
1564 		else if (str->type == V_ASN1_IA5STRING)
1565 			BIO_printf(bio_err,"IA5STRING:'");
1566 		else if (str->type == V_ASN1_UNIVERSALSTRING)
1567 			BIO_printf(bio_err,"UNIVERSALSTRING:'");
1568 		else
1569 			BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1570 
1571 		/* check some things */
1572 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1573 			(str->type != V_ASN1_IA5STRING))
1574 			{
1575 			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1576 			goto err;
1577 			}
1578 		j=ASN1_PRINTABLE_type(str->data,str->length);
1579 		if (	((j == V_ASN1_T61STRING) &&
1580 			 (str->type != V_ASN1_T61STRING)) ||
1581 			((j == V_ASN1_IA5STRING) &&
1582 			 (str->type == V_ASN1_PRINTABLESTRING)))
1583 			{
1584 			BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1585 			goto err;
1586 			}
1587 
1588 		p=(char *)str->data;
1589 		for (j=str->length; j>0; j--)
1590 			{
1591 			if ((*p >= ' ') && (*p <= '~'))
1592 				BIO_printf(bio_err,"%c",*p);
1593 			else if (*p & 0x80)
1594 				BIO_printf(bio_err,"\\0x%02X",*p);
1595 			else if ((unsigned char)*p == 0xf7)
1596 				BIO_printf(bio_err,"^?");
1597 			else	BIO_printf(bio_err,"^%c",*p+'@');
1598 			p++;
1599 			}
1600 		BIO_printf(bio_err,"'\n");
1601 		}
1602 
1603 	/* Ok, now we check the 'policy' stuff. */
1604 	if ((subject=X509_NAME_new()) == NULL)
1605 		{
1606 		BIO_printf(bio_err,"Memory allocation failure\n");
1607 		goto err;
1608 		}
1609 
1610 	/* take a copy of the issuer name before we mess with it. */
1611 	CAname=X509_NAME_dup(x509->cert_info->subject);
1612 	if (CAname == NULL) goto err;
1613 	str=str2=NULL;
1614 
1615 	for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1616 		{
1617 		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1618 		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1619 			{
1620 			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1621 			goto err;
1622 			}
1623 		obj=OBJ_nid2obj(j);
1624 
1625 		last= -1;
1626 		for (;;)
1627 			{
1628 			/* lookup the object in the supplied name list */
1629 			j=X509_NAME_get_index_by_OBJ(name,obj,last);
1630 			if (j < 0)
1631 				{
1632 				if (last != -1) break;
1633 				tne=NULL;
1634 				}
1635 			else
1636 				{
1637 				tne=X509_NAME_get_entry(name,j);
1638 				}
1639 			last=j;
1640 
1641 			/* depending on the 'policy', decide what to do. */
1642 			push=NULL;
1643 			if (strcmp(cv->value,"optional") == 0)
1644 				{
1645 				if (tne != NULL)
1646 					push=tne;
1647 				}
1648 			else if (strcmp(cv->value,"supplied") == 0)
1649 				{
1650 				if (tne == NULL)
1651 					{
1652 					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1653 					goto err;
1654 					}
1655 				else
1656 					push=tne;
1657 				}
1658 			else if (strcmp(cv->value,"match") == 0)
1659 				{
1660 				int last2;
1661 
1662 				if (tne == NULL)
1663 					{
1664 					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1665 					goto err;
1666 					}
1667 
1668 				last2= -1;
1669 
1670 again2:
1671 				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1672 				if ((j < 0) && (last2 == -1))
1673 					{
1674 					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1675 					goto err;
1676 					}
1677 				if (j >= 0)
1678 					{
1679 					push=X509_NAME_get_entry(CAname,j);
1680 					str=X509_NAME_ENTRY_get_data(tne);
1681 					str2=X509_NAME_ENTRY_get_data(push);
1682 					last2=j;
1683 					if (ASN1_STRING_cmp(str,str2) != 0)
1684 						goto again2;
1685 					}
1686 				if (j < 0)
1687 					{
1688 					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));
1689 					goto err;
1690 					}
1691 				}
1692 			else
1693 				{
1694 				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1695 				goto err;
1696 				}
1697 
1698 			if (push != NULL)
1699 				{
1700 				if (!X509_NAME_add_entry(subject,push, -1, 0))
1701 					{
1702 					if (push != NULL)
1703 						X509_NAME_ENTRY_free(push);
1704 					BIO_printf(bio_err,"Memory allocation failure\n");
1705 					goto err;
1706 					}
1707 				}
1708 			if (j < 0) break;
1709 			}
1710 		}
1711 
1712 	if (preserve)
1713 		{
1714 		X509_NAME_free(subject);
1715 		subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1716 		if (subject == NULL) goto err;
1717 		}
1718 
1719 	if (verbose)
1720 		BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1721 
1722 	row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1723 	row[DB_serial]=BN_bn2hex(serial);
1724 	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1725 		{
1726 		BIO_printf(bio_err,"Memory allocation failure\n");
1727 		goto err;
1728 		}
1729 
1730 	rrow=TXT_DB_get_by_index(db,DB_name,row);
1731 	if (rrow != NULL)
1732 		{
1733 		BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1734 			row[DB_name]);
1735 		}
1736 	else
1737 		{
1738 		rrow=TXT_DB_get_by_index(db,DB_serial,row);
1739 		if (rrow != NULL)
1740 			{
1741 			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1742 				row[DB_serial]);
1743 			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1744 			}
1745 		}
1746 
1747 	if (rrow != NULL)
1748 		{
1749 		BIO_printf(bio_err,
1750 			"The matching entry has the following details\n");
1751 		if (rrow[DB_type][0] == 'E')
1752 			p="Expired";
1753 		else if (rrow[DB_type][0] == 'R')
1754 			p="Revoked";
1755 		else if (rrow[DB_type][0] == 'V')
1756 			p="Valid";
1757 		else
1758 			p="\ninvalid type, Data base error\n";
1759 		BIO_printf(bio_err,"Type	  :%s\n",p);;
1760 		if (rrow[DB_type][0] == 'R')
1761 			{
1762 			p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1763 			BIO_printf(bio_err,"Was revoked on:%s\n",p);
1764 			}
1765 		p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1766 		BIO_printf(bio_err,"Expires on    :%s\n",p);
1767 		p=rrow[DB_serial]; if (p == NULL) p="undef";
1768 		BIO_printf(bio_err,"Serial Number :%s\n",p);
1769 		p=rrow[DB_file]; if (p == NULL) p="undef";
1770 		BIO_printf(bio_err,"File name     :%s\n",p);
1771 		p=rrow[DB_name]; if (p == NULL) p="undef";
1772 		BIO_printf(bio_err,"Subject Name  :%s\n",p);
1773 		ok= -1; /* This is now a 'bad' error. */
1774 		goto err;
1775 		}
1776 
1777 	/* We are now totally happy, lets make and sign the certificate */
1778 	if (verbose)
1779 		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1780 
1781 	if ((ret=X509_new()) == NULL) goto err;
1782 	ci=ret->cert_info;
1783 
1784 #ifdef X509_V3
1785 	/* Make it an X509 v3 certificate. */
1786 	if (!X509_set_version(x509,2)) goto err;
1787 #endif
1788 
1789 	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1790 		goto err;
1791 	if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1792 		goto err;
1793 
1794 	BIO_printf(bio_err,"Certificate is to be certified until ");
1795 	if (strcmp(startdate,"today") == 0)
1796 		X509_gmtime_adj(X509_get_notBefore(ret),0);
1797 	else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1798 
1799 	if (enddate == NULL)
1800 		X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1801 	else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1802 
1803 	ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1804 	if(days) BIO_printf(bio_err," (%d days)",days);
1805 	BIO_printf(bio_err, "\n");
1806 
1807 	if (!X509_set_subject_name(ret,subject)) goto err;
1808 
1809 	pktmp=X509_REQ_get_pubkey(req);
1810 	i = X509_set_pubkey(ret,pktmp);
1811 	EVP_PKEY_free(pktmp);
1812 	if (!i) goto err;
1813 
1814 	/* Lets add the extensions, if there are any */
1815 	if (ext_sect)
1816 		{
1817 		X509V3_CTX ctx;
1818 		if (ci->version == NULL)
1819 			if ((ci->version=ASN1_INTEGER_new()) == NULL)
1820 				goto err;
1821 		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1822 
1823 		/* Free the current entries if any, there should not
1824 		 * be any I believe */
1825 		if (ci->extensions != NULL)
1826 			sk_X509_EXTENSION_pop_free(ci->extensions,
1827 						   X509_EXTENSION_free);
1828 
1829 		ci->extensions = NULL;
1830 
1831 		X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1832 		X509V3_set_conf_lhash(&ctx, lconf);
1833 
1834 		if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1835 
1836 		}
1837 
1838 
1839 	if (!batch)
1840 		{
1841 		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1842 		(void)BIO_flush(bio_err);
1843 		buf[0]='\0';
1844 		fgets(buf,sizeof(buf)-1,stdin);
1845 		if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1846 			{
1847 			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1848 			ok=0;
1849 			goto err;
1850 			}
1851 		}
1852 
1853 
1854 #ifndef NO_DSA
1855 	if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1856 	pktmp=X509_get_pubkey(ret);
1857 	if (EVP_PKEY_missing_parameters(pktmp) &&
1858 		!EVP_PKEY_missing_parameters(pkey))
1859 		EVP_PKEY_copy_parameters(pktmp,pkey);
1860 	EVP_PKEY_free(pktmp);
1861 #endif
1862 
1863 	if (!X509_sign(ret,pkey,dgst))
1864 		goto err;
1865 
1866 	/* We now just add it to the database */
1867 	row[DB_type]=(char *)OPENSSL_malloc(2);
1868 
1869 	tm=X509_get_notAfter(ret);
1870 	row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1871 	memcpy(row[DB_exp_date],tm->data,tm->length);
1872 	row[DB_exp_date][tm->length]='\0';
1873 
1874 	row[DB_rev_date]=NULL;
1875 
1876 	/* row[DB_serial] done already */
1877 	row[DB_file]=(char *)OPENSSL_malloc(8);
1878 	/* row[DB_name] done already */
1879 
1880 	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1881 		(row[DB_file] == NULL))
1882 		{
1883 		BIO_printf(bio_err,"Memory allocation failure\n");
1884 		goto err;
1885 		}
1886 	strcpy(row[DB_file],"unknown");
1887 	row[DB_type][0]='V';
1888 	row[DB_type][1]='\0';
1889 
1890 	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1891 		{
1892 		BIO_printf(bio_err,"Memory allocation failure\n");
1893 		goto err;
1894 		}
1895 
1896 	for (i=0; i<DB_NUMBER; i++)
1897 		{
1898 		irow[i]=row[i];
1899 		row[i]=NULL;
1900 		}
1901 	irow[DB_NUMBER]=NULL;
1902 
1903 	if (!TXT_DB_insert(db,irow))
1904 		{
1905 		BIO_printf(bio_err,"failed to update database\n");
1906 		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1907 		goto err;
1908 		}
1909 	ok=1;
1910 err:
1911 	for (i=0; i<DB_NUMBER; i++)
1912 		if (row[i] != NULL) OPENSSL_free(row[i]);
1913 
1914 	if (CAname != NULL)
1915 		X509_NAME_free(CAname);
1916 	if (subject != NULL)
1917 		X509_NAME_free(subject);
1918 	if (tmptm != NULL)
1919 		ASN1_UTCTIME_free(tmptm);
1920 	if (ok <= 0)
1921 		{
1922 		if (ret != NULL) X509_free(ret);
1923 		ret=NULL;
1924 		}
1925 	else
1926 		*xret=ret;
1927 	return(ok);
1928 	}
1929 
1930 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1931 	{
1932 
1933 	if (output_der)
1934 		{
1935 		(void)i2d_X509_bio(bp,x);
1936 		return;
1937 		}
1938 #if 0
1939 	/* ??? Not needed since X509_print prints all this stuff anyway */
1940 	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1941 	BIO_printf(bp,"issuer :%s\n",f);
1942 
1943 	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1944 	BIO_printf(bp,"subject:%s\n",f);
1945 
1946 	BIO_puts(bp,"serial :");
1947 	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1948 	BIO_puts(bp,"\n\n");
1949 #endif
1950 	if(!notext)X509_print(bp,x);
1951 	PEM_write_bio_X509(bp,x);
1952 	}
1953 
1954 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1955 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1956 	     BIGNUM *serial, char *startdate, char *enddate, int days,
1957 	     char *ext_sect, LHASH *lconf, int verbose)
1958 	{
1959 	STACK_OF(CONF_VALUE) *sk=NULL;
1960 	LHASH *parms=NULL;
1961 	X509_REQ *req=NULL;
1962 	CONF_VALUE *cv=NULL;
1963 	NETSCAPE_SPKI *spki = NULL;
1964 	X509_REQ_INFO *ri;
1965 	char *type,*buf;
1966 	EVP_PKEY *pktmp=NULL;
1967 	X509_NAME *n=NULL;
1968 	X509_NAME_ENTRY *ne=NULL;
1969 	int ok= -1,i,j;
1970 	long errline;
1971 	int nid;
1972 
1973 	/*
1974 	 * Load input file into a hash table.  (This is just an easy
1975 	 * way to read and parse the file, then put it into a convenient
1976 	 * STACK format).
1977 	 */
1978 	parms=CONF_load(NULL,infile,&errline);
1979 	if (parms == NULL)
1980 		{
1981 		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
1982 		ERR_print_errors(bio_err);
1983 		goto err;
1984 		}
1985 
1986 	sk=CONF_get_section(parms, "default");
1987 	if (sk_CONF_VALUE_num(sk) == 0)
1988 		{
1989 		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
1990 		CONF_free(parms);
1991 		goto err;
1992 		}
1993 
1994 	/*
1995 	 * Now create a dummy X509 request structure.  We don't actually
1996 	 * have an X509 request, but we have many of the components
1997 	 * (a public key, various DN components).  The idea is that we
1998 	 * put these components into the right X509 request structure
1999 	 * and we can use the same code as if you had a real X509 request.
2000 	 */
2001 	req=X509_REQ_new();
2002 	if (req == NULL)
2003 		{
2004 		ERR_print_errors(bio_err);
2005 		goto err;
2006 		}
2007 
2008 	/*
2009 	 * Build up the subject name set.
2010 	 */
2011 	ri=req->req_info;
2012 	n = ri->subject;
2013 
2014 	for (i = 0; ; i++)
2015 		{
2016 		if (sk_CONF_VALUE_num(sk) <= i) break;
2017 
2018 		cv=sk_CONF_VALUE_value(sk,i);
2019 		type=cv->name;
2020 		/* Skip past any leading X. X: X, etc to allow for
2021 		 * multiple instances
2022 		 */
2023 		for(buf = cv->name; *buf ; buf++)
2024 			if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2025 					buf++;
2026 					if(*buf) type = buf;
2027 					break;
2028 		}
2029 
2030 		buf=cv->value;
2031 		if ((nid=OBJ_txt2nid(type)) == NID_undef)
2032 			{
2033 			if (strcmp(type, "SPKAC") == 0)
2034 				{
2035 				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2036 				if (spki == NULL)
2037 					{
2038 					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2039 					ERR_print_errors(bio_err);
2040 					goto err;
2041 					}
2042 				}
2043 			continue;
2044 			}
2045 
2046 		j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2047 		if (fix_data(nid, &j) == 0)
2048 			{
2049 			BIO_printf(bio_err,
2050 				"invalid characters in string %s\n",buf);
2051 			goto err;
2052 			}
2053 
2054 		if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2055 			(unsigned char *)buf,
2056 			strlen(buf))) == NULL)
2057 			goto err;
2058 
2059 		if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2060 		}
2061 	if (spki == NULL)
2062 		{
2063 		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2064 			infile);
2065 		goto err;
2066 		}
2067 
2068 	/*
2069 	 * Now extract the key from the SPKI structure.
2070 	 */
2071 
2072 	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2073 
2074 	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2075 		{
2076 		BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2077 		goto err;
2078 		}
2079 
2080 	j = NETSCAPE_SPKI_verify(spki, pktmp);
2081 	if (j <= 0)
2082 		{
2083 		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2084 		goto err;
2085 		}
2086 	BIO_printf(bio_err,"Signature ok\n");
2087 
2088 	X509_REQ_set_pubkey(req,pktmp);
2089 	EVP_PKEY_free(pktmp);
2090 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2091 		   days,1,verbose,req,ext_sect,lconf);
2092 err:
2093 	if (req != NULL) X509_REQ_free(req);
2094 	if (parms != NULL) CONF_free(parms);
2095 	if (spki != NULL) NETSCAPE_SPKI_free(spki);
2096 	if (ne != NULL) X509_NAME_ENTRY_free(ne);
2097 
2098 	return(ok);
2099 	}
2100 
2101 static int fix_data(int nid, int *type)
2102 	{
2103 	if (nid == NID_pkcs9_emailAddress)
2104 		*type=V_ASN1_IA5STRING;
2105 	if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2106 		*type=V_ASN1_T61STRING;
2107 	if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2108 		*type=V_ASN1_T61STRING;
2109 	if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2110 		return(0);
2111 	if (nid == NID_pkcs9_unstructuredName)
2112 		*type=V_ASN1_IA5STRING;
2113 	return(1);
2114 	}
2115 
2116 static int check_time_format(char *str)
2117 	{
2118 	ASN1_UTCTIME tm;
2119 
2120 	tm.data=(unsigned char *)str;
2121 	tm.length=strlen(str);
2122 	tm.type=V_ASN1_UTCTIME;
2123 	return(ASN1_UTCTIME_check(&tm));
2124 	}
2125 
2126 static int do_revoke(X509 *x509, TXT_DB *db)
2127 {
2128 	ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2129 	char *row[DB_NUMBER],**rrow,**irow;
2130 	BIGNUM *bn = NULL;
2131 	int ok=-1,i;
2132 
2133 	for (i=0; i<DB_NUMBER; i++)
2134 		row[i]=NULL;
2135 	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2136 	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2137 	row[DB_serial]=BN_bn2hex(bn);
2138 	BN_free(bn);
2139 	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2140 		{
2141 		BIO_printf(bio_err,"Memory allocation failure\n");
2142 		goto err;
2143 		}
2144 	/* We have to lookup by serial number because name lookup
2145 	 * skips revoked certs
2146  	 */
2147 	rrow=TXT_DB_get_by_index(db,DB_serial,row);
2148 	if (rrow == NULL)
2149 		{
2150 		BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2151 
2152 		/* We now just add it to the database */
2153 		row[DB_type]=(char *)OPENSSL_malloc(2);
2154 
2155 		tm=X509_get_notAfter(x509);
2156 		row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2157 		memcpy(row[DB_exp_date],tm->data,tm->length);
2158 		row[DB_exp_date][tm->length]='\0';
2159 
2160 		row[DB_rev_date]=NULL;
2161 
2162 		/* row[DB_serial] done already */
2163 		row[DB_file]=(char *)OPENSSL_malloc(8);
2164 
2165 		/* row[DB_name] done already */
2166 
2167 		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2168 			(row[DB_file] == NULL))
2169 			{
2170 			BIO_printf(bio_err,"Memory allocation failure\n");
2171 			goto err;
2172 			}
2173 		strcpy(row[DB_file],"unknown");
2174 		row[DB_type][0]='V';
2175 		row[DB_type][1]='\0';
2176 
2177 		if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2178 			{
2179 			BIO_printf(bio_err,"Memory allocation failure\n");
2180 			goto err;
2181 			}
2182 
2183 		for (i=0; i<DB_NUMBER; i++)
2184 			{
2185 			irow[i]=row[i];
2186 			row[i]=NULL;
2187 			}
2188 		irow[DB_NUMBER]=NULL;
2189 
2190 		if (!TXT_DB_insert(db,irow))
2191 			{
2192 			BIO_printf(bio_err,"failed to update database\n");
2193 			BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2194 			goto err;
2195 			}
2196 
2197 		/* Revoke Certificate */
2198 		ok = do_revoke(x509,db);
2199 
2200 		goto err;
2201 
2202 		}
2203 	else if (index_name_cmp(row,rrow))
2204 		{
2205 		BIO_printf(bio_err,"ERROR:name does not match %s\n",
2206 			   row[DB_name]);
2207 		goto err;
2208 		}
2209 	else if (rrow[DB_type][0]=='R')
2210 		{
2211 		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2212 			   row[DB_serial]);
2213 		goto err;
2214 		}
2215 	else
2216 		{
2217 		BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2218 		revtm = ASN1_UTCTIME_new();
2219 		revtm=X509_gmtime_adj(revtm,0);
2220 		rrow[DB_type][0]='R';
2221 		rrow[DB_type][1]='\0';
2222 		rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2223 		memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2224 		rrow[DB_rev_date][revtm->length]='\0';
2225 		ASN1_UTCTIME_free(revtm);
2226 		}
2227 	ok=1;
2228 err:
2229 	for (i=0; i<DB_NUMBER; i++)
2230 		{
2231 		if (row[i] != NULL)
2232 			OPENSSL_free(row[i]);
2233 		}
2234 	return(ok);
2235 }
2236 
2237