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