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