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