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