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