ca.c revision 59191
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 <sys/types.h>
65#include <sys/stat.h>
66#include "apps.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/pem.h>
77
78#ifndef W_OK
79#  ifdef VMS
80#    if defined(__DECC)
81#      include <unistd.h>
82#    else
83#      include <unixlib.h>
84#    endif
85#  else
86#    include <sys/file.h>
87#  endif
88#endif
89
90#ifndef W_OK
91#  define F_OK 0
92#  define X_OK 1
93#  define W_OK 2
94#  define R_OK 4
95#endif
96
97#undef PROG
98#define PROG ca_main
99
100#define BASE_SECTION	"ca"
101#define CONFIG_FILE "openssl.cnf"
102
103#define ENV_DEFAULT_CA		"default_ca"
104
105#define ENV_DIR			"dir"
106#define ENV_CERTS		"certs"
107#define ENV_CRL_DIR		"crl_dir"
108#define ENV_CA_DB		"CA_DB"
109#define ENV_NEW_CERTS_DIR	"new_certs_dir"
110#define ENV_CERTIFICATE 	"certificate"
111#define ENV_SERIAL		"serial"
112#define ENV_CRL			"crl"
113#define ENV_PRIVATE_KEY		"private_key"
114#define ENV_RANDFILE		"RANDFILE"
115#define ENV_DEFAULT_DAYS 	"default_days"
116#define ENV_DEFAULT_STARTDATE 	"default_startdate"
117#define ENV_DEFAULT_ENDDATE 	"default_enddate"
118#define ENV_DEFAULT_CRL_DAYS 	"default_crl_days"
119#define ENV_DEFAULT_CRL_HOURS 	"default_crl_hours"
120#define ENV_DEFAULT_MD		"default_md"
121#define ENV_PRESERVE		"preserve"
122#define ENV_POLICY      	"policy"
123#define ENV_EXTENSIONS      	"x509_extensions"
124#define ENV_CRLEXT      	"crl_extensions"
125#define ENV_MSIE_HACK		"msie_hack"
126
127#define ENV_DATABASE		"database"
128
129#define DB_type         0
130#define DB_exp_date     1
131#define DB_rev_date     2
132#define DB_serial       3       /* index - unique */
133#define DB_file         4
134#define DB_name         5       /* index - unique for active */
135#define DB_NUMBER       6
136
137#define DB_TYPE_REV	'R'
138#define DB_TYPE_EXP	'E'
139#define DB_TYPE_VAL	'V'
140
141static char *ca_usage[]={
142"usage: ca args\n",
143"\n",
144" -verbose        - Talk alot while doing things\n",
145" -config file    - A config file\n",
146" -name arg       - The particular CA definition to use\n",
147" -gencrl         - Generate a new CRL\n",
148" -crldays days   - Days is when the next CRL is due\n",
149" -crlhours hours - Hours is when the next CRL is due\n",
150" -startdate YYMMDDHHMMSSZ  - certificate validity notBefore\n",
151" -enddate YYMMDDHHMMSSZ    - certificate validity notAfter (overrides -days)\n",
152" -days arg       - number of days to certify the certificate for\n",
153" -md arg         - md to use, one of md2, md5, sha or sha1\n",
154" -policy arg     - The CA 'policy' to support\n",
155" -keyfile arg    - PEM private key file\n",
156" -key arg        - key to decode the private key if it is encrypted\n",
157" -cert file      - The CA certificate\n",
158" -in file        - The input PEM encoded certificate request(s)\n",
159" -out file       - Where to put the output file(s)\n",
160" -outdir dir     - Where to put output certificates\n",
161" -infiles ....   - The last argument, requests to process\n",
162" -spkac file     - File contains DN and signed public key and challenge\n",
163" -ss_cert file   - File contains a self signed cert to sign\n",
164" -preserveDN     - Don't re-order the DN\n",
165" -batch          - Don't ask questions\n",
166" -msie_hack      - msie modifications to handle all those universal strings\n",
167" -revoke file    - Revoke a certificate (given in file)\n",
168" -extensions ..  - Extension section (override value in config file)\n",
169" -crlexts ..     - CRL extension section (override value in config file)\n",
170NULL
171};
172
173#ifdef EFENCE
174extern int EF_PROTECT_FREE;
175extern int EF_PROTECT_BELOW;
176extern int EF_ALIGNMENT;
177#endif
178
179static int add_oid_section(LHASH *conf);
180static void lookup_fail(char *name,char *tag);
181static unsigned long index_serial_hash(char **a);
182static int index_serial_cmp(char **a, char **b);
183static unsigned long index_name_hash(char **a);
184static int index_name_qual(char **a);
185static int index_name_cmp(char **a,char **b);
186static BIGNUM *load_serial(char *serialfile);
187static int save_serial(char *serialfile, BIGNUM *serial);
188static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
189		   const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
190		   BIGNUM *serial, char *startdate,char *enddate, int days,
191		   int batch, char *ext_sect, LHASH *conf,int verbose);
192static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
193			const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
194			TXT_DB *db, BIGNUM *serial,char *startdate,
195			char *enddate, int days, int batch, char *ext_sect,
196			LHASH *conf,int verbose);
197static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
198			 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
199			 TXT_DB *db, BIGNUM *serial,char *startdate,
200			 char *enddate, int days, char *ext_sect,LHASH *conf,
201				int verbose);
202static int fix_data(int nid, int *type);
203static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
204static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
205	STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
206	char *startdate, char *enddate, int days, int batch, int verbose,
207	X509_REQ *req, char *ext_sect, LHASH *conf);
208static int do_revoke(X509 *x509, TXT_DB *db);
209static int check_time_format(char *str);
210static LHASH *conf=NULL;
211static char *section=NULL;
212
213static int preserve=0;
214static int msie_hack=0;
215
216int MAIN(int, char **);
217
218int MAIN(int argc, char **argv)
219	{
220	char *key=NULL;
221	int total=0;
222	int total_done=0;
223	int badops=0;
224	int ret=1;
225	int req=0;
226	int verbose=0;
227	int gencrl=0;
228	int dorevoke=0;
229	long crldays=0;
230	long crlhours=0;
231	long errorline= -1;
232	char *configfile=NULL;
233	char *md=NULL;
234	char *policy=NULL;
235	char *keyfile=NULL;
236	char *certfile=NULL;
237	char *infile=NULL;
238	char *spkac_file=NULL;
239	char *ss_cert_file=NULL;
240	EVP_PKEY *pkey=NULL;
241	int output_der = 0;
242	char *outfile=NULL;
243	char *outdir=NULL;
244	char *serialfile=NULL;
245	char *extensions=NULL;
246	char *crl_ext=NULL;
247	BIGNUM *serial=NULL;
248	char *startdate=NULL;
249	char *enddate=NULL;
250	int days=0;
251	int batch=0;
252	int notext=0;
253	X509 *x509=NULL;
254	X509 *x=NULL;
255	BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
256	char *dbfile=NULL;
257	TXT_DB *db=NULL;
258	X509_CRL *crl=NULL;
259	X509_CRL_INFO *ci=NULL;
260	X509_REVOKED *r=NULL;
261	char **pp,*p,*f;
262	int i,j;
263	long l;
264	const EVP_MD *dgst=NULL;
265	STACK_OF(CONF_VALUE) *attribs=NULL;
266	STACK *cert_sk=NULL;
267	BIO *hex=NULL;
268#undef BSIZE
269#define BSIZE 256
270	MS_STATIC char buf[3][BSIZE];
271	char *randfile=NULL;
272
273#ifdef EFENCE
274EF_PROTECT_FREE=1;
275EF_PROTECT_BELOW=1;
276EF_ALIGNMENT=0;
277#endif
278
279	apps_startup();
280
281	conf = NULL;
282	key = NULL;
283	section = NULL;
284
285	preserve=0;
286	msie_hack=0;
287	if (bio_err == NULL)
288		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
289			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
290
291	argc--;
292	argv++;
293	while (argc >= 1)
294		{
295		if	(strcmp(*argv,"-verbose") == 0)
296			verbose=1;
297		else if	(strcmp(*argv,"-config") == 0)
298			{
299			if (--argc < 1) goto bad;
300			configfile= *(++argv);
301			}
302		else if (strcmp(*argv,"-name") == 0)
303			{
304			if (--argc < 1) goto bad;
305			section= *(++argv);
306			}
307		else if (strcmp(*argv,"-startdate") == 0)
308			{
309			if (--argc < 1) goto bad;
310			startdate= *(++argv);
311			}
312		else if (strcmp(*argv,"-enddate") == 0)
313			{
314			if (--argc < 1) goto bad;
315			enddate= *(++argv);
316			}
317		else if (strcmp(*argv,"-days") == 0)
318			{
319			if (--argc < 1) goto bad;
320			days=atoi(*(++argv));
321			}
322		else if (strcmp(*argv,"-md") == 0)
323			{
324			if (--argc < 1) goto bad;
325			md= *(++argv);
326			}
327		else if (strcmp(*argv,"-policy") == 0)
328			{
329			if (--argc < 1) goto bad;
330			policy= *(++argv);
331			}
332		else if (strcmp(*argv,"-keyfile") == 0)
333			{
334			if (--argc < 1) goto bad;
335			keyfile= *(++argv);
336			}
337		else if (strcmp(*argv,"-key") == 0)
338			{
339			if (--argc < 1) goto bad;
340			key= *(++argv);
341			}
342		else if (strcmp(*argv,"-cert") == 0)
343			{
344			if (--argc < 1) goto bad;
345			certfile= *(++argv);
346			}
347		else if (strcmp(*argv,"-in") == 0)
348			{
349			if (--argc < 1) goto bad;
350			infile= *(++argv);
351			req=1;
352			}
353		else if (strcmp(*argv,"-out") == 0)
354			{
355			if (--argc < 1) goto bad;
356			outfile= *(++argv);
357			}
358		else if (strcmp(*argv,"-outdir") == 0)
359			{
360			if (--argc < 1) goto bad;
361			outdir= *(++argv);
362			}
363		else if (strcmp(*argv,"-notext") == 0)
364			notext=1;
365		else if (strcmp(*argv,"-batch") == 0)
366			batch=1;
367		else if (strcmp(*argv,"-preserveDN") == 0)
368			preserve=1;
369		else if (strcmp(*argv,"-gencrl") == 0)
370			gencrl=1;
371		else if (strcmp(*argv,"-msie_hack") == 0)
372			msie_hack=1;
373		else if (strcmp(*argv,"-crldays") == 0)
374			{
375			if (--argc < 1) goto bad;
376			crldays= atol(*(++argv));
377			}
378		else if (strcmp(*argv,"-crlhours") == 0)
379			{
380			if (--argc < 1) goto bad;
381			crlhours= atol(*(++argv));
382			}
383		else if (strcmp(*argv,"-infiles") == 0)
384			{
385			argc--;
386			argv++;
387			req=1;
388			break;
389			}
390		else if (strcmp(*argv, "-ss_cert") == 0)
391			{
392			if (--argc < 1) goto bad;
393			ss_cert_file = *(++argv);
394			req=1;
395			}
396		else if (strcmp(*argv, "-spkac") == 0)
397			{
398			if (--argc < 1) goto bad;
399			spkac_file = *(++argv);
400			req=1;
401			}
402		else if (strcmp(*argv,"-revoke") == 0)
403			{
404			if (--argc < 1) goto bad;
405			infile= *(++argv);
406			dorevoke=1;
407			}
408		else if (strcmp(*argv,"-extensions") == 0)
409			{
410			if (--argc < 1) goto bad;
411			extensions= *(++argv);
412			}
413		else if (strcmp(*argv,"-crlexts") == 0)
414			{
415			if (--argc < 1) goto bad;
416			crl_ext= *(++argv);
417			}
418		else
419			{
420bad:
421			BIO_printf(bio_err,"unknown option %s\n",*argv);
422			badops=1;
423			break;
424			}
425		argc--;
426		argv++;
427		}
428
429	if (badops)
430		{
431		for (pp=ca_usage; (*pp != NULL); pp++)
432			BIO_printf(bio_err,*pp);
433		goto err;
434		}
435
436	ERR_load_crypto_strings();
437
438	/*****************************************************************/
439	if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
440	if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
441	if (configfile == NULL)
442		{
443		/* We will just use 'buf[0]' as a temporary buffer.  */
444#ifdef VMS
445		strncpy(buf[0],X509_get_default_cert_area(),
446			sizeof(buf[0])-1-sizeof(CONFIG_FILE));
447#else
448		strncpy(buf[0],X509_get_default_cert_area(),
449			sizeof(buf[0])-2-sizeof(CONFIG_FILE));
450		strcat(buf[0],"/");
451#endif
452		strcat(buf[0],CONFIG_FILE);
453		configfile=buf[0];
454		}
455
456	BIO_printf(bio_err,"Using configuration from %s\n",configfile);
457	if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
458		{
459		if (errorline <= 0)
460			BIO_printf(bio_err,"error loading the config file '%s'\n",
461				configfile);
462		else
463			BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
464				,errorline,configfile);
465		goto err;
466		}
467
468	/* Lets get the config section we are using */
469	if (section == NULL)
470		{
471		section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
472		if (section == NULL)
473			{
474			lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
475			goto err;
476			}
477		}
478
479	if (conf != NULL)
480		{
481		p=CONF_get_string(conf,NULL,"oid_file");
482		if (p != NULL)
483			{
484			BIO *oid_bio;
485
486			oid_bio=BIO_new_file(p,"r");
487			if (oid_bio == NULL)
488				{
489				/*
490				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
491				ERR_print_errors(bio_err);
492				*/
493				ERR_clear_error();
494				}
495			else
496				{
497				OBJ_create_objects(oid_bio);
498				BIO_free(oid_bio);
499				}
500			}
501		if(!add_oid_section(conf))
502			{
503			ERR_print_errors(bio_err);
504			goto err;
505			}
506		}
507
508	randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
509	app_RAND_load_file(randfile, bio_err, 0);
510
511	in=BIO_new(BIO_s_file());
512	out=BIO_new(BIO_s_file());
513	Sout=BIO_new(BIO_s_file());
514	Cout=BIO_new(BIO_s_file());
515	if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
516		{
517		ERR_print_errors(bio_err);
518		goto err;
519		}
520
521	/*****************************************************************/
522	/* we definitely need an public key, so lets get it */
523
524	if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
525		section,ENV_PRIVATE_KEY)) == NULL))
526		{
527		lookup_fail(section,ENV_PRIVATE_KEY);
528		goto err;
529		}
530	if (BIO_read_filename(in,keyfile) <= 0)
531		{
532		perror(keyfile);
533		BIO_printf(bio_err,"trying to load CA private key\n");
534		goto err;
535		}
536		pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
537		if(key) memset(key,0,strlen(key));
538	if (pkey == NULL)
539		{
540		BIO_printf(bio_err,"unable to load CA private key\n");
541		goto err;
542		}
543
544	/*****************************************************************/
545	/* we need a certificate */
546	if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
547		section,ENV_CERTIFICATE)) == NULL))
548		{
549		lookup_fail(section,ENV_CERTIFICATE);
550		goto err;
551		}
552        if (BIO_read_filename(in,certfile) <= 0)
553		{
554		perror(certfile);
555		BIO_printf(bio_err,"trying to load CA certificate\n");
556		goto err;
557		}
558	x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
559	if (x509 == NULL)
560		{
561		BIO_printf(bio_err,"unable to load CA certificate\n");
562		goto err;
563		}
564
565	if (!X509_check_private_key(x509,pkey))
566		{
567		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
568		goto err;
569		}
570
571	f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
572	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
573		preserve=1;
574	f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
575	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
576		msie_hack=1;
577
578	/*****************************************************************/
579	/* lookup where to write new certificates */
580	if ((outdir == NULL) && (req))
581		{
582		struct stat sb;
583
584		if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
585			== NULL)
586			{
587			BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
588			goto err;
589			}
590#ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
591	       filename.  In any case, stat(), below, will catch the problem
592	       if outdir is not a directory spec, and the fopen() or open()
593	       will catch an error if there is no write access.
594
595	       Presumably, this problem could also be solved by using the DEC
596	       C routines to convert the directory syntax to Unixly, and give
597	       that to access().  However, time's too short to do that just
598	       now.
599            */
600		if (access(outdir,R_OK|W_OK|X_OK) != 0)
601			{
602			BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
603			perror(outdir);
604			goto err;
605			}
606
607		if (stat(outdir,&sb) != 0)
608			{
609			BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
610			perror(outdir);
611			goto err;
612			}
613#ifdef S_IFDIR
614		if (!(sb.st_mode & S_IFDIR))
615			{
616			BIO_printf(bio_err,"%s need to be a directory\n",outdir);
617			perror(outdir);
618			goto err;
619			}
620#endif
621#endif
622		}
623
624	/*****************************************************************/
625	/* we need to load the database file */
626	if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
627		{
628		lookup_fail(section,ENV_DATABASE);
629		goto err;
630		}
631	if (BIO_read_filename(in,dbfile) <= 0)
632		{
633		perror(dbfile);
634		BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
635		goto err;
636		}
637	db=TXT_DB_read(in,DB_NUMBER);
638	if (db == NULL) goto err;
639
640	/* Lets check some fields */
641	for (i=0; i<sk_num(db->data); i++)
642		{
643		pp=(char **)sk_value(db->data,i);
644		if ((pp[DB_type][0] != DB_TYPE_REV) &&
645			(pp[DB_rev_date][0] != '\0'))
646			{
647			BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
648			goto err;
649			}
650		if ((pp[DB_type][0] == DB_TYPE_REV) &&
651			!check_time_format(pp[DB_rev_date]))
652			{
653			BIO_printf(bio_err,"entry %d: invalid revocation date\n",
654				i+1);
655			goto err;
656			}
657		if (!check_time_format(pp[DB_exp_date]))
658			{
659			BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
660			goto err;
661			}
662		p=pp[DB_serial];
663		j=strlen(p);
664		if ((j&1) || (j < 2))
665			{
666			BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
667			goto err;
668			}
669		while (*p)
670			{
671			if (!(	((*p >= '0') && (*p <= '9')) ||
672				((*p >= 'A') && (*p <= 'F')) ||
673				((*p >= 'a') && (*p <= 'f')))  )
674				{
675				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);
676				goto err;
677				}
678			p++;
679			}
680		}
681	if (verbose)
682		{
683		BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
684		TXT_DB_write(out,db);
685		BIO_printf(bio_err,"%d entries loaded from the database\n",
686			db->data->num);
687		BIO_printf(bio_err,"generating index\n");
688		}
689
690	if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
691		index_serial_cmp))
692		{
693		BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
694		goto err;
695		}
696
697	if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
698		index_name_cmp))
699		{
700		BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
701			db->error,db->arg1,db->arg2);
702		goto err;
703		}
704
705	/*****************************************************************/
706	if (req || gencrl)
707		{
708		if (outfile != NULL)
709			{
710
711			if (BIO_write_filename(Sout,outfile) <= 0)
712				{
713				perror(outfile);
714				goto err;
715				}
716			}
717		else
718			BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
719		}
720
721	if (req)
722		{
723		if ((md == NULL) && ((md=CONF_get_string(conf,
724			section,ENV_DEFAULT_MD)) == NULL))
725			{
726			lookup_fail(section,ENV_DEFAULT_MD);
727			goto err;
728			}
729		if ((dgst=EVP_get_digestbyname(md)) == NULL)
730			{
731			BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
732			goto err;
733			}
734		if (verbose)
735			BIO_printf(bio_err,"message digest is %s\n",
736				OBJ_nid2ln(dgst->type));
737		if ((policy == NULL) && ((policy=CONF_get_string(conf,
738			section,ENV_POLICY)) == NULL))
739			{
740			lookup_fail(section,ENV_POLICY);
741			goto err;
742			}
743		if (verbose)
744			BIO_printf(bio_err,"policy is %s\n",policy);
745
746		if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
747			== NULL)
748			{
749			lookup_fail(section,ENV_SERIAL);
750			goto err;
751			}
752		if(!extensions)
753			extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
754		if(extensions) {
755			/* Check syntax of file */
756			X509V3_CTX ctx;
757			X509V3_set_ctx_test(&ctx);
758			X509V3_set_conf_lhash(&ctx, conf);
759			if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
760				BIO_printf(bio_err,
761				 "Error Loading extension section %s\n",
762								 extensions);
763				ret = 1;
764				goto err;
765			}
766		}
767
768		if (startdate == NULL)
769			{
770			startdate=CONF_get_string(conf,section,
771				ENV_DEFAULT_STARTDATE);
772			}
773		if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
774			{
775			BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
776			goto err;
777			}
778		if (startdate == NULL) startdate="today";
779
780		if (enddate == NULL)
781			{
782			enddate=CONF_get_string(conf,section,
783				ENV_DEFAULT_ENDDATE);
784			}
785		if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
786			{
787			BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
788			goto err;
789			}
790
791		if (days == 0)
792			{
793			days=(int)CONF_get_number(conf,section,
794				ENV_DEFAULT_DAYS);
795			}
796		if (!enddate && (days == 0))
797			{
798			BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
799			goto err;
800			}
801
802		if ((serial=load_serial(serialfile)) == NULL)
803			{
804			BIO_printf(bio_err,"error while loading serial number\n");
805			goto err;
806			}
807		if (verbose)
808			{
809			if ((f=BN_bn2hex(serial)) == NULL) goto err;
810			BIO_printf(bio_err,"next serial number is %s\n",f);
811			Free(f);
812			}
813
814		if ((attribs=CONF_get_section(conf,policy)) == NULL)
815			{
816			BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
817			goto err;
818			}
819
820		if ((cert_sk=sk_new_null()) == NULL)
821			{
822			BIO_printf(bio_err,"Malloc failure\n");
823			goto err;
824			}
825		if (spkac_file != NULL)
826			{
827			total++;
828			j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
829				serial,startdate,enddate, days,extensions,conf,
830				verbose);
831			if (j < 0) goto err;
832			if (j > 0)
833				{
834				total_done++;
835				BIO_printf(bio_err,"\n");
836				if (!BN_add_word(serial,1)) goto err;
837				if (!sk_push(cert_sk,(char *)x))
838					{
839					BIO_printf(bio_err,"Malloc failure\n");
840					goto err;
841					}
842				if (outfile)
843					{
844					output_der = 1;
845					batch = 1;
846					}
847				}
848			}
849		if (ss_cert_file != NULL)
850			{
851			total++;
852			j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
853				db,serial,startdate,enddate,days,batch,
854				extensions,conf,verbose);
855			if (j < 0) goto err;
856			if (j > 0)
857				{
858				total_done++;
859				BIO_printf(bio_err,"\n");
860				if (!BN_add_word(serial,1)) goto err;
861				if (!sk_push(cert_sk,(char *)x))
862					{
863					BIO_printf(bio_err,"Malloc failure\n");
864					goto err;
865					}
866				}
867			}
868		if (infile != NULL)
869			{
870			total++;
871			j=certify(&x,infile,pkey,x509,dgst,attribs,db,
872				serial,startdate,enddate,days,batch,
873				extensions,conf,verbose);
874			if (j < 0) goto err;
875			if (j > 0)
876				{
877				total_done++;
878				BIO_printf(bio_err,"\n");
879				if (!BN_add_word(serial,1)) goto err;
880				if (!sk_push(cert_sk,(char *)x))
881					{
882					BIO_printf(bio_err,"Malloc failure\n");
883					goto err;
884					}
885				}
886			}
887		for (i=0; i<argc; i++)
888			{
889			total++;
890			j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
891				serial,startdate,enddate,days,batch,
892				extensions,conf,verbose);
893			if (j < 0) goto err;
894			if (j > 0)
895				{
896				total_done++;
897				BIO_printf(bio_err,"\n");
898				if (!BN_add_word(serial,1)) goto err;
899				if (!sk_push(cert_sk,(char *)x))
900					{
901					BIO_printf(bio_err,"Malloc failure\n");
902					goto err;
903					}
904				}
905			}
906		/* we have a stack of newly certified certificates
907		 * and a data base and serial number that need
908		 * updating */
909
910		if (sk_num(cert_sk) > 0)
911			{
912			if (!batch)
913				{
914				BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
915				(void)BIO_flush(bio_err);
916				buf[0][0]='\0';
917				fgets(buf[0],10,stdin);
918				if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
919					{
920					BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
921					ret=0;
922					goto err;
923					}
924				}
925
926			BIO_printf(bio_err,"Write out database with %d new entries\n",sk_num(cert_sk));
927
928			strncpy(buf[0],serialfile,BSIZE-4);
929
930#ifdef VMS
931			strcat(buf[0],"-new");
932#else
933			strcat(buf[0],".new");
934#endif
935
936			if (!save_serial(buf[0],serial)) goto err;
937
938			strncpy(buf[1],dbfile,BSIZE-4);
939
940#ifdef VMS
941			strcat(buf[1],"-new");
942#else
943			strcat(buf[1],".new");
944#endif
945
946			if (BIO_write_filename(out,buf[1]) <= 0)
947				{
948				perror(dbfile);
949				BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
950				goto err;
951				}
952			l=TXT_DB_write(out,db);
953			if (l <= 0) goto err;
954			}
955
956		if (verbose)
957			BIO_printf(bio_err,"writing new certificates\n");
958		for (i=0; i<sk_num(cert_sk); i++)
959			{
960			int k;
961			unsigned char *n;
962
963			x=(X509 *)sk_value(cert_sk,i);
964
965			j=x->cert_info->serialNumber->length;
966			p=(char *)x->cert_info->serialNumber->data;
967
968			strncpy(buf[2],outdir,BSIZE-(j*2)-6);
969
970#ifndef VMS
971			strcat(buf[2],"/");
972#endif
973
974			n=(unsigned char *)&(buf[2][strlen(buf[2])]);
975			if (j > 0)
976				{
977				for (k=0; k<j; k++)
978					{
979					sprintf((char *)n,"%02X",(unsigned char)*(p++));
980					n+=2;
981					}
982				}
983			else
984				{
985				*(n++)='0';
986				*(n++)='0';
987				}
988			*(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
989			*n='\0';
990			if (verbose)
991				BIO_printf(bio_err,"writing %s\n",buf[2]);
992
993			if (BIO_write_filename(Cout,buf[2]) <= 0)
994				{
995				perror(buf[2]);
996				goto err;
997				}
998			write_new_certificate(Cout,x, 0, notext);
999			write_new_certificate(Sout,x, output_der, notext);
1000			}
1001
1002		if (sk_num(cert_sk))
1003			{
1004			/* Rename the database and the serial file */
1005			strncpy(buf[2],serialfile,BSIZE-4);
1006
1007#ifdef VMS
1008			strcat(buf[2],"-old");
1009#else
1010			strcat(buf[2],".old");
1011#endif
1012
1013			BIO_free(in);
1014			BIO_free(out);
1015			in=NULL;
1016			out=NULL;
1017			if (rename(serialfile,buf[2]) < 0)
1018				{
1019				BIO_printf(bio_err,"unable to rename %s to %s\n",
1020					serialfile,buf[2]);
1021				perror("reason");
1022				goto err;
1023				}
1024			if (rename(buf[0],serialfile) < 0)
1025				{
1026				BIO_printf(bio_err,"unable to rename %s to %s\n",
1027					buf[0],serialfile);
1028				perror("reason");
1029				rename(buf[2],serialfile);
1030				goto err;
1031				}
1032
1033			strncpy(buf[2],dbfile,BSIZE-4);
1034
1035#ifdef VMS
1036			strcat(buf[2],"-old");
1037#else
1038			strcat(buf[2],".old");
1039#endif
1040
1041			if (rename(dbfile,buf[2]) < 0)
1042				{
1043				BIO_printf(bio_err,"unable to rename %s to %s\n",
1044					dbfile,buf[2]);
1045				perror("reason");
1046				goto err;
1047				}
1048			if (rename(buf[1],dbfile) < 0)
1049				{
1050				BIO_printf(bio_err,"unable to rename %s to %s\n",
1051					buf[1],dbfile);
1052				perror("reason");
1053				rename(buf[2],dbfile);
1054				goto err;
1055				}
1056			BIO_printf(bio_err,"Data Base Updated\n");
1057			}
1058		}
1059
1060	/*****************************************************************/
1061	if (gencrl)
1062		{
1063		if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1064		if(crl_ext) {
1065			/* Check syntax of file */
1066			X509V3_CTX ctx;
1067			X509V3_set_ctx_test(&ctx);
1068			X509V3_set_conf_lhash(&ctx, conf);
1069			if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1070				BIO_printf(bio_err,
1071				 "Error Loading CRL extension section %s\n",
1072								 crl_ext);
1073				ret = 1;
1074				goto err;
1075			}
1076		}
1077		if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1078
1079		if (!crldays && !crlhours)
1080			{
1081			crldays=CONF_get_number(conf,section,
1082				ENV_DEFAULT_CRL_DAYS);
1083			crlhours=CONF_get_number(conf,section,
1084				ENV_DEFAULT_CRL_HOURS);
1085			}
1086		if ((crldays == 0) && (crlhours == 0))
1087			{
1088			BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1089			goto err;
1090			}
1091
1092		if (verbose) BIO_printf(bio_err,"making CRL\n");
1093		if ((crl=X509_CRL_new()) == NULL) goto err;
1094		ci=crl->crl;
1095		X509_NAME_free(ci->issuer);
1096		ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1097		if (ci->issuer == NULL) goto err;
1098
1099		X509_gmtime_adj(ci->lastUpdate,0);
1100		if (ci->nextUpdate == NULL)
1101			ci->nextUpdate=ASN1_UTCTIME_new();
1102		X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1103
1104		for (i=0; i<sk_num(db->data); i++)
1105			{
1106			pp=(char **)sk_value(db->data,i);
1107			if (pp[DB_type][0] == DB_TYPE_REV)
1108				{
1109				if ((r=X509_REVOKED_new()) == NULL) goto err;
1110				ASN1_STRING_set((ASN1_STRING *)
1111					r->revocationDate,
1112					(unsigned char *)pp[DB_rev_date],
1113					strlen(pp[DB_rev_date]));
1114				/* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1115
1116				(void)BIO_reset(hex);
1117				if (!BIO_puts(hex,pp[DB_serial]))
1118					goto err;
1119				if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1120					buf[0],BSIZE)) goto err;
1121
1122				sk_X509_REVOKED_push(ci->revoked,r);
1123				}
1124			}
1125		/* sort the data so it will be written in serial
1126		 * number order */
1127		sk_X509_REVOKED_sort(ci->revoked);
1128		for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1129			{
1130			r=sk_X509_REVOKED_value(ci->revoked,i);
1131			r->sequence=i;
1132			}
1133
1134		/* we now have a CRL */
1135		if (verbose) BIO_printf(bio_err,"signing CRL\n");
1136		if (md != NULL)
1137			{
1138			if ((dgst=EVP_get_digestbyname(md)) == NULL)
1139				{
1140				BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1141				goto err;
1142				}
1143			}
1144		else
1145		    {
1146#ifndef NO_DSA
1147		    if (pkey->type == EVP_PKEY_DSA)
1148			dgst=EVP_dss1();
1149		    else
1150#endif
1151			dgst=EVP_md5();
1152		    }
1153
1154		/* Add any extensions asked for */
1155
1156		if(crl_ext) {
1157		    X509V3_CTX crlctx;
1158		    if (ci->version == NULL)
1159		    if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1160		    ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1161		    X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1162		    X509V3_set_conf_lhash(&crlctx, conf);
1163
1164		    if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1165						 crl_ext, crl)) goto err;
1166		}
1167
1168		if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1169
1170		PEM_write_bio_X509_CRL(Sout,crl);
1171		}
1172	/*****************************************************************/
1173	if (dorevoke)
1174		{
1175		if (infile == NULL)
1176			{
1177			BIO_printf(bio_err,"no input files\n");
1178			goto err;
1179			}
1180		else
1181			{
1182			X509 *revcert;
1183			if (BIO_read_filename(in,infile) <= 0)
1184				{
1185				perror(infile);
1186				BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1187				goto err;
1188				}
1189			revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1190			if (revcert == NULL)
1191				{
1192				BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1193				goto err;
1194				}
1195			j=do_revoke(revcert,db);
1196			if (j <= 0) goto err;
1197			X509_free(revcert);
1198
1199			strncpy(buf[0],dbfile,BSIZE-4);
1200			strcat(buf[0],".new");
1201			if (BIO_write_filename(out,buf[0]) <= 0)
1202				{
1203				perror(dbfile);
1204				BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1205				goto err;
1206				}
1207			j=TXT_DB_write(out,db);
1208			if (j <= 0) goto err;
1209			strncpy(buf[1],dbfile,BSIZE-4);
1210			strcat(buf[1],".old");
1211			if (rename(dbfile,buf[1]) < 0)
1212				{
1213				BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1214				perror("reason");
1215				goto err;
1216				}
1217			if (rename(buf[0],dbfile) < 0)
1218				{
1219				BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1220				perror("reason");
1221				rename(buf[1],dbfile);
1222				goto err;
1223				}
1224			BIO_printf(bio_err,"Data Base Updated\n");
1225			}
1226		}
1227	/*****************************************************************/
1228	ret=0;
1229err:
1230	BIO_free(hex);
1231	BIO_free(Cout);
1232	BIO_free(Sout);
1233	BIO_free(out);
1234	BIO_free(in);
1235
1236	sk_pop_free(cert_sk,X509_free);
1237
1238	if (ret) ERR_print_errors(bio_err);
1239	app_RAND_write_file(randfile, bio_err);
1240	BN_free(serial);
1241	TXT_DB_free(db);
1242	EVP_PKEY_free(pkey);
1243	X509_free(x509);
1244	X509_CRL_free(crl);
1245	CONF_free(conf);
1246	OBJ_cleanup();
1247	EXIT(ret);
1248	}
1249
1250static void lookup_fail(char *name, char *tag)
1251	{
1252	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1253	}
1254
1255static unsigned long index_serial_hash(char **a)
1256	{
1257	char *n;
1258
1259	n=a[DB_serial];
1260	while (*n == '0') n++;
1261	return(lh_strhash(n));
1262	}
1263
1264static int index_serial_cmp(char **a, char **b)
1265	{
1266	char *aa,*bb;
1267
1268	for (aa=a[DB_serial]; *aa == '0'; aa++);
1269	for (bb=b[DB_serial]; *bb == '0'; bb++);
1270	return(strcmp(aa,bb));
1271	}
1272
1273static unsigned long index_name_hash(char **a)
1274	{ return(lh_strhash(a[DB_name])); }
1275
1276static int index_name_qual(char **a)
1277	{ return(a[0][0] == 'V'); }
1278
1279static int index_name_cmp(char **a, char **b)
1280	{ return(strcmp(a[DB_name],
1281	     b[DB_name])); }
1282
1283static BIGNUM *load_serial(char *serialfile)
1284	{
1285	BIO *in=NULL;
1286	BIGNUM *ret=NULL;
1287	MS_STATIC char buf[1024];
1288	ASN1_INTEGER *ai=NULL;
1289
1290	if ((in=BIO_new(BIO_s_file())) == NULL)
1291		{
1292		ERR_print_errors(bio_err);
1293		goto err;
1294		}
1295
1296	if (BIO_read_filename(in,serialfile) <= 0)
1297		{
1298		perror(serialfile);
1299		goto err;
1300		}
1301	ai=ASN1_INTEGER_new();
1302	if (ai == NULL) goto err;
1303	if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1304		{
1305		BIO_printf(bio_err,"unable to load number from %s\n",
1306			serialfile);
1307		goto err;
1308		}
1309	ret=ASN1_INTEGER_to_BN(ai,NULL);
1310	if (ret == NULL)
1311		{
1312		BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1313		goto err;
1314		}
1315err:
1316	if (in != NULL) BIO_free(in);
1317	if (ai != NULL) ASN1_INTEGER_free(ai);
1318	return(ret);
1319	}
1320
1321static int save_serial(char *serialfile, BIGNUM *serial)
1322	{
1323	BIO *out;
1324	int ret=0;
1325	ASN1_INTEGER *ai=NULL;
1326
1327	out=BIO_new(BIO_s_file());
1328	if (out == NULL)
1329		{
1330		ERR_print_errors(bio_err);
1331		goto err;
1332		}
1333	if (BIO_write_filename(out,serialfile) <= 0)
1334		{
1335		perror(serialfile);
1336		goto err;
1337		}
1338
1339	if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1340		{
1341		BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1342		goto err;
1343		}
1344	i2a_ASN1_INTEGER(out,ai);
1345	BIO_puts(out,"\n");
1346	ret=1;
1347err:
1348	if (out != NULL) BIO_free(out);
1349	if (ai != NULL) ASN1_INTEGER_free(ai);
1350	return(ret);
1351	}
1352
1353static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1354	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1355	     BIGNUM *serial, char *startdate, char *enddate, int days,
1356	     int batch, char *ext_sect, LHASH *lconf, int verbose)
1357	{
1358	X509_REQ *req=NULL;
1359	BIO *in=NULL;
1360	EVP_PKEY *pktmp=NULL;
1361	int ok= -1,i;
1362
1363	in=BIO_new(BIO_s_file());
1364
1365	if (BIO_read_filename(in,infile) <= 0)
1366		{
1367		perror(infile);
1368		goto err;
1369		}
1370	if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1371		{
1372		BIO_printf(bio_err,"Error reading certificate request in %s\n",
1373			infile);
1374		goto err;
1375		}
1376	if (verbose)
1377		X509_REQ_print(bio_err,req);
1378
1379	BIO_printf(bio_err,"Check that the request matches the signature\n");
1380
1381	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1382		{
1383		BIO_printf(bio_err,"error unpacking public key\n");
1384		goto err;
1385		}
1386	i=X509_REQ_verify(req,pktmp);
1387	EVP_PKEY_free(pktmp);
1388	if (i < 0)
1389		{
1390		ok=0;
1391		BIO_printf(bio_err,"Signature verification problems....\n");
1392		goto err;
1393		}
1394	if (i == 0)
1395		{
1396		ok=0;
1397		BIO_printf(bio_err,"Signature did not match the certificate request\n");
1398		goto err;
1399		}
1400	else
1401		BIO_printf(bio_err,"Signature ok\n");
1402
1403	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1404		days,batch,verbose,req,ext_sect,lconf);
1405
1406err:
1407	if (req != NULL) X509_REQ_free(req);
1408	if (in != NULL) BIO_free(in);
1409	return(ok);
1410	}
1411
1412static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1413	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1414	     BIGNUM *serial, char *startdate, char *enddate, int days,
1415	     int batch, char *ext_sect, LHASH *lconf, int verbose)
1416	{
1417	X509 *req=NULL;
1418	X509_REQ *rreq=NULL;
1419	BIO *in=NULL;
1420	EVP_PKEY *pktmp=NULL;
1421	int ok= -1,i;
1422
1423	in=BIO_new(BIO_s_file());
1424
1425	if (BIO_read_filename(in,infile) <= 0)
1426		{
1427		perror(infile);
1428		goto err;
1429		}
1430	if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1431		{
1432		BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1433		goto err;
1434		}
1435	if (verbose)
1436		X509_print(bio_err,req);
1437
1438	BIO_printf(bio_err,"Check that the request matches the signature\n");
1439
1440	if ((pktmp=X509_get_pubkey(req)) == NULL)
1441		{
1442		BIO_printf(bio_err,"error unpacking public key\n");
1443		goto err;
1444		}
1445	i=X509_verify(req,pktmp);
1446	EVP_PKEY_free(pktmp);
1447	if (i < 0)
1448		{
1449		ok=0;
1450		BIO_printf(bio_err,"Signature verification problems....\n");
1451		goto err;
1452		}
1453	if (i == 0)
1454		{
1455		ok=0;
1456		BIO_printf(bio_err,"Signature did not match the certificate\n");
1457		goto err;
1458		}
1459	else
1460		BIO_printf(bio_err,"Signature ok\n");
1461
1462	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1463		goto err;
1464
1465	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1466		batch,verbose,rreq,ext_sect,lconf);
1467
1468err:
1469	if (rreq != NULL) X509_REQ_free(rreq);
1470	if (req != NULL) X509_free(req);
1471	if (in != NULL) BIO_free(in);
1472	return(ok);
1473	}
1474
1475static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1476	     STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1477	     char *startdate, char *enddate, int days, int batch, int verbose,
1478	     X509_REQ *req, char *ext_sect, LHASH *lconf)
1479	{
1480	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1481	ASN1_UTCTIME *tm,*tmptm;
1482	ASN1_STRING *str,*str2;
1483	ASN1_OBJECT *obj;
1484	X509 *ret=NULL;
1485	X509_CINF *ci;
1486	X509_NAME_ENTRY *ne;
1487	X509_NAME_ENTRY *tne,*push;
1488	EVP_PKEY *pktmp;
1489	int ok= -1,i,j,last,nid;
1490	char *p;
1491	CONF_VALUE *cv;
1492	char *row[DB_NUMBER],**rrow,**irow=NULL;
1493	char buf[25],*pbuf;
1494
1495	tmptm=ASN1_UTCTIME_new();
1496	if (tmptm == NULL)
1497		{
1498		BIO_printf(bio_err,"malloc error\n");
1499		return(0);
1500		}
1501
1502	for (i=0; i<DB_NUMBER; i++)
1503		row[i]=NULL;
1504
1505	BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1506	name=X509_REQ_get_subject_name(req);
1507	for (i=0; i<X509_NAME_entry_count(name); i++)
1508		{
1509		ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1510		obj=X509_NAME_ENTRY_get_object(ne);
1511		j=i2a_ASN1_OBJECT(bio_err,obj);
1512		str=X509_NAME_ENTRY_get_data(ne);
1513		pbuf=buf;
1514		for (j=22-j; j>0; j--)
1515			*(pbuf++)=' ';
1516		*(pbuf++)=':';
1517		*(pbuf++)='\0';
1518		BIO_puts(bio_err,buf);
1519
1520		if (msie_hack)
1521			{
1522			/* assume all type should be strings */
1523			nid=OBJ_obj2nid(ne->object);
1524
1525			if (str->type == V_ASN1_UNIVERSALSTRING)
1526				ASN1_UNIVERSALSTRING_to_string(str);
1527
1528			if ((str->type == V_ASN1_IA5STRING) &&
1529				(nid != NID_pkcs9_emailAddress))
1530				str->type=V_ASN1_T61STRING;
1531
1532			if ((nid == NID_pkcs9_emailAddress) &&
1533				(str->type == V_ASN1_PRINTABLESTRING))
1534				str->type=V_ASN1_IA5STRING;
1535			}
1536
1537		if (str->type == V_ASN1_PRINTABLESTRING)
1538			BIO_printf(bio_err,"PRINTABLE:'");
1539		else if (str->type == V_ASN1_T61STRING)
1540			BIO_printf(bio_err,"T61STRING:'");
1541		else if (str->type == V_ASN1_IA5STRING)
1542			BIO_printf(bio_err,"IA5STRING:'");
1543		else if (str->type == V_ASN1_UNIVERSALSTRING)
1544			BIO_printf(bio_err,"UNIVERSALSTRING:'");
1545		else
1546			BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1547
1548		/* check some things */
1549		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1550			(str->type != V_ASN1_IA5STRING))
1551			{
1552			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1553			goto err;
1554			}
1555		j=ASN1_PRINTABLE_type(str->data,str->length);
1556		if (	((j == V_ASN1_T61STRING) &&
1557			 (str->type != V_ASN1_T61STRING)) ||
1558			((j == V_ASN1_IA5STRING) &&
1559			 (str->type == V_ASN1_PRINTABLESTRING)))
1560			{
1561			BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1562			goto err;
1563			}
1564
1565		p=(char *)str->data;
1566		for (j=str->length; j>0; j--)
1567			{
1568			if ((*p >= ' ') && (*p <= '~'))
1569				BIO_printf(bio_err,"%c",*p);
1570			else if (*p & 0x80)
1571				BIO_printf(bio_err,"\\0x%02X",*p);
1572			else if ((unsigned char)*p == 0xf7)
1573				BIO_printf(bio_err,"^?");
1574			else	BIO_printf(bio_err,"^%c",*p+'@');
1575			p++;
1576			}
1577		BIO_printf(bio_err,"'\n");
1578		}
1579
1580	/* Ok, now we check the 'policy' stuff. */
1581	if ((subject=X509_NAME_new()) == NULL)
1582		{
1583		BIO_printf(bio_err,"Malloc failure\n");
1584		goto err;
1585		}
1586
1587	/* take a copy of the issuer name before we mess with it. */
1588	CAname=X509_NAME_dup(x509->cert_info->subject);
1589	if (CAname == NULL) goto err;
1590	str=str2=NULL;
1591
1592	for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1593		{
1594		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1595		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1596			{
1597			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1598			goto err;
1599			}
1600		obj=OBJ_nid2obj(j);
1601
1602		last= -1;
1603		for (;;)
1604			{
1605			/* lookup the object in the supplied name list */
1606			j=X509_NAME_get_index_by_OBJ(name,obj,last);
1607			if (j < 0)
1608				{
1609				if (last != -1) break;
1610				tne=NULL;
1611				}
1612			else
1613				{
1614				tne=X509_NAME_get_entry(name,j);
1615				}
1616			last=j;
1617
1618			/* depending on the 'policy', decide what to do. */
1619			push=NULL;
1620			if (strcmp(cv->value,"optional") == 0)
1621				{
1622				if (tne != NULL)
1623					push=tne;
1624				}
1625			else if (strcmp(cv->value,"supplied") == 0)
1626				{
1627				if (tne == NULL)
1628					{
1629					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1630					goto err;
1631					}
1632				else
1633					push=tne;
1634				}
1635			else if (strcmp(cv->value,"match") == 0)
1636				{
1637				int last2;
1638
1639				if (tne == NULL)
1640					{
1641					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1642					goto err;
1643					}
1644
1645				last2= -1;
1646
1647again2:
1648				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1649				if ((j < 0) && (last2 == -1))
1650					{
1651					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1652					goto err;
1653					}
1654				if (j >= 0)
1655					{
1656					push=X509_NAME_get_entry(CAname,j);
1657					str=X509_NAME_ENTRY_get_data(tne);
1658					str2=X509_NAME_ENTRY_get_data(push);
1659					last2=j;
1660					if (ASN1_STRING_cmp(str,str2) != 0)
1661						goto again2;
1662					}
1663				if (j < 0)
1664					{
1665					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));
1666					goto err;
1667					}
1668				}
1669			else
1670				{
1671				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1672				goto err;
1673				}
1674
1675			if (push != NULL)
1676				{
1677				if (!X509_NAME_add_entry(subject,push, -1, 0))
1678					{
1679					if (push != NULL)
1680						X509_NAME_ENTRY_free(push);
1681					BIO_printf(bio_err,"Malloc failure\n");
1682					goto err;
1683					}
1684				}
1685			if (j < 0) break;
1686			}
1687		}
1688
1689	if (preserve)
1690		{
1691		X509_NAME_free(subject);
1692		subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1693		if (subject == NULL) goto err;
1694		}
1695
1696	if (verbose)
1697		BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1698
1699	row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1700	row[DB_serial]=BN_bn2hex(serial);
1701	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1702		{
1703		BIO_printf(bio_err,"Malloc failure\n");
1704		goto err;
1705		}
1706
1707	rrow=TXT_DB_get_by_index(db,DB_name,row);
1708	if (rrow != NULL)
1709		{
1710		BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1711			row[DB_name]);
1712		}
1713	else
1714		{
1715		rrow=TXT_DB_get_by_index(db,DB_serial,row);
1716		if (rrow != NULL)
1717			{
1718			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1719				row[DB_serial]);
1720			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1721			}
1722		}
1723
1724	if (rrow != NULL)
1725		{
1726		BIO_printf(bio_err,
1727			"The matching entry has the following details\n");
1728		if (rrow[DB_type][0] == 'E')
1729			p="Expired";
1730		else if (rrow[DB_type][0] == 'R')
1731			p="Revoked";
1732		else if (rrow[DB_type][0] == 'V')
1733			p="Valid";
1734		else
1735			p="\ninvalid type, Data base error\n";
1736		BIO_printf(bio_err,"Type	  :%s\n",p);;
1737		if (rrow[DB_type][0] == 'R')
1738			{
1739			p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1740			BIO_printf(bio_err,"Was revoked on:%s\n",p);
1741			}
1742		p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1743		BIO_printf(bio_err,"Expires on    :%s\n",p);
1744		p=rrow[DB_serial]; if (p == NULL) p="undef";
1745		BIO_printf(bio_err,"Serial Number :%s\n",p);
1746		p=rrow[DB_file]; if (p == NULL) p="undef";
1747		BIO_printf(bio_err,"File name     :%s\n",p);
1748		p=rrow[DB_name]; if (p == NULL) p="undef";
1749		BIO_printf(bio_err,"Subject Name  :%s\n",p);
1750		ok= -1; /* This is now a 'bad' error. */
1751		goto err;
1752		}
1753
1754	/* We are now totally happy, lets make and sign the certificate */
1755	if (verbose)
1756		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1757
1758	if ((ret=X509_new()) == NULL) goto err;
1759	ci=ret->cert_info;
1760
1761#ifdef X509_V3
1762	/* Make it an X509 v3 certificate. */
1763	if (!X509_set_version(x509,2)) goto err;
1764#endif
1765
1766	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1767		goto err;
1768	if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1769		goto err;
1770
1771	BIO_printf(bio_err,"Certificate is to be certified until ");
1772	if (strcmp(startdate,"today") == 0)
1773		X509_gmtime_adj(X509_get_notBefore(ret),0);
1774	else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1775
1776	if (enddate == NULL)
1777		X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1778	else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1779
1780	ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1781	if(days) BIO_printf(bio_err," (%d days)",days);
1782	BIO_printf(bio_err, "\n");
1783
1784	if (!X509_set_subject_name(ret,subject)) goto err;
1785
1786	pktmp=X509_REQ_get_pubkey(req);
1787	i = X509_set_pubkey(ret,pktmp);
1788	EVP_PKEY_free(pktmp);
1789	if (!i) goto err;
1790
1791	/* Lets add the extensions, if there are any */
1792	if (ext_sect)
1793		{
1794		X509V3_CTX ctx;
1795		if (ci->version == NULL)
1796			if ((ci->version=ASN1_INTEGER_new()) == NULL)
1797				goto err;
1798		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1799
1800		/* Free the current entries if any, there should not
1801		 * be any I believe */
1802		if (ci->extensions != NULL)
1803			sk_X509_EXTENSION_pop_free(ci->extensions,
1804						   X509_EXTENSION_free);
1805
1806		ci->extensions = NULL;
1807
1808		X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1809		X509V3_set_conf_lhash(&ctx, lconf);
1810
1811		if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1812
1813		}
1814
1815
1816	if (!batch)
1817		{
1818		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1819		(void)BIO_flush(bio_err);
1820		buf[0]='\0';
1821		fgets(buf,sizeof(buf)-1,stdin);
1822		if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1823			{
1824			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1825			ok=0;
1826			goto err;
1827			}
1828		}
1829
1830
1831#ifndef NO_DSA
1832	if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1833	pktmp=X509_get_pubkey(ret);
1834	if (EVP_PKEY_missing_parameters(pktmp) &&
1835		!EVP_PKEY_missing_parameters(pkey))
1836		EVP_PKEY_copy_parameters(pktmp,pkey);
1837	EVP_PKEY_free(pktmp);
1838#endif
1839
1840	if (!X509_sign(ret,pkey,dgst))
1841		goto err;
1842
1843	/* We now just add it to the database */
1844	row[DB_type]=(char *)Malloc(2);
1845
1846	tm=X509_get_notAfter(ret);
1847	row[DB_exp_date]=(char *)Malloc(tm->length+1);
1848	memcpy(row[DB_exp_date],tm->data,tm->length);
1849	row[DB_exp_date][tm->length]='\0';
1850
1851	row[DB_rev_date]=NULL;
1852
1853	/* row[DB_serial] done already */
1854	row[DB_file]=(char *)Malloc(8);
1855	/* row[DB_name] done already */
1856
1857	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1858		(row[DB_file] == NULL))
1859		{
1860		BIO_printf(bio_err,"Malloc failure\n");
1861		goto err;
1862		}
1863	strcpy(row[DB_file],"unknown");
1864	row[DB_type][0]='V';
1865	row[DB_type][1]='\0';
1866
1867	if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1868		{
1869		BIO_printf(bio_err,"Malloc failure\n");
1870		goto err;
1871		}
1872
1873	for (i=0; i<DB_NUMBER; i++)
1874		{
1875		irow[i]=row[i];
1876		row[i]=NULL;
1877		}
1878	irow[DB_NUMBER]=NULL;
1879
1880	if (!TXT_DB_insert(db,irow))
1881		{
1882		BIO_printf(bio_err,"failed to update database\n");
1883		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1884		goto err;
1885		}
1886	ok=1;
1887err:
1888	for (i=0; i<DB_NUMBER; i++)
1889		if (row[i] != NULL) Free(row[i]);
1890
1891	if (CAname != NULL)
1892		X509_NAME_free(CAname);
1893	if (subject != NULL)
1894		X509_NAME_free(subject);
1895	if (tmptm != NULL)
1896		ASN1_UTCTIME_free(tmptm);
1897	if (ok <= 0)
1898		{
1899		if (ret != NULL) X509_free(ret);
1900		ret=NULL;
1901		}
1902	else
1903		*xret=ret;
1904	return(ok);
1905	}
1906
1907static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1908	{
1909
1910	if (output_der)
1911		{
1912		(void)i2d_X509_bio(bp,x);
1913		return;
1914		}
1915#if 0
1916	/* ??? Not needed since X509_print prints all this stuff anyway */
1917	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1918	BIO_printf(bp,"issuer :%s\n",f);
1919
1920	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1921	BIO_printf(bp,"subject:%s\n",f);
1922
1923	BIO_puts(bp,"serial :");
1924	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1925	BIO_puts(bp,"\n\n");
1926#endif
1927	if(!notext)X509_print(bp,x);
1928	PEM_write_bio_X509(bp,x);
1929	}
1930
1931static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1932	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1933	     BIGNUM *serial, char *startdate, char *enddate, int days,
1934	     char *ext_sect, LHASH *lconf, int verbose)
1935	{
1936	STACK_OF(CONF_VALUE) *sk=NULL;
1937	LHASH *parms=NULL;
1938	X509_REQ *req=NULL;
1939	CONF_VALUE *cv=NULL;
1940	NETSCAPE_SPKI *spki = NULL;
1941	X509_REQ_INFO *ri;
1942	char *type,*buf;
1943	EVP_PKEY *pktmp=NULL;
1944	X509_NAME *n=NULL;
1945	X509_NAME_ENTRY *ne=NULL;
1946	int ok= -1,i,j;
1947	long errline;
1948	int nid;
1949
1950	/*
1951	 * Load input file into a hash table.  (This is just an easy
1952	 * way to read and parse the file, then put it into a convenient
1953	 * STACK format).
1954	 */
1955	parms=CONF_load(NULL,infile,&errline);
1956	if (parms == NULL)
1957		{
1958		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
1959		ERR_print_errors(bio_err);
1960		goto err;
1961		}
1962
1963	sk=CONF_get_section(parms, "default");
1964	if (sk_CONF_VALUE_num(sk) == 0)
1965		{
1966		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
1967		CONF_free(parms);
1968		goto err;
1969		}
1970
1971	/*
1972	 * Now create a dummy X509 request structure.  We don't actually
1973	 * have an X509 request, but we have many of the components
1974	 * (a public key, various DN components).  The idea is that we
1975	 * put these components into the right X509 request structure
1976	 * and we can use the same code as if you had a real X509 request.
1977	 */
1978	req=X509_REQ_new();
1979	if (req == NULL)
1980		{
1981		ERR_print_errors(bio_err);
1982		goto err;
1983		}
1984
1985	/*
1986	 * Build up the subject name set.
1987	 */
1988	ri=req->req_info;
1989	n = ri->subject;
1990
1991	for (i = 0; ; i++)
1992		{
1993		if (sk_CONF_VALUE_num(sk) <= i) break;
1994
1995		cv=sk_CONF_VALUE_value(sk,i);
1996		type=cv->name;
1997		/* Skip past any leading X. X: X, etc to allow for
1998		 * multiple instances
1999		 */
2000		for(buf = cv->name; *buf ; buf++)
2001			if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2002					buf++;
2003					if(*buf) type = buf;
2004					break;
2005		}
2006
2007		buf=cv->value;
2008		if ((nid=OBJ_txt2nid(type)) == NID_undef)
2009			{
2010			if (strcmp(type, "SPKAC") == 0)
2011				{
2012				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2013				if (spki == NULL)
2014					{
2015					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2016					ERR_print_errors(bio_err);
2017					goto err;
2018					}
2019				}
2020			continue;
2021			}
2022
2023		j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2024		if (fix_data(nid, &j) == 0)
2025			{
2026			BIO_printf(bio_err,
2027				"invalid characters in string %s\n",buf);
2028			goto err;
2029			}
2030
2031		if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2032			(unsigned char *)buf,
2033			strlen(buf))) == NULL)
2034			goto err;
2035
2036		if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2037		}
2038	if (spki == NULL)
2039		{
2040		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2041			infile);
2042		goto err;
2043		}
2044
2045	/*
2046	 * Now extract the key from the SPKI structure.
2047	 */
2048
2049	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2050
2051	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2052		{
2053		BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2054		goto err;
2055		}
2056
2057	j = NETSCAPE_SPKI_verify(spki, pktmp);
2058	if (j <= 0)
2059		{
2060		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2061		goto err;
2062		}
2063	BIO_printf(bio_err,"Signature ok\n");
2064
2065	X509_REQ_set_pubkey(req,pktmp);
2066	EVP_PKEY_free(pktmp);
2067	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2068		   days,1,verbose,req,ext_sect,lconf);
2069err:
2070	if (req != NULL) X509_REQ_free(req);
2071	if (parms != NULL) CONF_free(parms);
2072	if (spki != NULL) NETSCAPE_SPKI_free(spki);
2073	if (ne != NULL) X509_NAME_ENTRY_free(ne);
2074
2075	return(ok);
2076	}
2077
2078static int fix_data(int nid, int *type)
2079	{
2080	if (nid == NID_pkcs9_emailAddress)
2081		*type=V_ASN1_IA5STRING;
2082	if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2083		*type=V_ASN1_T61STRING;
2084	if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2085		*type=V_ASN1_T61STRING;
2086	if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2087		return(0);
2088	if (nid == NID_pkcs9_unstructuredName)
2089		*type=V_ASN1_IA5STRING;
2090	return(1);
2091	}
2092
2093static int check_time_format(char *str)
2094	{
2095	ASN1_UTCTIME tm;
2096
2097	tm.data=(unsigned char *)str;
2098	tm.length=strlen(str);
2099	tm.type=V_ASN1_UTCTIME;
2100	return(ASN1_UTCTIME_check(&tm));
2101	}
2102
2103static int add_oid_section(LHASH *hconf)
2104{
2105	char *p;
2106	STACK_OF(CONF_VALUE) *sktmp;
2107	CONF_VALUE *cnf;
2108	int i;
2109	if(!(p=CONF_get_string(hconf,NULL,"oid_section"))) return 1;
2110	if(!(sktmp = CONF_get_section(hconf, p))) {
2111		BIO_printf(bio_err, "problem loading oid section %s\n", p);
2112		return 0;
2113	}
2114	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
2115		cnf = sk_CONF_VALUE_value(sktmp, i);
2116		if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
2117			BIO_printf(bio_err, "problem creating object %s=%s\n",
2118							 cnf->name, cnf->value);
2119			return 0;
2120		}
2121	}
2122	return 1;
2123}
2124
2125static int do_revoke(X509 *x509, TXT_DB *db)
2126{
2127	ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2128	char *row[DB_NUMBER],**rrow,**irow;
2129	BIGNUM *bn = NULL;
2130	int ok=-1,i;
2131
2132	for (i=0; i<DB_NUMBER; i++)
2133		row[i]=NULL;
2134	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2135	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2136	row[DB_serial]=BN_bn2hex(bn);
2137	BN_free(bn);
2138	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2139		{
2140		BIO_printf(bio_err,"Malloc failure\n");
2141		goto err;
2142		}
2143	/* We have to lookup by serial number because name lookup
2144	 * skips revoked certs
2145 	 */
2146	rrow=TXT_DB_get_by_index(db,DB_serial,row);
2147	if (rrow == NULL)
2148		{
2149		BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2150
2151		/* We now just add it to the database */
2152		row[DB_type]=(char *)Malloc(2);
2153
2154		tm=X509_get_notAfter(x509);
2155		row[DB_exp_date]=(char *)Malloc(tm->length+1);
2156		memcpy(row[DB_exp_date],tm->data,tm->length);
2157		row[DB_exp_date][tm->length]='\0';
2158
2159		row[DB_rev_date]=NULL;
2160
2161		/* row[DB_serial] done already */
2162		row[DB_file]=(char *)Malloc(8);
2163
2164		/* row[DB_name] done already */
2165
2166		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2167			(row[DB_file] == NULL))
2168			{
2169			BIO_printf(bio_err,"Malloc failure\n");
2170			goto err;
2171			}
2172		strcpy(row[DB_file],"unknown");
2173		row[DB_type][0]='V';
2174		row[DB_type][1]='\0';
2175
2176		if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2177			{
2178			BIO_printf(bio_err,"Malloc failure\n");
2179			goto err;
2180			}
2181
2182		for (i=0; i<DB_NUMBER; i++)
2183			{
2184			irow[i]=row[i];
2185			row[i]=NULL;
2186			}
2187		irow[DB_NUMBER]=NULL;
2188
2189		if (!TXT_DB_insert(db,irow))
2190			{
2191			BIO_printf(bio_err,"failed to update database\n");
2192			BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2193			goto err;
2194			}
2195
2196		/* Revoke Certificate */
2197		ok = do_revoke(x509,db);
2198
2199		goto err;
2200
2201		}
2202	else if (index_name_cmp(row,rrow))
2203		{
2204		BIO_printf(bio_err,"ERROR:name does not match %s\n",
2205			   row[DB_name]);
2206		goto err;
2207		}
2208	else if (rrow[DB_type][0]=='R')
2209		{
2210		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2211			   row[DB_serial]);
2212		goto err;
2213		}
2214	else
2215		{
2216		BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2217		revtm = ASN1_UTCTIME_new();
2218		revtm=X509_gmtime_adj(revtm,0);
2219		rrow[DB_type][0]='R';
2220		rrow[DB_type][1]='\0';
2221		rrow[DB_rev_date]=(char *)Malloc(revtm->length+1);
2222		memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2223		rrow[DB_rev_date][revtm->length]='\0';
2224		ASN1_UTCTIME_free(revtm);
2225		}
2226	ok=1;
2227err:
2228	for (i=0; i<DB_NUMBER; i++)
2229		{
2230		if (row[i] != NULL)
2231			Free(row[i]);
2232		}
2233	return(ok);
2234}
2235
2236