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