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