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