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