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