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 			ERR_clear_error();
   1412 			}
   1413 		if ((crldays == 0) && (crlhours == 0) && (crlsec == 0))
   1414 			{
   1415 			BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
   1416 			goto err;
   1417 			}
   1418 
   1419 		if (verbose) BIO_printf(bio_err,"making CRL\n");
   1420 		if ((crl=X509_CRL_new()) == NULL) goto err;
   1421 		if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
   1422 
   1423 		tmptm = ASN1_TIME_new();
   1424 		if (!tmptm) goto err;
   1425 		X509_gmtime_adj(tmptm,0);
   1426 		X509_CRL_set_lastUpdate(crl, tmptm);
   1427 		if (!X509_time_adj_ex(tmptm, crldays, crlhours*60*60 + crlsec,
   1428 			NULL))
   1429 			{
   1430 			BIO_puts(bio_err, "error setting CRL nextUpdate\n");
   1431 			goto err;
   1432 			}
   1433 		X509_CRL_set_nextUpdate(crl, tmptm);
   1434 
   1435 		ASN1_TIME_free(tmptm);
   1436 
   1437 		for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
   1438 			{
   1439 			pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
   1440 			if (pp[DB_type][0] == DB_TYPE_REV)
   1441 				{
   1442 				if ((r=X509_REVOKED_new()) == NULL) goto err;
   1443 				j = make_revoked(r, pp[DB_rev_date]);
   1444 				if (!j) goto err;
   1445 				if (j == 2) crl_v2 = 1;
   1446 				if (!BN_hex2bn(&serial, pp[DB_serial]))
   1447 					goto err;
   1448 				tmpser = BN_to_ASN1_INTEGER(serial, NULL);
   1449 				BN_free(serial);
   1450 				serial = NULL;
   1451 				if (!tmpser)
   1452 					goto err;
   1453 				X509_REVOKED_set_serialNumber(r, tmpser);
   1454 				ASN1_INTEGER_free(tmpser);
   1455 				X509_CRL_add0_revoked(crl,r);
   1456 				}
   1457 			}
   1458 
   1459 		/* sort the data so it will be written in serial
   1460 		 * number order */
   1461 		X509_CRL_sort(crl);
   1462 
   1463 		/* we now have a CRL */
   1464 		if (verbose) BIO_printf(bio_err,"signing CRL\n");
   1465 
   1466 		/* Add any extensions asked for */
   1467 
   1468 		if (crl_ext || crlnumberfile != NULL)
   1469 			{
   1470 			X509V3_CTX crlctx;
   1471 			X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
   1472 			X509V3_set_nconf(&crlctx, conf);
   1473 
   1474 			if (crl_ext)
   1475 				if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
   1476 					crl_ext, crl)) goto err;
   1477 			if (crlnumberfile != NULL)
   1478 				{
   1479 				tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
   1480 				if (!tmpser) goto err;
   1481 				X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
   1482 				ASN1_INTEGER_free(tmpser);
   1483 				crl_v2 = 1;
   1484 				if (!BN_add_word(crlnumber,1)) goto err;
   1485 				}
   1486 			}
   1487 		if (crl_ext || crl_v2)
   1488 			{
   1489 			if (!X509_CRL_set_version(crl, 1))
   1490 				goto err; /* version 2 CRL */
   1491 			}
   1492 
   1493 
   1494 		if (crlnumberfile != NULL)	/* we have a CRL number that need updating */
   1495 			if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
   1496 
   1497 		if (crlnumber)
   1498 			{
   1499 			BN_free(crlnumber);
   1500 			crlnumber = NULL;
   1501 			}
   1502 
   1503 		if (!do_X509_CRL_sign(bio_err,crl,pkey,dgst,sigopts)) goto err;
   1504 
   1505 		PEM_write_bio_X509_CRL(Sout,crl);
   1506 
   1507 		if (crlnumberfile != NULL)	/* Rename the crlnumber file */
   1508 			if (!rotate_serial(crlnumberfile,"new","old")) goto err;
   1509 
   1510 		}
   1511 	/*****************************************************************/
   1512 	if (dorevoke)
   1513 		{
   1514 		if (infile == NULL)
   1515 			{
   1516 			BIO_printf(bio_err,"no input files\n");
   1517 			goto err;
   1518 			}
   1519 		else
   1520 			{
   1521 			X509 *revcert;
   1522 			revcert=load_cert(bio_err, infile, FORMAT_PEM,
   1523 				NULL, e, infile);
   1524 			if (revcert == NULL)
   1525 				goto err;
   1526 			j=do_revoke(revcert,db, rev_type, rev_arg);
   1527 			if (j <= 0) goto err;
   1528 			X509_free(revcert);
   1529 
   1530 			if (!save_index(dbfile, "new", db)) goto err;
   1531 
   1532 			if (!rotate_index(dbfile, "new", "old")) goto err;
   1533 
   1534 			BIO_printf(bio_err,"Data Base Updated\n");
   1535 			}
   1536 		}
   1537 	/*****************************************************************/
   1538 	ret=0;
   1539 err:
   1540 	if(tofree)
   1541 		OPENSSL_free(tofree);
   1542 	BIO_free_all(Cout);
   1543 	BIO_free_all(Sout);
   1544 	BIO_free_all(out);
   1545 	BIO_free_all(in);
   1546 
   1547 	if (cert_sk)
   1548 		sk_X509_pop_free(cert_sk,X509_free);
   1549 
   1550 	if (ret) ERR_print_errors(bio_err);
   1551 	app_RAND_write_file(randfile, bio_err);
   1552 	if (free_key && key)
   1553 		OPENSSL_free(key);
   1554 	BN_free(serial);
   1555 	BN_free(crlnumber);
   1556 	free_index(db);
   1557 	if (sigopts)
   1558 		sk_OPENSSL_STRING_free(sigopts);
   1559 	EVP_PKEY_free(pkey);
   1560 	if (x509) X509_free(x509);
   1561 	X509_CRL_free(crl);
   1562 	NCONF_free(conf);
   1563 	NCONF_free(extconf);
   1564 	OBJ_cleanup();
   1565 	apps_shutdown();
   1566 	OPENSSL_EXIT(ret);
   1567 	}
   1568 
   1569 static void lookup_fail(const char *name, const char *tag)
   1570 	{
   1571 	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
   1572 	}
   1573 
   1574 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
   1575 	     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
   1576 	     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
   1577 	     BIGNUM *serial, char *subj,unsigned long chtype, int multirdn,
   1578 	     int email_dn, char *startdate, char *enddate,
   1579 	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
   1580 	     unsigned long certopt, unsigned long nameopt, int default_op,
   1581 	     int ext_copy, int selfsign)
   1582 	{
   1583 	X509_REQ *req=NULL;
   1584 	BIO *in=NULL;
   1585 	EVP_PKEY *pktmp=NULL;
   1586 	int ok= -1,i;
   1587 
   1588 	in=BIO_new(BIO_s_file());
   1589 
   1590 	if (BIO_read_filename(in,infile) <= 0)
   1591 		{
   1592 		perror(infile);
   1593 		goto err;
   1594 		}
   1595 	if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
   1596 		{
   1597 		BIO_printf(bio_err,"Error reading certificate request in %s\n",
   1598 			infile);
   1599 		goto err;
   1600 		}
   1601 	if (verbose)
   1602 		X509_REQ_print(bio_err,req);
   1603 
   1604 	BIO_printf(bio_err,"Check that the request matches the signature\n");
   1605 
   1606 	if (selfsign && !X509_REQ_check_private_key(req,pkey))
   1607 		{
   1608 		BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
   1609 		ok=0;
   1610 		goto err;
   1611 		}
   1612 	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
   1613 		{
   1614 		BIO_printf(bio_err,"error unpacking public key\n");
   1615 		goto err;
   1616 		}
   1617 	i=X509_REQ_verify(req,pktmp);
   1618 	EVP_PKEY_free(pktmp);
   1619 	if (i < 0)
   1620 		{
   1621 		ok=0;
   1622 		BIO_printf(bio_err,"Signature verification problems....\n");
   1623 		ERR_print_errors(bio_err);
   1624 		goto err;
   1625 		}
   1626 	if (i == 0)
   1627 		{
   1628 		ok=0;
   1629 		BIO_printf(bio_err,"Signature did not match the certificate request\n");
   1630 		ERR_print_errors(bio_err);
   1631 		goto err;
   1632 		}
   1633 	else
   1634 		BIO_printf(bio_err,"Signature ok\n");
   1635 
   1636 	ok=do_body(xret,pkey,x509,dgst,sigopts, policy,db,serial,subj,chtype,
   1637 		multirdn, email_dn,
   1638 		startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
   1639 		certopt, nameopt, default_op, ext_copy, selfsign);
   1640 
   1641 err:
   1642 	if (req != NULL) X509_REQ_free(req);
   1643 	if (in != NULL) BIO_free(in);
   1644 	return(ok);
   1645 	}
   1646 
   1647 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
   1648 	     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
   1649 	     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
   1650 	     BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
   1651 	     long days, int batch, char *ext_sect, CONF *lconf, int verbose,
   1652 	     unsigned long certopt, unsigned long nameopt, int default_op,
   1653 	     int ext_copy, ENGINE *e)
   1654 	{
   1655 	X509 *req=NULL;
   1656 	X509_REQ *rreq=NULL;
   1657 	EVP_PKEY *pktmp=NULL;
   1658 	int ok= -1,i;
   1659 
   1660 	if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
   1661 		goto err;
   1662 	if (verbose)
   1663 		X509_print(bio_err,req);
   1664 
   1665 	BIO_printf(bio_err,"Check that the request matches the signature\n");
   1666 
   1667 	if ((pktmp=X509_get_pubkey(req)) == NULL)
   1668 		{
   1669 		BIO_printf(bio_err,"error unpacking public key\n");
   1670 		goto err;
   1671 		}
   1672 	i=X509_verify(req,pktmp);
   1673 	EVP_PKEY_free(pktmp);
   1674 	if (i < 0)
   1675 		{
   1676 		ok=0;
   1677 		BIO_printf(bio_err,"Signature verification problems....\n");
   1678 		goto err;
   1679 		}
   1680 	if (i == 0)
   1681 		{
   1682 		ok=0;
   1683 		BIO_printf(bio_err,"Signature did not match the certificate\n");
   1684 		goto err;
   1685 		}
   1686 	else
   1687 		BIO_printf(bio_err,"Signature ok\n");
   1688 
   1689 	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
   1690 		goto err;
   1691 
   1692 	ok=do_body(xret,pkey,x509,dgst,sigopts,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
   1693 		days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
   1694 		ext_copy, 0);
   1695 
   1696 err:
   1697 	if (rreq != NULL) X509_REQ_free(rreq);
   1698 	if (req != NULL) X509_free(req);
   1699 	return(ok);
   1700 	}
   1701 
   1702 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
   1703 	     STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy,
   1704              CA_DB *db, BIGNUM *serial, char *subj,
   1705 	     unsigned long chtype, int multirdn,
   1706 	     int email_dn, char *startdate, char *enddate, long days, int batch,
   1707 	     int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
   1708 	     unsigned long certopt, unsigned long nameopt, int default_op,
   1709 	     int ext_copy, int selfsign)
   1710 	{
   1711 	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
   1712 	ASN1_UTCTIME *tm,*tmptm;
   1713 	ASN1_STRING *str,*str2;
   1714 	ASN1_OBJECT *obj;
   1715 	X509 *ret=NULL;
   1716 	X509_CINF *ci;
   1717 	X509_NAME_ENTRY *ne;
   1718 	X509_NAME_ENTRY *tne,*push;
   1719 	EVP_PKEY *pktmp;
   1720 	int ok= -1,i,j,last,nid;
   1721 	const char *p;
   1722 	CONF_VALUE *cv;
   1723 	OPENSSL_STRING row[DB_NUMBER];
   1724 	OPENSSL_STRING *irow=NULL;
   1725 	OPENSSL_STRING *rrow=NULL;
   1726 	char buf[25];
   1727 
   1728 	tmptm=ASN1_UTCTIME_new();
   1729 	if (tmptm == NULL)
   1730 		{
   1731 		BIO_printf(bio_err,"malloc error\n");
   1732 		return(0);
   1733 		}
   1734 
   1735 	for (i=0; i<DB_NUMBER; i++)
   1736 		row[i]=NULL;
   1737 
   1738 	if (subj)
   1739 		{
   1740 		X509_NAME *n = parse_name(subj, chtype, multirdn);
   1741 
   1742 		if (!n)
   1743 			{
   1744 			ERR_print_errors(bio_err);
   1745 			goto err;
   1746 			}
   1747 		X509_REQ_set_subject_name(req,n);
   1748 		req->req_info->enc.modified = 1;
   1749 		X509_NAME_free(n);
   1750 		}
   1751 
   1752 	if (default_op)
   1753 		BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
   1754 
   1755 	name=X509_REQ_get_subject_name(req);
   1756 	for (i=0; i<X509_NAME_entry_count(name); i++)
   1757 		{
   1758 		ne= X509_NAME_get_entry(name,i);
   1759 		str=X509_NAME_ENTRY_get_data(ne);
   1760 		obj=X509_NAME_ENTRY_get_object(ne);
   1761 
   1762 		if (msie_hack)
   1763 			{
   1764 			/* assume all type should be strings */
   1765 			nid=OBJ_obj2nid(ne->object);
   1766 
   1767 			if (str->type == V_ASN1_UNIVERSALSTRING)
   1768 				ASN1_UNIVERSALSTRING_to_string(str);
   1769 
   1770 			if ((str->type == V_ASN1_IA5STRING) &&
   1771 				(nid != NID_pkcs9_emailAddress))
   1772 				str->type=V_ASN1_T61STRING;
   1773 
   1774 			if ((nid == NID_pkcs9_emailAddress) &&
   1775 				(str->type == V_ASN1_PRINTABLESTRING))
   1776 				str->type=V_ASN1_IA5STRING;
   1777 			}
   1778 
   1779 		/* If no EMAIL is wanted in the subject */
   1780 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
   1781 			continue;
   1782 
   1783 		/* check some things */
   1784 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
   1785 			(str->type != V_ASN1_IA5STRING))
   1786 			{
   1787 			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
   1788 			goto err;
   1789 			}
   1790 		if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
   1791 			{
   1792 			j=ASN1_PRINTABLE_type(str->data,str->length);
   1793 			if (	((j == V_ASN1_T61STRING) &&
   1794 				 (str->type != V_ASN1_T61STRING)) ||
   1795 				((j == V_ASN1_IA5STRING) &&
   1796 				 (str->type == V_ASN1_PRINTABLESTRING)))
   1797 				{
   1798 				BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
   1799 				goto err;
   1800 				}
   1801 			}
   1802 
   1803 		if (default_op)
   1804 			old_entry_print(bio_err, obj, str);
   1805 		}
   1806 
   1807 	/* Ok, now we check the 'policy' stuff. */
   1808 	if ((subject=X509_NAME_new()) == NULL)
   1809 		{
   1810 		BIO_printf(bio_err,"Memory allocation failure\n");
   1811 		goto err;
   1812 		}
   1813 
   1814 	/* take a copy of the issuer name before we mess with it. */
   1815 	if (selfsign)
   1816 		CAname=X509_NAME_dup(name);
   1817 	else
   1818 		CAname=X509_NAME_dup(x509->cert_info->subject);
   1819 	if (CAname == NULL) goto err;
   1820 	str=str2=NULL;
   1821 
   1822 	for (i=0; i<sk_CONF_VALUE_num(policy); i++)
   1823 		{
   1824 		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
   1825 		if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
   1826 			{
   1827 			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
   1828 			goto err;
   1829 			}
   1830 		obj=OBJ_nid2obj(j);
   1831 
   1832 		last= -1;
   1833 		for (;;)
   1834 			{
   1835 			/* lookup the object in the supplied name list */
   1836 			j=X509_NAME_get_index_by_OBJ(name,obj,last);
   1837 			if (j < 0)
   1838 				{
   1839 				if (last != -1) break;
   1840 				tne=NULL;
   1841 				}
   1842 			else
   1843 				{
   1844 				tne=X509_NAME_get_entry(name,j);
   1845 				}
   1846 			last=j;
   1847 
   1848 			/* depending on the 'policy', decide what to do. */
   1849 			push=NULL;
   1850 			if (strcmp(cv->value,"optional") == 0)
   1851 				{
   1852 				if (tne != NULL)
   1853 					push=tne;
   1854 				}
   1855 			else if (strcmp(cv->value,"supplied") == 0)
   1856 				{
   1857 				if (tne == NULL)
   1858 					{
   1859 					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
   1860 					goto err;
   1861 					}
   1862 				else
   1863 					push=tne;
   1864 				}
   1865 			else if (strcmp(cv->value,"match") == 0)
   1866 				{
   1867 				int last2;
   1868 
   1869 				if (tne == NULL)
   1870 					{
   1871 					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
   1872 					goto err;
   1873 					}
   1874 
   1875 				last2= -1;
   1876 
   1877 again2:
   1878 				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
   1879 				if ((j < 0) && (last2 == -1))
   1880 					{
   1881 					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
   1882 					goto err;
   1883 					}
   1884 				if (j >= 0)
   1885 					{
   1886 					push=X509_NAME_get_entry(CAname,j);
   1887 					str=X509_NAME_ENTRY_get_data(tne);
   1888 					str2=X509_NAME_ENTRY_get_data(push);
   1889 					last2=j;
   1890 					if (ASN1_STRING_cmp(str,str2) != 0)
   1891 						goto again2;
   1892 					}
   1893 				if (j < 0)
   1894 					{
   1895 					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));
   1896 					goto err;
   1897 					}
   1898 				}
   1899 			else
   1900 				{
   1901 				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
   1902 				goto err;
   1903 				}
   1904 
   1905 			if (push != NULL)
   1906 				{
   1907 				if (!X509_NAME_add_entry(subject,push, -1, 0))
   1908 					{
   1909 					if (push != NULL)
   1910 						X509_NAME_ENTRY_free(push);
   1911 					BIO_printf(bio_err,"Memory allocation failure\n");
   1912 					goto err;
   1913 					}
   1914 				}
   1915 			if (j < 0) break;
   1916 			}
   1917 		}
   1918 
   1919 	if (preserve)
   1920 		{
   1921 		X509_NAME_free(subject);
   1922 		/* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
   1923 		subject=X509_NAME_dup(name);
   1924 		if (subject == NULL) goto err;
   1925 		}
   1926 
   1927 	if (verbose)
   1928 		BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
   1929 
   1930 	/* Build the correct Subject if no e-mail is wanted in the subject */
   1931 	/* and add it later on because of the method extensions are added (altName) */
   1932 
   1933 	if (email_dn)
   1934 		dn_subject = subject;
   1935 	else
   1936 		{
   1937 		X509_NAME_ENTRY *tmpne;
   1938 		/* Its best to dup the subject DN and then delete any email
   1939 		 * addresses because this retains its structure.
   1940 		 */
   1941 		if (!(dn_subject = X509_NAME_dup(subject)))
   1942 			{
   1943 			BIO_printf(bio_err,"Memory allocation failure\n");
   1944 			goto err;
   1945 			}
   1946 		while((i = X509_NAME_get_index_by_NID(dn_subject,
   1947 					NID_pkcs9_emailAddress, -1)) >= 0)
   1948 			{
   1949 			tmpne = X509_NAME_get_entry(dn_subject, i);
   1950 			X509_NAME_delete_entry(dn_subject, i);
   1951 			X509_NAME_ENTRY_free(tmpne);
   1952 			}
   1953 		}
   1954 
   1955 	if (BN_is_zero(serial))
   1956 		row[DB_serial]=BUF_strdup("00");
   1957 	else
   1958 		row[DB_serial]=BN_bn2hex(serial);
   1959 	if (row[DB_serial] == NULL)
   1960 		{
   1961 		BIO_printf(bio_err,"Memory allocation failure\n");
   1962 		goto err;
   1963 		}
   1964 
   1965 	if (db->attributes.unique_subject)
   1966 		{
   1967 		OPENSSL_STRING *crow=row;
   1968 
   1969 		rrow=TXT_DB_get_by_index(db->db,DB_name,crow);
   1970 		if (rrow != NULL)
   1971 			{
   1972 			BIO_printf(bio_err,
   1973 				"ERROR:There is already a certificate for %s\n",
   1974 				row[DB_name]);
   1975 			}
   1976 		}
   1977 	if (rrow == NULL)
   1978 		{
   1979 		rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
   1980 		if (rrow != NULL)
   1981 			{
   1982 			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
   1983 				row[DB_serial]);
   1984 			BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
   1985 			}
   1986 		}
   1987 
   1988 	if (rrow != NULL)
   1989 		{
   1990 		BIO_printf(bio_err,
   1991 			"The matching entry has the following details\n");
   1992 		if (rrow[DB_type][0] == 'E')
   1993 			p="Expired";
   1994 		else if (rrow[DB_type][0] == 'R')
   1995 			p="Revoked";
   1996 		else if (rrow[DB_type][0] == 'V')
   1997 			p="Valid";
   1998 		else
   1999 			p="\ninvalid type, Data base error\n";
   2000 		BIO_printf(bio_err,"Type	  :%s\n",p);;
   2001 		if (rrow[DB_type][0] == 'R')
   2002 			{
   2003 			p=rrow[DB_exp_date]; if (p == NULL) p="undef";
   2004 			BIO_printf(bio_err,"Was revoked on:%s\n",p);
   2005 			}
   2006 		p=rrow[DB_exp_date]; if (p == NULL) p="undef";
   2007 		BIO_printf(bio_err,"Expires on    :%s\n",p);
   2008 		p=rrow[DB_serial]; if (p == NULL) p="undef";
   2009 		BIO_printf(bio_err,"Serial Number :%s\n",p);
   2010 		p=rrow[DB_file]; if (p == NULL) p="undef";
   2011 		BIO_printf(bio_err,"File name     :%s\n",p);
   2012 		p=rrow[DB_name]; if (p == NULL) p="undef";
   2013 		BIO_printf(bio_err,"Subject Name  :%s\n",p);
   2014 		ok= -1; /* This is now a 'bad' error. */
   2015 		goto err;
   2016 		}
   2017 
   2018 	/* We are now totally happy, lets make and sign the certificate */
   2019 	if (verbose)
   2020 		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
   2021 
   2022 	if ((ret=X509_new()) == NULL) goto err;
   2023 	ci=ret->cert_info;
   2024 
   2025 #ifdef X509_V3
   2026 	/* Make it an X509 v3 certificate. */
   2027 	if (!X509_set_version(ret,2)) goto err;
   2028 #endif
   2029 
   2030 	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
   2031 		goto err;
   2032 	if (selfsign)
   2033 		{
   2034 		if (!X509_set_issuer_name(ret,subject))
   2035 			goto err;
   2036 		}
   2037 	else
   2038 		{
   2039 		if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
   2040 			goto err;
   2041 		}
   2042 
   2043 	if (strcmp(startdate,"today") == 0)
   2044 		X509_gmtime_adj(X509_get_notBefore(ret),0);
   2045 	else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate);
   2046 
   2047 	if (enddate == NULL)
   2048 		X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL);
   2049 	else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate);
   2050 
   2051 	if (!X509_set_subject_name(ret,subject)) goto err;
   2052 
   2053 	pktmp=X509_REQ_get_pubkey(req);
   2054 	i = X509_set_pubkey(ret,pktmp);
   2055 	EVP_PKEY_free(pktmp);
   2056 	if (!i) goto err;
   2057 
   2058 	/* Lets add the extensions, if there are any */
   2059 	if (ext_sect)
   2060 		{
   2061 		X509V3_CTX ctx;
   2062 		if (ci->version == NULL)
   2063 			if ((ci->version=ASN1_INTEGER_new()) == NULL)
   2064 				goto err;
   2065 		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
   2066 
   2067 		/* Free the current entries if any, there should not
   2068 		 * be any I believe */
   2069 		if (ci->extensions != NULL)
   2070 			sk_X509_EXTENSION_pop_free(ci->extensions,
   2071 						   X509_EXTENSION_free);
   2072 
   2073 		ci->extensions = NULL;
   2074 
   2075 		/* Initialize the context structure */
   2076 		if (selfsign)
   2077 			X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
   2078 		else
   2079 			X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
   2080 
   2081 		if (extconf)
   2082 			{
   2083 			if (verbose)
   2084 				BIO_printf(bio_err, "Extra configuration file found\n");
   2085 
   2086 			/* Use the extconf configuration db LHASH */
   2087 			X509V3_set_nconf(&ctx, extconf);
   2088 
   2089 			/* Test the structure (needed?) */
   2090 			/* X509V3_set_ctx_test(&ctx); */
   2091 
   2092 			/* Adds exts contained in the configuration file */
   2093 			if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
   2094 				{
   2095 				BIO_printf(bio_err,
   2096 				    "ERROR: adding extensions in section %s\n",
   2097 								ext_sect);
   2098 				ERR_print_errors(bio_err);
   2099 				goto err;
   2100 				}
   2101 			if (verbose)
   2102 				BIO_printf(bio_err, "Successfully added extensions from file.\n");
   2103 			}
   2104 		else if (ext_sect)
   2105 			{
   2106 			/* We found extensions to be set from config file */
   2107 			X509V3_set_nconf(&ctx, lconf);
   2108 
   2109 			if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
   2110 				{
   2111 				BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
   2112 				ERR_print_errors(bio_err);
   2113 				goto err;
   2114 				}
   2115 
   2116 			if (verbose)
   2117 				BIO_printf(bio_err, "Successfully added extensions from config\n");
   2118 			}
   2119 		}
   2120 
   2121 	/* Copy extensions from request (if any) */
   2122 
   2123 	if (!copy_extensions(ret, req, ext_copy))
   2124 		{
   2125 		BIO_printf(bio_err, "ERROR: adding extensions from request\n");
   2126 		ERR_print_errors(bio_err);
   2127 		goto err;
   2128 		}
   2129 
   2130 	/* Set the right value for the noemailDN option */
   2131 	if( email_dn == 0 )
   2132 		{
   2133 		if (!X509_set_subject_name(ret,dn_subject)) goto err;
   2134 		}
   2135 
   2136 	if (!default_op)
   2137 		{
   2138 		BIO_printf(bio_err, "Certificate Details:\n");
   2139 		/* Never print signature details because signature not present */
   2140 		certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
   2141 		X509_print_ex(bio_err, ret, nameopt, certopt);
   2142 		}
   2143 
   2144 	BIO_printf(bio_err,"Certificate is to be certified until ");
   2145 	ASN1_TIME_print(bio_err,X509_get_notAfter(ret));
   2146 	if (days) BIO_printf(bio_err," (%ld days)",days);
   2147 	BIO_printf(bio_err, "\n");
   2148 
   2149 	if (!batch)
   2150 		{
   2151 
   2152 		BIO_printf(bio_err,"Sign the certificate? [y/n]:");
   2153 		(void)BIO_flush(bio_err);
   2154 		buf[0]='\0';
   2155 		if (!fgets(buf,sizeof(buf)-1,stdin))
   2156 			{
   2157 			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
   2158 			ok=0;
   2159 			goto err;
   2160 			}
   2161 		if (!((buf[0] == 'y') || (buf[0] == 'Y')))
   2162 			{
   2163 			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
   2164 			ok=0;
   2165 			goto err;
   2166 			}
   2167 		}
   2168 
   2169 	pktmp=X509_get_pubkey(ret);
   2170 	if (EVP_PKEY_missing_parameters(pktmp) &&
   2171 		!EVP_PKEY_missing_parameters(pkey))
   2172 		EVP_PKEY_copy_parameters(pktmp,pkey);
   2173 	EVP_PKEY_free(pktmp);
   2174 
   2175 	if (!do_X509_sign(bio_err, ret,pkey,dgst, sigopts))
   2176 		goto err;
   2177 
   2178 	/* We now just add it to the database */
   2179 	row[DB_type]=(char *)OPENSSL_malloc(2);
   2180 
   2181 	tm=X509_get_notAfter(ret);
   2182 	row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
   2183 	memcpy(row[DB_exp_date],tm->data,tm->length);
   2184 	row[DB_exp_date][tm->length]='\0';
   2185 
   2186 	row[DB_rev_date]=NULL;
   2187 
   2188 	/* row[DB_serial] done already */
   2189 	row[DB_file]=(char *)OPENSSL_malloc(8);
   2190 	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
   2191 
   2192 	if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
   2193 		(row[DB_file] == NULL) || (row[DB_name] == NULL))
   2194 		{
   2195 		BIO_printf(bio_err,"Memory allocation failure\n");
   2196 		goto err;
   2197 		}
   2198 	BUF_strlcpy(row[DB_file],"unknown",8);
   2199 	row[DB_type][0]='V';
   2200 	row[DB_type][1]='\0';
   2201 
   2202 	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
   2203 		{
   2204 		BIO_printf(bio_err,"Memory allocation failure\n");
   2205 		goto err;
   2206 		}
   2207 
   2208 	for (i=0; i<DB_NUMBER; i++)
   2209 		{
   2210 		irow[i]=row[i];
   2211 		row[i]=NULL;
   2212 		}
   2213 	irow[DB_NUMBER]=NULL;
   2214 
   2215 	if (!TXT_DB_insert(db->db,irow))
   2216 		{
   2217 		BIO_printf(bio_err,"failed to update database\n");
   2218 		BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
   2219 		goto err;
   2220 		}
   2221 	ok=1;
   2222 err:
   2223 	for (i=0; i<DB_NUMBER; i++)
   2224 		if (row[i] != NULL) OPENSSL_free(row[i]);
   2225 
   2226 	if (CAname != NULL)
   2227 		X509_NAME_free(CAname);
   2228 	if (subject != NULL)
   2229 		X509_NAME_free(subject);
   2230 	if ((dn_subject != NULL) && !email_dn)
   2231 		X509_NAME_free(dn_subject);
   2232 	if (tmptm != NULL)
   2233 		ASN1_UTCTIME_free(tmptm);
   2234 	if (ok <= 0)
   2235 		{
   2236 		if (ret != NULL) X509_free(ret);
   2237 		ret=NULL;
   2238 		}
   2239 	else
   2240 		*xret=ret;
   2241 	return(ok);
   2242 	}
   2243 
   2244 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
   2245 	{
   2246 
   2247 	if (output_der)
   2248 		{
   2249 		(void)i2d_X509_bio(bp,x);
   2250 		return;
   2251 		}
   2252 #if 0
   2253 	/* ??? Not needed since X509_print prints all this stuff anyway */
   2254 	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
   2255 	BIO_printf(bp,"issuer :%s\n",f);
   2256 
   2257 	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
   2258 	BIO_printf(bp,"subject:%s\n",f);
   2259 
   2260 	BIO_puts(bp,"serial :");
   2261 	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
   2262 	BIO_puts(bp,"\n\n");
   2263 #endif
   2264 	if (!notext)X509_print(bp,x);
   2265 	PEM_write_bio_X509(bp,x);
   2266 	}
   2267 
   2268 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
   2269 	     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
   2270 	     STACK_OF(CONF_VALUE) *policy, CA_DB *db,
   2271 	     BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
   2272 	     long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
   2273 	     unsigned long nameopt, int default_op, int ext_copy)
   2274 	{
   2275 	STACK_OF(CONF_VALUE) *sk=NULL;
   2276 	LHASH_OF(CONF_VALUE) *parms=NULL;
   2277 	X509_REQ *req=NULL;
   2278 	CONF_VALUE *cv=NULL;
   2279 	NETSCAPE_SPKI *spki = NULL;
   2280 	X509_REQ_INFO *ri;
   2281 	char *type,*buf;
   2282 	EVP_PKEY *pktmp=NULL;
   2283 	X509_NAME *n=NULL;
   2284 	X509_NAME_ENTRY *ne=NULL;
   2285 	int ok= -1,i,j;
   2286 	long errline;
   2287 	int nid;
   2288 
   2289 	/*
   2290 	 * Load input file into a hash table.  (This is just an easy
   2291 	 * way to read and parse the file, then put it into a convenient
   2292 	 * STACK format).
   2293 	 */
   2294 	parms=CONF_load(NULL,infile,&errline);
   2295 	if (parms == NULL)
   2296 		{
   2297 		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
   2298 		ERR_print_errors(bio_err);
   2299 		goto err;
   2300 		}
   2301 
   2302 	sk=CONF_get_section(parms, "default");
   2303 	if (sk_CONF_VALUE_num(sk) == 0)
   2304 		{
   2305 		BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
   2306 		CONF_free(parms);
   2307 		goto err;
   2308 		}
   2309 
   2310 	/*
   2311 	 * Now create a dummy X509 request structure.  We don't actually
   2312 	 * have an X509 request, but we have many of the components
   2313 	 * (a public key, various DN components).  The idea is that we
   2314 	 * put these components into the right X509 request structure
   2315 	 * and we can use the same code as if you had a real X509 request.
   2316 	 */
   2317 	req=X509_REQ_new();
   2318 	if (req == NULL)
   2319 		{
   2320 		ERR_print_errors(bio_err);
   2321 		goto err;
   2322 		}
   2323 
   2324 	/*
   2325 	 * Build up the subject name set.
   2326 	 */
   2327 	ri=req->req_info;
   2328 	n = ri->subject;
   2329 
   2330 	for (i = 0; ; i++)
   2331 		{
   2332 		if (sk_CONF_VALUE_num(sk) <= i) break;
   2333 
   2334 		cv=sk_CONF_VALUE_value(sk,i);
   2335 		type=cv->name;
   2336 		/* Skip past any leading X. X: X, etc to allow for
   2337 		 * multiple instances
   2338 		 */
   2339 		for (buf = cv->name; *buf ; buf++)
   2340 			if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
   2341 				{
   2342 				buf++;
   2343 				if (*buf) type = buf;
   2344 				break;
   2345 				}
   2346 
   2347 		buf=cv->value;
   2348 		if ((nid=OBJ_txt2nid(type)) == NID_undef)
   2349 			{
   2350 			if (strcmp(type, "SPKAC") == 0)
   2351 				{
   2352 				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
   2353 				if (spki == NULL)
   2354 					{
   2355 					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
   2356 					ERR_print_errors(bio_err);
   2357 					goto err;
   2358 					}
   2359 				}
   2360 			continue;
   2361 			}
   2362 
   2363 		if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
   2364 				(unsigned char *)buf, -1, -1, 0))
   2365 			goto err;
   2366 		}
   2367 	if (spki == NULL)
   2368 		{
   2369 		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
   2370 			infile);
   2371 		goto err;
   2372 		}
   2373 
   2374 	/*
   2375 	 * Now extract the key from the SPKI structure.
   2376 	 */
   2377 
   2378 	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
   2379 
   2380 	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
   2381 		{
   2382 		BIO_printf(bio_err,"error unpacking SPKAC public key\n");
   2383 		goto err;
   2384 		}
   2385 
   2386 	j = NETSCAPE_SPKI_verify(spki, pktmp);
   2387 	if (j <= 0)
   2388 		{
   2389 		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
   2390 		goto err;
   2391 		}
   2392 	BIO_printf(bio_err,"Signature ok\n");
   2393 
   2394 	X509_REQ_set_pubkey(req,pktmp);
   2395 	EVP_PKEY_free(pktmp);
   2396 	ok=do_body(xret,pkey,x509,dgst,sigopts,policy,db,serial,subj,chtype,
   2397 		   multirdn,email_dn,startdate,enddate, days,1,verbose,req,
   2398 		   ext_sect,lconf, certopt, nameopt, default_op, ext_copy, 0);
   2399 err:
   2400 	if (req != NULL) X509_REQ_free(req);
   2401 	if (parms != NULL) CONF_free(parms);
   2402 	if (spki != NULL) NETSCAPE_SPKI_free(spki);
   2403 	if (ne != NULL) X509_NAME_ENTRY_free(ne);
   2404 
   2405 	return(ok);
   2406 	}
   2407 
   2408 static int check_time_format(const char *str)
   2409 	{
   2410 	return ASN1_TIME_set_string(NULL, str);
   2411 	}
   2412 
   2413 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
   2414 	{
   2415 	ASN1_UTCTIME *tm=NULL;
   2416 	char *row[DB_NUMBER],**rrow,**irow;
   2417 	char *rev_str = NULL;
   2418 	BIGNUM *bn = NULL;
   2419 	int ok=-1,i;
   2420 
   2421 	for (i=0; i<DB_NUMBER; i++)
   2422 		row[i]=NULL;
   2423 	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
   2424 	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
   2425 	if (!bn)
   2426 		goto err;
   2427 	if (BN_is_zero(bn))
   2428 		row[DB_serial]=BUF_strdup("00");
   2429 	else
   2430 		row[DB_serial]=BN_bn2hex(bn);
   2431 	BN_free(bn);
   2432 	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
   2433 		{
   2434 		BIO_printf(bio_err,"Memory allocation failure\n");
   2435 		goto err;
   2436 		}
   2437 	/* We have to lookup by serial number because name lookup
   2438 	 * skips revoked certs
   2439  	 */
   2440 	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
   2441 	if (rrow == NULL)
   2442 		{
   2443 		BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
   2444 
   2445 		/* We now just add it to the database */
   2446 		row[DB_type]=(char *)OPENSSL_malloc(2);
   2447 
   2448 		tm=X509_get_notAfter(x509);
   2449 		row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
   2450 		memcpy(row[DB_exp_date],tm->data,tm->length);
   2451 		row[DB_exp_date][tm->length]='\0';
   2452 
   2453 		row[DB_rev_date]=NULL;
   2454 
   2455 		/* row[DB_serial] done already */
   2456 		row[DB_file]=(char *)OPENSSL_malloc(8);
   2457 
   2458 		/* row[DB_name] done already */
   2459 
   2460 		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
   2461 			(row[DB_file] == NULL))
   2462 			{
   2463 			BIO_printf(bio_err,"Memory allocation failure\n");
   2464 			goto err;
   2465 			}
   2466 		BUF_strlcpy(row[DB_file],"unknown",8);
   2467 		row[DB_type][0]='V';
   2468 		row[DB_type][1]='\0';
   2469 
   2470 		if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
   2471 			{
   2472 			BIO_printf(bio_err,"Memory allocation failure\n");
   2473 			goto err;
   2474 			}
   2475 
   2476 		for (i=0; i<DB_NUMBER; i++)
   2477 			{
   2478 			irow[i]=row[i];
   2479 			row[i]=NULL;
   2480 			}
   2481 		irow[DB_NUMBER]=NULL;
   2482 
   2483 		if (!TXT_DB_insert(db->db,irow))
   2484 			{
   2485 			BIO_printf(bio_err,"failed to update database\n");
   2486 			BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
   2487 			goto err;
   2488 			}
   2489 
   2490 		/* Revoke Certificate */
   2491 		ok = do_revoke(x509,db, type, value);
   2492 
   2493 		goto err;
   2494 
   2495 		}
   2496 	else if (index_name_cmp_noconst(row, rrow))
   2497 		{
   2498 		BIO_printf(bio_err,"ERROR:name does not match %s\n",
   2499 			   row[DB_name]);
   2500 		goto err;
   2501 		}
   2502 	else if (rrow[DB_type][0]=='R')
   2503 		{
   2504 		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
   2505 			   row[DB_serial]);
   2506 		goto err;
   2507 		}
   2508 	else
   2509 		{
   2510 		BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
   2511 		rev_str = make_revocation_str(type, value);
   2512 		if (!rev_str)
   2513 			{
   2514 			BIO_printf(bio_err, "Error in revocation arguments\n");
   2515 			goto err;
   2516 			}
   2517 		rrow[DB_type][0]='R';
   2518 		rrow[DB_type][1]='\0';
   2519 		rrow[DB_rev_date] = rev_str;
   2520 		}
   2521 	ok=1;
   2522 err:
   2523 	for (i=0; i<DB_NUMBER; i++)
   2524 		{
   2525 		if (row[i] != NULL)
   2526 			OPENSSL_free(row[i]);
   2527 		}
   2528 	return(ok);
   2529 	}
   2530 
   2531 static int get_certificate_status(const char *serial, CA_DB *db)
   2532 	{
   2533 	char *row[DB_NUMBER],**rrow;
   2534 	int ok=-1,i;
   2535 
   2536 	/* Free Resources */
   2537 	for (i=0; i<DB_NUMBER; i++)
   2538 		row[i]=NULL;
   2539 
   2540 	/* Malloc needed char spaces */
   2541 	row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
   2542 	if (row[DB_serial] == NULL)
   2543 		{
   2544 		BIO_printf(bio_err,"Malloc failure\n");
   2545 		goto err;
   2546 		}
   2547 
   2548 	if (strlen(serial) % 2)
   2549 		{
   2550 		/* Set the first char to 0 */;
   2551 		row[DB_serial][0]='0';
   2552 
   2553 		/* Copy String from serial to row[DB_serial] */
   2554 		memcpy(row[DB_serial]+1, serial, strlen(serial));
   2555 		row[DB_serial][strlen(serial)+1]='\0';
   2556 		}
   2557 	else
   2558 		{
   2559 		/* Copy String from serial to row[DB_serial] */
   2560 		memcpy(row[DB_serial], serial, strlen(serial));
   2561 		row[DB_serial][strlen(serial)]='\0';
   2562 		}
   2563 
   2564 	/* Make it Upper Case */
   2565 	for (i=0; row[DB_serial][i] != '\0'; i++)
   2566 		row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]);
   2567 
   2568 
   2569 	ok=1;
   2570 
   2571 	/* Search for the certificate */
   2572 	rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
   2573 	if (rrow == NULL)
   2574 		{
   2575 		BIO_printf(bio_err,"Serial %s not present in db.\n",
   2576 				 row[DB_serial]);
   2577 		ok=-1;
   2578 		goto err;
   2579 		}
   2580 	else if (rrow[DB_type][0]=='V')
   2581 		{
   2582 		BIO_printf(bio_err,"%s=Valid (%c)\n",
   2583 			row[DB_serial], rrow[DB_type][0]);
   2584 		goto err;
   2585 		}
   2586 	else if (rrow[DB_type][0]=='R')
   2587 		{
   2588 		BIO_printf(bio_err,"%s=Revoked (%c)\n",
   2589 			row[DB_serial], rrow[DB_type][0]);
   2590 		goto err;
   2591 		}
   2592 	else if (rrow[DB_type][0]=='E')
   2593 		{
   2594 		BIO_printf(bio_err,"%s=Expired (%c)\n",
   2595 			row[DB_serial], rrow[DB_type][0]);
   2596 		goto err;
   2597 		}
   2598 	else if (rrow[DB_type][0]=='S')
   2599 		{
   2600 		BIO_printf(bio_err,"%s=Suspended (%c)\n",
   2601 			row[DB_serial], rrow[DB_type][0]);
   2602 		goto err;
   2603 		}
   2604 	else
   2605 		{
   2606 		BIO_printf(bio_err,"%s=Unknown (%c).\n",
   2607 			row[DB_serial], rrow[DB_type][0]);
   2608 		ok=-1;
   2609 		}
   2610 err:
   2611 	for (i=0; i<DB_NUMBER; i++)
   2612 		{
   2613 		if (row[i] != NULL)
   2614 			OPENSSL_free(row[i]);
   2615 		}
   2616 	return(ok);
   2617 	}
   2618 
   2619 static int do_updatedb (CA_DB *db)
   2620 	{
   2621 	ASN1_UTCTIME	*a_tm = NULL;
   2622 	int i, cnt = 0;
   2623 	int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */
   2624 	char **rrow, *a_tm_s;
   2625 
   2626 	a_tm = ASN1_UTCTIME_new();
   2627 
   2628 	/* get actual time and make a string */
   2629 	a_tm = X509_gmtime_adj(a_tm, 0);
   2630 	a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
   2631 	if (a_tm_s == NULL)
   2632 		{
   2633 		cnt = -1;
   2634 		goto err;
   2635 		}
   2636 
   2637 	memcpy(a_tm_s, a_tm->data, a_tm->length);
   2638 	a_tm_s[a_tm->length] = '\0';
   2639 
   2640 	if (strncmp(a_tm_s, "49", 2) <= 0)
   2641 		a_y2k = 1;
   2642 	else
   2643 		a_y2k = 0;
   2644 
   2645 	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
   2646 		{
   2647 		rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
   2648 
   2649 		if (rrow[DB_type][0] == 'V')
   2650 		 	{
   2651 			/* ignore entries that are not valid */
   2652 			if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
   2653 				db_y2k = 1;
   2654 			else
   2655 				db_y2k = 0;
   2656 
   2657 			if (db_y2k == a_y2k)
   2658 				{
   2659 				/* all on the same y2k side */
   2660 				if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
   2661 				       	{
   2662 				       	rrow[DB_type][0]  = 'E';
   2663 				       	rrow[DB_type][1]  = '\0';
   2664 	  				cnt++;
   2665 
   2666 					BIO_printf(bio_err, "%s=Expired\n",
   2667 							rrow[DB_serial]);
   2668 					}
   2669 				}
   2670 			else if (db_y2k < a_y2k)
   2671 				{
   2672 		  		rrow[DB_type][0]  = 'E';
   2673 		  		rrow[DB_type][1]  = '\0';
   2674 	  			cnt++;
   2675 
   2676 				BIO_printf(bio_err, "%s=Expired\n",
   2677 							rrow[DB_serial]);
   2678 				}
   2679 
   2680 			}
   2681     		}
   2682 
   2683 err:
   2684 
   2685 	ASN1_UTCTIME_free(a_tm);
   2686 	OPENSSL_free(a_tm_s);
   2687 
   2688 	return (cnt);
   2689 	}
   2690 
   2691 static const char *crl_reasons[] = {
   2692 	/* CRL reason strings */
   2693 	"unspecified",
   2694 	"keyCompromise",
   2695 	"CACompromise",
   2696 	"affiliationChanged",
   2697 	"superseded",
   2698 	"cessationOfOperation",
   2699 	"certificateHold",
   2700 	"removeFromCRL",
   2701 	/* Additional pseudo reasons */
   2702 	"holdInstruction",
   2703 	"keyTime",
   2704 	"CAkeyTime"
   2705 };
   2706 
   2707 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
   2708 
   2709 /* Given revocation information convert to a DB string.
   2710  * The format of the string is:
   2711  * revtime[,reason,extra]. Where 'revtime' is the
   2712  * revocation time (the current time). 'reason' is the
   2713  * optional CRL reason and 'extra' is any additional
   2714  * argument
   2715  */
   2716 
   2717 char *make_revocation_str(int rev_type, char *rev_arg)
   2718 	{
   2719 	char *other = NULL, *str;
   2720 	const char *reason = NULL;
   2721 	ASN1_OBJECT *otmp;
   2722 	ASN1_UTCTIME *revtm = NULL;
   2723 	int i;
   2724 	switch (rev_type)
   2725 		{
   2726 	case REV_NONE:
   2727 		break;
   2728 
   2729 	case REV_CRL_REASON:
   2730 		for (i = 0; i < 8; i++)
   2731 			{
   2732 			if (!strcasecmp(rev_arg, crl_reasons[i]))
   2733 				{
   2734 				reason = crl_reasons[i];
   2735 				break;
   2736 				}
   2737 			}
   2738 		if (reason == NULL)
   2739 			{
   2740 			BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
   2741 			return NULL;
   2742 			}
   2743 		break;
   2744 
   2745 	case REV_HOLD:
   2746 		/* Argument is an OID */
   2747 
   2748 		otmp = OBJ_txt2obj(rev_arg, 0);
   2749 		ASN1_OBJECT_free(otmp);
   2750 
   2751 		if (otmp == NULL)
   2752 			{
   2753 			BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
   2754 			return NULL;
   2755 			}
   2756 
   2757 		reason = "holdInstruction";
   2758 		other = rev_arg;
   2759 		break;
   2760 
   2761 	case REV_KEY_COMPROMISE:
   2762 	case REV_CA_COMPROMISE:
   2763 
   2764 		/* Argument is the key compromise time  */
   2765 		if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
   2766 			{
   2767 			BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
   2768 			return NULL;
   2769 			}
   2770 		other = rev_arg;
   2771 		if (rev_type == REV_KEY_COMPROMISE)
   2772 			reason = "keyTime";
   2773 		else
   2774 			reason = "CAkeyTime";
   2775 
   2776 		break;
   2777 
   2778 		}
   2779 
   2780 	revtm = X509_gmtime_adj(NULL, 0);
   2781 
   2782 	if (!revtm)
   2783 		return NULL;
   2784 
   2785 	i = revtm->length + 1;
   2786 
   2787 	if (reason) i += strlen(reason) + 1;
   2788 	if (other) i += strlen(other) + 1;
   2789 
   2790 	str = OPENSSL_malloc(i);
   2791 
   2792 	if (!str) return NULL;
   2793 
   2794 	BUF_strlcpy(str, (char *)revtm->data, i);
   2795 	if (reason)
   2796 		{
   2797 		BUF_strlcat(str, ",", i);
   2798 		BUF_strlcat(str, reason, i);
   2799 		}
   2800 	if (other)
   2801 		{
   2802 		BUF_strlcat(str, ",", i);
   2803 		BUF_strlcat(str, other, i);
   2804 		}
   2805 	ASN1_UTCTIME_free(revtm);
   2806 	return str;
   2807 	}
   2808 
   2809 /* Convert revocation field to X509_REVOKED entry
   2810  * return code:
   2811  * 0 error
   2812  * 1 OK
   2813  * 2 OK and some extensions added (i.e. V2 CRL)
   2814  */
   2815 
   2816 
   2817 int make_revoked(X509_REVOKED *rev, const char *str)
   2818 	{
   2819 	char *tmp = NULL;
   2820 	int reason_code = -1;
   2821 	int i, ret = 0;
   2822 	ASN1_OBJECT *hold = NULL;
   2823 	ASN1_GENERALIZEDTIME *comp_time = NULL;
   2824 	ASN1_ENUMERATED *rtmp = NULL;
   2825 
   2826 	ASN1_TIME *revDate = NULL;
   2827 
   2828 	i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
   2829 
   2830 	if (i == 0)
   2831 		goto err;
   2832 
   2833 	if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
   2834 		goto err;
   2835 
   2836 	if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
   2837 		{
   2838 		rtmp = ASN1_ENUMERATED_new();
   2839 		if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
   2840 			goto err;
   2841 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
   2842 			goto err;
   2843 		}
   2844 
   2845 	if (rev && comp_time)
   2846 		{
   2847 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
   2848 			goto err;
   2849 		}
   2850 	if (rev && hold)
   2851 		{
   2852 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
   2853 			goto err;
   2854 		}
   2855 
   2856 	if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
   2857 		ret = 2;
   2858 	else ret = 1;
   2859 
   2860 	err:
   2861 
   2862 	if (tmp) OPENSSL_free(tmp);
   2863 	ASN1_OBJECT_free(hold);
   2864 	ASN1_GENERALIZEDTIME_free(comp_time);
   2865 	ASN1_ENUMERATED_free(rtmp);
   2866 	ASN1_TIME_free(revDate);
   2867 
   2868 	return ret;
   2869 	}
   2870 
   2871 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
   2872 	{
   2873 	char buf[25],*pbuf, *p;
   2874 	int j;
   2875 	j=i2a_ASN1_OBJECT(bp,obj);
   2876 	pbuf=buf;
   2877 	for (j=22-j; j>0; j--)
   2878 		*(pbuf++)=' ';
   2879 	*(pbuf++)=':';
   2880 	*(pbuf++)='\0';
   2881 	BIO_puts(bp,buf);
   2882 
   2883 	if (str->type == V_ASN1_PRINTABLESTRING)
   2884 		BIO_printf(bp,"PRINTABLE:'");
   2885 	else if (str->type == V_ASN1_T61STRING)
   2886 		BIO_printf(bp,"T61STRING:'");
   2887 	else if (str->type == V_ASN1_IA5STRING)
   2888 		BIO_printf(bp,"IA5STRING:'");
   2889 	else if (str->type == V_ASN1_UNIVERSALSTRING)
   2890 		BIO_printf(bp,"UNIVERSALSTRING:'");
   2891 	else
   2892 		BIO_printf(bp,"ASN.1 %2d:'",str->type);
   2893 
   2894 	p=(char *)str->data;
   2895 	for (j=str->length; j>0; j--)
   2896 		{
   2897 		if ((*p >= ' ') && (*p <= '~'))
   2898 			BIO_printf(bp,"%c",*p);
   2899 		else if (*p & 0x80)
   2900 			BIO_printf(bp,"\\0x%02X",*p);
   2901 		else if ((unsigned char)*p == 0xf7)
   2902 			BIO_printf(bp,"^?");
   2903 		else	BIO_printf(bp,"^%c",*p+'@');
   2904 		p++;
   2905 		}
   2906 	BIO_printf(bp,"'\n");
   2907 	return 1;
   2908 	}
   2909 
   2910 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
   2911 	{
   2912 	char *tmp = NULL;
   2913 	char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
   2914 	int reason_code = -1;
   2915 	int ret = 0;
   2916 	unsigned int i;
   2917 	ASN1_OBJECT *hold = NULL;
   2918 	ASN1_GENERALIZEDTIME *comp_time = NULL;
   2919 	tmp = BUF_strdup(str);
   2920 
   2921 	p = strchr(tmp, ',');
   2922 
   2923 	rtime_str = tmp;
   2924 
   2925 	if (p)
   2926 		{
   2927 		*p = '\0';
   2928 		p++;
   2929 		reason_str = p;
   2930 		p = strchr(p, ',');
   2931 		if (p)
   2932 			{
   2933 			*p = '\0';
   2934 			arg_str = p + 1;
   2935 			}
   2936 		}
   2937 
   2938 	if (prevtm)
   2939 		{
   2940 		*prevtm = ASN1_UTCTIME_new();
   2941 		if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
   2942 			{
   2943 			BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
   2944 			goto err;
   2945 			}
   2946 		}
   2947 	if (reason_str)
   2948 		{
   2949 		for (i = 0; i < NUM_REASONS; i++)
   2950 			{
   2951 			if(!strcasecmp(reason_str, crl_reasons[i]))
   2952 				{
   2953 				reason_code = i;
   2954 				break;
   2955 				}
   2956 			}
   2957 		if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
   2958 			{
   2959 			BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
   2960 			goto err;
   2961 			}
   2962 
   2963 		if (reason_code == 7)
   2964 			reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
   2965 		else if (reason_code == 8)		/* Hold instruction */
   2966 			{
   2967 			if (!arg_str)
   2968 				{
   2969 				BIO_printf(bio_err, "missing hold instruction\n");
   2970 				goto err;
   2971 				}
   2972 			reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
   2973 			hold = OBJ_txt2obj(arg_str, 0);
   2974 
   2975 			if (!hold)
   2976 				{
   2977 				BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
   2978 				goto err;
   2979 				}
   2980 			if (phold) *phold = hold;
   2981 			}
   2982 		else if ((reason_code == 9) || (reason_code == 10))
   2983 			{
   2984 			if (!arg_str)
   2985 				{
   2986 				BIO_printf(bio_err, "missing compromised time\n");
   2987 				goto err;
   2988 				}
   2989 			comp_time = ASN1_GENERALIZEDTIME_new();
   2990 			if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
   2991 				{
   2992 				BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
   2993 				goto err;
   2994 				}
   2995 			if (reason_code == 9)
   2996 				reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
   2997 			else
   2998 				reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
   2999 			}
   3000 		}
   3001 
   3002 	if (preason) *preason = reason_code;
   3003 	if (pinvtm) *pinvtm = comp_time;
   3004 	else ASN1_GENERALIZEDTIME_free(comp_time);
   3005 
   3006 	ret = 1;
   3007 
   3008 	err:
   3009 
   3010 	if (tmp) OPENSSL_free(tmp);
   3011 	if (!phold) ASN1_OBJECT_free(hold);
   3012 	if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
   3013 
   3014 	return ret;
   3015 	}
   3016