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