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