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