xref: /freebsd/crypto/openssl/apps/ca.c (revision 6be8ae07)
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 <ctype.h>
65 #include <sys/types.h>
66 #include <sys/stat.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/ocsp.h>
77 #include <openssl/pem.h>
78 
79 #ifndef W_OK
80 #  ifdef OPENSSL_SYS_VMS
81 #    if defined(__DECC)
82 #      include <unistd.h>
83 #    else
84 #      include <unixlib.h>
85 #    endif
86 #  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
87 #    include <sys/file.h>
88 #  endif
89 #endif
90 
91 #include "apps.h"
92 
93 #ifndef W_OK
94 #  define F_OK 0
95 #  define X_OK 1
96 #  define W_OK 2
97 #  define R_OK 4
98 #endif
99 
100 #undef PROG
101 #define PROG ca_main
102 
103 #define BASE_SECTION	"ca"
104 #define CONFIG_FILE "openssl.cnf"
105 
106 #define ENV_DEFAULT_CA		"default_ca"
107 
108 #define ENV_DIR			"dir"
109 #define ENV_CERTS		"certs"
110 #define ENV_CRL_DIR		"crl_dir"
111 #define ENV_CA_DB		"CA_DB"
112 #define ENV_NEW_CERTS_DIR	"new_certs_dir"
113 #define ENV_CERTIFICATE 	"certificate"
114 #define ENV_SERIAL		"serial"
115 #define ENV_CRLNUMBER		"crlnumber"
116 #define ENV_CRL			"crl"
117 #define ENV_PRIVATE_KEY		"private_key"
118 #define ENV_RANDFILE		"RANDFILE"
119 #define ENV_DEFAULT_DAYS 	"default_days"
120 #define ENV_DEFAULT_STARTDATE 	"default_startdate"
121 #define ENV_DEFAULT_ENDDATE 	"default_enddate"
122 #define ENV_DEFAULT_CRL_DAYS 	"default_crl_days"
123 #define ENV_DEFAULT_CRL_HOURS 	"default_crl_hours"
124 #define ENV_DEFAULT_MD		"default_md"
125 #define ENV_DEFAULT_EMAIL_DN	"email_in_dn"
126 #define ENV_PRESERVE		"preserve"
127 #define ENV_POLICY      	"policy"
128 #define ENV_EXTENSIONS      	"x509_extensions"
129 #define ENV_CRLEXT      	"crl_extensions"
130 #define ENV_MSIE_HACK		"msie_hack"
131 #define ENV_NAMEOPT		"name_opt"
132 #define ENV_CERTOPT		"cert_opt"
133 #define ENV_EXTCOPY		"copy_extensions"
134 
135 #define ENV_DATABASE		"database"
136 
137 /* Additional revocation information types */
138 
139 #define REV_NONE		0	/* No addditional information */
140 #define REV_CRL_REASON		1	/* Value is CRL reason code */
141 #define REV_HOLD		2	/* Value is hold instruction */
142 #define REV_KEY_COMPROMISE	3	/* Value is cert key compromise time */
143 #define REV_CA_COMPROMISE	4	/* Value is CA key compromise time */
144 
145 static char *ca_usage[]={
146 "usage: ca args\n",
147 "\n",
148 " -verbose        - Talk alot while doing things\n",
149 " -config file    - A config file\n",
150 " -name arg       - The particular CA definition to use\n",
151 " -gencrl         - Generate a new CRL\n",
152 " -crldays days   - Days is when the next CRL is due\n",
153 " -crlhours hours - Hours is when the next CRL is due\n",
154 " -startdate YYMMDDHHMMSSZ  - certificate validity notBefore\n",
155 " -enddate YYMMDDHHMMSSZ    - certificate validity notAfter (overrides -days)\n",
156 " -days arg       - number of days to certify the certificate for\n",
157 " -md arg         - md to use, one of md2, md5, sha or sha1\n",
158 " -policy arg     - The CA 'policy' to support\n",
159 " -keyfile arg    - private key file\n",
160 " -keyform arg    - private key file format (PEM or ENGINE)\n",
161 " -key arg        - key to decode the private key if it is encrypted\n",
162 " -cert file      - The CA certificate\n",
163 " -in file        - The input PEM encoded certificate request(s)\n",
164 " -out file       - Where to put the output file(s)\n",
165 " -outdir dir     - Where to put output certificates\n",
166 " -infiles ....   - The last argument, requests to process\n",
167 " -spkac file     - File contains DN and signed public key and challenge\n",
168 " -ss_cert file   - File contains a self signed cert to sign\n",
169 " -preserveDN     - Don't re-order the DN\n",
170 " -noemailDN      - Don't add the EMAIL field into certificate' subject\n",
171 " -batch          - Don't ask questions\n",
172 " -msie_hack      - msie modifications to handle all those universal strings\n",
173 " -revoke file    - Revoke a certificate (given in file)\n",
174 " -subj arg       - Use arg instead of request's subject\n",
175 " -extensions ..  - Extension section (override value in config file)\n",
176 " -extfile file   - Configuration file with X509v3 extentions to add\n",
177 " -crlexts ..     - CRL extension section (override value in config file)\n",
178 #ifndef OPENSSL_NO_ENGINE
179 " -engine e       - use engine e, possibly a hardware device.\n",
180 #endif
181 " -status serial  - Shows certificate status given the serial number\n",
182 " -updatedb       - Updates db for expired certificates\n",
183 NULL
184 };
185 
186 #ifdef EFENCE
187 extern int EF_PROTECT_FREE;
188 extern int EF_PROTECT_BELOW;
189 extern int EF_ALIGNMENT;
190 #endif
191 
192 static void lookup_fail(char *name,char *tag);
193 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
194 		   const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db,
195 		   BIGNUM *serial, char *subj, int email_dn, char *startdate,
196 		   char *enddate, long days, int batch, char *ext_sect, CONF *conf,
197 		   int verbose, unsigned long certopt, unsigned long nameopt,
198 		   int default_op, int ext_copy);
199 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
200 			const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
201 			CA_DB *db, BIGNUM *serial, char *subj, int email_dn,
202 			char *startdate, char *enddate, long days, int batch,
203 			char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
204 			unsigned long nameopt, int default_op, int ext_copy,
205 			ENGINE *e);
206 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
207 			 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
208 			 CA_DB *db, BIGNUM *serial,char *subj, int email_dn,
209 			 char *startdate, char *enddate, long days, char *ext_sect,
210 			 CONF *conf, int verbose, unsigned long certopt,
211 			 unsigned long nameopt, int default_op, int ext_copy);
212 static int fix_data(int nid, int *type);
213 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
214 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
215 	STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,
216 	int email_dn, char *startdate, char *enddate, long days, int batch,
217        	int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
218 	unsigned long certopt, unsigned long nameopt, int default_op,
219 	int ext_copy);
220 static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
221 static int get_certificate_status(const char *ser_status, CA_DB *db);
222 static int do_updatedb(CA_DB *db);
223 static int check_time_format(char *str);
224 char *make_revocation_str(int rev_type, char *rev_arg);
225 int make_revoked(X509_REVOKED *rev, char *str);
226 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
227 static CONF *conf=NULL;
228 static CONF *extconf=NULL;
229 static char *section=NULL;
230 
231 static int preserve=0;
232 static int msie_hack=0;
233 
234 
235 int MAIN(int, char **);
236 
237 int MAIN(int argc, char **argv)
238 	{
239 	ENGINE *e = NULL;
240 	char *key=NULL,*passargin=NULL;
241 	int create_ser = 0;
242 	int free_key = 0;
243 	int total=0;
244 	int total_done=0;
245 	int badops=0;
246 	int ret=1;
247 	int email_dn=1;
248 	int req=0;
249 	int verbose=0;
250 	int gencrl=0;
251 	int dorevoke=0;
252 	int doupdatedb=0;
253 	long crldays=0;
254 	long crlhours=0;
255 	long errorline= -1;
256 	char *configfile=NULL;
257 	char *md=NULL;
258 	char *policy=NULL;
259 	char *keyfile=NULL;
260 	char *certfile=NULL;
261 	int keyform=FORMAT_PEM;
262 	char *infile=NULL;
263 	char *spkac_file=NULL;
264 	char *ss_cert_file=NULL;
265 	char *ser_status=NULL;
266 	EVP_PKEY *pkey=NULL;
267 	int output_der = 0;
268 	char *outfile=NULL;
269 	char *outdir=NULL;
270 	char *serialfile=NULL;
271 	char *crlnumberfile=NULL;
272 	char *extensions=NULL;
273 	char *extfile=NULL;
274 	char *subj=NULL;
275 	char *tmp_email_dn=NULL;
276 	char *crl_ext=NULL;
277 	int rev_type = REV_NONE;
278 	char *rev_arg = NULL;
279 	BIGNUM *serial=NULL;
280 	BIGNUM *crlnumber=NULL;
281 	char *startdate=NULL;
282 	char *enddate=NULL;
283 	long days=0;
284 	int batch=0;
285 	int notext=0;
286 	unsigned long nameopt = 0, certopt = 0;
287 	int default_op = 1;
288 	int ext_copy = EXT_COPY_NONE;
289 	X509 *x509=NULL;
290 	X509 *x=NULL;
291 	BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
292 	char *dbfile=NULL;
293 	CA_DB *db=NULL;
294 	X509_CRL *crl=NULL;
295 	X509_REVOKED *r=NULL;
296 	ASN1_TIME *tmptm;
297 	ASN1_INTEGER *tmpser;
298 	char **pp,*p,*f;
299 	int i,j;
300 	const EVP_MD *dgst=NULL;
301 	STACK_OF(CONF_VALUE) *attribs=NULL;
302 	STACK_OF(X509) *cert_sk=NULL;
303 #undef BSIZE
304 #define BSIZE 256
305 	MS_STATIC char buf[3][BSIZE];
306 	char *randfile=NULL;
307 #ifndef OPENSSL_NO_ENGINE
308 	char *engine = NULL;
309 #endif
310 	char *tofree=NULL;
311 	DB_ATTR db_attr;
312 
313 #ifdef EFENCE
314 EF_PROTECT_FREE=1;
315 EF_PROTECT_BELOW=1;
316 EF_ALIGNMENT=0;
317 #endif
318 
319 	apps_startup();
320 
321 	conf = NULL;
322 	key = NULL;
323 	section = NULL;
324 
325 	preserve=0;
326 	msie_hack=0;
327 	if (bio_err == NULL)
328 		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
329 			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
330 
331 	argc--;
332 	argv++;
333 	while (argc >= 1)
334 		{
335 		if	(strcmp(*argv,"-verbose") == 0)
336 			verbose=1;
337 		else if	(strcmp(*argv,"-config") == 0)
338 			{
339 			if (--argc < 1) goto bad;
340 			configfile= *(++argv);
341 			}
342 		else if (strcmp(*argv,"-name") == 0)
343 			{
344 			if (--argc < 1) goto bad;
345 			section= *(++argv);
346 			}
347 		else if (strcmp(*argv,"-subj") == 0)
348 			{
349 			if (--argc < 1) goto bad;
350 			subj= *(++argv);
351 			/* preserve=1; */
352 			}
353 		else if (strcmp(*argv,"-startdate") == 0)
354 			{
355 			if (--argc < 1) goto bad;
356 			startdate= *(++argv);
357 			}
358 		else if (strcmp(*argv,"-enddate") == 0)
359 			{
360 			if (--argc < 1) goto bad;
361 			enddate= *(++argv);
362 			}
363 		else if (strcmp(*argv,"-days") == 0)
364 			{
365 			if (--argc < 1) goto bad;
366 			days=atoi(*(++argv));
367 			}
368 		else if (strcmp(*argv,"-md") == 0)
369 			{
370 			if (--argc < 1) goto bad;
371 			md= *(++argv);
372 			}
373 		else if (strcmp(*argv,"-policy") == 0)
374 			{
375 			if (--argc < 1) goto bad;
376 			policy= *(++argv);
377 			}
378 		else if (strcmp(*argv,"-keyfile") == 0)
379 			{
380 			if (--argc < 1) goto bad;
381 			keyfile= *(++argv);
382 			}
383 		else if (strcmp(*argv,"-keyform") == 0)
384 			{
385 			if (--argc < 1) goto bad;
386 			keyform=str2fmt(*(++argv));
387 			}
388 		else if (strcmp(*argv,"-passin") == 0)
389 			{
390 			if (--argc < 1) goto bad;
391 			passargin= *(++argv);
392 			}
393 		else if (strcmp(*argv,"-key") == 0)
394 			{
395 			if (--argc < 1) goto bad;
396 			key= *(++argv);
397 			}
398 		else if (strcmp(*argv,"-cert") == 0)
399 			{
400 			if (--argc < 1) goto bad;
401 			certfile= *(++argv);
402 			}
403 		else if (strcmp(*argv,"-in") == 0)
404 			{
405 			if (--argc < 1) goto bad;
406 			infile= *(++argv);
407 			req=1;
408 			}
409 		else if (strcmp(*argv,"-out") == 0)
410 			{
411 			if (--argc < 1) goto bad;
412 			outfile= *(++argv);
413 			}
414 		else if (strcmp(*argv,"-outdir") == 0)
415 			{
416 			if (--argc < 1) goto bad;
417 			outdir= *(++argv);
418 			}
419 		else if (strcmp(*argv,"-notext") == 0)
420 			notext=1;
421 		else if (strcmp(*argv,"-batch") == 0)
422 			batch=1;
423 		else if (strcmp(*argv,"-preserveDN") == 0)
424 			preserve=1;
425 		else if (strcmp(*argv,"-noemailDN") == 0)
426 			email_dn=0;
427 		else if (strcmp(*argv,"-gencrl") == 0)
428 			gencrl=1;
429 		else if (strcmp(*argv,"-msie_hack") == 0)
430 			msie_hack=1;
431 		else if (strcmp(*argv,"-crldays") == 0)
432 			{
433 			if (--argc < 1) goto bad;
434 			crldays= atol(*(++argv));
435 			}
436 		else if (strcmp(*argv,"-crlhours") == 0)
437 			{
438 			if (--argc < 1) goto bad;
439 			crlhours= atol(*(++argv));
440 			}
441 		else if (strcmp(*argv,"-infiles") == 0)
442 			{
443 			argc--;
444 			argv++;
445 			req=1;
446 			break;
447 			}
448 		else if (strcmp(*argv, "-ss_cert") == 0)
449 			{
450 			if (--argc < 1) goto bad;
451 			ss_cert_file = *(++argv);
452 			req=1;
453 			}
454 		else if (strcmp(*argv, "-spkac") == 0)
455 			{
456 			if (--argc < 1) goto bad;
457 			spkac_file = *(++argv);
458 			req=1;
459 			}
460 		else if (strcmp(*argv,"-revoke") == 0)
461 			{
462 			if (--argc < 1) goto bad;
463 			infile= *(++argv);
464 			dorevoke=1;
465 			}
466 		else if (strcmp(*argv,"-extensions") == 0)
467 			{
468 			if (--argc < 1) goto bad;
469 			extensions= *(++argv);
470 			}
471 		else if (strcmp(*argv,"-extfile") == 0)
472 			{
473 			if (--argc < 1) goto bad;
474 			extfile= *(++argv);
475 			}
476 		else if (strcmp(*argv,"-status") == 0)
477 			{
478 			if (--argc < 1) goto bad;
479 			ser_status= *(++argv);
480 			}
481 		else if (strcmp(*argv,"-updatedb") == 0)
482 			{
483 			doupdatedb=1;
484 			}
485 		else if (strcmp(*argv,"-crlexts") == 0)
486 			{
487 			if (--argc < 1) goto bad;
488 			crl_ext= *(++argv);
489 			}
490 		else if (strcmp(*argv,"-crl_reason") == 0)
491 			{
492 			if (--argc < 1) goto bad;
493 			rev_arg = *(++argv);
494 			rev_type = REV_CRL_REASON;
495 			}
496 		else if (strcmp(*argv,"-crl_hold") == 0)
497 			{
498 			if (--argc < 1) goto bad;
499 			rev_arg = *(++argv);
500 			rev_type = REV_HOLD;
501 			}
502 		else if (strcmp(*argv,"-crl_compromise") == 0)
503 			{
504 			if (--argc < 1) goto bad;
505 			rev_arg = *(++argv);
506 			rev_type = REV_KEY_COMPROMISE;
507 			}
508 		else if (strcmp(*argv,"-crl_CA_compromise") == 0)
509 			{
510 			if (--argc < 1) goto bad;
511 			rev_arg = *(++argv);
512 			rev_type = REV_CA_COMPROMISE;
513 			}
514 #ifndef OPENSSL_NO_ENGINE
515 		else if (strcmp(*argv,"-engine") == 0)
516 			{
517 			if (--argc < 1) goto bad;
518 			engine= *(++argv);
519 			}
520 #endif
521 		else
522 			{
523 bad:
524 			BIO_printf(bio_err,"unknown option %s\n",*argv);
525 			badops=1;
526 			break;
527 			}
528 		argc--;
529 		argv++;
530 		}
531 
532 	if (badops)
533 		{
534 		for (pp=ca_usage; (*pp != NULL); pp++)
535 			BIO_printf(bio_err,"%s",*pp);
536 		goto err;
537 		}
538 
539 	ERR_load_crypto_strings();
540 
541 	/*****************************************************************/
542 	tofree=NULL;
543 	if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
544 	if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
545 	if (configfile == NULL)
546 		{
547 		const char *s=X509_get_default_cert_area();
548 		size_t len;
549 
550 #ifdef OPENSSL_SYS_VMS
551 		len = strlen(s)+sizeof(CONFIG_FILE);
552 		tofree=OPENSSL_malloc(len);
553 		strcpy(tofree,s);
554 #else
555 		len = strlen(s)+sizeof(CONFIG_FILE)+1;
556 		tofree=OPENSSL_malloc(len);
557 		BUF_strlcpy(tofree,s,len);
558 		BUF_strlcat(tofree,"/",len);
559 #endif
560 		BUF_strlcat(tofree,CONFIG_FILE,len);
561 		configfile=tofree;
562 		}
563 
564 	BIO_printf(bio_err,"Using configuration from %s\n",configfile);
565 	conf = NCONF_new(NULL);
566 	if (NCONF_load(conf,configfile,&errorline) <= 0)
567 		{
568 		if (errorline <= 0)
569 			BIO_printf(bio_err,"error loading the config file '%s'\n",
570 				configfile);
571 		else
572 			BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
573 				,errorline,configfile);
574 		goto err;
575 		}
576 	if(tofree)
577 		{
578 		OPENSSL_free(tofree);
579 		tofree = NULL;
580 		}
581 
582 	if (!load_config(bio_err, conf))
583 		goto err;
584 
585 #ifndef OPENSSL_NO_ENGINE
586 	e = setup_engine(bio_err, engine, 0);
587 #endif
588 
589 	/* Lets get the config section we are using */
590 	if (section == NULL)
591 		{
592 		section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
593 		if (section == NULL)
594 			{
595 			lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
596 			goto err;
597 			}
598 		}
599 
600 	if (conf != NULL)
601 		{
602 		p=NCONF_get_string(conf,NULL,"oid_file");
603 		if (p == NULL)
604 			ERR_clear_error();
605 		if (p != NULL)
606 			{
607 			BIO *oid_bio;
608 
609 			oid_bio=BIO_new_file(p,"r");
610 			if (oid_bio == NULL)
611 				{
612 				/*
613 				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
614 				ERR_print_errors(bio_err);
615 				*/
616 				ERR_clear_error();
617 				}
618 			else
619 				{
620 				OBJ_create_objects(oid_bio);
621 				BIO_free(oid_bio);
622 				}
623 			}
624 		if (!add_oid_section(bio_err,conf))
625 			{
626 			ERR_print_errors(bio_err);
627 			goto err;
628 			}
629 		}
630 
631 	randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
632 	if (randfile == NULL)
633 		ERR_clear_error();
634 	app_RAND_load_file(randfile, bio_err, 0);
635 
636 	db_attr.unique_subject = 1;
637 	p = NCONF_get_string(conf, section, "unique_subject");
638 	if (p)
639 		{
640 #ifdef RL_DEBUG
641 		BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
642 #endif
643 		switch(*p)
644 			{
645 		case 'f': /* false */
646 		case 'F': /* FALSE */
647 		case 'n': /* no */
648 		case 'N': /* NO */
649 			db_attr.unique_subject = 0;
650 			break;
651 		case 't': /* true */
652 		case 'T': /* TRUE */
653 		case 'y': /* yes */
654 		case 'Y': /* YES */
655 		default:
656 			db_attr.unique_subject = 1;
657 			break;
658 			}
659 		}
660 	else
661 		ERR_clear_error();
662 #ifdef RL_DEBUG
663 	if (!p)
664 		BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
665 #endif
666 #ifdef RL_DEBUG
667 	BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",
668 		db_attr.unique_subject);
669 #endif
670 
671 	in=BIO_new(BIO_s_file());
672 	out=BIO_new(BIO_s_file());
673 	Sout=BIO_new(BIO_s_file());
674 	Cout=BIO_new(BIO_s_file());
675 	if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
676 		{
677 		ERR_print_errors(bio_err);
678 		goto err;
679 		}
680 
681 	/*****************************************************************/
682 	/* report status of cert with serial number given on command line */
683 	if (ser_status)
684 	{
685 		if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
686 			{
687 			lookup_fail(section,ENV_DATABASE);
688 			goto err;
689 			}
690 		db = load_index(dbfile,&db_attr);
691 		if (db == NULL) goto err;
692 
693 		if (!index_index(db)) goto err;
694 
695 		if (get_certificate_status(ser_status,db) != 1)
696 			BIO_printf(bio_err,"Error verifying serial %s!\n",
697 				 ser_status);
698 		goto err;
699 	}
700 
701 	/*****************************************************************/
702 	/* we definitely need a public key, so let's get it */
703 
704 	if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
705 		section,ENV_PRIVATE_KEY)) == NULL))
706 		{
707 		lookup_fail(section,ENV_PRIVATE_KEY);
708 		goto err;
709 		}
710 	if (!key)
711 		{
712 		free_key = 1;
713 		if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
714 			{
715 			BIO_printf(bio_err,"Error getting password\n");
716 			goto err;
717 			}
718 		}
719 	pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
720 		"CA private key");
721 	if (key) OPENSSL_cleanse(key,strlen(key));
722 	if (pkey == NULL)
723 		{
724 		/* load_key() has already printed an appropriate message */
725 		goto err;
726 		}
727 
728 	/*****************************************************************/
729 	/* we need a certificate */
730 	if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
731 		section,ENV_CERTIFICATE)) == NULL))
732 		{
733 		lookup_fail(section,ENV_CERTIFICATE);
734 		goto err;
735 		}
736 	x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
737 		"CA certificate");
738 	if (x509 == NULL)
739 		goto err;
740 
741 	if (!X509_check_private_key(x509,pkey))
742 		{
743 		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
744 		goto err;
745 		}
746 
747 	f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
748 	if (f == NULL)
749 		ERR_clear_error();
750 	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
751 		preserve=1;
752 	f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
753 	if (f == NULL)
754 		ERR_clear_error();
755 	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
756 		msie_hack=1;
757 
758 	f=NCONF_get_string(conf,section,ENV_NAMEOPT);
759 
760 	if (f)
761 		{
762 		if (!set_name_ex(&nameopt, f))
763 			{
764 			BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
765 			goto err;
766 			}
767 		default_op = 0;
768 		}
769 	else
770 		ERR_clear_error();
771 
772 	f=NCONF_get_string(conf,section,ENV_CERTOPT);
773 
774 	if (f)
775 		{
776 		if (!set_cert_ex(&certopt, f))
777 			{
778 			BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
779 			goto err;
780 			}
781 		default_op = 0;
782 		}
783 	else
784 		ERR_clear_error();
785 
786 	f=NCONF_get_string(conf,section,ENV_EXTCOPY);
787 
788 	if (f)
789 		{
790 		if (!set_ext_copy(&ext_copy, f))
791 			{
792 			BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
793 			goto err;
794 			}
795 		}
796 	else
797 		ERR_clear_error();
798 
799 	/*****************************************************************/
800 	/* lookup where to write new certificates */
801 	if ((outdir == NULL) && (req))
802 		{
803 		struct stat sb;
804 
805 		if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
806 			== NULL)
807 			{
808 			BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
809 			goto err;
810 			}
811 #ifndef OPENSSL_SYS_VMS
812 	    /* outdir is a directory spec, but access() for VMS demands a
813 	       filename.  In any case, stat(), below, will catch the problem
814 	       if outdir is not a directory spec, and the fopen() or open()
815 	       will catch an error if there is no write access.
816 
817 	       Presumably, this problem could also be solved by using the DEC
818 	       C routines to convert the directory syntax to Unixly, and give
819 	       that to access().  However, time's too short to do that just
820 	       now.
821 	    */
822 		if (access(outdir,R_OK|W_OK|X_OK) != 0)
823 			{
824 			BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
825 			perror(outdir);
826 			goto err;
827 			}
828 
829 		if (stat(outdir,&sb) != 0)
830 			{
831 			BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
832 			perror(outdir);
833 			goto err;
834 			}
835 #ifdef S_IFDIR
836 		if (!(sb.st_mode & S_IFDIR))
837 			{
838 			BIO_printf(bio_err,"%s need to be a directory\n",outdir);
839 			perror(outdir);
840 			goto err;
841 			}
842 #endif
843 #endif
844 		}
845 
846 	/*****************************************************************/
847 	/* we need to load the database file */
848 	if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
849 		{
850 		lookup_fail(section,ENV_DATABASE);
851 		goto err;
852 		}
853 	db = load_index(dbfile, &db_attr);
854 	if (db == NULL) goto err;
855 
856 	/* Lets check some fields */
857 	for (i=0; i<sk_num(db->db->data); i++)
858 		{
859 		pp=(char **)sk_value(db->db->data,i);
860 		if ((pp[DB_type][0] != DB_TYPE_REV) &&
861 			(pp[DB_rev_date][0] != '\0'))
862 			{
863 			BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
864 			goto err;
865 			}
866 		if ((pp[DB_type][0] == DB_TYPE_REV) &&
867 			!make_revoked(NULL, pp[DB_rev_date]))
868 			{
869 			BIO_printf(bio_err," in entry %d\n", i+1);
870 			goto err;
871 			}
872 		if (!check_time_format(pp[DB_exp_date]))
873 			{
874 			BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
875 			goto err;
876 			}
877 		p=pp[DB_serial];
878 		j=strlen(p);
879 		if (*p == '-')
880 			{
881 			p++;
882 			j--;
883 			}
884 		if ((j&1) || (j < 2))
885 			{
886 			BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
887 			goto err;
888 			}
889 		while (*p)
890 			{
891 			if (!(	((*p >= '0') && (*p <= '9')) ||
892 				((*p >= 'A') && (*p <= 'F')) ||
893 				((*p >= 'a') && (*p <= 'f')))  )
894 				{
895 				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);
896 				goto err;
897 				}
898 			p++;
899 			}
900 		}
901 	if (verbose)
902 		{
903 		BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
904 #ifdef OPENSSL_SYS_VMS
905 		{
906 		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
907 		out = BIO_push(tmpbio, out);
908 		}
909 #endif
910 		TXT_DB_write(out,db->db);
911 		BIO_printf(bio_err,"%d entries loaded from the database\n",
912 			db->db->data->num);
913 		BIO_printf(bio_err,"generating index\n");
914 		}
915 
916 	if (!index_index(db)) goto err;
917 
918 	/*****************************************************************/
919 	/* Update the db file for expired certificates */
920 	if (doupdatedb)
921 		{
922 		if (verbose)
923 			BIO_printf(bio_err, "Updating %s ...\n",
924 							dbfile);
925 
926 		i = do_updatedb(db);
927 		if (i == -1)
928 			{
929 			BIO_printf(bio_err,"Malloc failure\n");
930 			goto err;
931 			}
932 		else if (i == 0)
933 			{
934 			if (verbose) BIO_printf(bio_err,
935 					"No entries found to mark expired\n");
936 			}
937 	    	else
938 			{
939 			if (!save_index(dbfile,"new",db)) goto err;
940 
941 			if (!rotate_index(dbfile,"new","old")) goto err;
942 
943 			if (verbose) BIO_printf(bio_err,
944 				"Done. %d entries marked as expired\n",i);
945 	      		}
946 			goto err;
947 	  	}
948 
949  	/*****************************************************************/
950 	/* Read extentions config file                                   */
951 	if (extfile)
952 		{
953 		extconf = NCONF_new(NULL);
954 		if (NCONF_load(extconf,extfile,&errorline) <= 0)
955 			{
956 			if (errorline <= 0)
957 				BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
958 					extfile);
959 			else
960 				BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
961 					errorline,extfile);
962 			ret = 1;
963 			goto err;
964 			}
965 
966 		if (verbose)
967 			BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
968 
969 		/* We can have sections in the ext file */
970 		if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
971 			extensions = "default";
972 		}
973 
974 	/*****************************************************************/
975 	if (req || gencrl)
976 		{
977 		if (outfile != NULL)
978 			{
979 			if (BIO_write_filename(Sout,outfile) <= 0)
980 				{
981 				perror(outfile);
982 				goto err;
983 				}
984 			}
985 		else
986 			{
987 			BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
988 #ifdef OPENSSL_SYS_VMS
989 			{
990 			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
991 			Sout = BIO_push(tmpbio, Sout);
992 			}
993 #endif
994 			}
995 		}
996 
997 	if (req)
998 		{
999 		if ((md == NULL) && ((md=NCONF_get_string(conf,
1000 			section,ENV_DEFAULT_MD)) == NULL))
1001 			{
1002 			lookup_fail(section,ENV_DEFAULT_MD);
1003 			goto err;
1004 			}
1005 		if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1006 			section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1007 			{
1008 			if(strcmp(tmp_email_dn,"no") == 0)
1009 				email_dn=0;
1010 			}
1011 		if ((dgst=EVP_get_digestbyname(md)) == NULL)
1012 			{
1013 			BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1014 			goto err;
1015 			}
1016 		if (verbose)
1017 			BIO_printf(bio_err,"message digest is %s\n",
1018 				OBJ_nid2ln(dgst->type));
1019 		if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1020 			section,ENV_POLICY)) == NULL))
1021 			{
1022 			lookup_fail(section,ENV_POLICY);
1023 			goto err;
1024 			}
1025 		if (verbose)
1026 			BIO_printf(bio_err,"policy is %s\n",policy);
1027 
1028 		if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1029 			== NULL)
1030 			{
1031 			lookup_fail(section,ENV_SERIAL);
1032 			goto err;
1033 			}
1034 
1035 		if (!extconf)
1036 			{
1037 			/* no '-extfile' option, so we look for extensions
1038 			 * in the main configuration file */
1039 			if (!extensions)
1040 				{
1041 				extensions=NCONF_get_string(conf,section,
1042 								ENV_EXTENSIONS);
1043 				if (!extensions)
1044 					ERR_clear_error();
1045 				}
1046 			if (extensions)
1047 				{
1048 				/* Check syntax of file */
1049 				X509V3_CTX ctx;
1050 				X509V3_set_ctx_test(&ctx);
1051 				X509V3_set_nconf(&ctx, conf);
1052 				if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1053 								NULL))
1054 					{
1055 					BIO_printf(bio_err,
1056 				 	"Error Loading extension section %s\n",
1057 								 extensions);
1058 					ret = 1;
1059 					goto err;
1060 					}
1061 				}
1062 			}
1063 
1064 		if (startdate == NULL)
1065 			{
1066 			startdate=NCONF_get_string(conf,section,
1067 				ENV_DEFAULT_STARTDATE);
1068 			if (startdate == NULL)
1069 				ERR_clear_error();
1070 			}
1071 		if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1072 			{
1073 			BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1074 			goto err;
1075 			}
1076 		if (startdate == NULL) startdate="today";
1077 
1078 		if (enddate == NULL)
1079 			{
1080 			enddate=NCONF_get_string(conf,section,
1081 				ENV_DEFAULT_ENDDATE);
1082 			if (enddate == NULL)
1083 				ERR_clear_error();
1084 			}
1085 		if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1086 			{
1087 			BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1088 			goto err;
1089 			}
1090 
1091 		if (days == 0)
1092 			{
1093 			if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1094 				days = 0;
1095 			}
1096 		if (!enddate && (days == 0))
1097 			{
1098 			BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1099 			goto err;
1100 			}
1101 
1102 		if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL)
1103 			{
1104 			BIO_printf(bio_err,"error while loading serial number\n");
1105 			goto err;
1106 			}
1107 		if (verbose)
1108 			{
1109 			if (BN_is_zero(serial))
1110 				BIO_printf(bio_err,"next serial number is 00\n");
1111 			else
1112 				{
1113 				if ((f=BN_bn2hex(serial)) == NULL) goto err;
1114 				BIO_printf(bio_err,"next serial number is %s\n",f);
1115 				OPENSSL_free(f);
1116 				}
1117 			}
1118 
1119 		if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1120 			{
1121 			BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1122 			goto err;
1123 			}
1124 
1125 		if ((cert_sk=sk_X509_new_null()) == NULL)
1126 			{
1127 			BIO_printf(bio_err,"Memory allocation failure\n");
1128 			goto err;
1129 			}
1130 		if (spkac_file != NULL)
1131 			{
1132 			total++;
1133 			j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1134 				serial,subj,email_dn,startdate,enddate,days,extensions,
1135 				conf,verbose,certopt,nameopt,default_op,ext_copy);
1136 			if (j < 0) goto err;
1137 			if (j > 0)
1138 				{
1139 				total_done++;
1140 				BIO_printf(bio_err,"\n");
1141 				if (!BN_add_word(serial,1)) goto err;
1142 				if (!sk_X509_push(cert_sk,x))
1143 					{
1144 					BIO_printf(bio_err,"Memory allocation failure\n");
1145 					goto err;
1146 					}
1147 				if (outfile)
1148 					{
1149 					output_der = 1;
1150 					batch = 1;
1151 					}
1152 				}
1153 			}
1154 		if (ss_cert_file != NULL)
1155 			{
1156 			total++;
1157 			j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1158 				db,serial,subj,email_dn,startdate,enddate,days,batch,
1159 				extensions,conf,verbose, certopt, nameopt,
1160 				default_op, ext_copy, e);
1161 			if (j < 0) goto err;
1162 			if (j > 0)
1163 				{
1164 				total_done++;
1165 				BIO_printf(bio_err,"\n");
1166 				if (!BN_add_word(serial,1)) goto err;
1167 				if (!sk_X509_push(cert_sk,x))
1168 					{
1169 					BIO_printf(bio_err,"Memory allocation failure\n");
1170 					goto err;
1171 					}
1172 				}
1173 			}
1174 		if (infile != NULL)
1175 			{
1176 			total++;
1177 			j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1178 				serial,subj,email_dn,startdate,enddate,days,batch,
1179 				extensions,conf,verbose, certopt, nameopt,
1180 				default_op, ext_copy);
1181 			if (j < 0) goto err;
1182 			if (j > 0)
1183 				{
1184 				total_done++;
1185 				BIO_printf(bio_err,"\n");
1186 				if (!BN_add_word(serial,1)) goto err;
1187 				if (!sk_X509_push(cert_sk,x))
1188 					{
1189 					BIO_printf(bio_err,"Memory allocation failure\n");
1190 					goto err;
1191 					}
1192 				}
1193 			}
1194 		for (i=0; i<argc; i++)
1195 			{
1196 			total++;
1197 			j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1198 				serial,subj,email_dn,startdate,enddate,days,batch,
1199 				extensions,conf,verbose, certopt, nameopt,
1200 				default_op, ext_copy);
1201 			if (j < 0) goto err;
1202 			if (j > 0)
1203 				{
1204 				total_done++;
1205 				BIO_printf(bio_err,"\n");
1206 				if (!BN_add_word(serial,1)) goto err;
1207 				if (!sk_X509_push(cert_sk,x))
1208 					{
1209 					BIO_printf(bio_err,"Memory allocation failure\n");
1210 					goto err;
1211 					}
1212 				}
1213 			}
1214 		/* we have a stack of newly certified certificates
1215 		 * and a data base and serial number that need
1216 		 * updating */
1217 
1218 		if (sk_X509_num(cert_sk) > 0)
1219 			{
1220 			if (!batch)
1221 				{
1222 				BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1223 				(void)BIO_flush(bio_err);
1224 				buf[0][0]='\0';
1225 				fgets(buf[0],10,stdin);
1226 				if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1227 					{
1228 					BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1229 					ret=0;
1230 					goto err;
1231 					}
1232 				}
1233 
1234 			BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1235 
1236 			if (!save_serial(serialfile,"new",serial,NULL)) goto err;
1237 
1238 			if (!save_index(dbfile, "new", db)) goto err;
1239 			}
1240 
1241 		if (verbose)
1242 			BIO_printf(bio_err,"writing new certificates\n");
1243 		for (i=0; i<sk_X509_num(cert_sk); i++)
1244 			{
1245 			int k;
1246 			char *n;
1247 
1248 			x=sk_X509_value(cert_sk,i);
1249 
1250 			j=x->cert_info->serialNumber->length;
1251 			p=(char *)x->cert_info->serialNumber->data;
1252 
1253 			if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1254 				{
1255 				BIO_printf(bio_err,"certificate file name too long\n");
1256 				goto err;
1257 				}
1258 
1259 			strcpy(buf[2],outdir);
1260 
1261 #ifndef OPENSSL_SYS_VMS
1262 			BUF_strlcat(buf[2],"/",sizeof(buf[2]));
1263 #endif
1264 
1265 			n=(char *)&(buf[2][strlen(buf[2])]);
1266 			if (j > 0)
1267 				{
1268 				for (k=0; k<j; k++)
1269 					{
1270 					if (n >= &(buf[2][sizeof(buf[2])]))
1271 						break;
1272 					BIO_snprintf(n,
1273 						     &buf[2][0] + sizeof(buf[2]) - n,
1274 						     "%02X",(unsigned char)*(p++));
1275 					n+=2;
1276 					}
1277 				}
1278 			else
1279 				{
1280 				*(n++)='0';
1281 				*(n++)='0';
1282 				}
1283 			*(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1284 			*n='\0';
1285 			if (verbose)
1286 				BIO_printf(bio_err,"writing %s\n",buf[2]);
1287 
1288 			if (BIO_write_filename(Cout,buf[2]) <= 0)
1289 				{
1290 				perror(buf[2]);
1291 				goto err;
1292 				}
1293 			write_new_certificate(Cout,x, 0, notext);
1294 			write_new_certificate(Sout,x, output_der, notext);
1295 			}
1296 
1297 		if (sk_X509_num(cert_sk))
1298 			{
1299 			/* Rename the database and the serial file */
1300 			if (!rotate_serial(serialfile,"new","old")) goto err;
1301 
1302 			if (!rotate_index(dbfile,"new","old")) goto err;
1303 
1304 			BIO_printf(bio_err,"Data Base Updated\n");
1305 			}
1306 		}
1307 
1308 	/*****************************************************************/
1309 	if (gencrl)
1310 		{
1311 		int crl_v2 = 0;
1312 		if (!crl_ext)
1313 			{
1314 			crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1315 			if (!crl_ext)
1316 				ERR_clear_error();
1317 			}
1318 		if (crl_ext)
1319 			{
1320 			/* Check syntax of file */
1321 			X509V3_CTX ctx;
1322 			X509V3_set_ctx_test(&ctx);
1323 			X509V3_set_nconf(&ctx, conf);
1324 			if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1325 				{
1326 				BIO_printf(bio_err,
1327 				 "Error Loading CRL extension section %s\n",
1328 								 crl_ext);
1329 				ret = 1;
1330 				goto err;
1331 				}
1332 			}
1333 
1334 		if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER))
1335 			!= NULL)
1336 			if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL)
1337 				{
1338 				BIO_printf(bio_err,"error while loading CRL number\n");
1339 				goto err;
1340 				}
1341 
1342 		if (!crldays && !crlhours)
1343 			{
1344 			if (!NCONF_get_number(conf,section,
1345 				ENV_DEFAULT_CRL_DAYS, &crldays))
1346 				crldays = 0;
1347 			if (!NCONF_get_number(conf,section,
1348 				ENV_DEFAULT_CRL_HOURS, &crlhours))
1349 				crlhours = 0;
1350 			}
1351 		if ((crldays == 0) && (crlhours == 0))
1352 			{
1353 			BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1354 			goto err;
1355 			}
1356 
1357 		if (verbose) BIO_printf(bio_err,"making CRL\n");
1358 		if ((crl=X509_CRL_new()) == NULL) goto err;
1359 		if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1360 
1361 		tmptm = ASN1_TIME_new();
1362 		if (!tmptm) goto err;
1363 		X509_gmtime_adj(tmptm,0);
1364 		X509_CRL_set_lastUpdate(crl, tmptm);
1365 		X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1366 		X509_CRL_set_nextUpdate(crl, tmptm);
1367 
1368 		ASN1_TIME_free(tmptm);
1369 
1370 		for (i=0; i<sk_num(db->db->data); i++)
1371 			{
1372 			pp=(char **)sk_value(db->db->data,i);
1373 			if (pp[DB_type][0] == DB_TYPE_REV)
1374 				{
1375 				if ((r=X509_REVOKED_new()) == NULL) goto err;
1376 				j = make_revoked(r, pp[DB_rev_date]);
1377 				if (!j) goto err;
1378 				if (j == 2) crl_v2 = 1;
1379 				if (!BN_hex2bn(&serial, pp[DB_serial]))
1380 					goto err;
1381 				tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1382 				BN_free(serial);
1383 				serial = NULL;
1384 				if (!tmpser)
1385 					goto err;
1386 				X509_REVOKED_set_serialNumber(r, tmpser);
1387 				ASN1_INTEGER_free(tmpser);
1388 				X509_CRL_add0_revoked(crl,r);
1389 				}
1390 			}
1391 
1392 		/* sort the data so it will be written in serial
1393 		 * number order */
1394 		X509_CRL_sort(crl);
1395 
1396 		/* we now have a CRL */
1397 		if (verbose) BIO_printf(bio_err,"signing CRL\n");
1398 		if (md != NULL)
1399 			{
1400 			if ((dgst=EVP_get_digestbyname(md)) == NULL)
1401 				{
1402 				BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1403 				goto err;
1404 				}
1405 			}
1406 		else
1407 			{
1408 #ifndef OPENSSL_NO_DSA
1409 			if (pkey->type == EVP_PKEY_DSA)
1410 				dgst=EVP_dss1();
1411 			else
1412 #endif
1413 				dgst=EVP_md5();
1414 			}
1415 
1416 		/* Add any extensions asked for */
1417 
1418 		if (crl_ext || crlnumberfile != NULL)
1419 			{
1420 			X509V3_CTX crlctx;
1421 			X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1422 			X509V3_set_nconf(&crlctx, conf);
1423 
1424 			if (crl_ext)
1425 				if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1426 					crl_ext, crl)) goto err;
1427 			if (crlnumberfile != NULL)
1428 				{
1429 				tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
1430 				if (!tmpser) goto err;
1431 				X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
1432 				ASN1_INTEGER_free(tmpser);
1433 				crl_v2 = 1;
1434 				if (!BN_add_word(crlnumber,1)) goto err;
1435 				}
1436 			}
1437 		if (crl_ext || crl_v2)
1438 			{
1439 			if (!X509_CRL_set_version(crl, 1))
1440 				goto err; /* version 2 CRL */
1441 			}
1442 
1443 
1444 		if (crlnumberfile != NULL)	/* we have a CRL number that need updating */
1445 			if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
1446 
1447 		if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1448 
1449 		PEM_write_bio_X509_CRL(Sout,crl);
1450 
1451 		if (crlnumberfile != NULL)	/* Rename the crlnumber file */
1452 			if (!rotate_serial(crlnumberfile,"new","old")) goto err;
1453 
1454 		}
1455 	/*****************************************************************/
1456 	if (dorevoke)
1457 		{
1458 		if (infile == NULL)
1459 			{
1460 			BIO_printf(bio_err,"no input files\n");
1461 			goto err;
1462 			}
1463 		else
1464 			{
1465 			X509 *revcert;
1466 			revcert=load_cert(bio_err, infile, FORMAT_PEM,
1467 				NULL, e, infile);
1468 			if (revcert == NULL)
1469 				goto err;
1470 			j=do_revoke(revcert,db, rev_type, rev_arg);
1471 			if (j <= 0) goto err;
1472 			X509_free(revcert);
1473 
1474 			if (!save_index(dbfile, "new", db)) goto err;
1475 
1476 			if (!rotate_index(dbfile, "new", "old")) goto err;
1477 
1478 			BIO_printf(bio_err,"Data Base Updated\n");
1479 			}
1480 		}
1481 	/*****************************************************************/
1482 	ret=0;
1483 err:
1484 	if(tofree)
1485 		OPENSSL_free(tofree);
1486 	BIO_free_all(Cout);
1487 	BIO_free_all(Sout);
1488 	BIO_free_all(out);
1489 	BIO_free_all(in);
1490 
1491 	if (cert_sk)
1492 		sk_X509_pop_free(cert_sk,X509_free);
1493 
1494 	if (ret) ERR_print_errors(bio_err);
1495 	app_RAND_write_file(randfile, bio_err);
1496 	if (free_key && key)
1497 		OPENSSL_free(key);
1498 	BN_free(serial);
1499 	free_index(db);
1500 	EVP_PKEY_free(pkey);
1501 	X509_free(x509);
1502 	X509_CRL_free(crl);
1503 	NCONF_free(conf);
1504 	OBJ_cleanup();
1505 	apps_shutdown();
1506 	OPENSSL_EXIT(ret);
1507 	}
1508 
1509 static void lookup_fail(char *name, char *tag)
1510 	{
1511 	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1512 	}
1513 
1514 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1515 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1516 	     BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1517 	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1518 	     unsigned long certopt, unsigned long nameopt, int default_op,
1519 	     int ext_copy)
1520 	{
1521 	X509_REQ *req=NULL;
1522 	BIO *in=NULL;
1523 	EVP_PKEY *pktmp=NULL;
1524 	int ok= -1,i;
1525 
1526 	in=BIO_new(BIO_s_file());
1527 
1528 	if (BIO_read_filename(in,infile) <= 0)
1529 		{
1530 		perror(infile);
1531 		goto err;
1532 		}
1533 	if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1534 		{
1535 		BIO_printf(bio_err,"Error reading certificate request in %s\n",
1536 			infile);
1537 		goto err;
1538 		}
1539 	if (verbose)
1540 		X509_REQ_print(bio_err,req);
1541 
1542 	BIO_printf(bio_err,"Check that the request matches the signature\n");
1543 
1544 	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1545 		{
1546 		BIO_printf(bio_err,"error unpacking public key\n");
1547 		goto err;
1548 		}
1549 	i=X509_REQ_verify(req,pktmp);
1550 	EVP_PKEY_free(pktmp);
1551 	if (i < 0)
1552 		{
1553 		ok=0;
1554 		BIO_printf(bio_err,"Signature verification problems....\n");
1555 		goto err;
1556 		}
1557 	if (i == 0)
1558 		{
1559 		ok=0;
1560 		BIO_printf(bio_err,"Signature did not match the certificate request\n");
1561 		goto err;
1562 		}
1563 	else
1564 		BIO_printf(bio_err,"Signature ok\n");
1565 
1566 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1567 		startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1568 		certopt, nameopt, default_op, ext_copy);
1569 
1570 err:
1571 	if (req != NULL) X509_REQ_free(req);
1572 	if (in != NULL) BIO_free(in);
1573 	return(ok);
1574 	}
1575 
1576 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1577 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1578 	     BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1579 	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1580 	     unsigned long certopt, unsigned long nameopt, int default_op,
1581 	     int ext_copy, ENGINE *e)
1582 	{
1583 	X509 *req=NULL;
1584 	X509_REQ *rreq=NULL;
1585 	EVP_PKEY *pktmp=NULL;
1586 	int ok= -1,i;
1587 
1588 	if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1589 		goto err;
1590 	if (verbose)
1591 		X509_print(bio_err,req);
1592 
1593 	BIO_printf(bio_err,"Check that the request matches the signature\n");
1594 
1595 	if ((pktmp=X509_get_pubkey(req)) == NULL)
1596 		{
1597 		BIO_printf(bio_err,"error unpacking public key\n");
1598 		goto err;
1599 		}
1600 	i=X509_verify(req,pktmp);
1601 	EVP_PKEY_free(pktmp);
1602 	if (i < 0)
1603 		{
1604 		ok=0;
1605 		BIO_printf(bio_err,"Signature verification problems....\n");
1606 		goto err;
1607 		}
1608 	if (i == 0)
1609 		{
1610 		ok=0;
1611 		BIO_printf(bio_err,"Signature did not match the certificate\n");
1612 		goto err;
1613 		}
1614 	else
1615 		BIO_printf(bio_err,"Signature ok\n");
1616 
1617 	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1618 		goto err;
1619 
1620 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1621 		days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1622 		ext_copy);
1623 
1624 err:
1625 	if (rreq != NULL) X509_REQ_free(rreq);
1626 	if (req != NULL) X509_free(req);
1627 	return(ok);
1628 	}
1629 
1630 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1631 	     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1632 	     int email_dn, char *startdate, char *enddate, long days, int batch,
1633 	     int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1634 	     unsigned long certopt, unsigned long nameopt, int default_op,
1635 	     int ext_copy)
1636 	{
1637 	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1638 	ASN1_UTCTIME *tm,*tmptm;
1639 	ASN1_STRING *str,*str2;
1640 	ASN1_OBJECT *obj;
1641 	X509 *ret=NULL;
1642 	X509_CINF *ci;
1643 	X509_NAME_ENTRY *ne;
1644 	X509_NAME_ENTRY *tne,*push;
1645 	EVP_PKEY *pktmp;
1646 	int ok= -1,i,j,last,nid;
1647 	char *p;
1648 	CONF_VALUE *cv;
1649 	char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
1650 	char buf[25];
1651 
1652 	tmptm=ASN1_UTCTIME_new();
1653 	if (tmptm == NULL)
1654 		{
1655 		BIO_printf(bio_err,"malloc error\n");
1656 		return(0);
1657 		}
1658 
1659 	for (i=0; i<DB_NUMBER; i++)
1660 		row[i]=NULL;
1661 
1662 	if (subj)
1663 		{
1664 		X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1665 
1666 		if (!n)
1667 			{
1668 			ERR_print_errors(bio_err);
1669 			goto err;
1670 			}
1671 		X509_REQ_set_subject_name(req,n);
1672 		req->req_info->enc.modified = 1;
1673 		X509_NAME_free(n);
1674 		}
1675 
1676 	if (default_op)
1677 		BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1678 
1679 	name=X509_REQ_get_subject_name(req);
1680 	for (i=0; i<X509_NAME_entry_count(name); i++)
1681 		{
1682 		ne= X509_NAME_get_entry(name,i);
1683 		str=X509_NAME_ENTRY_get_data(ne);
1684 		obj=X509_NAME_ENTRY_get_object(ne);
1685 
1686 		if (msie_hack)
1687 			{
1688 			/* assume all type should be strings */
1689 			nid=OBJ_obj2nid(ne->object);
1690 
1691 			if (str->type == V_ASN1_UNIVERSALSTRING)
1692 				ASN1_UNIVERSALSTRING_to_string(str);
1693 
1694 			if ((str->type == V_ASN1_IA5STRING) &&
1695 				(nid != NID_pkcs9_emailAddress))
1696 				str->type=V_ASN1_T61STRING;
1697 
1698 			if ((nid == NID_pkcs9_emailAddress) &&
1699 				(str->type == V_ASN1_PRINTABLESTRING))
1700 				str->type=V_ASN1_IA5STRING;
1701 			}
1702 
1703 		/* If no EMAIL is wanted in the subject */
1704 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1705 			continue;
1706 
1707 		/* check some things */
1708 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1709 			(str->type != V_ASN1_IA5STRING))
1710 			{
1711 			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1712 			goto err;
1713 			}
1714 		if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1715 			{
1716 			j=ASN1_PRINTABLE_type(str->data,str->length);
1717 			if (	((j == V_ASN1_T61STRING) &&
1718 				 (str->type != V_ASN1_T61STRING)) ||
1719 				((j == V_ASN1_IA5STRING) &&
1720 				 (str->type == V_ASN1_PRINTABLESTRING)))
1721 				{
1722 				BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1723 				goto err;
1724 				}
1725 			}
1726 
1727 		if (default_op)
1728 			old_entry_print(bio_err, obj, str);
1729 		}
1730 
1731 	/* Ok, now we check the 'policy' stuff. */
1732 	if ((subject=X509_NAME_new()) == NULL)
1733 		{
1734 		BIO_printf(bio_err,"Memory allocation failure\n");
1735 		goto err;
1736 		}
1737 
1738 	/* take a copy of the issuer name before we mess with it. */
1739 	CAname=X509_NAME_dup(x509->cert_info->subject);
1740 	if (CAname == NULL) goto err;
1741 	str=str2=NULL;
1742 
1743 	for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1744 		{
1745 		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1746 		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1747 			{
1748 			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1749 			goto err;
1750 			}
1751 		obj=OBJ_nid2obj(j);
1752 
1753 		last= -1;
1754 		for (;;)
1755 			{
1756 			/* lookup the object in the supplied name list */
1757 			j=X509_NAME_get_index_by_OBJ(name,obj,last);
1758 			if (j < 0)
1759 				{
1760 				if (last != -1) break;
1761 				tne=NULL;
1762 				}
1763 			else
1764 				{
1765 				tne=X509_NAME_get_entry(name,j);
1766 				}
1767 			last=j;
1768 
1769 			/* depending on the 'policy', decide what to do. */
1770 			push=NULL;
1771 			if (strcmp(cv->value,"optional") == 0)
1772 				{
1773 				if (tne != NULL)
1774 					push=tne;
1775 				}
1776 			else if (strcmp(cv->value,"supplied") == 0)
1777 				{
1778 				if (tne == NULL)
1779 					{
1780 					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1781 					goto err;
1782 					}
1783 				else
1784 					push=tne;
1785 				}
1786 			else if (strcmp(cv->value,"match") == 0)
1787 				{
1788 				int last2;
1789 
1790 				if (tne == NULL)
1791 					{
1792 					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1793 					goto err;
1794 					}
1795 
1796 				last2= -1;
1797 
1798 again2:
1799 				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1800 				if ((j < 0) && (last2 == -1))
1801 					{
1802 					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1803 					goto err;
1804 					}
1805 				if (j >= 0)
1806 					{
1807 					push=X509_NAME_get_entry(CAname,j);
1808 					str=X509_NAME_ENTRY_get_data(tne);
1809 					str2=X509_NAME_ENTRY_get_data(push);
1810 					last2=j;
1811 					if (ASN1_STRING_cmp(str,str2) != 0)
1812 						goto again2;
1813 					}
1814 				if (j < 0)
1815 					{
1816 					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));
1817 					goto err;
1818 					}
1819 				}
1820 			else
1821 				{
1822 				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1823 				goto err;
1824 				}
1825 
1826 			if (push != NULL)
1827 				{
1828 				if (!X509_NAME_add_entry(subject,push, -1, 0))
1829 					{
1830 					if (push != NULL)
1831 						X509_NAME_ENTRY_free(push);
1832 					BIO_printf(bio_err,"Memory allocation failure\n");
1833 					goto err;
1834 					}
1835 				}
1836 			if (j < 0) break;
1837 			}
1838 		}
1839 
1840 	if (preserve)
1841 		{
1842 		X509_NAME_free(subject);
1843 		/* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1844 		subject=X509_NAME_dup(name);
1845 		if (subject == NULL) goto err;
1846 		}
1847 
1848 	if (verbose)
1849 		BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1850 
1851 	/* Build the correct Subject if no e-mail is wanted in the subject */
1852 	/* and add it later on because of the method extensions are added (altName) */
1853 
1854 	if (email_dn)
1855 		dn_subject = subject;
1856 	else
1857 		{
1858 		X509_NAME_ENTRY *tmpne;
1859 		/* Its best to dup the subject DN and then delete any email
1860 		 * addresses because this retains its structure.
1861 		 */
1862 		if (!(dn_subject = X509_NAME_dup(subject)))
1863 			{
1864 			BIO_printf(bio_err,"Memory allocation failure\n");
1865 			goto err;
1866 			}
1867 		while((i = X509_NAME_get_index_by_NID(dn_subject,
1868 					NID_pkcs9_emailAddress, -1)) >= 0)
1869 			{
1870 			tmpne = X509_NAME_get_entry(dn_subject, i);
1871 			X509_NAME_delete_entry(dn_subject, i);
1872 			X509_NAME_ENTRY_free(tmpne);
1873 			}
1874 		}
1875 
1876 	if (BN_is_zero(serial))
1877 		row[DB_serial]=BUF_strdup("00");
1878 	else
1879 		row[DB_serial]=BN_bn2hex(serial);
1880 	if (row[DB_serial] == NULL)
1881 		{
1882 		BIO_printf(bio_err,"Memory allocation failure\n");
1883 		goto err;
1884 		}
1885 
1886 	if (db->attributes.unique_subject)
1887 		{
1888 		rrow=TXT_DB_get_by_index(db->db,DB_name,row);
1889 		if (rrow != NULL)
1890 			{
1891 			BIO_printf(bio_err,
1892 				"ERROR:There is already a certificate for %s\n",
1893 				row[DB_name]);
1894 			}
1895 		}
1896 	if (rrow == NULL)
1897 		{
1898 		rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1899 		if (rrow != NULL)
1900 			{
1901 			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1902 				row[DB_serial]);
1903 			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1904 			}
1905 		}
1906 
1907 	if (rrow != NULL)
1908 		{
1909 		BIO_printf(bio_err,
1910 			"The matching entry has the following details\n");
1911 		if (rrow[DB_type][0] == 'E')
1912 			p="Expired";
1913 		else if (rrow[DB_type][0] == 'R')
1914 			p="Revoked";
1915 		else if (rrow[DB_type][0] == 'V')
1916 			p="Valid";
1917 		else
1918 			p="\ninvalid type, Data base error\n";
1919 		BIO_printf(bio_err,"Type	  :%s\n",p);;
1920 		if (rrow[DB_type][0] == 'R')
1921 			{
1922 			p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1923 			BIO_printf(bio_err,"Was revoked on:%s\n",p);
1924 			}
1925 		p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1926 		BIO_printf(bio_err,"Expires on    :%s\n",p);
1927 		p=rrow[DB_serial]; if (p == NULL) p="undef";
1928 		BIO_printf(bio_err,"Serial Number :%s\n",p);
1929 		p=rrow[DB_file]; if (p == NULL) p="undef";
1930 		BIO_printf(bio_err,"File name     :%s\n",p);
1931 		p=rrow[DB_name]; if (p == NULL) p="undef";
1932 		BIO_printf(bio_err,"Subject Name  :%s\n",p);
1933 		ok= -1; /* This is now a 'bad' error. */
1934 		goto err;
1935 		}
1936 
1937 	/* We are now totally happy, lets make and sign the certificate */
1938 	if (verbose)
1939 		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1940 
1941 	if ((ret=X509_new()) == NULL) goto err;
1942 	ci=ret->cert_info;
1943 
1944 #ifdef X509_V3
1945 	/* Make it an X509 v3 certificate. */
1946 	if (!X509_set_version(ret,2)) goto err;
1947 #endif
1948 
1949 	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1950 		goto err;
1951 	if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1952 		goto err;
1953 
1954 	if (strcmp(startdate,"today") == 0)
1955 		X509_gmtime_adj(X509_get_notBefore(ret),0);
1956 	else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1957 
1958 	if (enddate == NULL)
1959 		X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1960 	else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1961 
1962 	if (!X509_set_subject_name(ret,subject)) goto err;
1963 
1964 	pktmp=X509_REQ_get_pubkey(req);
1965 	i = X509_set_pubkey(ret,pktmp);
1966 	EVP_PKEY_free(pktmp);
1967 	if (!i) goto err;
1968 
1969 	/* Lets add the extensions, if there are any */
1970 	if (ext_sect)
1971 		{
1972 		X509V3_CTX ctx;
1973 		if (ci->version == NULL)
1974 			if ((ci->version=ASN1_INTEGER_new()) == NULL)
1975 				goto err;
1976 		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1977 
1978 		/* Free the current entries if any, there should not
1979 		 * be any I believe */
1980 		if (ci->extensions != NULL)
1981 			sk_X509_EXTENSION_pop_free(ci->extensions,
1982 						   X509_EXTENSION_free);
1983 
1984 		ci->extensions = NULL;
1985 
1986 		/* Initialize the context structure */
1987 		X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1988 
1989 		if (extconf)
1990 			{
1991 			if (verbose)
1992 				BIO_printf(bio_err, "Extra configuration file found\n");
1993 
1994 			/* Use the extconf configuration db LHASH */
1995 			X509V3_set_nconf(&ctx, extconf);
1996 
1997 			/* Test the structure (needed?) */
1998 			/* X509V3_set_ctx_test(&ctx); */
1999 
2000 			/* Adds exts contained in the configuration file */
2001 			if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2002 				{
2003 				BIO_printf(bio_err,
2004 				    "ERROR: adding extensions in section %s\n",
2005 								ext_sect);
2006 				ERR_print_errors(bio_err);
2007 				goto err;
2008 				}
2009 			if (verbose)
2010 				BIO_printf(bio_err, "Successfully added extensions from file.\n");
2011 			}
2012 		else if (ext_sect)
2013 			{
2014 			/* We found extensions to be set from config file */
2015 			X509V3_set_nconf(&ctx, lconf);
2016 
2017 			if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2018 				{
2019 				BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2020 				ERR_print_errors(bio_err);
2021 				goto err;
2022 				}
2023 
2024 			if (verbose)
2025 				BIO_printf(bio_err, "Successfully added extensions from config\n");
2026 			}
2027 		}
2028 
2029 	/* Copy extensions from request (if any) */
2030 
2031 	if (!copy_extensions(ret, req, ext_copy))
2032 		{
2033 		BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2034 		ERR_print_errors(bio_err);
2035 		goto err;
2036 		}
2037 
2038 	/* Set the right value for the noemailDN option */
2039 	if( email_dn == 0 )
2040 		{
2041 		if (!X509_set_subject_name(ret,dn_subject)) goto err;
2042 		}
2043 
2044 	if (!default_op)
2045 		{
2046 		BIO_printf(bio_err, "Certificate Details:\n");
2047 		/* Never print signature details because signature not present */
2048 		certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2049 		X509_print_ex(bio_err, ret, nameopt, certopt);
2050 		}
2051 
2052 	BIO_printf(bio_err,"Certificate is to be certified until ");
2053 	ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2054 	if (days) BIO_printf(bio_err," (%d days)",days);
2055 	BIO_printf(bio_err, "\n");
2056 
2057 	if (!batch)
2058 		{
2059 
2060 		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2061 		(void)BIO_flush(bio_err);
2062 		buf[0]='\0';
2063 		fgets(buf,sizeof(buf)-1,stdin);
2064 		if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2065 			{
2066 			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2067 			ok=0;
2068 			goto err;
2069 			}
2070 		}
2071 
2072 
2073 #ifndef OPENSSL_NO_DSA
2074 	if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2075 	pktmp=X509_get_pubkey(ret);
2076 	if (EVP_PKEY_missing_parameters(pktmp) &&
2077 		!EVP_PKEY_missing_parameters(pkey))
2078 		EVP_PKEY_copy_parameters(pktmp,pkey);
2079 	EVP_PKEY_free(pktmp);
2080 #endif
2081 
2082 	if (!X509_sign(ret,pkey,dgst))
2083 		goto err;
2084 
2085 	/* We now just add it to the database */
2086 	row[DB_type]=(char *)OPENSSL_malloc(2);
2087 
2088 	tm=X509_get_notAfter(ret);
2089 	row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2090 	memcpy(row[DB_exp_date],tm->data,tm->length);
2091 	row[DB_exp_date][tm->length]='\0';
2092 
2093 	row[DB_rev_date]=NULL;
2094 
2095 	/* row[DB_serial] done already */
2096 	row[DB_file]=(char *)OPENSSL_malloc(8);
2097 	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2098 
2099 	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2100 		(row[DB_file] == NULL) || (row[DB_name] == NULL))
2101 		{
2102 		BIO_printf(bio_err,"Memory allocation failure\n");
2103 		goto err;
2104 		}
2105 	BUF_strlcpy(row[DB_file],"unknown",8);
2106 	row[DB_type][0]='V';
2107 	row[DB_type][1]='\0';
2108 
2109 	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2110 		{
2111 		BIO_printf(bio_err,"Memory allocation failure\n");
2112 		goto err;
2113 		}
2114 
2115 	for (i=0; i<DB_NUMBER; i++)
2116 		{
2117 		irow[i]=row[i];
2118 		row[i]=NULL;
2119 		}
2120 	irow[DB_NUMBER]=NULL;
2121 
2122 	if (!TXT_DB_insert(db->db,irow))
2123 		{
2124 		BIO_printf(bio_err,"failed to update database\n");
2125 		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2126 		goto err;
2127 		}
2128 	ok=1;
2129 err:
2130 	for (i=0; i<DB_NUMBER; i++)
2131 		if (row[i] != NULL) OPENSSL_free(row[i]);
2132 
2133 	if (CAname != NULL)
2134 		X509_NAME_free(CAname);
2135 	if (subject != NULL)
2136 		X509_NAME_free(subject);
2137 	if ((dn_subject != NULL) && !email_dn)
2138 		X509_NAME_free(dn_subject);
2139 	if (tmptm != NULL)
2140 		ASN1_UTCTIME_free(tmptm);
2141 	if (ok <= 0)
2142 		{
2143 		if (ret != NULL) X509_free(ret);
2144 		ret=NULL;
2145 		}
2146 	else
2147 		*xret=ret;
2148 	return(ok);
2149 	}
2150 
2151 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2152 	{
2153 
2154 	if (output_der)
2155 		{
2156 		(void)i2d_X509_bio(bp,x);
2157 		return;
2158 		}
2159 #if 0
2160 	/* ??? Not needed since X509_print prints all this stuff anyway */
2161 	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2162 	BIO_printf(bp,"issuer :%s\n",f);
2163 
2164 	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2165 	BIO_printf(bp,"subject:%s\n",f);
2166 
2167 	BIO_puts(bp,"serial :");
2168 	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2169 	BIO_puts(bp,"\n\n");
2170 #endif
2171 	if (!notext)X509_print(bp,x);
2172 	PEM_write_bio_X509(bp,x);
2173 	}
2174 
2175 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2176 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2177 	     BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2178 	     long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2179 	     unsigned long nameopt, int default_op, int ext_copy)
2180 	{
2181 	STACK_OF(CONF_VALUE) *sk=NULL;
2182 	LHASH *parms=NULL;
2183 	X509_REQ *req=NULL;
2184 	CONF_VALUE *cv=NULL;
2185 	NETSCAPE_SPKI *spki = NULL;
2186 	X509_REQ_INFO *ri;
2187 	char *type,*buf;
2188 	EVP_PKEY *pktmp=NULL;
2189 	X509_NAME *n=NULL;
2190 	X509_NAME_ENTRY *ne=NULL;
2191 	int ok= -1,i,j;
2192 	long errline;
2193 	int nid;
2194 
2195 	/*
2196 	 * Load input file into a hash table.  (This is just an easy
2197 	 * way to read and parse the file, then put it into a convenient
2198 	 * STACK format).
2199 	 */
2200 	parms=CONF_load(NULL,infile,&errline);
2201 	if (parms == NULL)
2202 		{
2203 		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2204 		ERR_print_errors(bio_err);
2205 		goto err;
2206 		}
2207 
2208 	sk=CONF_get_section(parms, "default");
2209 	if (sk_CONF_VALUE_num(sk) == 0)
2210 		{
2211 		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2212 		CONF_free(parms);
2213 		goto err;
2214 		}
2215 
2216 	/*
2217 	 * Now create a dummy X509 request structure.  We don't actually
2218 	 * have an X509 request, but we have many of the components
2219 	 * (a public key, various DN components).  The idea is that we
2220 	 * put these components into the right X509 request structure
2221 	 * and we can use the same code as if you had a real X509 request.
2222 	 */
2223 	req=X509_REQ_new();
2224 	if (req == NULL)
2225 		{
2226 		ERR_print_errors(bio_err);
2227 		goto err;
2228 		}
2229 
2230 	/*
2231 	 * Build up the subject name set.
2232 	 */
2233 	ri=req->req_info;
2234 	n = ri->subject;
2235 
2236 	for (i = 0; ; i++)
2237 		{
2238 		if (sk_CONF_VALUE_num(sk) <= i) break;
2239 
2240 		cv=sk_CONF_VALUE_value(sk,i);
2241 		type=cv->name;
2242 		/* Skip past any leading X. X: X, etc to allow for
2243 		 * multiple instances
2244 		 */
2245 		for (buf = cv->name; *buf ; buf++)
2246 			if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2247 				{
2248 				buf++;
2249 				if (*buf) type = buf;
2250 				break;
2251 				}
2252 
2253 		buf=cv->value;
2254 		if ((nid=OBJ_txt2nid(type)) == NID_undef)
2255 			{
2256 			if (strcmp(type, "SPKAC") == 0)
2257 				{
2258 				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2259 				if (spki == NULL)
2260 					{
2261 					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2262 					ERR_print_errors(bio_err);
2263 					goto err;
2264 					}
2265 				}
2266 			continue;
2267 			}
2268 
2269 		/*
2270 		if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2271 			continue;
2272 		*/
2273 
2274 		j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2275 		if (fix_data(nid, &j) == 0)
2276 			{
2277 			BIO_printf(bio_err,
2278 				"invalid characters in string %s\n",buf);
2279 			goto err;
2280 			}
2281 
2282 		if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2283 			(unsigned char *)buf,
2284 			strlen(buf))) == NULL)
2285 			goto err;
2286 
2287 		if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2288 		}
2289 	if (spki == NULL)
2290 		{
2291 		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2292 			infile);
2293 		goto err;
2294 		}
2295 
2296 	/*
2297 	 * Now extract the key from the SPKI structure.
2298 	 */
2299 
2300 	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2301 
2302 	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2303 		{
2304 		BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2305 		goto err;
2306 		}
2307 
2308 	j = NETSCAPE_SPKI_verify(spki, pktmp);
2309 	if (j <= 0)
2310 		{
2311 		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2312 		goto err;
2313 		}
2314 	BIO_printf(bio_err,"Signature ok\n");
2315 
2316 	X509_REQ_set_pubkey(req,pktmp);
2317 	EVP_PKEY_free(pktmp);
2318 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2319 		   days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2320 			ext_copy);
2321 err:
2322 	if (req != NULL) X509_REQ_free(req);
2323 	if (parms != NULL) CONF_free(parms);
2324 	if (spki != NULL) NETSCAPE_SPKI_free(spki);
2325 	if (ne != NULL) X509_NAME_ENTRY_free(ne);
2326 
2327 	return(ok);
2328 	}
2329 
2330 static int fix_data(int nid, int *type)
2331 	{
2332 	if (nid == NID_pkcs9_emailAddress)
2333 		*type=V_ASN1_IA5STRING;
2334 	if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2335 		*type=V_ASN1_T61STRING;
2336 	if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2337 		*type=V_ASN1_T61STRING;
2338 	if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2339 		return(0);
2340 	if (nid == NID_pkcs9_unstructuredName)
2341 		*type=V_ASN1_IA5STRING;
2342 	return(1);
2343 	}
2344 
2345 static int check_time_format(char *str)
2346 	{
2347 	ASN1_UTCTIME tm;
2348 
2349 	tm.data=(unsigned char *)str;
2350 	tm.length=strlen(str);
2351 	tm.type=V_ASN1_UTCTIME;
2352 	return(ASN1_UTCTIME_check(&tm));
2353 	}
2354 
2355 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2356 	{
2357 	ASN1_UTCTIME *tm=NULL;
2358 	char *row[DB_NUMBER],**rrow,**irow;
2359 	char *rev_str = NULL;
2360 	BIGNUM *bn = NULL;
2361 	int ok=-1,i;
2362 
2363 	for (i=0; i<DB_NUMBER; i++)
2364 		row[i]=NULL;
2365 	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2366 	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2367 	if (BN_is_zero(bn))
2368 		row[DB_serial]=BUF_strdup("00");
2369 	else
2370 		row[DB_serial]=BN_bn2hex(bn);
2371 	BN_free(bn);
2372 	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2373 		{
2374 		BIO_printf(bio_err,"Memory allocation failure\n");
2375 		goto err;
2376 		}
2377 	/* We have to lookup by serial number because name lookup
2378 	 * skips revoked certs
2379  	 */
2380 	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2381 	if (rrow == NULL)
2382 		{
2383 		BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2384 
2385 		/* We now just add it to the database */
2386 		row[DB_type]=(char *)OPENSSL_malloc(2);
2387 
2388 		tm=X509_get_notAfter(x509);
2389 		row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2390 		memcpy(row[DB_exp_date],tm->data,tm->length);
2391 		row[DB_exp_date][tm->length]='\0';
2392 
2393 		row[DB_rev_date]=NULL;
2394 
2395 		/* row[DB_serial] done already */
2396 		row[DB_file]=(char *)OPENSSL_malloc(8);
2397 
2398 		/* row[DB_name] done already */
2399 
2400 		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2401 			(row[DB_file] == NULL))
2402 			{
2403 			BIO_printf(bio_err,"Memory allocation failure\n");
2404 			goto err;
2405 			}
2406 		BUF_strlcpy(row[DB_file],"unknown",8);
2407 		row[DB_type][0]='V';
2408 		row[DB_type][1]='\0';
2409 
2410 		if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2411 			{
2412 			BIO_printf(bio_err,"Memory allocation failure\n");
2413 			goto err;
2414 			}
2415 
2416 		for (i=0; i<DB_NUMBER; i++)
2417 			{
2418 			irow[i]=row[i];
2419 			row[i]=NULL;
2420 			}
2421 		irow[DB_NUMBER]=NULL;
2422 
2423 		if (!TXT_DB_insert(db->db,irow))
2424 			{
2425 			BIO_printf(bio_err,"failed to update database\n");
2426 			BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2427 			goto err;
2428 			}
2429 
2430 		/* Revoke Certificate */
2431 		ok = do_revoke(x509,db, type, value);
2432 
2433 		goto err;
2434 
2435 		}
2436 	else if (index_name_cmp((const char **)row,(const char **)rrow))
2437 		{
2438 		BIO_printf(bio_err,"ERROR:name does not match %s\n",
2439 			   row[DB_name]);
2440 		goto err;
2441 		}
2442 	else if (rrow[DB_type][0]=='R')
2443 		{
2444 		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2445 			   row[DB_serial]);
2446 		goto err;
2447 		}
2448 	else
2449 		{
2450 		BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2451 		rev_str = make_revocation_str(type, value);
2452 		if (!rev_str)
2453 			{
2454 			BIO_printf(bio_err, "Error in revocation arguments\n");
2455 			goto err;
2456 			}
2457 		rrow[DB_type][0]='R';
2458 		rrow[DB_type][1]='\0';
2459 		rrow[DB_rev_date] = rev_str;
2460 		}
2461 	ok=1;
2462 err:
2463 	for (i=0; i<DB_NUMBER; i++)
2464 		{
2465 		if (row[i] != NULL)
2466 			OPENSSL_free(row[i]);
2467 		}
2468 	return(ok);
2469 	}
2470 
2471 static int get_certificate_status(const char *serial, CA_DB *db)
2472 	{
2473 	char *row[DB_NUMBER],**rrow;
2474 	int ok=-1,i;
2475 
2476 	/* Free Resources */
2477 	for (i=0; i<DB_NUMBER; i++)
2478 		row[i]=NULL;
2479 
2480 	/* Malloc needed char spaces */
2481 	row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2482 	if (row[DB_serial] == NULL)
2483 		{
2484 		BIO_printf(bio_err,"Malloc failure\n");
2485 		goto err;
2486 		}
2487 
2488 	if (strlen(serial) % 2)
2489 		{
2490 		/* Set the first char to 0 */;
2491 		row[DB_serial][0]='0';
2492 
2493 		/* Copy String from serial to row[DB_serial] */
2494 		memcpy(row[DB_serial]+1, serial, strlen(serial));
2495 		row[DB_serial][strlen(serial)+1]='\0';
2496 		}
2497 	else
2498 		{
2499 		/* Copy String from serial to row[DB_serial] */
2500 		memcpy(row[DB_serial], serial, strlen(serial));
2501 		row[DB_serial][strlen(serial)]='\0';
2502 		}
2503 
2504 	/* Make it Upper Case */
2505 	for (i=0; row[DB_serial][i] != '\0'; i++)
2506 		row[DB_serial][i] = toupper(row[DB_serial][i]);
2507 
2508 
2509 	ok=1;
2510 
2511 	/* Search for the certificate */
2512 	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2513 	if (rrow == NULL)
2514 		{
2515 		BIO_printf(bio_err,"Serial %s not present in db.\n",
2516 				 row[DB_serial]);
2517 		ok=-1;
2518 		goto err;
2519 		}
2520 	else if (rrow[DB_type][0]=='V')
2521 		{
2522 		BIO_printf(bio_err,"%s=Valid (%c)\n",
2523 			row[DB_serial], rrow[DB_type][0]);
2524 		goto err;
2525 		}
2526 	else if (rrow[DB_type][0]=='R')
2527 		{
2528 		BIO_printf(bio_err,"%s=Revoked (%c)\n",
2529 			row[DB_serial], rrow[DB_type][0]);
2530 		goto err;
2531 		}
2532 	else if (rrow[DB_type][0]=='E')
2533 		{
2534 		BIO_printf(bio_err,"%s=Expired (%c)\n",
2535 			row[DB_serial], rrow[DB_type][0]);
2536 		goto err;
2537 		}
2538 	else if (rrow[DB_type][0]=='S')
2539 		{
2540 		BIO_printf(bio_err,"%s=Suspended (%c)\n",
2541 			row[DB_serial], rrow[DB_type][0]);
2542 		goto err;
2543 		}
2544 	else
2545 		{
2546 		BIO_printf(bio_err,"%s=Unknown (%c).\n",
2547 			row[DB_serial], rrow[DB_type][0]);
2548 		ok=-1;
2549 		}
2550 err:
2551 	for (i=0; i<DB_NUMBER; i++)
2552 		{
2553 		if (row[i] != NULL)
2554 			OPENSSL_free(row[i]);
2555 		}
2556 	return(ok);
2557 	}
2558 
2559 static int do_updatedb (CA_DB *db)
2560 	{
2561 	ASN1_UTCTIME	*a_tm = NULL;
2562 	int i, cnt = 0;
2563 	int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */
2564 	char **rrow, *a_tm_s;
2565 
2566 	a_tm = ASN1_UTCTIME_new();
2567 
2568 	/* get actual time and make a string */
2569 	a_tm = X509_gmtime_adj(a_tm, 0);
2570 	a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2571 	if (a_tm_s == NULL)
2572 		{
2573 		cnt = -1;
2574 		goto err;
2575 		}
2576 
2577 	memcpy(a_tm_s, a_tm->data, a_tm->length);
2578 	a_tm_s[a_tm->length] = '\0';
2579 
2580 	if (strncmp(a_tm_s, "49", 2) <= 0)
2581 		a_y2k = 1;
2582 	else
2583 		a_y2k = 0;
2584 
2585 	for (i = 0; i < sk_num(db->db->data); i++)
2586 		{
2587 		rrow = (char **) sk_value(db->db->data, i);
2588 
2589 		if (rrow[DB_type][0] == 'V')
2590 		 	{
2591 			/* ignore entries that are not valid */
2592 			if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2593 				db_y2k = 1;
2594 			else
2595 				db_y2k = 0;
2596 
2597 			if (db_y2k == a_y2k)
2598 				{
2599 				/* all on the same y2k side */
2600 				if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2601 				       	{
2602 				       	rrow[DB_type][0]  = 'E';
2603 				       	rrow[DB_type][1]  = '\0';
2604 	  				cnt++;
2605 
2606 					BIO_printf(bio_err, "%s=Expired\n",
2607 							rrow[DB_serial]);
2608 					}
2609 				}
2610 			else if (db_y2k < a_y2k)
2611 				{
2612 		  		rrow[DB_type][0]  = 'E';
2613 		  		rrow[DB_type][1]  = '\0';
2614 	  			cnt++;
2615 
2616 				BIO_printf(bio_err, "%s=Expired\n",
2617 							rrow[DB_serial]);
2618 				}
2619 
2620 			}
2621     		}
2622 
2623 err:
2624 
2625 	ASN1_UTCTIME_free(a_tm);
2626 	OPENSSL_free(a_tm_s);
2627 
2628 	return (cnt);
2629 	}
2630 
2631 static char *crl_reasons[] = {
2632 	/* CRL reason strings */
2633 	"unspecified",
2634 	"keyCompromise",
2635 	"CACompromise",
2636 	"affiliationChanged",
2637 	"superseded",
2638 	"cessationOfOperation",
2639 	"certificateHold",
2640 	"removeFromCRL",
2641 	/* Additional pseudo reasons */
2642 	"holdInstruction",
2643 	"keyTime",
2644 	"CAkeyTime"
2645 };
2646 
2647 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2648 
2649 /* Given revocation information convert to a DB string.
2650  * The format of the string is:
2651  * revtime[,reason,extra]. Where 'revtime' is the
2652  * revocation time (the current time). 'reason' is the
2653  * optional CRL reason and 'extra' is any additional
2654  * argument
2655  */
2656 
2657 char *make_revocation_str(int rev_type, char *rev_arg)
2658 	{
2659 	char *reason = NULL, *other = NULL, *str;
2660 	ASN1_OBJECT *otmp;
2661 	ASN1_UTCTIME *revtm = NULL;
2662 	int i;
2663 	switch (rev_type)
2664 		{
2665 	case REV_NONE:
2666 		break;
2667 
2668 	case REV_CRL_REASON:
2669 		for (i = 0; i < 8; i++)
2670 			{
2671 			if (!strcasecmp(rev_arg, crl_reasons[i]))
2672 				{
2673 				reason = crl_reasons[i];
2674 				break;
2675 				}
2676 			}
2677 		if (reason == NULL)
2678 			{
2679 			BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2680 			return NULL;
2681 			}
2682 		break;
2683 
2684 	case REV_HOLD:
2685 		/* Argument is an OID */
2686 
2687 		otmp = OBJ_txt2obj(rev_arg, 0);
2688 		ASN1_OBJECT_free(otmp);
2689 
2690 		if (otmp == NULL)
2691 			{
2692 			BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2693 			return NULL;
2694 			}
2695 
2696 		reason = "holdInstruction";
2697 		other = rev_arg;
2698 		break;
2699 
2700 	case REV_KEY_COMPROMISE:
2701 	case REV_CA_COMPROMISE:
2702 
2703 		/* Argument is the key compromise time  */
2704 		if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2705 			{
2706 			BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2707 			return NULL;
2708 			}
2709 		other = rev_arg;
2710 		if (rev_type == REV_KEY_COMPROMISE)
2711 			reason = "keyTime";
2712 		else
2713 			reason = "CAkeyTime";
2714 
2715 		break;
2716 
2717 		}
2718 
2719 	revtm = X509_gmtime_adj(NULL, 0);
2720 
2721 	i = revtm->length + 1;
2722 
2723 	if (reason) i += strlen(reason) + 1;
2724 	if (other) i += strlen(other) + 1;
2725 
2726 	str = OPENSSL_malloc(i);
2727 
2728 	if (!str) return NULL;
2729 
2730 	BUF_strlcpy(str, (char *)revtm->data, i);
2731 	if (reason)
2732 		{
2733 		BUF_strlcat(str, ",", i);
2734 		BUF_strlcat(str, reason, i);
2735 		}
2736 	if (other)
2737 		{
2738 		BUF_strlcat(str, ",", i);
2739 		BUF_strlcat(str, other, i);
2740 		}
2741 	ASN1_UTCTIME_free(revtm);
2742 	return str;
2743 	}
2744 
2745 /* Convert revocation field to X509_REVOKED entry
2746  * return code:
2747  * 0 error
2748  * 1 OK
2749  * 2 OK and some extensions added (i.e. V2 CRL)
2750  */
2751 
2752 
2753 int make_revoked(X509_REVOKED *rev, char *str)
2754 	{
2755 	char *tmp = NULL;
2756 	int reason_code = -1;
2757 	int i, ret = 0;
2758 	ASN1_OBJECT *hold = NULL;
2759 	ASN1_GENERALIZEDTIME *comp_time = NULL;
2760 	ASN1_ENUMERATED *rtmp = NULL;
2761 
2762 	ASN1_TIME *revDate = NULL;
2763 
2764 	i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2765 
2766 	if (i == 0)
2767 		goto err;
2768 
2769 	if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2770 		goto err;
2771 
2772 	if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2773 		{
2774 		rtmp = ASN1_ENUMERATED_new();
2775 		if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2776 			goto err;
2777 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2778 			goto err;
2779 		}
2780 
2781 	if (rev && comp_time)
2782 		{
2783 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2784 			goto err;
2785 		}
2786 	if (rev && hold)
2787 		{
2788 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2789 			goto err;
2790 		}
2791 
2792 	if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2793 		ret = 2;
2794 	else ret = 1;
2795 
2796 	err:
2797 
2798 	if (tmp) OPENSSL_free(tmp);
2799 	ASN1_OBJECT_free(hold);
2800 	ASN1_GENERALIZEDTIME_free(comp_time);
2801 	ASN1_ENUMERATED_free(rtmp);
2802 	ASN1_TIME_free(revDate);
2803 
2804 	return ret;
2805 	}
2806 
2807 /*
2808  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2809  * where characters may be escaped by \
2810  */
2811 X509_NAME *do_subject(char *subject, long chtype)
2812 	{
2813 	size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
2814 	char *buf = OPENSSL_malloc(buflen);
2815 	size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2816 	char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
2817 	char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
2818 
2819 	char *sp = subject, *bp = buf;
2820 	int i, ne_num = 0;
2821 
2822 	X509_NAME *n = NULL;
2823 	int nid;
2824 
2825 	if (!buf || !ne_types || !ne_values)
2826 	{
2827 		BIO_printf(bio_err, "malloc error\n");
2828 		goto error;
2829 	}
2830 
2831 	if (*subject != '/')
2832 	{
2833 		BIO_printf(bio_err, "Subject does not start with '/'.\n");
2834 		goto error;
2835 	}
2836 	sp++; /* skip leading / */
2837 
2838 	while (*sp)
2839 		{
2840 		/* collect type */
2841 		ne_types[ne_num] = bp;
2842 		while (*sp)
2843 			{
2844 			if (*sp == '\\') /* is there anything to escape in the type...? */
2845 				{
2846 				if (*++sp)
2847 					*bp++ = *sp++;
2848 				else
2849 					{
2850 					BIO_printf(bio_err, "escape character at end of string\n");
2851 					goto error;
2852 					}
2853 				}
2854 			else if (*sp == '=')
2855 				{
2856 				sp++;
2857 				*bp++ = '\0';
2858 				break;
2859 				}
2860 			else
2861 				*bp++ = *sp++;
2862 			}
2863 		if (!*sp)
2864 			{
2865 			BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
2866 			goto error;
2867 			}
2868 		ne_values[ne_num] = bp;
2869 		while (*sp)
2870 			{
2871 			if (*sp == '\\')
2872 				{
2873 				if (*++sp)
2874 					*bp++ = *sp++;
2875 				else
2876 					{
2877 					BIO_printf(bio_err, "escape character at end of string\n");
2878 					goto error;
2879 					}
2880 				}
2881 			else if (*sp == '/')
2882 				{
2883 				sp++;
2884 				break;
2885 				}
2886 			else
2887 				*bp++ = *sp++;
2888 			}
2889 		*bp++ = '\0';
2890 		ne_num++;
2891 		}
2892 
2893 	if (!(n = X509_NAME_new()))
2894 		goto error;
2895 
2896 	for (i = 0; i < ne_num; i++)
2897 		{
2898 		if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
2899 			{
2900 			BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
2901 			continue;
2902 			}
2903 
2904 		if (!*ne_values[i])
2905 			{
2906 			BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
2907 			continue;
2908 			}
2909 
2910 		if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
2911 			goto error;
2912 		}
2913 
2914 	OPENSSL_free(ne_values);
2915 	OPENSSL_free(ne_types);
2916 	OPENSSL_free(buf);
2917 	return n;
2918 
2919 error:
2920 	X509_NAME_free(n);
2921 	if (ne_values)
2922 		OPENSSL_free(ne_values);
2923 	if (ne_types)
2924 		OPENSSL_free(ne_types);
2925 	if (buf)
2926 		OPENSSL_free(buf);
2927 	return NULL;
2928 }
2929 
2930 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2931 	{
2932 	char buf[25],*pbuf, *p;
2933 	int j;
2934 	j=i2a_ASN1_OBJECT(bp,obj);
2935 	pbuf=buf;
2936 	for (j=22-j; j>0; j--)
2937 		*(pbuf++)=' ';
2938 	*(pbuf++)=':';
2939 	*(pbuf++)='\0';
2940 	BIO_puts(bp,buf);
2941 
2942 	if (str->type == V_ASN1_PRINTABLESTRING)
2943 		BIO_printf(bp,"PRINTABLE:'");
2944 	else if (str->type == V_ASN1_T61STRING)
2945 		BIO_printf(bp,"T61STRING:'");
2946 	else if (str->type == V_ASN1_IA5STRING)
2947 		BIO_printf(bp,"IA5STRING:'");
2948 	else if (str->type == V_ASN1_UNIVERSALSTRING)
2949 		BIO_printf(bp,"UNIVERSALSTRING:'");
2950 	else
2951 		BIO_printf(bp,"ASN.1 %2d:'",str->type);
2952 
2953 	p=(char *)str->data;
2954 	for (j=str->length; j>0; j--)
2955 		{
2956 		if ((*p >= ' ') && (*p <= '~'))
2957 			BIO_printf(bp,"%c",*p);
2958 		else if (*p & 0x80)
2959 			BIO_printf(bp,"\\0x%02X",*p);
2960 		else if ((unsigned char)*p == 0xf7)
2961 			BIO_printf(bp,"^?");
2962 		else	BIO_printf(bp,"^%c",*p+'@');
2963 		p++;
2964 		}
2965 	BIO_printf(bp,"'\n");
2966 	return 1;
2967 	}
2968 
2969 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
2970 	{
2971 	char *tmp = NULL;
2972 	char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2973 	int reason_code = -1;
2974 	int i, ret = 0;
2975 	ASN1_OBJECT *hold = NULL;
2976 	ASN1_GENERALIZEDTIME *comp_time = NULL;
2977 	tmp = BUF_strdup(str);
2978 
2979 	p = strchr(tmp, ',');
2980 
2981 	rtime_str = tmp;
2982 
2983 	if (p)
2984 		{
2985 		*p = '\0';
2986 		p++;
2987 		reason_str = p;
2988 		p = strchr(p, ',');
2989 		if (p)
2990 			{
2991 			*p = '\0';
2992 			arg_str = p + 1;
2993 			}
2994 		}
2995 
2996 	if (prevtm)
2997 		{
2998 		*prevtm = ASN1_UTCTIME_new();
2999 		if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3000 			{
3001 			BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3002 			goto err;
3003 			}
3004 		}
3005 	if (reason_str)
3006 		{
3007 		for (i = 0; i < NUM_REASONS; i++)
3008 			{
3009 			if(!strcasecmp(reason_str, crl_reasons[i]))
3010 				{
3011 				reason_code = i;
3012 				break;
3013 				}
3014 			}
3015 		if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3016 			{
3017 			BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3018 			goto err;
3019 			}
3020 
3021 		if (reason_code == 7)
3022 			reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3023 		else if (reason_code == 8)		/* Hold instruction */
3024 			{
3025 			if (!arg_str)
3026 				{
3027 				BIO_printf(bio_err, "missing hold instruction\n");
3028 				goto err;
3029 				}
3030 			reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3031 			hold = OBJ_txt2obj(arg_str, 0);
3032 
3033 			if (!hold)
3034 				{
3035 				BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3036 				goto err;
3037 				}
3038 			if (phold) *phold = hold;
3039 			}
3040 		else if ((reason_code == 9) || (reason_code == 10))
3041 			{
3042 			if (!arg_str)
3043 				{
3044 				BIO_printf(bio_err, "missing compromised time\n");
3045 				goto err;
3046 				}
3047 			comp_time = ASN1_GENERALIZEDTIME_new();
3048 			if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3049 				{
3050 				BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3051 				goto err;
3052 				}
3053 			if (reason_code == 9)
3054 				reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3055 			else
3056 				reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3057 			}
3058 		}
3059 
3060 	if (preason) *preason = reason_code;
3061 	if (pinvtm) *pinvtm = comp_time;
3062 	else ASN1_GENERALIZEDTIME_free(comp_time);
3063 
3064 	ret = 1;
3065 
3066 	err:
3067 
3068 	if (tmp) OPENSSL_free(tmp);
3069 	if (!phold) ASN1_OBJECT_free(hold);
3070 	if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3071 
3072 	return ret;
3073 	}
3074