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