BN_bn2hex() returns "0" instead of "00" for zero. This disrputs the
[oweals/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, 0, 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 (BN_is_zero(serial))
1162                                 BIO_printf(bio_err,"next serial number is 00\n");
1163                         else
1164                                 {
1165                                 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1166                                 BIO_printf(bio_err,"next serial number is %s\n",f);
1167                                 OPENSSL_free(f);
1168                                 }
1169                         }
1170
1171                 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1172                         {
1173                         BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1174                         goto err;
1175                         }
1176
1177                 if ((cert_sk=sk_X509_new_null()) == NULL)
1178                         {
1179                         BIO_printf(bio_err,"Memory allocation failure\n");
1180                         goto err;
1181                         }
1182                 if (spkac_file != NULL)
1183                         {
1184                         total++;
1185                         j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1186                                 serial,subj,email_dn,startdate,enddate,days,extensions,
1187                                 conf,verbose,certopt,nameopt,default_op,ext_copy);
1188                         if (j < 0) goto err;
1189                         if (j > 0)
1190                                 {
1191                                 total_done++;
1192                                 BIO_printf(bio_err,"\n");
1193                                 if (!BN_add_word(serial,1)) goto err;
1194                                 if (!sk_X509_push(cert_sk,x))
1195                                         {
1196                                         BIO_printf(bio_err,"Memory allocation failure\n");
1197                                         goto err;
1198                                         }
1199                                 if (outfile)
1200                                         {
1201                                         output_der = 1;
1202                                         batch = 1;
1203                                         }
1204                                 }
1205                         }
1206                 if (ss_cert_file != NULL)
1207                         {
1208                         total++;
1209                         j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1210                                 db,serial,subj,email_dn,startdate,enddate,days,batch,
1211                                 extensions,conf,verbose, certopt, nameopt,
1212                                 default_op, ext_copy, e);
1213                         if (j < 0) goto err;
1214                         if (j > 0)
1215                                 {
1216                                 total_done++;
1217                                 BIO_printf(bio_err,"\n");
1218                                 if (!BN_add_word(serial,1)) goto err;
1219                                 if (!sk_X509_push(cert_sk,x))
1220                                         {
1221                                         BIO_printf(bio_err,"Memory allocation failure\n");
1222                                         goto err;
1223                                         }
1224                                 }
1225                         }
1226                 if (infile != NULL)
1227                         {
1228                         total++;
1229                         j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1230                                 serial,subj,email_dn,startdate,enddate,days,batch,
1231                                 extensions,conf,verbose, certopt, nameopt,
1232                                 default_op, ext_copy);
1233                         if (j < 0) goto err;
1234                         if (j > 0)
1235                                 {
1236                                 total_done++;
1237                                 BIO_printf(bio_err,"\n");
1238                                 if (!BN_add_word(serial,1)) goto err;
1239                                 if (!sk_X509_push(cert_sk,x))
1240                                         {
1241                                         BIO_printf(bio_err,"Memory allocation failure\n");
1242                                         goto err;
1243                                         }
1244                                 }
1245                         }
1246                 for (i=0; i<argc; i++)
1247                         {
1248                         total++;
1249                         j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1250                                 serial,subj,email_dn,startdate,enddate,days,batch,
1251                                 extensions,conf,verbose, certopt, nameopt,
1252                                 default_op, ext_copy);
1253                         if (j < 0) goto err;
1254                         if (j > 0)
1255                                 {
1256                                 total_done++;
1257                                 BIO_printf(bio_err,"\n");
1258                                 if (!BN_add_word(serial,1)) goto err;
1259                                 if (!sk_X509_push(cert_sk,x))
1260                                         {
1261                                         BIO_printf(bio_err,"Memory allocation failure\n");
1262                                         goto err;
1263                                         }
1264                                 }
1265                         }       
1266                 /* we have a stack of newly certified certificates
1267                  * and a data base and serial number that need
1268                  * updating */
1269
1270                 if (sk_X509_num(cert_sk) > 0)
1271                         {
1272                         if (!batch)
1273                                 {
1274                                 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1275                                 (void)BIO_flush(bio_err);
1276                                 buf[0][0]='\0';
1277                                 fgets(buf[0],10,stdin);
1278                                 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1279                                         {
1280                                         BIO_printf(bio_err,"CERTIFICATION CANCELED\n"); 
1281                                         ret=0;
1282                                         goto err;
1283                                         }
1284                                 }
1285
1286                         BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1287
1288                         strncpy(buf[0],serialfile,BSIZE-4);
1289                         buf[0][BSIZE-4]='\0';
1290
1291 #ifdef OPENSSL_SYS_VMS
1292                         strcat(buf[0],"-new");
1293 #else
1294                         strcat(buf[0],".new");
1295 #endif
1296
1297                         if (!save_serial(buf[0],serial)) goto err;
1298
1299                         strncpy(buf[1],dbfile,BSIZE-4);
1300                         buf[1][BSIZE-4]='\0';
1301
1302 #ifdef OPENSSL_SYS_VMS
1303                         strcat(buf[1],"-new");
1304 #else
1305                         strcat(buf[1],".new");
1306 #endif
1307
1308                         if (BIO_write_filename(out,buf[1]) <= 0)
1309                                 {
1310                                 perror(dbfile);
1311                                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1312                                 goto err;
1313                                 }
1314                         l=TXT_DB_write(out,db);
1315                         if (l <= 0) goto err;
1316                         }
1317         
1318                 if (verbose)
1319                         BIO_printf(bio_err,"writing new certificates\n");
1320                 for (i=0; i<sk_X509_num(cert_sk); i++)
1321                         {
1322                         int k;
1323                         unsigned char *n;
1324
1325                         x=sk_X509_value(cert_sk,i);
1326
1327                         j=x->cert_info->serialNumber->length;
1328                         p=(char *)x->cert_info->serialNumber->data;
1329                         
1330                         strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1331                         buf[2][BSIZE-(j*2)-6]='\0';
1332
1333 #ifndef OPENSSL_SYS_VMS
1334                         strcat(buf[2],"/");
1335 #endif
1336
1337                         n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1338                         if (j > 0)
1339                                 {
1340                                 for (k=0; k<j; k++)
1341                                         {
1342                                         sprintf((char *)n,"%02X",(unsigned char)*(p++));
1343                                         n+=2;
1344                                         }
1345                                 }
1346                         else
1347                                 {
1348                                 *(n++)='0';
1349                                 *(n++)='0';
1350                                 }
1351                         *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1352                         *n='\0';
1353                         if (verbose)
1354                                 BIO_printf(bio_err,"writing %s\n",buf[2]);
1355
1356                         if (BIO_write_filename(Cout,buf[2]) <= 0)
1357                                 {
1358                                 perror(buf[2]);
1359                                 goto err;
1360                                 }
1361                         write_new_certificate(Cout,x, 0, notext);
1362                         write_new_certificate(Sout,x, output_der, notext);
1363                         }
1364
1365                 if (sk_X509_num(cert_sk))
1366                         {
1367                         /* Rename the database and the serial file */
1368                         strncpy(buf[2],serialfile,BSIZE-4);
1369                         buf[2][BSIZE-4]='\0';
1370
1371 #ifdef OPENSSL_SYS_VMS
1372                         strcat(buf[2],"-old");
1373 #else
1374                         strcat(buf[2],".old");
1375 #endif
1376
1377                         BIO_free(in);
1378                         BIO_free_all(out);
1379                         in=NULL;
1380                         out=NULL;
1381                         if (rename(serialfile,buf[2]) < 0)
1382                                 {
1383                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1384                                         serialfile,buf[2]);
1385                                 perror("reason");
1386                                 goto err;
1387                                 }
1388                         if (rename(buf[0],serialfile) < 0)
1389                                 {
1390                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1391                                         buf[0],serialfile);
1392                                 perror("reason");
1393                                 rename(buf[2],serialfile);
1394                                 goto err;
1395                                 }
1396
1397                         strncpy(buf[2],dbfile,BSIZE-4);
1398                         buf[2][BSIZE-4]='\0';
1399
1400 #ifdef OPENSSL_SYS_VMS
1401                         strcat(buf[2],"-old");
1402 #else
1403                         strcat(buf[2],".old");
1404 #endif
1405
1406                         if (rename(dbfile,buf[2]) < 0)
1407                                 {
1408                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1409                                         dbfile,buf[2]);
1410                                 perror("reason");
1411                                 goto err;
1412                                 }
1413                         if (rename(buf[1],dbfile) < 0)
1414                                 {
1415                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1416                                         buf[1],dbfile);
1417                                 perror("reason");
1418                                 rename(buf[2],dbfile);
1419                                 goto err;
1420                                 }
1421                         BIO_printf(bio_err,"Data Base Updated\n");
1422                         }
1423                 }
1424         
1425         /*****************************************************************/
1426         if (gencrl)
1427                 {
1428                 int crl_v2 = 0;
1429                 if (!crl_ext)
1430                         {
1431                         crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1432                         if (!crl_ext)
1433                                 ERR_clear_error();
1434                         }
1435                 if (crl_ext)
1436                         {
1437                         /* Check syntax of file */
1438                         X509V3_CTX ctx;
1439                         X509V3_set_ctx_test(&ctx);
1440                         X509V3_set_nconf(&ctx, conf);
1441                         if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1442                                 {
1443                                 BIO_printf(bio_err,
1444                                  "Error Loading CRL extension section %s\n",
1445                                                                  crl_ext);
1446                                 ret = 1;
1447                                 goto err;
1448                                 }
1449                         }
1450
1451                 if (!crldays && !crlhours)
1452                         {
1453                         if (!NCONF_get_number(conf,section,
1454                                 ENV_DEFAULT_CRL_DAYS, &crldays))
1455                                 crldays = 0;
1456                         if (!NCONF_get_number(conf,section,
1457                                 ENV_DEFAULT_CRL_HOURS, &crlhours))
1458                                 crlhours = 0;
1459                         }
1460                 if ((crldays == 0) && (crlhours == 0))
1461                         {
1462                         BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1463                         goto err;
1464                         }
1465
1466                 if (verbose) BIO_printf(bio_err,"making CRL\n");
1467                 if ((crl=X509_CRL_new()) == NULL) goto err;
1468                 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1469
1470                 tmptm = ASN1_TIME_new();
1471                 if (!tmptm) goto err;
1472                 X509_gmtime_adj(tmptm,0);
1473                 X509_CRL_set_lastUpdate(crl, tmptm);    
1474                 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1475                 X509_CRL_set_nextUpdate(crl, tmptm);    
1476
1477                 ASN1_TIME_free(tmptm);
1478
1479                 for (i=0; i<sk_num(db->data); i++)
1480                         {
1481                         pp=(char **)sk_value(db->data,i);
1482                         if (pp[DB_type][0] == DB_TYPE_REV)
1483                                 {
1484                                 if ((r=X509_REVOKED_new()) == NULL) goto err;
1485                                 j = make_revoked(r, pp[DB_rev_date]);
1486                                 if (!j) goto err;
1487                                 if (j == 2) crl_v2 = 1;
1488                                 if (!BN_hex2bn(&serial, pp[DB_serial]))
1489                                         goto err;
1490                                 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1491                                 BN_free(serial);
1492                                 serial = NULL;
1493                                 if (!tmpser)
1494                                         goto err;
1495                                 X509_REVOKED_set_serialNumber(r, tmpser);
1496                                 ASN1_INTEGER_free(tmpser);
1497                                 X509_CRL_add0_revoked(crl,r);
1498                                 }
1499                         }
1500
1501                 /* sort the data so it will be written in serial
1502                  * number order */
1503                 X509_CRL_sort(crl);
1504
1505                 /* we now have a CRL */
1506                 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1507                 if (md != NULL)
1508                         {
1509                         if ((dgst=EVP_get_digestbyname(md)) == NULL)
1510                                 {
1511                                 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1512                                 goto err;
1513                                 }
1514                         }
1515                 else
1516                         {
1517 #ifndef OPENSSL_NO_DSA
1518                         if (pkey->type == EVP_PKEY_DSA) 
1519                                 dgst=EVP_dss1();
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                         BIO_free_all(out);
1581                         out = NULL;
1582                         BIO_free_all(in);
1583                         in = NULL;
1584                         strncpy(buf[1],dbfile,BSIZE-4);
1585                         buf[1][BSIZE-4]='\0';
1586 #ifndef OPENSSL_SYS_VMS
1587                         strcat(buf[1],".old");
1588 #else
1589                         strcat(buf[1],"-old");
1590 #endif
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\n");
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         if (BN_is_zero(serial))
2098                 row[DB_serial]=BUF_strdup("00");
2099         else
2100                 row[DB_serial]=BN_bn2hex(serial);
2101         if (row[DB_serial] == NULL)
2102                 {
2103                 BIO_printf(bio_err,"Memory allocation failure\n");
2104                 goto err;
2105                 }
2106
2107         rrow=TXT_DB_get_by_index(db,DB_name,row);
2108         if (rrow != NULL)
2109                 {
2110                 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2111                         row[DB_name]);
2112                 }
2113         else
2114                 {
2115                 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2116                 if (rrow != NULL)
2117                         {
2118                         BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2119                                 row[DB_serial]);
2120                         BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
2121                         }
2122                 }
2123
2124         if (rrow != NULL)
2125                 {
2126                 BIO_printf(bio_err,
2127                         "The matching entry has the following details\n");
2128                 if (rrow[DB_type][0] == 'E')
2129                         p="Expired";
2130                 else if (rrow[DB_type][0] == 'R')
2131                         p="Revoked";
2132                 else if (rrow[DB_type][0] == 'V')
2133                         p="Valid";
2134                 else
2135                         p="\ninvalid type, Data base error\n";
2136                 BIO_printf(bio_err,"Type          :%s\n",p);;
2137                 if (rrow[DB_type][0] == 'R')
2138                         {
2139                         p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2140                         BIO_printf(bio_err,"Was revoked on:%s\n",p);
2141                         }
2142                 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2143                 BIO_printf(bio_err,"Expires on    :%s\n",p);
2144                 p=rrow[DB_serial]; if (p == NULL) p="undef";
2145                 BIO_printf(bio_err,"Serial Number :%s\n",p);
2146                 p=rrow[DB_file]; if (p == NULL) p="undef";
2147                 BIO_printf(bio_err,"File name     :%s\n",p);
2148                 p=rrow[DB_name]; if (p == NULL) p="undef";
2149                 BIO_printf(bio_err,"Subject Name  :%s\n",p);
2150                 ok= -1; /* This is now a 'bad' error. */
2151                 goto err;
2152                 }
2153
2154         /* We are now totally happy, lets make and sign the certificate */
2155         if (verbose)
2156                 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2157
2158         if ((ret=X509_new()) == NULL) goto err;
2159         ci=ret->cert_info;
2160
2161 #ifdef X509_V3
2162         /* Make it an X509 v3 certificate. */
2163         if (!X509_set_version(x509,2)) goto err;
2164 #endif
2165
2166         if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2167                 goto err;
2168         if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2169                 goto err;
2170
2171         if (strcmp(startdate,"today") == 0)
2172                 X509_gmtime_adj(X509_get_notBefore(ret),0);
2173         else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2174
2175         if (enddate == NULL)
2176                 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2177         else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2178
2179         if (!X509_set_subject_name(ret,subject)) goto err;
2180
2181         pktmp=X509_REQ_get_pubkey(req);
2182         i = X509_set_pubkey(ret,pktmp);
2183         EVP_PKEY_free(pktmp);
2184         if (!i) goto err;
2185
2186         /* Lets add the extensions, if there are any */
2187         if (ext_sect)
2188                 {
2189                 X509V3_CTX ctx;
2190                 if (ci->version == NULL)
2191                         if ((ci->version=ASN1_INTEGER_new()) == NULL)
2192                                 goto err;
2193                 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2194
2195                 /* Free the current entries if any, there should not
2196                  * be any I believe */
2197                 if (ci->extensions != NULL)
2198                         sk_X509_EXTENSION_pop_free(ci->extensions,
2199                                                    X509_EXTENSION_free);
2200
2201                 ci->extensions = NULL;
2202
2203                 /* Initialize the context structure */
2204                 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2205
2206                 if (extconf)
2207                         {
2208                         if (verbose)
2209                                 BIO_printf(bio_err, "Extra configuration file found\n");
2210  
2211                         /* Use the extconf configuration db LHASH */
2212                         X509V3_set_nconf(&ctx, extconf);
2213  
2214                         /* Test the structure (needed?) */
2215                         /* X509V3_set_ctx_test(&ctx); */
2216
2217                         /* Adds exts contained in the configuration file */
2218                         if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2219                                 {
2220                                 BIO_printf(bio_err,
2221                                     "ERROR: adding extensions in section %s\n",
2222                                                                 ext_sect);
2223                                 ERR_print_errors(bio_err);
2224                                 goto err;
2225                                 }
2226                         if (verbose)
2227                                 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2228                         }
2229                 else if (ext_sect)
2230                         {
2231                         /* We found extensions to be set from config file */
2232                         X509V3_set_nconf(&ctx, lconf);
2233
2234                         if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2235                                 {
2236                                 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2237                                 ERR_print_errors(bio_err);
2238                                 goto err;
2239                                 }
2240
2241                         if (verbose) 
2242                                 BIO_printf(bio_err, "Successfully added extensions from config\n");
2243                         }
2244                 }
2245
2246         /* Copy extensions from request (if any) */
2247
2248         if (!copy_extensions(ret, req, ext_copy))
2249                 {
2250                 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2251                 ERR_print_errors(bio_err);
2252                 goto err;
2253                 }
2254
2255         /* Set the right value for the noemailDN option */
2256         if( email_dn == 0 )
2257                 {
2258                 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2259                 }
2260
2261         if (!default_op)
2262                 {
2263                 BIO_printf(bio_err, "Certificate Details:\n");
2264                 /* Never print signature details because signature not present */
2265                 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2266                 X509_print_ex(bio_err, ret, nameopt, certopt); 
2267                 }
2268
2269         BIO_printf(bio_err,"Certificate is to be certified until ");
2270         ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2271         if (days) BIO_printf(bio_err," (%d days)",days);
2272         BIO_printf(bio_err, "\n");
2273
2274         if (!batch)
2275                 {
2276
2277                 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2278                 (void)BIO_flush(bio_err);
2279                 buf[0]='\0';
2280                 fgets(buf,sizeof(buf)-1,stdin);
2281                 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2282                         {
2283                         BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2284                         ok=0;
2285                         goto err;
2286                         }
2287                 }
2288
2289
2290 #ifndef OPENSSL_NO_DSA
2291         if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2292         pktmp=X509_get_pubkey(ret);
2293         if (EVP_PKEY_missing_parameters(pktmp) &&
2294                 !EVP_PKEY_missing_parameters(pkey))
2295                 EVP_PKEY_copy_parameters(pktmp,pkey);
2296         EVP_PKEY_free(pktmp);
2297 #endif
2298
2299         if (!X509_sign(ret,pkey,dgst))
2300                 goto err;
2301
2302         /* We now just add it to the database */
2303         row[DB_type]=(char *)OPENSSL_malloc(2);
2304
2305         tm=X509_get_notAfter(ret);
2306         row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2307         memcpy(row[DB_exp_date],tm->data,tm->length);
2308         row[DB_exp_date][tm->length]='\0';
2309
2310         row[DB_rev_date]=NULL;
2311
2312         /* row[DB_serial] done already */
2313         row[DB_file]=(char *)OPENSSL_malloc(8);
2314         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2315
2316         if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2317                 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2318                 {
2319                 BIO_printf(bio_err,"Memory allocation failure\n");
2320                 goto err;
2321                 }
2322         strcpy(row[DB_file],"unknown");
2323         row[DB_type][0]='V';
2324         row[DB_type][1]='\0';
2325
2326         if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2327                 {
2328                 BIO_printf(bio_err,"Memory allocation failure\n");
2329                 goto err;
2330                 }
2331
2332         for (i=0; i<DB_NUMBER; i++)
2333                 {
2334                 irow[i]=row[i];
2335                 row[i]=NULL;
2336                 }
2337         irow[DB_NUMBER]=NULL;
2338
2339         if (!TXT_DB_insert(db,irow))
2340                 {
2341                 BIO_printf(bio_err,"failed to update database\n");
2342                 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2343                 goto err;
2344                 }
2345         ok=1;
2346 err:
2347         for (i=0; i<DB_NUMBER; i++)
2348                 if (row[i] != NULL) OPENSSL_free(row[i]);
2349
2350         if (CAname != NULL)
2351                 X509_NAME_free(CAname);
2352         if (subject != NULL)
2353                 X509_NAME_free(subject);
2354         if ((dn_subject != NULL) && !email_dn)
2355                 X509_NAME_free(dn_subject);
2356         if (tmptm != NULL)
2357                 ASN1_UTCTIME_free(tmptm);
2358         if (ok <= 0)
2359                 {
2360                 if (ret != NULL) X509_free(ret);
2361                 ret=NULL;
2362                 }
2363         else
2364                 *xret=ret;
2365         return(ok);
2366         }
2367
2368 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2369         {
2370
2371         if (output_der)
2372                 {
2373                 (void)i2d_X509_bio(bp,x);
2374                 return;
2375                 }
2376 #if 0
2377         /* ??? Not needed since X509_print prints all this stuff anyway */
2378         f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2379         BIO_printf(bp,"issuer :%s\n",f);
2380
2381         f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2382         BIO_printf(bp,"subject:%s\n",f);
2383
2384         BIO_puts(bp,"serial :");
2385         i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2386         BIO_puts(bp,"\n\n");
2387 #endif
2388         if (!notext)X509_print(bp,x);
2389         PEM_write_bio_X509(bp,x);
2390         }
2391
2392 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2393              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2394              BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2395              long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2396              unsigned long nameopt, int default_op, int ext_copy)
2397         {
2398         STACK_OF(CONF_VALUE) *sk=NULL;
2399         LHASH *parms=NULL;
2400         X509_REQ *req=NULL;
2401         CONF_VALUE *cv=NULL;
2402         NETSCAPE_SPKI *spki = NULL;
2403         X509_REQ_INFO *ri;
2404         char *type,*buf;
2405         EVP_PKEY *pktmp=NULL;
2406         X509_NAME *n=NULL;
2407         X509_NAME_ENTRY *ne=NULL;
2408         int ok= -1,i,j;
2409         long errline;
2410         int nid;
2411
2412         /*
2413          * Load input file into a hash table.  (This is just an easy
2414          * way to read and parse the file, then put it into a convenient
2415          * STACK format).
2416          */
2417         parms=CONF_load(NULL,infile,&errline);
2418         if (parms == NULL)
2419                 {
2420                 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2421                 ERR_print_errors(bio_err);
2422                 goto err;
2423                 }
2424
2425         sk=CONF_get_section(parms, "default");
2426         if (sk_CONF_VALUE_num(sk) == 0)
2427                 {
2428                 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2429                 CONF_free(parms);
2430                 goto err;
2431                 }
2432
2433         /*
2434          * Now create a dummy X509 request structure.  We don't actually
2435          * have an X509 request, but we have many of the components
2436          * (a public key, various DN components).  The idea is that we
2437          * put these components into the right X509 request structure
2438          * and we can use the same code as if you had a real X509 request.
2439          */
2440         req=X509_REQ_new();
2441         if (req == NULL)
2442                 {
2443                 ERR_print_errors(bio_err);
2444                 goto err;
2445                 }
2446
2447         /*
2448          * Build up the subject name set.
2449          */
2450         ri=req->req_info;
2451         n = ri->subject;
2452
2453         for (i = 0; ; i++)
2454                 {
2455                 if (sk_CONF_VALUE_num(sk) <= i) break;
2456
2457                 cv=sk_CONF_VALUE_value(sk,i);
2458                 type=cv->name;
2459                 /* Skip past any leading X. X: X, etc to allow for
2460                  * multiple instances
2461                  */
2462                 for (buf = cv->name; *buf ; buf++)
2463                         if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2464                                 {
2465                                 buf++;
2466                                 if (*buf) type = buf;
2467                                 break;
2468                                 }
2469
2470                 buf=cv->value;
2471                 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2472                         {
2473                         if (strcmp(type, "SPKAC") == 0)
2474                                 {
2475                                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2476                                 if (spki == NULL)
2477                                         {
2478                                         BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2479                                         ERR_print_errors(bio_err);
2480                                         goto err;
2481                                         }
2482                                 }
2483                         continue;
2484                         }
2485
2486                 /*
2487                 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2488                         continue;
2489                 */
2490                 
2491                 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2492                 if (fix_data(nid, &j) == 0)
2493                         {
2494                         BIO_printf(bio_err,
2495                                 "invalid characters in string %s\n",buf);
2496                         goto err;
2497                         }
2498
2499                 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2500                         (unsigned char *)buf,
2501                         strlen(buf))) == NULL)
2502                         goto err;
2503
2504                 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2505                 }
2506         if (spki == NULL)
2507                 {
2508                 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2509                         infile);
2510                 goto err;
2511                 }
2512
2513         /*
2514          * Now extract the key from the SPKI structure.
2515          */
2516
2517         BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2518
2519         if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2520                 {
2521                 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2522                 goto err;
2523                 }
2524
2525         j = NETSCAPE_SPKI_verify(spki, pktmp);
2526         if (j <= 0)
2527                 {
2528                 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2529                 goto err;
2530                 }
2531         BIO_printf(bio_err,"Signature ok\n");
2532
2533         X509_REQ_set_pubkey(req,pktmp);
2534         EVP_PKEY_free(pktmp);
2535         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2536                    days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2537                         ext_copy);
2538 err:
2539         if (req != NULL) X509_REQ_free(req);
2540         if (parms != NULL) CONF_free(parms);
2541         if (spki != NULL) NETSCAPE_SPKI_free(spki);
2542         if (ne != NULL) X509_NAME_ENTRY_free(ne);
2543
2544         return(ok);
2545         }
2546
2547 static int fix_data(int nid, int *type)
2548         {
2549         if (nid == NID_pkcs9_emailAddress)
2550                 *type=V_ASN1_IA5STRING;
2551         if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2552                 *type=V_ASN1_T61STRING;
2553         if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2554                 *type=V_ASN1_T61STRING;
2555         if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2556                 return(0);
2557         if (nid == NID_pkcs9_unstructuredName)
2558                 *type=V_ASN1_IA5STRING;
2559         return(1);
2560         }
2561
2562 static int check_time_format(char *str)
2563         {
2564         ASN1_UTCTIME tm;
2565
2566         tm.data=(unsigned char *)str;
2567         tm.length=strlen(str);
2568         tm.type=V_ASN1_UTCTIME;
2569         return(ASN1_UTCTIME_check(&tm));
2570         }
2571
2572 static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2573         {
2574         ASN1_UTCTIME *tm=NULL;
2575         char *row[DB_NUMBER],**rrow,**irow;
2576         char *rev_str = NULL;
2577         BIGNUM *bn = NULL;
2578         int ok=-1,i;
2579
2580         for (i=0; i<DB_NUMBER; i++)
2581                 row[i]=NULL;
2582         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2583         bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2584         if (BN_is_zero(bn))
2585                 row[DB_serial]=BUF_strdup("00");
2586         else
2587                 row[DB_serial]=BN_bn2hex(bn);
2588         BN_free(bn);
2589         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2590                 {
2591                 BIO_printf(bio_err,"Memory allocation failure\n");
2592                 goto err;
2593                 }
2594         /* We have to lookup by serial number because name lookup
2595          * skips revoked certs
2596          */
2597         rrow=TXT_DB_get_by_index(db,DB_serial,row);
2598         if (rrow == NULL)
2599                 {
2600                 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2601
2602                 /* We now just add it to the database */
2603                 row[DB_type]=(char *)OPENSSL_malloc(2);
2604
2605                 tm=X509_get_notAfter(x509);
2606                 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2607                 memcpy(row[DB_exp_date],tm->data,tm->length);
2608                 row[DB_exp_date][tm->length]='\0';
2609
2610                 row[DB_rev_date]=NULL;
2611
2612                 /* row[DB_serial] done already */
2613                 row[DB_file]=(char *)OPENSSL_malloc(8);
2614
2615                 /* row[DB_name] done already */
2616
2617                 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2618                         (row[DB_file] == NULL))
2619                         {
2620                         BIO_printf(bio_err,"Memory allocation failure\n");
2621                         goto err;
2622                         }
2623                 strcpy(row[DB_file],"unknown");
2624                 row[DB_type][0]='V';
2625                 row[DB_type][1]='\0';
2626
2627                 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2628                         {
2629                         BIO_printf(bio_err,"Memory allocation failure\n");
2630                         goto err;
2631                         }
2632
2633                 for (i=0; i<DB_NUMBER; i++)
2634                         {
2635                         irow[i]=row[i];
2636                         row[i]=NULL;
2637                         }
2638                 irow[DB_NUMBER]=NULL;
2639
2640                 if (!TXT_DB_insert(db,irow))
2641                         {
2642                         BIO_printf(bio_err,"failed to update database\n");
2643                         BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2644                         goto err;
2645                         }
2646
2647                 /* Revoke Certificate */
2648                 ok = do_revoke(x509,db, type, value);
2649
2650                 goto err;
2651
2652                 }
2653         else if (index_name_cmp((const char **)row,(const char **)rrow))
2654                 {
2655                 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2656                            row[DB_name]);
2657                 goto err;
2658                 }
2659         else if (rrow[DB_type][0]=='R')
2660                 {
2661                 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2662                            row[DB_serial]);
2663                 goto err;
2664                 }
2665         else
2666                 {
2667                 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2668                 rev_str = make_revocation_str(type, value);
2669                 if (!rev_str)
2670                         {
2671                         BIO_printf(bio_err, "Error in revocation arguments\n");
2672                         goto err;
2673                         }
2674                 rrow[DB_type][0]='R';
2675                 rrow[DB_type][1]='\0';
2676                 rrow[DB_rev_date] = rev_str;
2677                 }
2678         ok=1;
2679 err:
2680         for (i=0; i<DB_NUMBER; i++)
2681                 {
2682                 if (row[i] != NULL) 
2683                         OPENSSL_free(row[i]);
2684                 }
2685         return(ok);
2686         }
2687
2688 static int get_certificate_status(const char *serial, TXT_DB *db)
2689         {
2690         char *row[DB_NUMBER],**rrow;
2691         int ok=-1,i;
2692
2693         /* Free Resources */
2694         for (i=0; i<DB_NUMBER; i++)
2695                 row[i]=NULL;
2696
2697         /* Malloc needed char spaces */
2698         row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2699         if (row[DB_serial] == NULL)
2700                 {
2701                 BIO_printf(bio_err,"Malloc failure\n");
2702                 goto err;
2703                 }
2704
2705         if (strlen(serial) % 2)
2706                 {
2707                 /* Set the first char to 0 */;
2708                 row[DB_serial][0]='0';
2709
2710                 /* Copy String from serial to row[DB_serial] */
2711                 memcpy(row[DB_serial]+1, serial, strlen(serial));
2712                 row[DB_serial][strlen(serial)+1]='\0';
2713                 }
2714         else
2715                 {
2716                 /* Copy String from serial to row[DB_serial] */
2717                 memcpy(row[DB_serial], serial, strlen(serial));
2718                 row[DB_serial][strlen(serial)]='\0';
2719                 }
2720                         
2721         /* Make it Upper Case */
2722         for (i=0; row[DB_serial][i] != '\0'; i++)
2723                 row[DB_serial][i] = toupper(row[DB_serial][i]);
2724         
2725
2726         ok=1;
2727
2728         /* Search for the certificate */
2729         rrow=TXT_DB_get_by_index(db,DB_serial,row);
2730         if (rrow == NULL)
2731                 {
2732                 BIO_printf(bio_err,"Serial %s not present in db.\n",
2733                                  row[DB_serial]);
2734                 ok=-1;
2735                 goto err;
2736                 }
2737         else if (rrow[DB_type][0]=='V')
2738                 {
2739                 BIO_printf(bio_err,"%s=Valid (%c)\n",
2740                         row[DB_serial], rrow[DB_type][0]);
2741                 goto err;
2742                 }
2743         else if (rrow[DB_type][0]=='R')
2744                 {
2745                 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2746                         row[DB_serial], rrow[DB_type][0]);
2747                 goto err;
2748                 }
2749         else if (rrow[DB_type][0]=='E')
2750                 {
2751                 BIO_printf(bio_err,"%s=Expired (%c)\n",
2752                         row[DB_serial], rrow[DB_type][0]);
2753                 goto err;
2754                 }
2755         else if (rrow[DB_type][0]=='S')
2756                 {
2757                 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2758                         row[DB_serial], rrow[DB_type][0]);
2759                 goto err;
2760                 }
2761         else
2762                 {
2763                 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2764                         row[DB_serial], rrow[DB_type][0]);
2765                 ok=-1;
2766                 }
2767 err:
2768         for (i=0; i<DB_NUMBER; i++)
2769                 {
2770                 if (row[i] != NULL)
2771                         OPENSSL_free(row[i]);
2772                 }
2773         return(ok);
2774         }
2775
2776 static int do_updatedb (TXT_DB *db)
2777         {
2778         ASN1_UTCTIME    *a_tm = NULL;
2779         int i, cnt = 0;
2780         int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */ 
2781         char **rrow, *a_tm_s;
2782
2783         a_tm = ASN1_UTCTIME_new();
2784
2785         /* get actual time and make a string */
2786         a_tm = X509_gmtime_adj(a_tm, 0);
2787         a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2788         if (a_tm_s == NULL)
2789                 {
2790                 cnt = -1;
2791                 goto err;
2792                 }
2793
2794         memcpy(a_tm_s, a_tm->data, a_tm->length);
2795         a_tm_s[a_tm->length] = '\0';
2796
2797         if (strncmp(a_tm_s, "49", 2) <= 0)
2798                 a_y2k = 1;
2799         else
2800                 a_y2k = 0;
2801
2802         for (i = 0; i < sk_num(db->data); i++)
2803                 {
2804                 rrow = (char **) sk_value(db->data, i);
2805
2806                 if (rrow[DB_type][0] == 'V')
2807                         {
2808                         /* ignore entries that are not valid */
2809                         if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2810                                 db_y2k = 1;
2811                         else
2812                                 db_y2k = 0;
2813
2814                         if (db_y2k == a_y2k)
2815                                 {
2816                                 /* all on the same y2k side */
2817                                 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2818                                         {
2819                                         rrow[DB_type][0]  = 'E';
2820                                         rrow[DB_type][1]  = '\0';
2821                                         cnt++;
2822
2823                                         BIO_printf(bio_err, "%s=Expired\n",
2824                                                         rrow[DB_serial]);
2825                                         }
2826                                 }
2827                         else if (db_y2k < a_y2k)
2828                                 {
2829                                 rrow[DB_type][0]  = 'E';
2830                                 rrow[DB_type][1]  = '\0';
2831                                 cnt++;
2832
2833                                 BIO_printf(bio_err, "%s=Expired\n",
2834                                                         rrow[DB_serial]);
2835                                 }
2836
2837                         }
2838                 }
2839
2840 err:
2841
2842         ASN1_UTCTIME_free(a_tm);
2843         OPENSSL_free(a_tm_s);
2844
2845         return (cnt);
2846         }
2847
2848 static char *crl_reasons[] = {
2849         /* CRL reason strings */
2850         "unspecified",
2851         "keyCompromise",
2852         "CACompromise",
2853         "affiliationChanged",
2854         "superseded", 
2855         "cessationOfOperation",
2856         "certificateHold",
2857         "removeFromCRL",
2858         /* Additional pseudo reasons */
2859         "holdInstruction",
2860         "keyTime",
2861         "CAkeyTime"
2862 };
2863
2864 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2865
2866 /* Given revocation information convert to a DB string.
2867  * The format of the string is:
2868  * revtime[,reason,extra]. Where 'revtime' is the
2869  * revocation time (the current time). 'reason' is the
2870  * optional CRL reason and 'extra' is any additional
2871  * argument
2872  */
2873
2874 char *make_revocation_str(int rev_type, char *rev_arg)
2875         {
2876         char *reason = NULL, *other = NULL, *str;
2877         ASN1_OBJECT *otmp;
2878         ASN1_UTCTIME *revtm = NULL;
2879         int i;
2880         switch (rev_type)
2881                 {
2882         case REV_NONE:
2883                 break;
2884
2885         case REV_CRL_REASON:
2886                 for (i = 0; i < 8; i++)
2887                         {
2888                         if (!strcasecmp(rev_arg, crl_reasons[i]))
2889                                 {
2890                                 reason = crl_reasons[i];
2891                                 break;
2892                                 }
2893                         }
2894                 if (reason == NULL)
2895                         {
2896                         BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2897                         return NULL;
2898                         }
2899                 break;
2900
2901         case REV_HOLD:
2902                 /* Argument is an OID */
2903
2904                 otmp = OBJ_txt2obj(rev_arg, 0);
2905                 ASN1_OBJECT_free(otmp);
2906
2907                 if (otmp == NULL)
2908                         {
2909                         BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2910                         return NULL;
2911                         }
2912
2913                 reason = "holdInstruction";
2914                 other = rev_arg;
2915                 break;
2916                 
2917         case REV_KEY_COMPROMISE:
2918         case REV_CA_COMPROMISE:
2919
2920                 /* Argument is the key compromise time  */
2921                 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2922                         {       
2923                         BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2924                         return NULL;
2925                         }
2926                 other = rev_arg;
2927                 if (rev_type == REV_KEY_COMPROMISE)
2928                         reason = "keyTime";
2929                 else 
2930                         reason = "CAkeyTime";
2931
2932                 break;
2933
2934                 }
2935
2936         revtm = X509_gmtime_adj(NULL, 0);
2937
2938         i = revtm->length + 1;
2939
2940         if (reason) i += strlen(reason) + 1;
2941         if (other) i += strlen(other) + 1;
2942
2943         str = OPENSSL_malloc(i);
2944
2945         if (!str) return NULL;
2946
2947         strcpy(str, (char *)revtm->data);
2948         if (reason)
2949                 {
2950                 strcat(str, ",");
2951                 strcat(str, reason);
2952                 }
2953         if (other)
2954                 {
2955                 strcat(str, ",");
2956                 strcat(str, other);
2957                 }
2958         ASN1_UTCTIME_free(revtm);
2959         return str;
2960         }
2961
2962 /* Convert revocation field to X509_REVOKED entry 
2963  * return code:
2964  * 0 error
2965  * 1 OK
2966  * 2 OK and some extensions added (i.e. V2 CRL)
2967  */
2968
2969
2970 int make_revoked(X509_REVOKED *rev, char *str)
2971         {
2972         char *tmp = NULL;
2973         int reason_code = -1;
2974         int i, ret = 0;
2975         ASN1_OBJECT *hold = NULL;
2976         ASN1_GENERALIZEDTIME *comp_time = NULL;
2977         ASN1_ENUMERATED *rtmp = NULL;
2978
2979         ASN1_TIME *revDate = NULL;
2980
2981         i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2982
2983         if (i == 0)
2984                 goto err;
2985
2986         if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2987                 goto err;
2988
2989         if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2990                 {
2991                 rtmp = ASN1_ENUMERATED_new();
2992                 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2993                         goto err;
2994                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2995                         goto err;
2996                 }
2997
2998         if (rev && comp_time)
2999                 {
3000                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3001                         goto err;
3002                 }
3003         if (rev && hold)
3004                 {
3005                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3006                         goto err;
3007                 }
3008
3009         if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3010                 ret = 2;
3011         else ret = 1;
3012
3013         err:
3014
3015         if (tmp) OPENSSL_free(tmp);
3016         ASN1_OBJECT_free(hold);
3017         ASN1_GENERALIZEDTIME_free(comp_time);
3018         ASN1_ENUMERATED_free(rtmp);
3019         ASN1_TIME_free(revDate);
3020
3021         return ret;
3022         }
3023
3024 /*
3025  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
3026  * where characters may be escaped by \
3027  */
3028 X509_NAME *do_subject(char *subject, long chtype)
3029         {
3030         size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
3031         char *buf = OPENSSL_malloc(buflen);
3032         size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
3033         char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
3034         char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
3035
3036         char *sp = subject, *bp = buf;
3037         int i, ne_num = 0;
3038
3039         X509_NAME *n = NULL;
3040         int nid;
3041
3042         if (!buf || !ne_types || !ne_values)
3043         {
3044                 BIO_printf(bio_err, "malloc error\n");
3045                 goto error;
3046         }
3047
3048         if (*subject != '/')
3049         {
3050                 BIO_printf(bio_err, "Subject does not start with '/'.\n");
3051                 goto error;
3052         }
3053         sp++; /* skip leading / */
3054
3055         while (*sp)
3056         {
3057                 /* collect type */
3058                 ne_types[ne_num] = bp;
3059                 while (*sp)
3060                 {
3061                         if (*sp == '\\') /* is there anything to escape in the type...? */
3062                                 if (*++sp)
3063                                         *bp++ = *sp++;
3064                                 else
3065                                 {
3066                                         BIO_printf(bio_err, "escape character at end of string\n");
3067                                         goto error;
3068                                 }
3069                         else if (*sp == '=')
3070                         {
3071                                 sp++;
3072                                 *bp++ = '\0';
3073                                 break;
3074                         }
3075                         else
3076                                 *bp++ = *sp++;
3077                 }
3078                 if (!*sp)
3079                 {
3080                         BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
3081                         goto error;
3082                 }
3083                 ne_values[ne_num] = bp;
3084                 while (*sp)
3085                 {
3086                         if (*sp == '\\')
3087                                 if (*++sp)
3088                                         *bp++ = *sp++;
3089                                 else
3090                                 {
3091                                         BIO_printf(bio_err, "escape character at end of string\n");
3092                                         goto error;
3093                                 }
3094                         else if (*sp == '/')
3095                         {
3096                                 sp++;
3097                                 break;
3098                         }
3099                         else
3100                                 *bp++ = *sp++;
3101                 }
3102                 *bp++ = '\0';
3103                 ne_num++;
3104         }
3105
3106         if (!(n = X509_NAME_new()))
3107                 goto error;
3108
3109         for (i = 0; i < ne_num; i++)
3110                 {
3111                 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
3112                         {
3113                         BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
3114                         continue;
3115                         }
3116
3117                 if (!*ne_values[i])
3118                         {
3119                         BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
3120                         continue;
3121                         }
3122
3123                 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
3124                         goto error;
3125                 }
3126
3127         OPENSSL_free(ne_values);
3128         OPENSSL_free(ne_types);
3129         OPENSSL_free(buf);
3130         return n;
3131
3132 error:
3133         X509_NAME_free(n);
3134         if (ne_values)
3135                 OPENSSL_free(ne_values);
3136         if (ne_types)
3137                 OPENSSL_free(ne_types);
3138         if (buf)
3139                 OPENSSL_free(buf);
3140         return NULL;
3141 }
3142
3143 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3144         {
3145         char buf[25],*pbuf, *p;
3146         int j;
3147         j=i2a_ASN1_OBJECT(bp,obj);
3148         pbuf=buf;
3149         for (j=22-j; j>0; j--)
3150                 *(pbuf++)=' ';
3151         *(pbuf++)=':';
3152         *(pbuf++)='\0';
3153         BIO_puts(bp,buf);
3154
3155         if (str->type == V_ASN1_PRINTABLESTRING)
3156                 BIO_printf(bp,"PRINTABLE:'");
3157         else if (str->type == V_ASN1_T61STRING)
3158                 BIO_printf(bp,"T61STRING:'");
3159         else if (str->type == V_ASN1_IA5STRING)
3160                 BIO_printf(bp,"IA5STRING:'");
3161         else if (str->type == V_ASN1_UNIVERSALSTRING)
3162                 BIO_printf(bp,"UNIVERSALSTRING:'");
3163         else
3164                 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3165                         
3166         p=(char *)str->data;
3167         for (j=str->length; j>0; j--)
3168                 {
3169                 if ((*p >= ' ') && (*p <= '~'))
3170                         BIO_printf(bp,"%c",*p);
3171                 else if (*p & 0x80)
3172                         BIO_printf(bp,"\\0x%02X",*p);
3173                 else if ((unsigned char)*p == 0xf7)
3174                         BIO_printf(bp,"^?");
3175                 else    BIO_printf(bp,"^%c",*p+'@');
3176                 p++;
3177                 }
3178         BIO_printf(bp,"'\n");
3179         return 1;
3180         }
3181
3182 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
3183         {
3184         char *tmp = NULL;
3185         char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3186         int reason_code = -1;
3187         int i, ret = 0;
3188         ASN1_OBJECT *hold = NULL;
3189         ASN1_GENERALIZEDTIME *comp_time = NULL;
3190         tmp = BUF_strdup(str);
3191
3192         p = strchr(tmp, ',');
3193
3194         rtime_str = tmp;
3195
3196         if (p)
3197                 {
3198                 *p = '\0';
3199                 p++;
3200                 reason_str = p;
3201                 p = strchr(p, ',');
3202                 if (p)
3203                         {
3204                         *p = '\0';
3205                         arg_str = p + 1;
3206                         }
3207                 }
3208
3209         if (prevtm)
3210                 {
3211                 *prevtm = ASN1_UTCTIME_new();
3212                 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3213                         {
3214                         BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3215                         goto err;
3216                         }
3217                 }
3218         if (reason_str)
3219                 {
3220                 for (i = 0; i < NUM_REASONS; i++)
3221                         {
3222                         if(!strcasecmp(reason_str, crl_reasons[i]))
3223                                 {
3224                                 reason_code = i;
3225                                 break;
3226                                 }
3227                         }
3228                 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3229                         {
3230                         BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3231                         goto err;
3232                         }
3233
3234                 if (reason_code == 7)
3235                         reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3236                 else if (reason_code == 8)              /* Hold instruction */
3237                         {
3238                         if (!arg_str)
3239                                 {       
3240                                 BIO_printf(bio_err, "missing hold instruction\n");
3241                                 goto err;
3242                                 }
3243                         reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3244                         hold = OBJ_txt2obj(arg_str, 0);
3245
3246                         if (!hold)
3247                                 {
3248                                 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3249                                 goto err;
3250                                 }
3251                         if (phold) *phold = hold;
3252                         }
3253                 else if ((reason_code == 9) || (reason_code == 10))
3254                         {
3255                         if (!arg_str)
3256                                 {       
3257                                 BIO_printf(bio_err, "missing compromised time\n");
3258                                 goto err;
3259                                 }
3260                         comp_time = ASN1_GENERALIZEDTIME_new();
3261                         if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3262                                 {       
3263                                 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3264                                 goto err;
3265                                 }
3266                         if (reason_code == 9)
3267                                 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3268                         else
3269                                 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3270                         }
3271                 }
3272
3273         if (preason) *preason = reason_code;
3274         if (pinvtm) *pinvtm = comp_time;
3275         else ASN1_GENERALIZEDTIME_free(comp_time);
3276
3277         ret = 1;
3278
3279         err:
3280
3281         if (tmp) OPENSSL_free(tmp);
3282         if (!phold) ASN1_OBJECT_free(hold);
3283         if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3284
3285         return ret;
3286         }
3287
3288 int make_serial_index(TXT_DB *db)
3289         {
3290         if (!TXT_DB_create_index(db, DB_serial, NULL,
3291                                 LHASH_HASH_FN(index_serial_hash),
3292                                 LHASH_COMP_FN(index_serial_cmp)))
3293                 {
3294                 BIO_printf(bio_err,
3295                   "error creating serial number index:(%ld,%ld,%ld)\n",
3296                                         db->error,db->arg1,db->arg2);
3297                         return 0;
3298                 }
3299         return 1;
3300         }