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