xref: /onnv-gate/usr/src/common/openssl/apps/ca.c (revision 871:f917b2ed7d21)
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_ISDIR
843 		if (!S_ISDIR(sb.st_mode))
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 	if (db)
1507 		free_index(db);
1508 	EVP_PKEY_free(pkey);
1509 	X509_free(x509);
1510 	X509_CRL_free(crl);
1511 	NCONF_free(conf);
1512 	OBJ_cleanup();
1513 	apps_shutdown();
1514 	OPENSSL_EXIT(ret);
1515 	}
1516 
1517 static void lookup_fail(char *name, char *tag)
1518 	{
1519 	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1520 	}
1521 
1522 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1523 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1524 	     BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1525 	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1526 	     unsigned long certopt, unsigned long nameopt, int default_op,
1527 	     int ext_copy)
1528 	{
1529 	X509_REQ *req=NULL;
1530 	BIO *in=NULL;
1531 	EVP_PKEY *pktmp=NULL;
1532 	int ok= -1,i;
1533 
1534 	in=BIO_new(BIO_s_file());
1535 
1536 	if (BIO_read_filename(in,infile) <= 0)
1537 		{
1538 		perror(infile);
1539 		goto err;
1540 		}
1541 	if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1542 		{
1543 		BIO_printf(bio_err,"Error reading certificate request in %s\n",
1544 			infile);
1545 		goto err;
1546 		}
1547 	if (verbose)
1548 		X509_REQ_print(bio_err,req);
1549 
1550 	BIO_printf(bio_err,"Check that the request matches the signature\n");
1551 
1552 	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1553 		{
1554 		BIO_printf(bio_err,"error unpacking public key\n");
1555 		goto err;
1556 		}
1557 	i=X509_REQ_verify(req,pktmp);
1558 	EVP_PKEY_free(pktmp);
1559 	if (i < 0)
1560 		{
1561 		ok=0;
1562 		BIO_printf(bio_err,"Signature verification problems....\n");
1563 		goto err;
1564 		}
1565 	if (i == 0)
1566 		{
1567 		ok=0;
1568 		BIO_printf(bio_err,"Signature did not match the certificate request\n");
1569 		goto err;
1570 		}
1571 	else
1572 		BIO_printf(bio_err,"Signature ok\n");
1573 
1574 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1575 		startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1576 		certopt, nameopt, default_op, ext_copy);
1577 
1578 err:
1579 	if (req != NULL) X509_REQ_free(req);
1580 	if (in != NULL) BIO_free(in);
1581 	return(ok);
1582 	}
1583 
1584 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1585 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1586 	     BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1587 	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1588 	     unsigned long certopt, unsigned long nameopt, int default_op,
1589 	     int ext_copy, ENGINE *e)
1590 	{
1591 	X509 *req=NULL;
1592 	X509_REQ *rreq=NULL;
1593 	EVP_PKEY *pktmp=NULL;
1594 	int ok= -1,i;
1595 
1596 	if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1597 		goto err;
1598 	if (verbose)
1599 		X509_print(bio_err,req);
1600 
1601 	BIO_printf(bio_err,"Check that the request matches the signature\n");
1602 
1603 	if ((pktmp=X509_get_pubkey(req)) == NULL)
1604 		{
1605 		BIO_printf(bio_err,"error unpacking public key\n");
1606 		goto err;
1607 		}
1608 	i=X509_verify(req,pktmp);
1609 	EVP_PKEY_free(pktmp);
1610 	if (i < 0)
1611 		{
1612 		ok=0;
1613 		BIO_printf(bio_err,"Signature verification problems....\n");
1614 		goto err;
1615 		}
1616 	if (i == 0)
1617 		{
1618 		ok=0;
1619 		BIO_printf(bio_err,"Signature did not match the certificate\n");
1620 		goto err;
1621 		}
1622 	else
1623 		BIO_printf(bio_err,"Signature ok\n");
1624 
1625 	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1626 		goto err;
1627 
1628 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1629 		days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1630 		ext_copy);
1631 
1632 err:
1633 	if (rreq != NULL) X509_REQ_free(rreq);
1634 	if (req != NULL) X509_free(req);
1635 	return(ok);
1636 	}
1637 
1638 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1639 	     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1640 	     int email_dn, char *startdate, char *enddate, long days, int batch,
1641 	     int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1642 	     unsigned long certopt, unsigned long nameopt, int default_op,
1643 	     int ext_copy)
1644 	{
1645 	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1646 	ASN1_UTCTIME *tm,*tmptm;
1647 	ASN1_STRING *str,*str2;
1648 	ASN1_OBJECT *obj;
1649 	X509 *ret=NULL;
1650 	X509_CINF *ci;
1651 	X509_NAME_ENTRY *ne;
1652 	X509_NAME_ENTRY *tne,*push;
1653 	EVP_PKEY *pktmp;
1654 	int ok= -1,i,j,last,nid;
1655 	char *p;
1656 	CONF_VALUE *cv;
1657 	char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
1658 	char buf[25];
1659 
1660 	tmptm=ASN1_UTCTIME_new();
1661 	if (tmptm == NULL)
1662 		{
1663 		BIO_printf(bio_err,"malloc error\n");
1664 		return(0);
1665 		}
1666 
1667 	for (i=0; i<DB_NUMBER; i++)
1668 		row[i]=NULL;
1669 
1670 	if (subj)
1671 		{
1672 		X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1673 
1674 		if (!n)
1675 			{
1676 			ERR_print_errors(bio_err);
1677 			goto err;
1678 			}
1679 		X509_REQ_set_subject_name(req,n);
1680 		req->req_info->enc.modified = 1;
1681 		X509_NAME_free(n);
1682 		}
1683 
1684 	if (default_op)
1685 		BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1686 
1687 	name=X509_REQ_get_subject_name(req);
1688 	for (i=0; i<X509_NAME_entry_count(name); i++)
1689 		{
1690 		ne= X509_NAME_get_entry(name,i);
1691 		str=X509_NAME_ENTRY_get_data(ne);
1692 		obj=X509_NAME_ENTRY_get_object(ne);
1693 
1694 		if (msie_hack)
1695 			{
1696 			/* assume all type should be strings */
1697 			nid=OBJ_obj2nid(ne->object);
1698 
1699 			if (str->type == V_ASN1_UNIVERSALSTRING)
1700 				ASN1_UNIVERSALSTRING_to_string(str);
1701 
1702 			if ((str->type == V_ASN1_IA5STRING) &&
1703 				(nid != NID_pkcs9_emailAddress))
1704 				str->type=V_ASN1_T61STRING;
1705 
1706 			if ((nid == NID_pkcs9_emailAddress) &&
1707 				(str->type == V_ASN1_PRINTABLESTRING))
1708 				str->type=V_ASN1_IA5STRING;
1709 			}
1710 
1711 		/* If no EMAIL is wanted in the subject */
1712 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1713 			continue;
1714 
1715 		/* check some things */
1716 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1717 			(str->type != V_ASN1_IA5STRING))
1718 			{
1719 			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1720 			goto err;
1721 			}
1722 		if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1723 			{
1724 			j=ASN1_PRINTABLE_type(str->data,str->length);
1725 			if (	((j == V_ASN1_T61STRING) &&
1726 				 (str->type != V_ASN1_T61STRING)) ||
1727 				((j == V_ASN1_IA5STRING) &&
1728 				 (str->type == V_ASN1_PRINTABLESTRING)))
1729 				{
1730 				BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1731 				goto err;
1732 				}
1733 			}
1734 
1735 		if (default_op)
1736 			old_entry_print(bio_err, obj, str);
1737 		}
1738 
1739 	/* Ok, now we check the 'policy' stuff. */
1740 	if ((subject=X509_NAME_new()) == NULL)
1741 		{
1742 		BIO_printf(bio_err,"Memory allocation failure\n");
1743 		goto err;
1744 		}
1745 
1746 	/* take a copy of the issuer name before we mess with it. */
1747 	CAname=X509_NAME_dup(x509->cert_info->subject);
1748 	if (CAname == NULL) goto err;
1749 	str=str2=NULL;
1750 
1751 	for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1752 		{
1753 		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1754 		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1755 			{
1756 			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1757 			goto err;
1758 			}
1759 		obj=OBJ_nid2obj(j);
1760 
1761 		last= -1;
1762 		for (;;)
1763 			{
1764 			/* lookup the object in the supplied name list */
1765 			j=X509_NAME_get_index_by_OBJ(name,obj,last);
1766 			if (j < 0)
1767 				{
1768 				if (last != -1) break;
1769 				tne=NULL;
1770 				}
1771 			else
1772 				{
1773 				tne=X509_NAME_get_entry(name,j);
1774 				}
1775 			last=j;
1776 
1777 			/* depending on the 'policy', decide what to do. */
1778 			push=NULL;
1779 			if (strcmp(cv->value,"optional") == 0)
1780 				{
1781 				if (tne != NULL)
1782 					push=tne;
1783 				}
1784 			else if (strcmp(cv->value,"supplied") == 0)
1785 				{
1786 				if (tne == NULL)
1787 					{
1788 					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1789 					goto err;
1790 					}
1791 				else
1792 					push=tne;
1793 				}
1794 			else if (strcmp(cv->value,"match") == 0)
1795 				{
1796 				int last2;
1797 
1798 				if (tne == NULL)
1799 					{
1800 					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1801 					goto err;
1802 					}
1803 
1804 				last2= -1;
1805 
1806 again2:
1807 				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1808 				if ((j < 0) && (last2 == -1))
1809 					{
1810 					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1811 					goto err;
1812 					}
1813 				if (j >= 0)
1814 					{
1815 					push=X509_NAME_get_entry(CAname,j);
1816 					str=X509_NAME_ENTRY_get_data(tne);
1817 					str2=X509_NAME_ENTRY_get_data(push);
1818 					last2=j;
1819 					if (ASN1_STRING_cmp(str,str2) != 0)
1820 						goto again2;
1821 					}
1822 				if (j < 0)
1823 					{
1824 					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));
1825 					goto err;
1826 					}
1827 				}
1828 			else
1829 				{
1830 				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1831 				goto err;
1832 				}
1833 
1834 			if (push != NULL)
1835 				{
1836 				if (!X509_NAME_add_entry(subject,push, -1, 0))
1837 					{
1838 					if (push != NULL)
1839 						X509_NAME_ENTRY_free(push);
1840 					BIO_printf(bio_err,"Memory allocation failure\n");
1841 					goto err;
1842 					}
1843 				}
1844 			if (j < 0) break;
1845 			}
1846 		}
1847 
1848 	if (preserve)
1849 		{
1850 		X509_NAME_free(subject);
1851 		/* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1852 		subject=X509_NAME_dup(name);
1853 		if (subject == NULL) goto err;
1854 		}
1855 
1856 	if (verbose)
1857 		BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1858 
1859 	/* Build the correct Subject if no e-mail is wanted in the subject */
1860 	/* and add it later on because of the method extensions are added (altName) */
1861 
1862 	if (email_dn)
1863 		dn_subject = subject;
1864 	else
1865 		{
1866 		X509_NAME_ENTRY *tmpne;
1867 		/* Its best to dup the subject DN and then delete any email
1868 		 * addresses because this retains its structure.
1869 		 */
1870 		if (!(dn_subject = X509_NAME_dup(subject)))
1871 			{
1872 			BIO_printf(bio_err,"Memory allocation failure\n");
1873 			goto err;
1874 			}
1875 		while((i = X509_NAME_get_index_by_NID(dn_subject,
1876 					NID_pkcs9_emailAddress, -1)) >= 0)
1877 			{
1878 			tmpne = X509_NAME_get_entry(dn_subject, i);
1879 			X509_NAME_delete_entry(dn_subject, i);
1880 			X509_NAME_ENTRY_free(tmpne);
1881 			}
1882 		}
1883 
1884 	if (BN_is_zero(serial))
1885 		row[DB_serial]=BUF_strdup("00");
1886 	else
1887 		row[DB_serial]=BN_bn2hex(serial);
1888 	if (row[DB_serial] == NULL)
1889 		{
1890 		BIO_printf(bio_err,"Memory allocation failure\n");
1891 		goto err;
1892 		}
1893 
1894 	if (db->attributes.unique_subject)
1895 		{
1896 		rrow=TXT_DB_get_by_index(db->db,DB_name,row);
1897 		if (rrow != NULL)
1898 			{
1899 			BIO_printf(bio_err,
1900 				"ERROR:There is already a certificate for %s\n",
1901 				row[DB_name]);
1902 			}
1903 		}
1904 	if (rrow == NULL)
1905 		{
1906 		rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1907 		if (rrow != NULL)
1908 			{
1909 			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1910 				row[DB_serial]);
1911 			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1912 			}
1913 		}
1914 
1915 	if (rrow != NULL)
1916 		{
1917 		BIO_printf(bio_err,
1918 			"The matching entry has the following details\n");
1919 		if (rrow[DB_type][0] == 'E')
1920 			p="Expired";
1921 		else if (rrow[DB_type][0] == 'R')
1922 			p="Revoked";
1923 		else if (rrow[DB_type][0] == 'V')
1924 			p="Valid";
1925 		else
1926 			p="\ninvalid type, Data base error\n";
1927 		BIO_printf(bio_err,"Type	  :%s\n",p);;
1928 		if (rrow[DB_type][0] == 'R')
1929 			{
1930 			p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1931 			BIO_printf(bio_err,"Was revoked on:%s\n",p);
1932 			}
1933 		p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1934 		BIO_printf(bio_err,"Expires on    :%s\n",p);
1935 		p=rrow[DB_serial]; if (p == NULL) p="undef";
1936 		BIO_printf(bio_err,"Serial Number :%s\n",p);
1937 		p=rrow[DB_file]; if (p == NULL) p="undef";
1938 		BIO_printf(bio_err,"File name     :%s\n",p);
1939 		p=rrow[DB_name]; if (p == NULL) p="undef";
1940 		BIO_printf(bio_err,"Subject Name  :%s\n",p);
1941 		ok= -1; /* This is now a 'bad' error. */
1942 		goto err;
1943 		}
1944 
1945 	/* We are now totally happy, lets make and sign the certificate */
1946 	if (verbose)
1947 		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1948 
1949 	if ((ret=X509_new()) == NULL) goto err;
1950 	ci=ret->cert_info;
1951 
1952 #ifdef X509_V3
1953 	/* Make it an X509 v3 certificate. */
1954 	if (!X509_set_version(ret,2)) goto err;
1955 #endif
1956 
1957 	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1958 		goto err;
1959 	if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1960 		goto err;
1961 
1962 	if (strcmp(startdate,"today") == 0)
1963 		X509_gmtime_adj(X509_get_notBefore(ret),0);
1964 	else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1965 
1966 	if (enddate == NULL)
1967 		X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1968 	else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1969 
1970 	if (!X509_set_subject_name(ret,subject)) goto err;
1971 
1972 	pktmp=X509_REQ_get_pubkey(req);
1973 	i = X509_set_pubkey(ret,pktmp);
1974 	EVP_PKEY_free(pktmp);
1975 	if (!i) goto err;
1976 
1977 	/* Lets add the extensions, if there are any */
1978 	if (ext_sect)
1979 		{
1980 		X509V3_CTX ctx;
1981 		if (ci->version == NULL)
1982 			if ((ci->version=ASN1_INTEGER_new()) == NULL)
1983 				goto err;
1984 		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1985 
1986 		/* Free the current entries if any, there should not
1987 		 * be any I believe */
1988 		if (ci->extensions != NULL)
1989 			sk_X509_EXTENSION_pop_free(ci->extensions,
1990 						   X509_EXTENSION_free);
1991 
1992 		ci->extensions = NULL;
1993 
1994 		/* Initialize the context structure */
1995 		X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1996 
1997 		if (extconf)
1998 			{
1999 			if (verbose)
2000 				BIO_printf(bio_err, "Extra configuration file found\n");
2001 
2002 			/* Use the extconf configuration db LHASH */
2003 			X509V3_set_nconf(&ctx, extconf);
2004 
2005 			/* Test the structure (needed?) */
2006 			/* X509V3_set_ctx_test(&ctx); */
2007 
2008 			/* Adds exts contained in the configuration file */
2009 			if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2010 				{
2011 				BIO_printf(bio_err,
2012 				    "ERROR: adding extensions in section %s\n",
2013 								ext_sect);
2014 				ERR_print_errors(bio_err);
2015 				goto err;
2016 				}
2017 			if (verbose)
2018 				BIO_printf(bio_err, "Successfully added extensions from file.\n");
2019 			}
2020 		else if (ext_sect)
2021 			{
2022 			/* We found extensions to be set from config file */
2023 			X509V3_set_nconf(&ctx, lconf);
2024 
2025 			if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2026 				{
2027 				BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2028 				ERR_print_errors(bio_err);
2029 				goto err;
2030 				}
2031 
2032 			if (verbose)
2033 				BIO_printf(bio_err, "Successfully added extensions from config\n");
2034 			}
2035 		}
2036 
2037 	/* Copy extensions from request (if any) */
2038 
2039 	if (!copy_extensions(ret, req, ext_copy))
2040 		{
2041 		BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2042 		ERR_print_errors(bio_err);
2043 		goto err;
2044 		}
2045 
2046 	/* Set the right value for the noemailDN option */
2047 	if( email_dn == 0 )
2048 		{
2049 		if (!X509_set_subject_name(ret,dn_subject)) goto err;
2050 		}
2051 
2052 	if (!default_op)
2053 		{
2054 		BIO_printf(bio_err, "Certificate Details:\n");
2055 		/* Never print signature details because signature not present */
2056 		certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2057 		X509_print_ex(bio_err, ret, nameopt, certopt);
2058 		}
2059 
2060 	BIO_printf(bio_err,"Certificate is to be certified until ");
2061 	ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2062 	if (days) BIO_printf(bio_err," (%d days)",days);
2063 	BIO_printf(bio_err, "\n");
2064 
2065 	if (!batch)
2066 		{
2067 
2068 		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2069 		(void)BIO_flush(bio_err);
2070 		buf[0]='\0';
2071 		fgets(buf,sizeof(buf)-1,stdin);
2072 		if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2073 			{
2074 			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2075 			ok=0;
2076 			goto err;
2077 			}
2078 		}
2079 
2080 
2081 #ifndef OPENSSL_NO_DSA
2082 	if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2083 	pktmp=X509_get_pubkey(ret);
2084 	if (EVP_PKEY_missing_parameters(pktmp) &&
2085 		!EVP_PKEY_missing_parameters(pkey))
2086 		EVP_PKEY_copy_parameters(pktmp,pkey);
2087 	EVP_PKEY_free(pktmp);
2088 #endif
2089 
2090 	if (!X509_sign(ret,pkey,dgst))
2091 		goto err;
2092 
2093 	/* We now just add it to the database */
2094 	row[DB_type]=(char *)OPENSSL_malloc(2);
2095 
2096 	tm=X509_get_notAfter(ret);
2097 	row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2098 	memcpy(row[DB_exp_date],tm->data,tm->length);
2099 	row[DB_exp_date][tm->length]='\0';
2100 
2101 	row[DB_rev_date]=NULL;
2102 
2103 	/* row[DB_serial] done already */
2104 	row[DB_file]=(char *)OPENSSL_malloc(8);
2105 	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2106 
2107 	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2108 		(row[DB_file] == NULL) || (row[DB_name] == NULL))
2109 		{
2110 		BIO_printf(bio_err,"Memory allocation failure\n");
2111 		goto err;
2112 		}
2113 	BUF_strlcpy(row[DB_file],"unknown",8);
2114 	row[DB_type][0]='V';
2115 	row[DB_type][1]='\0';
2116 
2117 	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2118 		{
2119 		BIO_printf(bio_err,"Memory allocation failure\n");
2120 		goto err;
2121 		}
2122 
2123 	for (i=0; i<DB_NUMBER; i++)
2124 		{
2125 		irow[i]=row[i];
2126 		row[i]=NULL;
2127 		}
2128 	irow[DB_NUMBER]=NULL;
2129 
2130 	if (!TXT_DB_insert(db->db,irow))
2131 		{
2132 		BIO_printf(bio_err,"failed to update database\n");
2133 		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2134 		goto err;
2135 		}
2136 	ok=1;
2137 err:
2138 	for (i=0; i<DB_NUMBER; i++)
2139 		if (row[i] != NULL) OPENSSL_free(row[i]);
2140 
2141 	if (CAname != NULL)
2142 		X509_NAME_free(CAname);
2143 	if (subject != NULL)
2144 		X509_NAME_free(subject);
2145 	if ((dn_subject != NULL) && !email_dn)
2146 		X509_NAME_free(dn_subject);
2147 	if (tmptm != NULL)
2148 		ASN1_UTCTIME_free(tmptm);
2149 	if (ok <= 0)
2150 		{
2151 		if (ret != NULL) X509_free(ret);
2152 		ret=NULL;
2153 		}
2154 	else
2155 		*xret=ret;
2156 	return(ok);
2157 	}
2158 
2159 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2160 	{
2161 
2162 	if (output_der)
2163 		{
2164 		(void)i2d_X509_bio(bp,x);
2165 		return;
2166 		}
2167 #if 0
2168 	/* ??? Not needed since X509_print prints all this stuff anyway */
2169 	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2170 	BIO_printf(bp,"issuer :%s\n",f);
2171 
2172 	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2173 	BIO_printf(bp,"subject:%s\n",f);
2174 
2175 	BIO_puts(bp,"serial :");
2176 	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2177 	BIO_puts(bp,"\n\n");
2178 #endif
2179 	if (!notext)X509_print(bp,x);
2180 	PEM_write_bio_X509(bp,x);
2181 	}
2182 
2183 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2184 	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2185 	     BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2186 	     long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2187 	     unsigned long nameopt, int default_op, int ext_copy)
2188 	{
2189 	STACK_OF(CONF_VALUE) *sk=NULL;
2190 	LHASH *parms=NULL;
2191 	X509_REQ *req=NULL;
2192 	CONF_VALUE *cv=NULL;
2193 	NETSCAPE_SPKI *spki = NULL;
2194 	X509_REQ_INFO *ri;
2195 	char *type,*buf;
2196 	EVP_PKEY *pktmp=NULL;
2197 	X509_NAME *n=NULL;
2198 	X509_NAME_ENTRY *ne=NULL;
2199 	int ok= -1,i,j;
2200 	long errline;
2201 	int nid;
2202 
2203 	/*
2204 	 * Load input file into a hash table.  (This is just an easy
2205 	 * way to read and parse the file, then put it into a convenient
2206 	 * STACK format).
2207 	 */
2208 	parms=CONF_load(NULL,infile,&errline);
2209 	if (parms == NULL)
2210 		{
2211 		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2212 		ERR_print_errors(bio_err);
2213 		goto err;
2214 		}
2215 
2216 	sk=CONF_get_section(parms, "default");
2217 	if (sk_CONF_VALUE_num(sk) == 0)
2218 		{
2219 		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2220 		CONF_free(parms);
2221 		goto err;
2222 		}
2223 
2224 	/*
2225 	 * Now create a dummy X509 request structure.  We don't actually
2226 	 * have an X509 request, but we have many of the components
2227 	 * (a public key, various DN components).  The idea is that we
2228 	 * put these components into the right X509 request structure
2229 	 * and we can use the same code as if you had a real X509 request.
2230 	 */
2231 	req=X509_REQ_new();
2232 	if (req == NULL)
2233 		{
2234 		ERR_print_errors(bio_err);
2235 		goto err;
2236 		}
2237 
2238 	/*
2239 	 * Build up the subject name set.
2240 	 */
2241 	ri=req->req_info;
2242 	n = ri->subject;
2243 
2244 	for (i = 0; ; i++)
2245 		{
2246 		if (sk_CONF_VALUE_num(sk) <= i) break;
2247 
2248 		cv=sk_CONF_VALUE_value(sk,i);
2249 		type=cv->name;
2250 		/* Skip past any leading X. X: X, etc to allow for
2251 		 * multiple instances
2252 		 */
2253 		for (buf = cv->name; *buf ; buf++)
2254 			if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2255 				{
2256 				buf++;
2257 				if (*buf) type = buf;
2258 				break;
2259 				}
2260 
2261 		buf=cv->value;
2262 		if ((nid=OBJ_txt2nid(type)) == NID_undef)
2263 			{
2264 			if (strcmp(type, "SPKAC") == 0)
2265 				{
2266 				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2267 				if (spki == NULL)
2268 					{
2269 					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2270 					ERR_print_errors(bio_err);
2271 					goto err;
2272 					}
2273 				}
2274 			continue;
2275 			}
2276 
2277 		/*
2278 		if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2279 			continue;
2280 		*/
2281 
2282 		j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2283 		if (fix_data(nid, &j) == 0)
2284 			{
2285 			BIO_printf(bio_err,
2286 				"invalid characters in string %s\n",buf);
2287 			goto err;
2288 			}
2289 
2290 		if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2291 			(unsigned char *)buf,
2292 			strlen(buf))) == NULL)
2293 			goto err;
2294 
2295 		if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2296 		}
2297 	if (spki == NULL)
2298 		{
2299 		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2300 			infile);
2301 		goto err;
2302 		}
2303 
2304 	/*
2305 	 * Now extract the key from the SPKI structure.
2306 	 */
2307 
2308 	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2309 
2310 	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2311 		{
2312 		BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2313 		goto err;
2314 		}
2315 
2316 	j = NETSCAPE_SPKI_verify(spki, pktmp);
2317 	if (j <= 0)
2318 		{
2319 		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2320 		goto err;
2321 		}
2322 	BIO_printf(bio_err,"Signature ok\n");
2323 
2324 	X509_REQ_set_pubkey(req,pktmp);
2325 	EVP_PKEY_free(pktmp);
2326 	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2327 		   days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2328 			ext_copy);
2329 err:
2330 	if (req != NULL) X509_REQ_free(req);
2331 	if (parms != NULL) CONF_free(parms);
2332 	if (spki != NULL) NETSCAPE_SPKI_free(spki);
2333 	if (ne != NULL) X509_NAME_ENTRY_free(ne);
2334 
2335 	return(ok);
2336 	}
2337 
2338 static int fix_data(int nid, int *type)
2339 	{
2340 	if (nid == NID_pkcs9_emailAddress)
2341 		*type=V_ASN1_IA5STRING;
2342 	if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2343 		*type=V_ASN1_T61STRING;
2344 	if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2345 		*type=V_ASN1_T61STRING;
2346 	if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2347 		return(0);
2348 	if (nid == NID_pkcs9_unstructuredName)
2349 		*type=V_ASN1_IA5STRING;
2350 	return(1);
2351 	}
2352 
2353 static int check_time_format(char *str)
2354 	{
2355 	ASN1_UTCTIME tm;
2356 
2357 	tm.data=(unsigned char *)str;
2358 	tm.length=strlen(str);
2359 	tm.type=V_ASN1_UTCTIME;
2360 	return(ASN1_UTCTIME_check(&tm));
2361 	}
2362 
2363 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2364 	{
2365 	ASN1_UTCTIME *tm=NULL;
2366 	char *row[DB_NUMBER],**rrow,**irow;
2367 	char *rev_str = NULL;
2368 	BIGNUM *bn = NULL;
2369 	int ok=-1,i;
2370 
2371 	for (i=0; i<DB_NUMBER; i++)
2372 		row[i]=NULL;
2373 	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2374 	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2375 	if (BN_is_zero(bn))
2376 		row[DB_serial]=BUF_strdup("00");
2377 	else
2378 		row[DB_serial]=BN_bn2hex(bn);
2379 	BN_free(bn);
2380 	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2381 		{
2382 		BIO_printf(bio_err,"Memory allocation failure\n");
2383 		goto err;
2384 		}
2385 	/* We have to lookup by serial number because name lookup
2386 	 * skips revoked certs
2387  	 */
2388 	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2389 	if (rrow == NULL)
2390 		{
2391 		BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2392 
2393 		/* We now just add it to the database */
2394 		row[DB_type]=(char *)OPENSSL_malloc(2);
2395 
2396 		tm=X509_get_notAfter(x509);
2397 		row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2398 		memcpy(row[DB_exp_date],tm->data,tm->length);
2399 		row[DB_exp_date][tm->length]='\0';
2400 
2401 		row[DB_rev_date]=NULL;
2402 
2403 		/* row[DB_serial] done already */
2404 		row[DB_file]=(char *)OPENSSL_malloc(8);
2405 
2406 		/* row[DB_name] done already */
2407 
2408 		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2409 			(row[DB_file] == NULL))
2410 			{
2411 			BIO_printf(bio_err,"Memory allocation failure\n");
2412 			goto err;
2413 			}
2414 		BUF_strlcpy(row[DB_file],"unknown",8);
2415 		row[DB_type][0]='V';
2416 		row[DB_type][1]='\0';
2417 
2418 		if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2419 			{
2420 			BIO_printf(bio_err,"Memory allocation failure\n");
2421 			goto err;
2422 			}
2423 
2424 		for (i=0; i<DB_NUMBER; i++)
2425 			{
2426 			irow[i]=row[i];
2427 			row[i]=NULL;
2428 			}
2429 		irow[DB_NUMBER]=NULL;
2430 
2431 		if (!TXT_DB_insert(db->db,irow))
2432 			{
2433 			BIO_printf(bio_err,"failed to update database\n");
2434 			BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2435 			goto err;
2436 			}
2437 
2438 		/* Revoke Certificate */
2439 		ok = do_revoke(x509,db, type, value);
2440 
2441 		goto err;
2442 
2443 		}
2444 	else if (index_name_cmp((const char **)row,(const char **)rrow))
2445 		{
2446 		BIO_printf(bio_err,"ERROR:name does not match %s\n",
2447 			   row[DB_name]);
2448 		goto err;
2449 		}
2450 	else if (rrow[DB_type][0]=='R')
2451 		{
2452 		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2453 			   row[DB_serial]);
2454 		goto err;
2455 		}
2456 	else
2457 		{
2458 		BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2459 		rev_str = make_revocation_str(type, value);
2460 		if (!rev_str)
2461 			{
2462 			BIO_printf(bio_err, "Error in revocation arguments\n");
2463 			goto err;
2464 			}
2465 		rrow[DB_type][0]='R';
2466 		rrow[DB_type][1]='\0';
2467 		rrow[DB_rev_date] = rev_str;
2468 		}
2469 	ok=1;
2470 err:
2471 	for (i=0; i<DB_NUMBER; i++)
2472 		{
2473 		if (row[i] != NULL)
2474 			OPENSSL_free(row[i]);
2475 		}
2476 	return(ok);
2477 	}
2478 
2479 static int get_certificate_status(const char *serial, CA_DB *db)
2480 	{
2481 	char *row[DB_NUMBER],**rrow;
2482 	int ok=-1,i;
2483 
2484 	/* Free Resources */
2485 	for (i=0; i<DB_NUMBER; i++)
2486 		row[i]=NULL;
2487 
2488 	/* Malloc needed char spaces */
2489 	row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2490 	if (row[DB_serial] == NULL)
2491 		{
2492 		BIO_printf(bio_err,"Malloc failure\n");
2493 		goto err;
2494 		}
2495 
2496 	if (strlen(serial) % 2)
2497 		{
2498 		/* Set the first char to 0 */;
2499 		row[DB_serial][0]='0';
2500 
2501 		/* Copy String from serial to row[DB_serial] */
2502 		memcpy(row[DB_serial]+1, serial, strlen(serial));
2503 		row[DB_serial][strlen(serial)+1]='\0';
2504 		}
2505 	else
2506 		{
2507 		/* Copy String from serial to row[DB_serial] */
2508 		memcpy(row[DB_serial], serial, strlen(serial));
2509 		row[DB_serial][strlen(serial)]='\0';
2510 		}
2511 
2512 	/* Make it Upper Case */
2513 	for (i=0; row[DB_serial][i] != '\0'; i++)
2514 		row[DB_serial][i] = toupper(row[DB_serial][i]);
2515 
2516 
2517 	ok=1;
2518 
2519 	/* Search for the certificate */
2520 	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2521 	if (rrow == NULL)
2522 		{
2523 		BIO_printf(bio_err,"Serial %s not present in db.\n",
2524 				 row[DB_serial]);
2525 		ok=-1;
2526 		goto err;
2527 		}
2528 	else if (rrow[DB_type][0]=='V')
2529 		{
2530 		BIO_printf(bio_err,"%s=Valid (%c)\n",
2531 			row[DB_serial], rrow[DB_type][0]);
2532 		goto err;
2533 		}
2534 	else if (rrow[DB_type][0]=='R')
2535 		{
2536 		BIO_printf(bio_err,"%s=Revoked (%c)\n",
2537 			row[DB_serial], rrow[DB_type][0]);
2538 		goto err;
2539 		}
2540 	else if (rrow[DB_type][0]=='E')
2541 		{
2542 		BIO_printf(bio_err,"%s=Expired (%c)\n",
2543 			row[DB_serial], rrow[DB_type][0]);
2544 		goto err;
2545 		}
2546 	else if (rrow[DB_type][0]=='S')
2547 		{
2548 		BIO_printf(bio_err,"%s=Suspended (%c)\n",
2549 			row[DB_serial], rrow[DB_type][0]);
2550 		goto err;
2551 		}
2552 	else
2553 		{
2554 		BIO_printf(bio_err,"%s=Unknown (%c).\n",
2555 			row[DB_serial], rrow[DB_type][0]);
2556 		ok=-1;
2557 		}
2558 err:
2559 	for (i=0; i<DB_NUMBER; i++)
2560 		{
2561 		if (row[i] != NULL)
2562 			OPENSSL_free(row[i]);
2563 		}
2564 	return(ok);
2565 	}
2566 
2567 static int do_updatedb (CA_DB *db)
2568 	{
2569 	ASN1_UTCTIME	*a_tm = NULL;
2570 	int i, cnt = 0;
2571 	int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */
2572 	char **rrow, *a_tm_s;
2573 
2574 	a_tm = ASN1_UTCTIME_new();
2575 
2576 	/* get actual time and make a string */
2577 	a_tm = X509_gmtime_adj(a_tm, 0);
2578 	a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2579 	if (a_tm_s == NULL)
2580 		{
2581 		cnt = -1;
2582 		goto err;
2583 		}
2584 
2585 	memcpy(a_tm_s, a_tm->data, a_tm->length);
2586 	a_tm_s[a_tm->length] = '\0';
2587 
2588 	if (strncmp(a_tm_s, "49", 2) <= 0)
2589 		a_y2k = 1;
2590 	else
2591 		a_y2k = 0;
2592 
2593 	for (i = 0; i < sk_num(db->db->data); i++)
2594 		{
2595 		rrow = (char **) sk_value(db->db->data, i);
2596 
2597 		if (rrow[DB_type][0] == 'V')
2598 		 	{
2599 			/* ignore entries that are not valid */
2600 			if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2601 				db_y2k = 1;
2602 			else
2603 				db_y2k = 0;
2604 
2605 			if (db_y2k == a_y2k)
2606 				{
2607 				/* all on the same y2k side */
2608 				if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2609 				       	{
2610 				       	rrow[DB_type][0]  = 'E';
2611 				       	rrow[DB_type][1]  = '\0';
2612 	  				cnt++;
2613 
2614 					BIO_printf(bio_err, "%s=Expired\n",
2615 							rrow[DB_serial]);
2616 					}
2617 				}
2618 			else if (db_y2k < a_y2k)
2619 				{
2620 		  		rrow[DB_type][0]  = 'E';
2621 		  		rrow[DB_type][1]  = '\0';
2622 	  			cnt++;
2623 
2624 				BIO_printf(bio_err, "%s=Expired\n",
2625 							rrow[DB_serial]);
2626 				}
2627 
2628 			}
2629     		}
2630 
2631 err:
2632 
2633 	ASN1_UTCTIME_free(a_tm);
2634 	OPENSSL_free(a_tm_s);
2635 
2636 	return (cnt);
2637 	}
2638 
2639 static char *crl_reasons[] = {
2640 	/* CRL reason strings */
2641 	"unspecified",
2642 	"keyCompromise",
2643 	"CACompromise",
2644 	"affiliationChanged",
2645 	"superseded",
2646 	"cessationOfOperation",
2647 	"certificateHold",
2648 	"removeFromCRL",
2649 	/* Additional pseudo reasons */
2650 	"holdInstruction",
2651 	"keyTime",
2652 	"CAkeyTime"
2653 };
2654 
2655 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2656 
2657 /* Given revocation information convert to a DB string.
2658  * The format of the string is:
2659  * revtime[,reason,extra]. Where 'revtime' is the
2660  * revocation time (the current time). 'reason' is the
2661  * optional CRL reason and 'extra' is any additional
2662  * argument
2663  */
2664 
2665 char *make_revocation_str(int rev_type, char *rev_arg)
2666 	{
2667 	char *reason = NULL, *other = NULL, *str;
2668 	ASN1_OBJECT *otmp;
2669 	ASN1_UTCTIME *revtm = NULL;
2670 	int i;
2671 	switch (rev_type)
2672 		{
2673 	case REV_NONE:
2674 		break;
2675 
2676 	case REV_CRL_REASON:
2677 		for (i = 0; i < 8; i++)
2678 			{
2679 			if (!strcasecmp(rev_arg, crl_reasons[i]))
2680 				{
2681 				reason = crl_reasons[i];
2682 				break;
2683 				}
2684 			}
2685 		if (reason == NULL)
2686 			{
2687 			BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2688 			return NULL;
2689 			}
2690 		break;
2691 
2692 	case REV_HOLD:
2693 		/* Argument is an OID */
2694 
2695 		otmp = OBJ_txt2obj(rev_arg, 0);
2696 		ASN1_OBJECT_free(otmp);
2697 
2698 		if (otmp == NULL)
2699 			{
2700 			BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2701 			return NULL;
2702 			}
2703 
2704 		reason = "holdInstruction";
2705 		other = rev_arg;
2706 		break;
2707 
2708 	case REV_KEY_COMPROMISE:
2709 	case REV_CA_COMPROMISE:
2710 
2711 		/* Argument is the key compromise time  */
2712 		if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2713 			{
2714 			BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2715 			return NULL;
2716 			}
2717 		other = rev_arg;
2718 		if (rev_type == REV_KEY_COMPROMISE)
2719 			reason = "keyTime";
2720 		else
2721 			reason = "CAkeyTime";
2722 
2723 		break;
2724 
2725 		}
2726 
2727 	revtm = X509_gmtime_adj(NULL, 0);
2728 
2729 	i = revtm->length + 1;
2730 
2731 	if (reason) i += strlen(reason) + 1;
2732 	if (other) i += strlen(other) + 1;
2733 
2734 	str = OPENSSL_malloc(i);
2735 
2736 	if (!str) return NULL;
2737 
2738 	BUF_strlcpy(str, (char *)revtm->data, i);
2739 	if (reason)
2740 		{
2741 		BUF_strlcat(str, ",", i);
2742 		BUF_strlcat(str, reason, i);
2743 		}
2744 	if (other)
2745 		{
2746 		BUF_strlcat(str, ",", i);
2747 		BUF_strlcat(str, other, i);
2748 		}
2749 	ASN1_UTCTIME_free(revtm);
2750 	return str;
2751 	}
2752 
2753 /* Convert revocation field to X509_REVOKED entry
2754  * return code:
2755  * 0 error
2756  * 1 OK
2757  * 2 OK and some extensions added (i.e. V2 CRL)
2758  */
2759 
2760 
2761 int make_revoked(X509_REVOKED *rev, char *str)
2762 	{
2763 	char *tmp = NULL;
2764 	int reason_code = -1;
2765 	int i, ret = 0;
2766 	ASN1_OBJECT *hold = NULL;
2767 	ASN1_GENERALIZEDTIME *comp_time = NULL;
2768 	ASN1_ENUMERATED *rtmp = NULL;
2769 
2770 	ASN1_TIME *revDate = NULL;
2771 
2772 	i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2773 
2774 	if (i == 0)
2775 		goto err;
2776 
2777 	if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2778 		goto err;
2779 
2780 	if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2781 		{
2782 		rtmp = ASN1_ENUMERATED_new();
2783 		if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2784 			goto err;
2785 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2786 			goto err;
2787 		}
2788 
2789 	if (rev && comp_time)
2790 		{
2791 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2792 			goto err;
2793 		}
2794 	if (rev && hold)
2795 		{
2796 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2797 			goto err;
2798 		}
2799 
2800 	if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2801 		ret = 2;
2802 	else ret = 1;
2803 
2804 	err:
2805 
2806 	if (tmp) OPENSSL_free(tmp);
2807 	ASN1_OBJECT_free(hold);
2808 	ASN1_GENERALIZEDTIME_free(comp_time);
2809 	ASN1_ENUMERATED_free(rtmp);
2810 	ASN1_TIME_free(revDate);
2811 
2812 	return ret;
2813 	}
2814 
2815 /*
2816  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2817  * where characters may be escaped by \
2818  */
2819 X509_NAME *do_subject(char *subject, long chtype)
2820 	{
2821 	size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
2822 	char *buf = OPENSSL_malloc(buflen);
2823 	size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2824 	char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
2825 	char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
2826 
2827 	char *sp = subject, *bp = buf;
2828 	int i, ne_num = 0;
2829 
2830 	X509_NAME *n = NULL;
2831 	int nid;
2832 
2833 	if (!buf || !ne_types || !ne_values)
2834 	{
2835 		BIO_printf(bio_err, "malloc error\n");
2836 		goto error;
2837 	}
2838 
2839 	if (*subject != '/')
2840 	{
2841 		BIO_printf(bio_err, "Subject does not start with '/'.\n");
2842 		goto error;
2843 	}
2844 	sp++; /* skip leading / */
2845 
2846 	while (*sp)
2847 		{
2848 		/* collect type */
2849 		ne_types[ne_num] = bp;
2850 		while (*sp)
2851 			{
2852 			if (*sp == '\\') /* is there anything to escape in the type...? */
2853 				{
2854 				if (*++sp)
2855 					*bp++ = *sp++;
2856 				else
2857 					{
2858 					BIO_printf(bio_err, "escape character at end of string\n");
2859 					goto error;
2860 					}
2861 				}
2862 			else if (*sp == '=')
2863 				{
2864 				sp++;
2865 				*bp++ = '\0';
2866 				break;
2867 				}
2868 			else
2869 				*bp++ = *sp++;
2870 			}
2871 		if (!*sp)
2872 			{
2873 			BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
2874 			goto error;
2875 			}
2876 		ne_values[ne_num] = bp;
2877 		while (*sp)
2878 			{
2879 			if (*sp == '\\')
2880 				{
2881 				if (*++sp)
2882 					*bp++ = *sp++;
2883 				else
2884 					{
2885 					BIO_printf(bio_err, "escape character at end of string\n");
2886 					goto error;
2887 					}
2888 				}
2889 			else if (*sp == '/')
2890 				{
2891 				sp++;
2892 				break;
2893 				}
2894 			else
2895 				*bp++ = *sp++;
2896 			}
2897 		*bp++ = '\0';
2898 		ne_num++;
2899 		}
2900 
2901 	if (!(n = X509_NAME_new()))
2902 		goto error;
2903 
2904 	for (i = 0; i < ne_num; i++)
2905 		{
2906 		if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
2907 			{
2908 			BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
2909 			continue;
2910 			}
2911 
2912 		if (!*ne_values[i])
2913 			{
2914 			BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
2915 			continue;
2916 			}
2917 
2918 		if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
2919 			goto error;
2920 		}
2921 
2922 	OPENSSL_free(ne_values);
2923 	OPENSSL_free(ne_types);
2924 	OPENSSL_free(buf);
2925 	return n;
2926 
2927 error:
2928 	X509_NAME_free(n);
2929 	if (ne_values)
2930 		OPENSSL_free(ne_values);
2931 	if (ne_types)
2932 		OPENSSL_free(ne_types);
2933 	if (buf)
2934 		OPENSSL_free(buf);
2935 	return NULL;
2936 }
2937 
2938 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2939 	{
2940 	char buf[25],*pbuf, *p;
2941 	int j;
2942 	j=i2a_ASN1_OBJECT(bp,obj);
2943 	pbuf=buf;
2944 	for (j=22-j; j>0; j--)
2945 		*(pbuf++)=' ';
2946 	*(pbuf++)=':';
2947 	*(pbuf++)='\0';
2948 	BIO_puts(bp,buf);
2949 
2950 	if (str->type == V_ASN1_PRINTABLESTRING)
2951 		BIO_printf(bp,"PRINTABLE:'");
2952 	else if (str->type == V_ASN1_T61STRING)
2953 		BIO_printf(bp,"T61STRING:'");
2954 	else if (str->type == V_ASN1_IA5STRING)
2955 		BIO_printf(bp,"IA5STRING:'");
2956 	else if (str->type == V_ASN1_UNIVERSALSTRING)
2957 		BIO_printf(bp,"UNIVERSALSTRING:'");
2958 	else
2959 		BIO_printf(bp,"ASN.1 %2d:'",str->type);
2960 
2961 	p=(char *)str->data;
2962 	for (j=str->length; j>0; j--)
2963 		{
2964 		if ((*p >= ' ') && (*p <= '~'))
2965 			BIO_printf(bp,"%c",*p);
2966 		else if (*p & 0x80)
2967 			BIO_printf(bp,"\\0x%02X",*p);
2968 		else if ((unsigned char)*p == 0xf7)
2969 			BIO_printf(bp,"^?");
2970 		else	BIO_printf(bp,"^%c",*p+'@');
2971 		p++;
2972 		}
2973 	BIO_printf(bp,"'\n");
2974 	return 1;
2975 	}
2976 
2977 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
2978 	{
2979 	char *tmp = NULL;
2980 	char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2981 	int reason_code = -1;
2982 	int i, ret = 0;
2983 	ASN1_OBJECT *hold = NULL;
2984 	ASN1_GENERALIZEDTIME *comp_time = NULL;
2985 	tmp = BUF_strdup(str);
2986 
2987 	p = strchr(tmp, ',');
2988 
2989 	rtime_str = tmp;
2990 
2991 	if (p)
2992 		{
2993 		*p = '\0';
2994 		p++;
2995 		reason_str = p;
2996 		p = strchr(p, ',');
2997 		if (p)
2998 			{
2999 			*p = '\0';
3000 			arg_str = p + 1;
3001 			}
3002 		}
3003 
3004 	if (prevtm)
3005 		{
3006 		*prevtm = ASN1_UTCTIME_new();
3007 		if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3008 			{
3009 			BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3010 			goto err;
3011 			}
3012 		}
3013 	if (reason_str)
3014 		{
3015 		for (i = 0; i < NUM_REASONS; i++)
3016 			{
3017 			if(!strcasecmp(reason_str, crl_reasons[i]))
3018 				{
3019 				reason_code = i;
3020 				break;
3021 				}
3022 			}
3023 		if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3024 			{
3025 			BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3026 			goto err;
3027 			}
3028 
3029 		if (reason_code == 7)
3030 			reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3031 		else if (reason_code == 8)		/* Hold instruction */
3032 			{
3033 			if (!arg_str)
3034 				{
3035 				BIO_printf(bio_err, "missing hold instruction\n");
3036 				goto err;
3037 				}
3038 			reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3039 			hold = OBJ_txt2obj(arg_str, 0);
3040 
3041 			if (!hold)
3042 				{
3043 				BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3044 				goto err;
3045 				}
3046 			if (phold) *phold = hold;
3047 			}
3048 		else if ((reason_code == 9) || (reason_code == 10))
3049 			{
3050 			if (!arg_str)
3051 				{
3052 				BIO_printf(bio_err, "missing compromised time\n");
3053 				goto err;
3054 				}
3055 			comp_time = ASN1_GENERALIZEDTIME_new();
3056 			if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3057 				{
3058 				BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3059 				goto err;
3060 				}
3061 			if (reason_code == 9)
3062 				reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3063 			else
3064 				reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3065 			}
3066 		}
3067 
3068 	if (preason) *preason = reason_code;
3069 	if (pinvtm) *pinvtm = comp_time;
3070 	else ASN1_GENERALIZEDTIME_free(comp_time);
3071 
3072 	ret = 1;
3073 
3074 	err:
3075 
3076 	if (tmp) OPENSSL_free(tmp);
3077 	if (!phold) ASN1_OBJECT_free(hold);
3078 	if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3079 
3080 	return ret;
3081 	}
3082