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