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