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