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