First step in tidying up the LHASH code. The callback prototypes (and
[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 <sys/types.h>
65 #include <sys/stat.h>
66 #include "apps.h"
67 #include <openssl/conf.h>
68 #include <openssl/bio.h>
69 #include <openssl/err.h>
70 #include <openssl/bn.h>
71 #include <openssl/txt_db.h>
72 #include <openssl/evp.h>
73 #include <openssl/x509.h>
74 #include <openssl/x509v3.h>
75 #include <openssl/objects.h>
76 #include <openssl/pem.h>
77 #include <openssl/engine.h>
78
79 #ifndef W_OK
80 #  ifdef VMS
81 #    if defined(__DECC)
82 #      include <unistd.h>
83 #    else
84 #      include <unixlib.h>
85 #    endif
86 #  else
87 #    include <sys/file.h>
88 #  endif
89 #endif
90
91 #ifndef W_OK
92 #  define F_OK 0
93 #  define X_OK 1
94 #  define W_OK 2
95 #  define R_OK 4
96 #endif
97
98 #undef PROG
99 #define PROG ca_main
100
101 #define BASE_SECTION    "ca"
102 #define CONFIG_FILE "openssl.cnf"
103
104 #define ENV_DEFAULT_CA          "default_ca"
105
106 #define ENV_DIR                 "dir"
107 #define ENV_CERTS               "certs"
108 #define ENV_CRL_DIR             "crl_dir"
109 #define ENV_CA_DB               "CA_DB"
110 #define ENV_NEW_CERTS_DIR       "new_certs_dir"
111 #define ENV_CERTIFICATE         "certificate"
112 #define ENV_SERIAL              "serial"
113 #define ENV_CRL                 "crl"
114 #define ENV_PRIVATE_KEY         "private_key"
115 #define ENV_RANDFILE            "RANDFILE"
116 #define ENV_DEFAULT_DAYS        "default_days"
117 #define ENV_DEFAULT_STARTDATE   "default_startdate"
118 #define ENV_DEFAULT_ENDDATE     "default_enddate"
119 #define ENV_DEFAULT_CRL_DAYS    "default_crl_days"
120 #define ENV_DEFAULT_CRL_HOURS   "default_crl_hours"
121 #define ENV_DEFAULT_MD          "default_md"
122 #define ENV_PRESERVE            "preserve"
123 #define ENV_POLICY              "policy"
124 #define ENV_EXTENSIONS          "x509_extensions"
125 #define ENV_CRLEXT              "crl_extensions"
126 #define ENV_MSIE_HACK           "msie_hack"
127
128 #define ENV_DATABASE            "database"
129
130 #define DB_type         0
131 #define DB_exp_date     1
132 #define DB_rev_date     2
133 #define DB_serial       3       /* index - unique */
134 #define DB_file         4       
135 #define DB_name         5       /* index - unique for active */
136 #define DB_NUMBER       6
137
138 #define DB_TYPE_REV     'R'
139 #define DB_TYPE_EXP     'E'
140 #define DB_TYPE_VAL     'V'
141
142 static char *ca_usage[]={
143 "usage: ca args\n",
144 "\n",
145 " -verbose        - Talk alot while doing things\n",
146 " -config file    - A config file\n",
147 " -name arg       - The particular CA definition to use\n",
148 " -gencrl         - Generate a new CRL\n",
149 " -crldays days   - Days is when the next CRL is due\n",
150 " -crlhours hours - Hours is when the next CRL is due\n",
151 " -startdate YYMMDDHHMMSSZ  - certificate validity notBefore\n",
152 " -enddate YYMMDDHHMMSSZ    - certificate validity notAfter (overrides -days)\n",
153 " -days arg       - number of days to certify the certificate for\n",
154 " -md arg         - md to use, one of md2, md5, sha or sha1\n",
155 " -policy arg     - The CA 'policy' to support\n",
156 " -keyfile arg    - private key file\n",
157 " -keyform arg    - private key file format (PEM or ENGINE)\n",
158 " -key arg        - key to decode the private key if it is encrypted\n",
159 " -cert file      - The CA certificate\n",
160 " -in file        - The input PEM encoded certificate request(s)\n",
161 " -out file       - Where to put the output file(s)\n",
162 " -outdir dir     - Where to put output certificates\n",
163 " -infiles ....   - The last argument, requests to process\n",
164 " -spkac file     - File contains DN and signed public key and challenge\n",
165 " -ss_cert file   - File contains a self signed cert to sign\n",
166 " -preserveDN     - Don't re-order the DN\n",
167 " -batch          - Don't ask questions\n",
168 " -msie_hack      - msie modifications to handle all those universal strings\n",
169 " -revoke file    - Revoke a certificate (given in file)\n",
170 " -extensions ..  - Extension section (override value in config file)\n",
171 " -crlexts ..     - CRL extension section (override value in config file)\n",
172 " -engine e       - use engine e, possibly a hardware device.\n",
173 NULL
174 };
175
176 #ifdef EFENCE
177 extern int EF_PROTECT_FREE;
178 extern int EF_PROTECT_BELOW;
179 extern int EF_ALIGNMENT;
180 #endif
181
182 static void lookup_fail(char *name,char *tag);
183 static unsigned long index_serial_hash(char **a);
184 static int index_serial_cmp(char **a, char **b);
185 static unsigned long index_name_hash(char **a);
186 static int index_name_qual(char **a);
187 static int index_name_cmp(char **a,char **b);
188 static BIGNUM *load_serial(char *serialfile);
189 static int save_serial(char *serialfile, BIGNUM *serial);
190 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
191                    const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
192                    BIGNUM *serial, char *startdate,char *enddate, int days,
193                    int batch, char *ext_sect, LHASH *conf,int verbose);
194 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
195                         const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
196                         TXT_DB *db, BIGNUM *serial,char *startdate,
197                         char *enddate, int days, int batch, char *ext_sect,
198                         LHASH *conf,int verbose);
199 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
200                          const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
201                          TXT_DB *db, BIGNUM *serial,char *startdate,
202                          char *enddate, int days, char *ext_sect,LHASH *conf,
203                                 int verbose);
204 static int fix_data(int nid, int *type);
205 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
206 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
207         STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
208         char *startdate, char *enddate, int days, int batch, int verbose,
209         X509_REQ *req, char *ext_sect, LHASH *conf);
210 static int do_revoke(X509 *x509, TXT_DB *db);
211 static int check_time_format(char *str);
212 static LHASH *conf=NULL;
213 static char *section=NULL;
214
215 static int preserve=0;
216 static int msie_hack=0;
217
218 int MAIN(int, char **);
219
220 int MAIN(int argc, char **argv)
221         {
222         ENGINE *e = NULL;
223         char *key=NULL,*passargin=NULL;
224         int total=0;
225         int total_done=0;
226         int badops=0;
227         int ret=1;
228         int req=0;
229         int verbose=0;
230         int gencrl=0;
231         int dorevoke=0;
232         long crldays=0;
233         long crlhours=0;
234         long errorline= -1;
235         char *configfile=NULL;
236         char *md=NULL;
237         char *policy=NULL;
238         char *keyfile=NULL;
239         char *certfile=NULL;
240         int keyform=FORMAT_PEM;
241         char *infile=NULL;
242         char *spkac_file=NULL;
243         char *ss_cert_file=NULL;
244         EVP_PKEY *pkey=NULL;
245         int output_der = 0;
246         char *outfile=NULL;
247         char *outdir=NULL;
248         char *serialfile=NULL;
249         char *extensions=NULL;
250         char *crl_ext=NULL;
251         BIGNUM *serial=NULL;
252         char *startdate=NULL;
253         char *enddate=NULL;
254         int days=0;
255         int batch=0;
256         int notext=0;
257         X509 *x509=NULL;
258         X509 *x=NULL;
259         BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
260         char *dbfile=NULL;
261         TXT_DB *db=NULL;
262         X509_CRL *crl=NULL;
263         X509_CRL_INFO *ci=NULL;
264         X509_REVOKED *r=NULL;
265         char **pp,*p,*f;
266         int i,j;
267         long l;
268         const EVP_MD *dgst=NULL;
269         STACK_OF(CONF_VALUE) *attribs=NULL;
270         STACK_OF(X509) *cert_sk=NULL;
271         BIO *hex=NULL;
272 #undef BSIZE
273 #define BSIZE 256
274         MS_STATIC char buf[3][BSIZE];
275         char *randfile=NULL;
276         char *engine = NULL;
277
278 #ifdef EFENCE
279 EF_PROTECT_FREE=1;
280 EF_PROTECT_BELOW=1;
281 EF_ALIGNMENT=0;
282 #endif
283
284         apps_startup();
285
286         conf = NULL;
287         key = NULL;
288         section = NULL;
289
290         preserve=0;
291         msie_hack=0;
292         if (bio_err == NULL)
293                 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
294                         BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
295
296         argc--;
297         argv++;
298         while (argc >= 1)
299                 {
300                 if      (strcmp(*argv,"-verbose") == 0)
301                         verbose=1;
302                 else if (strcmp(*argv,"-config") == 0)
303                         {
304                         if (--argc < 1) goto bad;
305                         configfile= *(++argv);
306                         }
307                 else if (strcmp(*argv,"-name") == 0)
308                         {
309                         if (--argc < 1) goto bad;
310                         section= *(++argv);
311                         }
312                 else if (strcmp(*argv,"-startdate") == 0)
313                         {
314                         if (--argc < 1) goto bad;
315                         startdate= *(++argv);
316                         }
317                 else if (strcmp(*argv,"-enddate") == 0)
318                         {
319                         if (--argc < 1) goto bad;
320                         enddate= *(++argv);
321                         }
322                 else if (strcmp(*argv,"-days") == 0)
323                         {
324                         if (--argc < 1) goto bad;
325                         days=atoi(*(++argv));
326                         }
327                 else if (strcmp(*argv,"-md") == 0)
328                         {
329                         if (--argc < 1) goto bad;
330                         md= *(++argv);
331                         }
332                 else if (strcmp(*argv,"-policy") == 0)
333                         {
334                         if (--argc < 1) goto bad;
335                         policy= *(++argv);
336                         }
337                 else if (strcmp(*argv,"-keyfile") == 0)
338                         {
339                         if (--argc < 1) goto bad;
340                         keyfile= *(++argv);
341                         }
342                 else if (strcmp(*argv,"-keyform") == 0)
343                         {
344                         if (--argc < 1) goto bad;
345                         keyform=str2fmt(*(++argv));
346                         }
347                 else if (strcmp(*argv,"-passin") == 0)
348                         {
349                         if (--argc < 1) goto bad;
350                         passargin= *(++argv);
351                         }
352                 else if (strcmp(*argv,"-key") == 0)
353                         {
354                         if (--argc < 1) goto bad;
355                         key= *(++argv);
356                         }
357                 else if (strcmp(*argv,"-cert") == 0)
358                         {
359                         if (--argc < 1) goto bad;
360                         certfile= *(++argv);
361                         }
362                 else if (strcmp(*argv,"-in") == 0)
363                         {
364                         if (--argc < 1) goto bad;
365                         infile= *(++argv);
366                         req=1;
367                         }
368                 else if (strcmp(*argv,"-out") == 0)
369                         {
370                         if (--argc < 1) goto bad;
371                         outfile= *(++argv);
372                         }
373                 else if (strcmp(*argv,"-outdir") == 0)
374                         {
375                         if (--argc < 1) goto bad;
376                         outdir= *(++argv);
377                         }
378                 else if (strcmp(*argv,"-notext") == 0)
379                         notext=1;
380                 else if (strcmp(*argv,"-batch") == 0)
381                         batch=1;
382                 else if (strcmp(*argv,"-preserveDN") == 0)
383                         preserve=1;
384                 else if (strcmp(*argv,"-gencrl") == 0)
385                         gencrl=1;
386                 else if (strcmp(*argv,"-msie_hack") == 0)
387                         msie_hack=1;
388                 else if (strcmp(*argv,"-crldays") == 0)
389                         {
390                         if (--argc < 1) goto bad;
391                         crldays= atol(*(++argv));
392                         }
393                 else if (strcmp(*argv,"-crlhours") == 0)
394                         {
395                         if (--argc < 1) goto bad;
396                         crlhours= atol(*(++argv));
397                         }
398                 else if (strcmp(*argv,"-infiles") == 0)
399                         {
400                         argc--;
401                         argv++;
402                         req=1;
403                         break;
404                         }
405                 else if (strcmp(*argv, "-ss_cert") == 0)
406                         {
407                         if (--argc < 1) goto bad;
408                         ss_cert_file = *(++argv);
409                         req=1;
410                         }
411                 else if (strcmp(*argv, "-spkac") == 0)
412                         {
413                         if (--argc < 1) goto bad;
414                         spkac_file = *(++argv);
415                         req=1;
416                         }
417                 else if (strcmp(*argv,"-revoke") == 0)
418                         {
419                         if (--argc < 1) goto bad;
420                         infile= *(++argv);
421                         dorevoke=1;
422                         }
423                 else if (strcmp(*argv,"-extensions") == 0)
424                         {
425                         if (--argc < 1) goto bad;
426                         extensions= *(++argv);
427                         }
428                 else if (strcmp(*argv,"-crlexts") == 0)
429                         {
430                         if (--argc < 1) goto bad;
431                         crl_ext= *(++argv);
432                         }
433                 else if (strcmp(*argv,"-engine") == 0)
434                         {
435                         if (--argc < 1) goto bad;
436                         engine= *(++argv);
437                         }
438                 else
439                         {
440 bad:
441                         BIO_printf(bio_err,"unknown option %s\n",*argv);
442                         badops=1;
443                         break;
444                         }
445                 argc--;
446                 argv++;
447                 }
448
449         if (badops)
450                 {
451                 for (pp=ca_usage; (*pp != NULL); pp++)
452                         BIO_printf(bio_err,*pp);
453                 goto err;
454                 }
455
456         ERR_load_crypto_strings();
457
458         if (engine != NULL)
459                 {
460                 if((e = ENGINE_by_id(engine)) == NULL)
461                         {
462                         BIO_printf(bio_err,"invalid engine \"%s\"\n",
463                                 engine);
464                         goto err;
465                         }
466                 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
467                         {
468                         BIO_printf(bio_err,"can't use that engine\n");
469                         goto err;
470                         }
471                 BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
472                 /* Free our "structural" reference. */
473                 ENGINE_free(e);
474                 }
475
476         /*****************************************************************/
477         if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
478         if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
479         if (configfile == NULL)
480                 {
481                 /* We will just use 'buf[0]' as a temporary buffer.  */
482 #ifdef VMS
483                 strncpy(buf[0],X509_get_default_cert_area(),
484                         sizeof(buf[0])-1-sizeof(CONFIG_FILE));
485 #else
486                 strncpy(buf[0],X509_get_default_cert_area(),
487                         sizeof(buf[0])-2-sizeof(CONFIG_FILE));
488                 strcat(buf[0],"/");
489 #endif
490                 strcat(buf[0],CONFIG_FILE);
491                 configfile=buf[0];
492                 }
493
494         BIO_printf(bio_err,"Using configuration from %s\n",configfile);
495         if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
496                 {
497                 if (errorline <= 0)
498                         BIO_printf(bio_err,"error loading the config file '%s'\n",
499                                 configfile);
500                 else
501                         BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
502                                 ,errorline,configfile);
503                 goto err;
504                 }
505
506         /* Lets get the config section we are using */
507         if (section == NULL)
508                 {
509                 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
510                 if (section == NULL)
511                         {
512                         lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
513                         goto err;
514                         }
515                 }
516
517         if (conf != NULL)
518                 {
519                 p=CONF_get_string(conf,NULL,"oid_file");
520                 if (p != NULL)
521                         {
522                         BIO *oid_bio;
523
524                         oid_bio=BIO_new_file(p,"r");
525                         if (oid_bio == NULL) 
526                                 {
527                                 /*
528                                 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
529                                 ERR_print_errors(bio_err);
530                                 */
531                                 ERR_clear_error();
532                                 }
533                         else
534                                 {
535                                 OBJ_create_objects(oid_bio);
536                                 BIO_free(oid_bio);
537                                 }
538                         }
539                 if(!add_oid_section(bio_err,conf)) 
540                         {
541                         ERR_print_errors(bio_err);
542                         goto err;
543                         }
544                 }
545
546         randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
547         app_RAND_load_file(randfile, bio_err, 0);
548         
549         in=BIO_new(BIO_s_file());
550         out=BIO_new(BIO_s_file());
551         Sout=BIO_new(BIO_s_file());
552         Cout=BIO_new(BIO_s_file());
553         if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
554                 {
555                 ERR_print_errors(bio_err);
556                 goto err;
557                 }
558
559         /*****************************************************************/
560         /* we definitely need an public key, so lets get it */
561
562         if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
563                 section,ENV_PRIVATE_KEY)) == NULL))
564                 {
565                 lookup_fail(section,ENV_PRIVATE_KEY);
566                 goto err;
567                 }
568         if(!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
569                 {
570                 BIO_printf(bio_err,"Error getting password\n");
571                 goto err;
572                 }
573         if (keyform == FORMAT_ENGINE)
574                 {
575                 if (!e)
576                         {
577                         BIO_printf(bio_err,"no engine specified\n");
578                         goto err;
579                         }
580                 pkey = ENGINE_load_private_key(e, keyfile, key);
581                 }
582         else if (keyform == FORMAT_PEM)
583                 {
584                 if (BIO_read_filename(in,keyfile) <= 0)
585                         {
586                         perror(keyfile);
587                         BIO_printf(bio_err,"trying to load CA private key\n");
588                         goto err;
589                         }
590                 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
591                 }
592         else
593                 {
594                 BIO_printf(bio_err,"bad input format specified for key file\n");
595                 goto err;
596                 }
597         if(key) memset(key,0,strlen(key));
598         if (pkey == NULL)
599                 {
600                 BIO_printf(bio_err,"unable to load CA private key\n");
601                 goto err;
602                 }
603
604         /*****************************************************************/
605         /* we need a certificate */
606         if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
607                 section,ENV_CERTIFICATE)) == NULL))
608                 {
609                 lookup_fail(section,ENV_CERTIFICATE);
610                 goto err;
611                 }
612         if (BIO_read_filename(in,certfile) <= 0)
613                 {
614                 perror(certfile);
615                 BIO_printf(bio_err,"trying to load CA certificate\n");
616                 goto err;
617                 }
618         x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
619         if (x509 == NULL)
620                 {
621                 BIO_printf(bio_err,"unable to load CA certificate\n");
622                 goto err;
623                 }
624
625         if (!X509_check_private_key(x509,pkey))
626                 {
627                 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
628                 goto err;
629                 }
630
631         f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
632         if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
633                 preserve=1;
634         f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
635         if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
636                 msie_hack=1;
637
638         /*****************************************************************/
639         /* lookup where to write new certificates */
640         if ((outdir == NULL) && (req))
641                 {
642                 struct stat sb;
643
644                 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
645                         == NULL)
646                         {
647                         BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
648                         goto err;
649                         }
650 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
651                filename.  In any case, stat(), below, will catch the problem
652                if outdir is not a directory spec, and the fopen() or open()
653                will catch an error if there is no write access.
654
655                Presumably, this problem could also be solved by using the DEC
656                C routines to convert the directory syntax to Unixly, and give
657                that to access().  However, time's too short to do that just
658                now.
659             */
660                 if (access(outdir,R_OK|W_OK|X_OK) != 0)
661                         {
662                         BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
663                         perror(outdir);
664                         goto err;
665                         }
666
667                 if (stat(outdir,&sb) != 0)
668                         {
669                         BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
670                         perror(outdir);
671                         goto err;
672                         }
673 #ifdef S_IFDIR
674                 if (!(sb.st_mode & S_IFDIR))
675                         {
676                         BIO_printf(bio_err,"%s need to be a directory\n",outdir);
677                         perror(outdir);
678                         goto err;
679                         }
680 #endif
681 #endif
682                 }
683
684         /*****************************************************************/
685         /* we need to load the database file */
686         if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
687                 {
688                 lookup_fail(section,ENV_DATABASE);
689                 goto err;
690                 }
691         if (BIO_read_filename(in,dbfile) <= 0)
692                 {
693                 perror(dbfile);
694                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
695                 goto err;
696                 }
697         db=TXT_DB_read(in,DB_NUMBER);
698         if (db == NULL) goto err;
699
700         /* Lets check some fields */
701         for (i=0; i<sk_num(db->data); i++)
702                 {
703                 pp=(char **)sk_value(db->data,i);
704                 if ((pp[DB_type][0] != DB_TYPE_REV) &&
705                         (pp[DB_rev_date][0] != '\0'))
706                         {
707                         BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
708                         goto err;
709                         }
710                 if ((pp[DB_type][0] == DB_TYPE_REV) &&
711                         !check_time_format(pp[DB_rev_date]))
712                         {
713                         BIO_printf(bio_err,"entry %d: invalid revocation date\n",
714                                 i+1);
715                         goto err;
716                         }
717                 if (!check_time_format(pp[DB_exp_date]))
718                         {
719                         BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
720                         goto err;
721                         }
722                 p=pp[DB_serial];
723                 j=strlen(p);
724                 if ((j&1) || (j < 2))
725                         {
726                         BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
727                         goto err;
728                         }
729                 while (*p)
730                         {
731                         if (!(  ((*p >= '0') && (*p <= '9')) ||
732                                 ((*p >= 'A') && (*p <= 'F')) ||
733                                 ((*p >= 'a') && (*p <= 'f')))  )
734                                 {
735                                 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);
736                                 goto err;
737                                 }
738                         p++;
739                         }
740                 }
741         if (verbose)
742                 {
743                 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
744 #ifdef VMS
745                 {
746                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
747                 out = BIO_push(tmpbio, out);
748                 }
749 #endif
750                 TXT_DB_write(out,db);
751                 BIO_printf(bio_err,"%d entries loaded from the database\n",
752                         db->data->num);
753                 BIO_printf(bio_err,"generating index\n");
754                 }
755         
756         if (!TXT_DB_create_index(db, DB_serial, NULL,
757                         (LHASH_HASH_FN_TYPE)index_serial_hash,
758                         (LHASH_COMP_FN_TYPE)index_serial_cmp))
759                 {
760                 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
761                 goto err;
762                 }
763
764         if (!TXT_DB_create_index(db, DB_name, index_name_qual,
765                         (LHASH_HASH_FN_TYPE)index_name_hash,
766                         (LHASH_COMP_FN_TYPE)index_name_cmp))
767                 {
768                 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
769                         db->error,db->arg1,db->arg2);
770                 goto err;
771                 }
772
773         /*****************************************************************/
774         if (req || gencrl)
775                 {
776                 if (outfile != NULL)
777                         {
778
779                         if (BIO_write_filename(Sout,outfile) <= 0)
780                                 {
781                                 perror(outfile);
782                                 goto err;
783                                 }
784                         }
785                 else
786                         {
787                         BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
788 #ifdef VMS
789                         {
790                         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
791                         Sout = BIO_push(tmpbio, Sout);
792                         }
793 #endif
794                         }
795                 }
796
797         if (req)
798                 {
799                 if ((md == NULL) && ((md=CONF_get_string(conf,
800                         section,ENV_DEFAULT_MD)) == NULL))
801                         {
802                         lookup_fail(section,ENV_DEFAULT_MD);
803                         goto err;
804                         }
805                 if ((dgst=EVP_get_digestbyname(md)) == NULL)
806                         {
807                         BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
808                         goto err;
809                         }
810                 if (verbose)
811                         BIO_printf(bio_err,"message digest is %s\n",
812                                 OBJ_nid2ln(dgst->type));
813                 if ((policy == NULL) && ((policy=CONF_get_string(conf,
814                         section,ENV_POLICY)) == NULL))
815                         {
816                         lookup_fail(section,ENV_POLICY);
817                         goto err;
818                         }
819                 if (verbose)
820                         BIO_printf(bio_err,"policy is %s\n",policy);
821
822                 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
823                         == NULL)
824                         {
825                         lookup_fail(section,ENV_SERIAL);
826                         goto err;
827                         }
828                 if(!extensions)
829                         extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
830                 if(extensions) {
831                         /* Check syntax of file */
832                         X509V3_CTX ctx;
833                         X509V3_set_ctx_test(&ctx);
834                         X509V3_set_conf_lhash(&ctx, conf);
835                         if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
836                                 BIO_printf(bio_err,
837                                  "Error Loading extension section %s\n",
838                                                                  extensions);
839                                 ret = 1;
840                                 goto err;
841                         }
842                 }
843
844                 if (startdate == NULL)
845                         {
846                         startdate=CONF_get_string(conf,section,
847                                 ENV_DEFAULT_STARTDATE);
848                         }
849                 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
850                         {
851                         BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
852                         goto err;
853                         }
854                 if (startdate == NULL) startdate="today";
855
856                 if (enddate == NULL)
857                         {
858                         enddate=CONF_get_string(conf,section,
859                                 ENV_DEFAULT_ENDDATE);
860                         }
861                 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
862                         {
863                         BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
864                         goto err;
865                         }
866
867                 if (days == 0)
868                         {
869                         days=(int)CONF_get_number(conf,section,
870                                 ENV_DEFAULT_DAYS);
871                         }
872                 if (!enddate && (days == 0))
873                         {
874                         BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
875                         goto err;
876                         }
877
878                 if ((serial=load_serial(serialfile)) == NULL)
879                         {
880                         BIO_printf(bio_err,"error while loading serial number\n");
881                         goto err;
882                         }
883                 if (verbose)
884                         {
885                         if ((f=BN_bn2hex(serial)) == NULL) goto err;
886                         BIO_printf(bio_err,"next serial number is %s\n",f);
887                         OPENSSL_free(f);
888                         }
889
890                 if ((attribs=CONF_get_section(conf,policy)) == NULL)
891                         {
892                         BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
893                         goto err;
894                         }
895
896                 if ((cert_sk=sk_X509_new_null()) == NULL)
897                         {
898                         BIO_printf(bio_err,"Memory allocation failure\n");
899                         goto err;
900                         }
901                 if (spkac_file != NULL)
902                         {
903                         total++;
904                         j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
905                                 serial,startdate,enddate, days,extensions,conf,
906                                 verbose);
907                         if (j < 0) goto err;
908                         if (j > 0)
909                                 {
910                                 total_done++;
911                                 BIO_printf(bio_err,"\n");
912                                 if (!BN_add_word(serial,1)) goto err;
913                                 if (!sk_X509_push(cert_sk,x))
914                                         {
915                                         BIO_printf(bio_err,"Memory allocation failure\n");
916                                         goto err;
917                                         }
918                                 if (outfile)
919                                         {
920                                         output_der = 1;
921                                         batch = 1;
922                                         }
923                                 }
924                         }
925                 if (ss_cert_file != NULL)
926                         {
927                         total++;
928                         j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
929                                 db,serial,startdate,enddate,days,batch,
930                                 extensions,conf,verbose);
931                         if (j < 0) goto err;
932                         if (j > 0)
933                                 {
934                                 total_done++;
935                                 BIO_printf(bio_err,"\n");
936                                 if (!BN_add_word(serial,1)) goto err;
937                                 if (!sk_X509_push(cert_sk,x))
938                                         {
939                                         BIO_printf(bio_err,"Memory allocation failure\n");
940                                         goto err;
941                                         }
942                                 }
943                         }
944                 if (infile != NULL)
945                         {
946                         total++;
947                         j=certify(&x,infile,pkey,x509,dgst,attribs,db,
948                                 serial,startdate,enddate,days,batch,
949                                 extensions,conf,verbose);
950                         if (j < 0) goto err;
951                         if (j > 0)
952                                 {
953                                 total_done++;
954                                 BIO_printf(bio_err,"\n");
955                                 if (!BN_add_word(serial,1)) goto err;
956                                 if (!sk_X509_push(cert_sk,x))
957                                         {
958                                         BIO_printf(bio_err,"Memory allocation failure\n");
959                                         goto err;
960                                         }
961                                 }
962                         }
963                 for (i=0; i<argc; i++)
964                         {
965                         total++;
966                         j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
967                                 serial,startdate,enddate,days,batch,
968                                 extensions,conf,verbose);
969                         if (j < 0) goto err;
970                         if (j > 0)
971                                 {
972                                 total_done++;
973                                 BIO_printf(bio_err,"\n");
974                                 if (!BN_add_word(serial,1)) goto err;
975                                 if (!sk_X509_push(cert_sk,x))
976                                         {
977                                         BIO_printf(bio_err,"Memory allocation failure\n");
978                                         goto err;
979                                         }
980                                 }
981                         }       
982                 /* we have a stack of newly certified certificates
983                  * and a data base and serial number that need
984                  * updating */
985
986                 if (sk_X509_num(cert_sk) > 0)
987                         {
988                         if (!batch)
989                                 {
990                                 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
991                                 (void)BIO_flush(bio_err);
992                                 buf[0][0]='\0';
993                                 fgets(buf[0],10,stdin);
994                                 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
995                                         {
996                                         BIO_printf(bio_err,"CERTIFICATION CANCELED\n"); 
997                                         ret=0;
998                                         goto err;
999                                         }
1000                                 }
1001
1002                         BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1003
1004                         strncpy(buf[0],serialfile,BSIZE-4);
1005
1006 #ifdef VMS
1007                         strcat(buf[0],"-new");
1008 #else
1009                         strcat(buf[0],".new");
1010 #endif
1011
1012                         if (!save_serial(buf[0],serial)) goto err;
1013
1014                         strncpy(buf[1],dbfile,BSIZE-4);
1015
1016 #ifdef VMS
1017                         strcat(buf[1],"-new");
1018 #else
1019                         strcat(buf[1],".new");
1020 #endif
1021
1022                         if (BIO_write_filename(out,buf[1]) <= 0)
1023                                 {
1024                                 perror(dbfile);
1025                                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1026                                 goto err;
1027                                 }
1028                         l=TXT_DB_write(out,db);
1029                         if (l <= 0) goto err;
1030                         }
1031         
1032                 if (verbose)
1033                         BIO_printf(bio_err,"writing new certificates\n");
1034                 for (i=0; i<sk_X509_num(cert_sk); i++)
1035                         {
1036                         int k;
1037                         unsigned char *n;
1038
1039                         x=sk_X509_value(cert_sk,i);
1040
1041                         j=x->cert_info->serialNumber->length;
1042                         p=(char *)x->cert_info->serialNumber->data;
1043                         
1044                         strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1045
1046 #ifndef VMS
1047                         strcat(buf[2],"/");
1048 #endif
1049
1050                         n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1051                         if (j > 0)
1052                                 {
1053                                 for (k=0; k<j; k++)
1054                                         {
1055                                         sprintf((char *)n,"%02X",(unsigned char)*(p++));
1056                                         n+=2;
1057                                         }
1058                                 }
1059                         else
1060                                 {
1061                                 *(n++)='0';
1062                                 *(n++)='0';
1063                                 }
1064                         *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1065                         *n='\0';
1066                         if (verbose)
1067                                 BIO_printf(bio_err,"writing %s\n",buf[2]);
1068
1069                         if (BIO_write_filename(Cout,buf[2]) <= 0)
1070                                 {
1071                                 perror(buf[2]);
1072                                 goto err;
1073                                 }
1074                         write_new_certificate(Cout,x, 0, notext);
1075                         write_new_certificate(Sout,x, output_der, notext);
1076                         }
1077
1078                 if (sk_X509_num(cert_sk))
1079                         {
1080                         /* Rename the database and the serial file */
1081                         strncpy(buf[2],serialfile,BSIZE-4);
1082
1083 #ifdef VMS
1084                         strcat(buf[2],"-old");
1085 #else
1086                         strcat(buf[2],".old");
1087 #endif
1088
1089                         BIO_free(in);
1090                         BIO_free_all(out);
1091                         in=NULL;
1092                         out=NULL;
1093                         if (rename(serialfile,buf[2]) < 0)
1094                                 {
1095                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1096                                         serialfile,buf[2]);
1097                                 perror("reason");
1098                                 goto err;
1099                                 }
1100                         if (rename(buf[0],serialfile) < 0)
1101                                 {
1102                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1103                                         buf[0],serialfile);
1104                                 perror("reason");
1105                                 rename(buf[2],serialfile);
1106                                 goto err;
1107                                 }
1108
1109                         strncpy(buf[2],dbfile,BSIZE-4);
1110
1111 #ifdef VMS
1112                         strcat(buf[2],"-old");
1113 #else
1114                         strcat(buf[2],".old");
1115 #endif
1116
1117                         if (rename(dbfile,buf[2]) < 0)
1118                                 {
1119                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1120                                         dbfile,buf[2]);
1121                                 perror("reason");
1122                                 goto err;
1123                                 }
1124                         if (rename(buf[1],dbfile) < 0)
1125                                 {
1126                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1127                                         buf[1],dbfile);
1128                                 perror("reason");
1129                                 rename(buf[2],dbfile);
1130                                 goto err;
1131                                 }
1132                         BIO_printf(bio_err,"Data Base Updated\n");
1133                         }
1134                 }
1135         
1136         /*****************************************************************/
1137         if (gencrl)
1138                 {
1139                 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1140                 if(crl_ext) {
1141                         /* Check syntax of file */
1142                         X509V3_CTX ctx;
1143                         X509V3_set_ctx_test(&ctx);
1144                         X509V3_set_conf_lhash(&ctx, conf);
1145                         if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1146                                 BIO_printf(bio_err,
1147                                  "Error Loading CRL extension section %s\n",
1148                                                                  crl_ext);
1149                                 ret = 1;
1150                                 goto err;
1151                         }
1152                 }
1153                 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1154
1155                 if (!crldays && !crlhours)
1156                         {
1157                         crldays=CONF_get_number(conf,section,
1158                                 ENV_DEFAULT_CRL_DAYS);
1159                         crlhours=CONF_get_number(conf,section,
1160                                 ENV_DEFAULT_CRL_HOURS);
1161                         }
1162                 if ((crldays == 0) && (crlhours == 0))
1163                         {
1164                         BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1165                         goto err;
1166                         }
1167
1168                 if (verbose) BIO_printf(bio_err,"making CRL\n");
1169                 if ((crl=X509_CRL_new()) == NULL) goto err;
1170                 ci=crl->crl;
1171                 X509_NAME_free(ci->issuer);
1172                 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1173                 if (ci->issuer == NULL) goto err;
1174
1175                 X509_gmtime_adj(ci->lastUpdate,0);
1176                 if (ci->nextUpdate == NULL)
1177                         ci->nextUpdate=ASN1_UTCTIME_new();
1178                 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1179
1180                 for (i=0; i<sk_num(db->data); i++)
1181                         {
1182                         pp=(char **)sk_value(db->data,i);
1183                         if (pp[DB_type][0] == DB_TYPE_REV)
1184                                 {
1185                                 if ((r=X509_REVOKED_new()) == NULL) goto err;
1186                                 ASN1_STRING_set((ASN1_STRING *)
1187                                         r->revocationDate,
1188                                         (unsigned char *)pp[DB_rev_date],
1189                                         strlen(pp[DB_rev_date]));
1190                                 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1191
1192                                 (void)BIO_reset(hex);
1193                                 if (!BIO_puts(hex,pp[DB_serial]))
1194                                         goto err;
1195                                 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1196                                         buf[0],BSIZE)) goto err;
1197
1198                                 sk_X509_REVOKED_push(ci->revoked,r);
1199                                 }
1200                         }
1201                 /* sort the data so it will be written in serial
1202                  * number order */
1203                 sk_X509_REVOKED_sort(ci->revoked);
1204                 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1205                         {
1206                         r=sk_X509_REVOKED_value(ci->revoked,i);
1207                         r->sequence=i;
1208                         }
1209
1210                 /* we now have a CRL */
1211                 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1212                 if (md != NULL)
1213                         {
1214                         if ((dgst=EVP_get_digestbyname(md)) == NULL)
1215                                 {
1216                                 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1217                                 goto err;
1218                                 }
1219                         }
1220                 else
1221                     {
1222 #ifndef NO_DSA
1223                     if (pkey->type == EVP_PKEY_DSA) 
1224                         dgst=EVP_dss1();
1225                     else
1226 #endif
1227                         dgst=EVP_md5();
1228                     }
1229
1230                 /* Add any extensions asked for */
1231
1232                 if(crl_ext) {
1233                     X509V3_CTX crlctx;
1234                     if (ci->version == NULL)
1235                     if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1236                     ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1237                     X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1238                     X509V3_set_conf_lhash(&crlctx, conf);
1239
1240                     if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1241                                                  crl_ext, crl)) goto err;
1242                 }
1243
1244                 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1245
1246                 PEM_write_bio_X509_CRL(Sout,crl);
1247                 }
1248         /*****************************************************************/
1249         if (dorevoke)
1250                 {
1251                 if (infile == NULL) 
1252                         {
1253                         BIO_printf(bio_err,"no input files\n");
1254                         goto err;
1255                         }
1256                 else
1257                         {
1258                         X509 *revcert;
1259                         if (BIO_read_filename(in,infile) <= 0)
1260                                 {
1261                                 perror(infile);
1262                                 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1263                                 goto err;
1264                                 }
1265                         revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1266                         if (revcert == NULL)
1267                                 {
1268                                 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1269                                 goto err;
1270                                 }
1271                         j=do_revoke(revcert,db);
1272                         if (j <= 0) goto err;
1273                         X509_free(revcert);
1274
1275                         strncpy(buf[0],dbfile,BSIZE-4);
1276                         strcat(buf[0],".new");
1277                         if (BIO_write_filename(out,buf[0]) <= 0)
1278                                 {
1279                                 perror(dbfile);
1280                                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1281                                 goto err;
1282                                 }
1283                         j=TXT_DB_write(out,db);
1284                         if (j <= 0) goto err;
1285                         strncpy(buf[1],dbfile,BSIZE-4);
1286                         strcat(buf[1],".old");
1287                         if (rename(dbfile,buf[1]) < 0)
1288                                 {
1289                                 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1290                                 perror("reason");
1291                                 goto err;
1292                                 }
1293                         if (rename(buf[0],dbfile) < 0)
1294                                 {
1295                                 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1296                                 perror("reason");
1297                                 rename(buf[1],dbfile);
1298                                 goto err;
1299                                 }
1300                         BIO_printf(bio_err,"Data Base Updated\n"); 
1301                         }
1302                 }
1303         /*****************************************************************/
1304         ret=0;
1305 err:
1306         BIO_free(hex);
1307         BIO_free_all(Cout);
1308         BIO_free_all(Sout);
1309         BIO_free_all(out);
1310         BIO_free(in);
1311
1312         sk_X509_pop_free(cert_sk,X509_free);
1313
1314         if (ret) ERR_print_errors(bio_err);
1315         app_RAND_write_file(randfile, bio_err);
1316         BN_free(serial);
1317         TXT_DB_free(db);
1318         EVP_PKEY_free(pkey);
1319         X509_free(x509);
1320         X509_CRL_free(crl);
1321         CONF_free(conf);
1322         OBJ_cleanup();
1323         EXIT(ret);
1324         }
1325
1326 static void lookup_fail(char *name, char *tag)
1327         {
1328         BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1329         }
1330
1331 static unsigned long index_serial_hash(char **a)
1332         {
1333         char *n;
1334
1335         n=a[DB_serial];
1336         while (*n == '0') n++;
1337         return(lh_strhash(n));
1338         }
1339
1340 static int index_serial_cmp(char **a, char **b)
1341         {
1342         char *aa,*bb;
1343
1344         for (aa=a[DB_serial]; *aa == '0'; aa++);
1345         for (bb=b[DB_serial]; *bb == '0'; bb++);
1346         return(strcmp(aa,bb));
1347         }
1348
1349 static unsigned long index_name_hash(char **a)
1350         { return(lh_strhash(a[DB_name])); }
1351
1352 static int index_name_qual(char **a)
1353         { return(a[0][0] == 'V'); }
1354
1355 static int index_name_cmp(char **a, char **b)
1356         { return(strcmp(a[DB_name],
1357              b[DB_name])); }
1358
1359 static BIGNUM *load_serial(char *serialfile)
1360         {
1361         BIO *in=NULL;
1362         BIGNUM *ret=NULL;
1363         MS_STATIC char buf[1024];
1364         ASN1_INTEGER *ai=NULL;
1365
1366         if ((in=BIO_new(BIO_s_file())) == NULL)
1367                 {
1368                 ERR_print_errors(bio_err);
1369                 goto err;
1370                 }
1371
1372         if (BIO_read_filename(in,serialfile) <= 0)
1373                 {
1374                 perror(serialfile);
1375                 goto err;
1376                 }
1377         ai=ASN1_INTEGER_new();
1378         if (ai == NULL) goto err;
1379         if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1380                 {
1381                 BIO_printf(bio_err,"unable to load number from %s\n",
1382                         serialfile);
1383                 goto err;
1384                 }
1385         ret=ASN1_INTEGER_to_BN(ai,NULL);
1386         if (ret == NULL)
1387                 {
1388                 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1389                 goto err;
1390                 }
1391 err:
1392         if (in != NULL) BIO_free(in);
1393         if (ai != NULL) ASN1_INTEGER_free(ai);
1394         return(ret);
1395         }
1396
1397 static int save_serial(char *serialfile, BIGNUM *serial)
1398         {
1399         BIO *out;
1400         int ret=0;
1401         ASN1_INTEGER *ai=NULL;
1402
1403         out=BIO_new(BIO_s_file());
1404         if (out == NULL)
1405                 {
1406                 ERR_print_errors(bio_err);
1407                 goto err;
1408                 }
1409         if (BIO_write_filename(out,serialfile) <= 0)
1410                 {
1411                 perror(serialfile);
1412                 goto err;
1413                 }
1414
1415         if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1416                 {
1417                 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1418                 goto err;
1419                 }
1420         i2a_ASN1_INTEGER(out,ai);
1421         BIO_puts(out,"\n");
1422         ret=1;
1423 err:
1424         if (out != NULL) BIO_free_all(out);
1425         if (ai != NULL) ASN1_INTEGER_free(ai);
1426         return(ret);
1427         }
1428
1429 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1430              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1431              BIGNUM *serial, char *startdate, char *enddate, int days,
1432              int batch, char *ext_sect, LHASH *lconf, int verbose)
1433         {
1434         X509_REQ *req=NULL;
1435         BIO *in=NULL;
1436         EVP_PKEY *pktmp=NULL;
1437         int ok= -1,i;
1438
1439         in=BIO_new(BIO_s_file());
1440
1441         if (BIO_read_filename(in,infile) <= 0)
1442                 {
1443                 perror(infile);
1444                 goto err;
1445                 }
1446         if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1447                 {
1448                 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1449                         infile);
1450                 goto err;
1451                 }
1452         if (verbose)
1453                 X509_REQ_print(bio_err,req);
1454
1455         BIO_printf(bio_err,"Check that the request matches the signature\n");
1456
1457         if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1458                 {
1459                 BIO_printf(bio_err,"error unpacking public key\n");
1460                 goto err;
1461                 }
1462         i=X509_REQ_verify(req,pktmp);
1463         EVP_PKEY_free(pktmp);
1464         if (i < 0)
1465                 {
1466                 ok=0;
1467                 BIO_printf(bio_err,"Signature verification problems....\n");
1468                 goto err;
1469                 }
1470         if (i == 0)
1471                 {
1472                 ok=0;
1473                 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1474                 goto err;
1475                 }
1476         else
1477                 BIO_printf(bio_err,"Signature ok\n");
1478
1479         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1480                 days,batch,verbose,req,ext_sect,lconf);
1481
1482 err:
1483         if (req != NULL) X509_REQ_free(req);
1484         if (in != NULL) BIO_free(in);
1485         return(ok);
1486         }
1487
1488 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1489              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1490              BIGNUM *serial, char *startdate, char *enddate, int days,
1491              int batch, char *ext_sect, LHASH *lconf, int verbose)
1492         {
1493         X509 *req=NULL;
1494         X509_REQ *rreq=NULL;
1495         BIO *in=NULL;
1496         EVP_PKEY *pktmp=NULL;
1497         int ok= -1,i;
1498
1499         in=BIO_new(BIO_s_file());
1500
1501         if (BIO_read_filename(in,infile) <= 0)
1502                 {
1503                 perror(infile);
1504                 goto err;
1505                 }
1506         if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1507                 {
1508                 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1509                 goto err;
1510                 }
1511         if (verbose)
1512                 X509_print(bio_err,req);
1513
1514         BIO_printf(bio_err,"Check that the request matches the signature\n");
1515
1516         if ((pktmp=X509_get_pubkey(req)) == NULL)
1517                 {
1518                 BIO_printf(bio_err,"error unpacking public key\n");
1519                 goto err;
1520                 }
1521         i=X509_verify(req,pktmp);
1522         EVP_PKEY_free(pktmp);
1523         if (i < 0)
1524                 {
1525                 ok=0;
1526                 BIO_printf(bio_err,"Signature verification problems....\n");
1527                 goto err;
1528                 }
1529         if (i == 0)
1530                 {
1531                 ok=0;
1532                 BIO_printf(bio_err,"Signature did not match the certificate\n");
1533                 goto err;
1534                 }
1535         else
1536                 BIO_printf(bio_err,"Signature ok\n");
1537
1538         if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1539                 goto err;
1540
1541         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1542                 batch,verbose,rreq,ext_sect,lconf);
1543
1544 err:
1545         if (rreq != NULL) X509_REQ_free(rreq);
1546         if (req != NULL) X509_free(req);
1547         if (in != NULL) BIO_free(in);
1548         return(ok);
1549         }
1550
1551 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1552              STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1553              char *startdate, char *enddate, int days, int batch, int verbose,
1554              X509_REQ *req, char *ext_sect, LHASH *lconf)
1555         {
1556         X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1557         ASN1_UTCTIME *tm,*tmptm;
1558         ASN1_STRING *str,*str2;
1559         ASN1_OBJECT *obj;
1560         X509 *ret=NULL;
1561         X509_CINF *ci;
1562         X509_NAME_ENTRY *ne;
1563         X509_NAME_ENTRY *tne,*push;
1564         EVP_PKEY *pktmp;
1565         int ok= -1,i,j,last,nid;
1566         char *p;
1567         CONF_VALUE *cv;
1568         char *row[DB_NUMBER],**rrow,**irow=NULL;
1569         char buf[25],*pbuf;
1570
1571         tmptm=ASN1_UTCTIME_new();
1572         if (tmptm == NULL)
1573                 {
1574                 BIO_printf(bio_err,"malloc error\n");
1575                 return(0);
1576                 }
1577
1578         for (i=0; i<DB_NUMBER; i++)
1579                 row[i]=NULL;
1580
1581         BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1582         name=X509_REQ_get_subject_name(req);
1583         for (i=0; i<X509_NAME_entry_count(name); i++)
1584                 {
1585                 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1586                 obj=X509_NAME_ENTRY_get_object(ne);
1587                 j=i2a_ASN1_OBJECT(bio_err,obj);
1588                 str=X509_NAME_ENTRY_get_data(ne);
1589                 pbuf=buf;
1590                 for (j=22-j; j>0; j--)
1591                         *(pbuf++)=' ';
1592                 *(pbuf++)=':';
1593                 *(pbuf++)='\0';
1594                 BIO_puts(bio_err,buf);
1595
1596                 if (msie_hack)
1597                         {
1598                         /* assume all type should be strings */
1599                         nid=OBJ_obj2nid(ne->object);
1600
1601                         if (str->type == V_ASN1_UNIVERSALSTRING)
1602                                 ASN1_UNIVERSALSTRING_to_string(str);
1603
1604                         if ((str->type == V_ASN1_IA5STRING) &&
1605                                 (nid != NID_pkcs9_emailAddress))
1606                                 str->type=V_ASN1_T61STRING;
1607
1608                         if ((nid == NID_pkcs9_emailAddress) &&
1609                                 (str->type == V_ASN1_PRINTABLESTRING))
1610                                 str->type=V_ASN1_IA5STRING;
1611                         }
1612
1613                 if (str->type == V_ASN1_PRINTABLESTRING)
1614                         BIO_printf(bio_err,"PRINTABLE:'");
1615                 else if (str->type == V_ASN1_T61STRING)
1616                         BIO_printf(bio_err,"T61STRING:'");
1617                 else if (str->type == V_ASN1_IA5STRING)
1618                         BIO_printf(bio_err,"IA5STRING:'");
1619                 else if (str->type == V_ASN1_UNIVERSALSTRING)
1620                         BIO_printf(bio_err,"UNIVERSALSTRING:'");
1621                 else
1622                         BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1623
1624                 /* check some things */
1625                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1626                         (str->type != V_ASN1_IA5STRING))
1627                         {
1628                         BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1629                         goto err;
1630                         }
1631                 j=ASN1_PRINTABLE_type(str->data,str->length);
1632                 if (    ((j == V_ASN1_T61STRING) &&
1633                          (str->type != V_ASN1_T61STRING)) ||
1634                         ((j == V_ASN1_IA5STRING) &&
1635                          (str->type == V_ASN1_PRINTABLESTRING)))
1636                         {
1637                         BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1638                         goto err;
1639                         }
1640                         
1641                 p=(char *)str->data;
1642                 for (j=str->length; j>0; j--)
1643                         {
1644                         if ((*p >= ' ') && (*p <= '~'))
1645                                 BIO_printf(bio_err,"%c",*p);
1646                         else if (*p & 0x80)
1647                                 BIO_printf(bio_err,"\\0x%02X",*p);
1648                         else if ((unsigned char)*p == 0xf7)
1649                                 BIO_printf(bio_err,"^?");
1650                         else    BIO_printf(bio_err,"^%c",*p+'@');
1651                         p++;
1652                         }
1653                 BIO_printf(bio_err,"'\n");
1654                 }
1655
1656         /* Ok, now we check the 'policy' stuff. */
1657         if ((subject=X509_NAME_new()) == NULL)
1658                 {
1659                 BIO_printf(bio_err,"Memory allocation failure\n");
1660                 goto err;
1661                 }
1662
1663         /* take a copy of the issuer name before we mess with it. */
1664         CAname=X509_NAME_dup(x509->cert_info->subject);
1665         if (CAname == NULL) goto err;
1666         str=str2=NULL;
1667
1668         for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1669                 {
1670                 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1671                 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1672                         {
1673                         BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1674                         goto err;
1675                         }
1676                 obj=OBJ_nid2obj(j);
1677
1678                 last= -1;
1679                 for (;;)
1680                         {
1681                         /* lookup the object in the supplied name list */
1682                         j=X509_NAME_get_index_by_OBJ(name,obj,last);
1683                         if (j < 0)
1684                                 {
1685                                 if (last != -1) break;
1686                                 tne=NULL;
1687                                 }
1688                         else
1689                                 {
1690                                 tne=X509_NAME_get_entry(name,j);
1691                                 }
1692                         last=j;
1693
1694                         /* depending on the 'policy', decide what to do. */
1695                         push=NULL;
1696                         if (strcmp(cv->value,"optional") == 0)
1697                                 {
1698                                 if (tne != NULL)
1699                                         push=tne;
1700                                 }
1701                         else if (strcmp(cv->value,"supplied") == 0)
1702                                 {
1703                                 if (tne == NULL)
1704                                         {
1705                                         BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1706                                         goto err;
1707                                         }
1708                                 else
1709                                         push=tne;
1710                                 }
1711                         else if (strcmp(cv->value,"match") == 0)
1712                                 {
1713                                 int last2;
1714
1715                                 if (tne == NULL)
1716                                         {
1717                                         BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1718                                         goto err;
1719                                         }
1720
1721                                 last2= -1;
1722
1723 again2:
1724                                 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1725                                 if ((j < 0) && (last2 == -1))
1726                                         {
1727                                         BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1728                                         goto err;
1729                                         }
1730                                 if (j >= 0)
1731                                         {
1732                                         push=X509_NAME_get_entry(CAname,j);
1733                                         str=X509_NAME_ENTRY_get_data(tne);
1734                                         str2=X509_NAME_ENTRY_get_data(push);
1735                                         last2=j;
1736                                         if (ASN1_STRING_cmp(str,str2) != 0)
1737                                                 goto again2;
1738                                         }
1739                                 if (j < 0)
1740                                         {
1741                                         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));
1742                                         goto err;
1743                                         }
1744                                 }
1745                         else
1746                                 {
1747                                 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1748                                 goto err;
1749                                 }
1750
1751                         if (push != NULL)
1752                                 {
1753                                 if (!X509_NAME_add_entry(subject,push, -1, 0))
1754                                         {
1755                                         if (push != NULL)
1756                                                 X509_NAME_ENTRY_free(push);
1757                                         BIO_printf(bio_err,"Memory allocation failure\n");
1758                                         goto err;
1759                                         }
1760                                 }
1761                         if (j < 0) break;
1762                         }
1763                 }
1764
1765         if (preserve)
1766                 {
1767                 X509_NAME_free(subject);
1768                 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1769                 if (subject == NULL) goto err;
1770                 }
1771
1772         if (verbose)
1773                 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1774
1775         row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1776         row[DB_serial]=BN_bn2hex(serial);
1777         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1778                 {
1779                 BIO_printf(bio_err,"Memory allocation failure\n");
1780                 goto err;
1781                 }
1782
1783         rrow=TXT_DB_get_by_index(db,DB_name,row);
1784         if (rrow != NULL)
1785                 {
1786                 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1787                         row[DB_name]);
1788                 }
1789         else
1790                 {
1791                 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1792                 if (rrow != NULL)
1793                         {
1794                         BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1795                                 row[DB_serial]);
1796                         BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1797                         }
1798                 }
1799
1800         if (rrow != NULL)
1801                 {
1802                 BIO_printf(bio_err,
1803                         "The matching entry has the following details\n");
1804                 if (rrow[DB_type][0] == 'E')
1805                         p="Expired";
1806                 else if (rrow[DB_type][0] == 'R')
1807                         p="Revoked";
1808                 else if (rrow[DB_type][0] == 'V')
1809                         p="Valid";
1810                 else
1811                         p="\ninvalid type, Data base error\n";
1812                 BIO_printf(bio_err,"Type          :%s\n",p);;
1813                 if (rrow[DB_type][0] == 'R')
1814                         {
1815                         p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1816                         BIO_printf(bio_err,"Was revoked on:%s\n",p);
1817                         }
1818                 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1819                 BIO_printf(bio_err,"Expires on    :%s\n",p);
1820                 p=rrow[DB_serial]; if (p == NULL) p="undef";
1821                 BIO_printf(bio_err,"Serial Number :%s\n",p);
1822                 p=rrow[DB_file]; if (p == NULL) p="undef";
1823                 BIO_printf(bio_err,"File name     :%s\n",p);
1824                 p=rrow[DB_name]; if (p == NULL) p="undef";
1825                 BIO_printf(bio_err,"Subject Name  :%s\n",p);
1826                 ok= -1; /* This is now a 'bad' error. */
1827                 goto err;
1828                 }
1829
1830         /* We are now totally happy, lets make and sign the certificate */
1831         if (verbose)
1832                 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1833
1834         if ((ret=X509_new()) == NULL) goto err;
1835         ci=ret->cert_info;
1836
1837 #ifdef X509_V3
1838         /* Make it an X509 v3 certificate. */
1839         if (!X509_set_version(x509,2)) goto err;
1840 #endif
1841
1842         if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1843                 goto err;
1844         if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1845                 goto err;
1846
1847         BIO_printf(bio_err,"Certificate is to be certified until ");
1848         if (strcmp(startdate,"today") == 0)
1849                 X509_gmtime_adj(X509_get_notBefore(ret),0);
1850         else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1851
1852         if (enddate == NULL)
1853                 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1854         else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1855
1856         ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1857         if(days) BIO_printf(bio_err," (%d days)",days);
1858         BIO_printf(bio_err, "\n");
1859
1860         if (!X509_set_subject_name(ret,subject)) goto err;
1861
1862         pktmp=X509_REQ_get_pubkey(req);
1863         i = X509_set_pubkey(ret,pktmp);
1864         EVP_PKEY_free(pktmp);
1865         if (!i) goto err;
1866
1867         /* Lets add the extensions, if there are any */
1868         if (ext_sect)
1869                 {
1870                 X509V3_CTX ctx;
1871                 if (ci->version == NULL)
1872                         if ((ci->version=ASN1_INTEGER_new()) == NULL)
1873                                 goto err;
1874                 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1875
1876                 /* Free the current entries if any, there should not
1877                  * be any I believe */
1878                 if (ci->extensions != NULL)
1879                         sk_X509_EXTENSION_pop_free(ci->extensions,
1880                                                    X509_EXTENSION_free);
1881
1882                 ci->extensions = NULL;
1883
1884                 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1885                 X509V3_set_conf_lhash(&ctx, lconf);
1886
1887                 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1888
1889                 }
1890
1891
1892         if (!batch)
1893                 {
1894                 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1895                 (void)BIO_flush(bio_err);
1896                 buf[0]='\0';
1897                 fgets(buf,sizeof(buf)-1,stdin);
1898                 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1899                         {
1900                         BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1901                         ok=0;
1902                         goto err;
1903                         }
1904                 }
1905
1906
1907 #ifndef NO_DSA
1908         if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1909         pktmp=X509_get_pubkey(ret);
1910         if (EVP_PKEY_missing_parameters(pktmp) &&
1911                 !EVP_PKEY_missing_parameters(pkey))
1912                 EVP_PKEY_copy_parameters(pktmp,pkey);
1913         EVP_PKEY_free(pktmp);
1914 #endif
1915
1916         if (!X509_sign(ret,pkey,dgst))
1917                 goto err;
1918
1919         /* We now just add it to the database */
1920         row[DB_type]=(char *)OPENSSL_malloc(2);
1921
1922         tm=X509_get_notAfter(ret);
1923         row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1924         memcpy(row[DB_exp_date],tm->data,tm->length);
1925         row[DB_exp_date][tm->length]='\0';
1926
1927         row[DB_rev_date]=NULL;
1928
1929         /* row[DB_serial] done already */
1930         row[DB_file]=(char *)OPENSSL_malloc(8);
1931         /* row[DB_name] done already */
1932
1933         if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1934                 (row[DB_file] == NULL))
1935                 {
1936                 BIO_printf(bio_err,"Memory allocation failure\n");
1937                 goto err;
1938                 }
1939         strcpy(row[DB_file],"unknown");
1940         row[DB_type][0]='V';
1941         row[DB_type][1]='\0';
1942
1943         if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1944                 {
1945                 BIO_printf(bio_err,"Memory allocation failure\n");
1946                 goto err;
1947                 }
1948
1949         for (i=0; i<DB_NUMBER; i++)
1950                 {
1951                 irow[i]=row[i];
1952                 row[i]=NULL;
1953                 }
1954         irow[DB_NUMBER]=NULL;
1955
1956         if (!TXT_DB_insert(db,irow))
1957                 {
1958                 BIO_printf(bio_err,"failed to update database\n");
1959                 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1960                 goto err;
1961                 }
1962         ok=1;
1963 err:
1964         for (i=0; i<DB_NUMBER; i++)
1965                 if (row[i] != NULL) OPENSSL_free(row[i]);
1966
1967         if (CAname != NULL)
1968                 X509_NAME_free(CAname);
1969         if (subject != NULL)
1970                 X509_NAME_free(subject);
1971         if (tmptm != NULL)
1972                 ASN1_UTCTIME_free(tmptm);
1973         if (ok <= 0)
1974                 {
1975                 if (ret != NULL) X509_free(ret);
1976                 ret=NULL;
1977                 }
1978         else
1979                 *xret=ret;
1980         return(ok);
1981         }
1982
1983 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1984         {
1985
1986         if (output_der)
1987                 {
1988                 (void)i2d_X509_bio(bp,x);
1989                 return;
1990                 }
1991 #if 0
1992         /* ??? Not needed since X509_print prints all this stuff anyway */
1993         f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1994         BIO_printf(bp,"issuer :%s\n",f);
1995
1996         f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1997         BIO_printf(bp,"subject:%s\n",f);
1998
1999         BIO_puts(bp,"serial :");
2000         i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2001         BIO_puts(bp,"\n\n");
2002 #endif
2003         if(!notext)X509_print(bp,x);
2004         PEM_write_bio_X509(bp,x);
2005         }
2006
2007 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2008              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2009              BIGNUM *serial, char *startdate, char *enddate, int days,
2010              char *ext_sect, LHASH *lconf, int verbose)
2011         {
2012         STACK_OF(CONF_VALUE) *sk=NULL;
2013         LHASH *parms=NULL;
2014         X509_REQ *req=NULL;
2015         CONF_VALUE *cv=NULL;
2016         NETSCAPE_SPKI *spki = NULL;
2017         X509_REQ_INFO *ri;
2018         char *type,*buf;
2019         EVP_PKEY *pktmp=NULL;
2020         X509_NAME *n=NULL;
2021         X509_NAME_ENTRY *ne=NULL;
2022         int ok= -1,i,j;
2023         long errline;
2024         int nid;
2025
2026         /*
2027          * Load input file into a hash table.  (This is just an easy
2028          * way to read and parse the file, then put it into a convenient
2029          * STACK format).
2030          */
2031         parms=CONF_load(NULL,infile,&errline);
2032         if (parms == NULL)
2033                 {
2034                 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2035                 ERR_print_errors(bio_err);
2036                 goto err;
2037                 }
2038
2039         sk=CONF_get_section(parms, "default");
2040         if (sk_CONF_VALUE_num(sk) == 0)
2041                 {
2042                 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2043                 CONF_free(parms);
2044                 goto err;
2045                 }
2046
2047         /*
2048          * Now create a dummy X509 request structure.  We don't actually
2049          * have an X509 request, but we have many of the components
2050          * (a public key, various DN components).  The idea is that we
2051          * put these components into the right X509 request structure
2052          * and we can use the same code as if you had a real X509 request.
2053          */
2054         req=X509_REQ_new();
2055         if (req == NULL)
2056                 {
2057                 ERR_print_errors(bio_err);
2058                 goto err;
2059                 }
2060
2061         /*
2062          * Build up the subject name set.
2063          */
2064         ri=req->req_info;
2065         n = ri->subject;
2066
2067         for (i = 0; ; i++)
2068                 {
2069                 if (sk_CONF_VALUE_num(sk) <= i) break;
2070
2071                 cv=sk_CONF_VALUE_value(sk,i);
2072                 type=cv->name;
2073                 /* Skip past any leading X. X: X, etc to allow for
2074                  * multiple instances
2075                  */
2076                 for(buf = cv->name; *buf ; buf++)
2077                         if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2078                                         buf++;
2079                                         if(*buf) type = buf;
2080                                         break;
2081                 }
2082
2083                 buf=cv->value;
2084                 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2085                         {
2086                         if (strcmp(type, "SPKAC") == 0)
2087                                 {
2088                                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2089                                 if (spki == NULL)
2090                                         {
2091                                         BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2092                                         ERR_print_errors(bio_err);
2093                                         goto err;
2094                                         }
2095                                 }
2096                         continue;
2097                         }
2098
2099                 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2100                 if (fix_data(nid, &j) == 0)
2101                         {
2102                         BIO_printf(bio_err,
2103                                 "invalid characters in string %s\n",buf);
2104                         goto err;
2105                         }
2106
2107                 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2108                         (unsigned char *)buf,
2109                         strlen(buf))) == NULL)
2110                         goto err;
2111
2112                 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2113                 }
2114         if (spki == NULL)
2115                 {
2116                 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2117                         infile);
2118                 goto err;
2119                 }
2120
2121         /*
2122          * Now extract the key from the SPKI structure.
2123          */
2124
2125         BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2126
2127         if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2128                 {
2129                 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2130                 goto err;
2131                 }
2132
2133         j = NETSCAPE_SPKI_verify(spki, pktmp);
2134         if (j <= 0)
2135                 {
2136                 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2137                 goto err;
2138                 }
2139         BIO_printf(bio_err,"Signature ok\n");
2140
2141         X509_REQ_set_pubkey(req,pktmp);
2142         EVP_PKEY_free(pktmp);
2143         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2144                    days,1,verbose,req,ext_sect,lconf);
2145 err:
2146         if (req != NULL) X509_REQ_free(req);
2147         if (parms != NULL) CONF_free(parms);
2148         if (spki != NULL) NETSCAPE_SPKI_free(spki);
2149         if (ne != NULL) X509_NAME_ENTRY_free(ne);
2150
2151         return(ok);
2152         }
2153
2154 static int fix_data(int nid, int *type)
2155         {
2156         if (nid == NID_pkcs9_emailAddress)
2157                 *type=V_ASN1_IA5STRING;
2158         if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2159                 *type=V_ASN1_T61STRING;
2160         if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2161                 *type=V_ASN1_T61STRING;
2162         if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2163                 return(0);
2164         if (nid == NID_pkcs9_unstructuredName)
2165                 *type=V_ASN1_IA5STRING;
2166         return(1);
2167         }
2168
2169 static int check_time_format(char *str)
2170         {
2171         ASN1_UTCTIME tm;
2172
2173         tm.data=(unsigned char *)str;
2174         tm.length=strlen(str);
2175         tm.type=V_ASN1_UTCTIME;
2176         return(ASN1_UTCTIME_check(&tm));
2177         }
2178
2179 static int do_revoke(X509 *x509, TXT_DB *db)
2180 {
2181         ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2182         char *row[DB_NUMBER],**rrow,**irow;
2183         BIGNUM *bn = NULL;
2184         int ok=-1,i;
2185
2186         for (i=0; i<DB_NUMBER; i++)
2187                 row[i]=NULL;
2188         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2189         bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2190         row[DB_serial]=BN_bn2hex(bn);
2191         BN_free(bn);
2192         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2193                 {
2194                 BIO_printf(bio_err,"Memory allocation failure\n");
2195                 goto err;
2196                 }
2197         /* We have to lookup by serial number because name lookup
2198          * skips revoked certs
2199          */
2200         rrow=TXT_DB_get_by_index(db,DB_serial,row);
2201         if (rrow == NULL)
2202                 {
2203                 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2204
2205                 /* We now just add it to the database */
2206                 row[DB_type]=(char *)OPENSSL_malloc(2);
2207
2208                 tm=X509_get_notAfter(x509);
2209                 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2210                 memcpy(row[DB_exp_date],tm->data,tm->length);
2211                 row[DB_exp_date][tm->length]='\0';
2212
2213                 row[DB_rev_date]=NULL;
2214
2215                 /* row[DB_serial] done already */
2216                 row[DB_file]=(char *)OPENSSL_malloc(8);
2217
2218                 /* row[DB_name] done already */
2219
2220                 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2221                         (row[DB_file] == NULL))
2222                         {
2223                         BIO_printf(bio_err,"Memory allocation failure\n");
2224                         goto err;
2225                         }
2226                 strcpy(row[DB_file],"unknown");
2227                 row[DB_type][0]='V';
2228                 row[DB_type][1]='\0';
2229
2230                 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2231                         {
2232                         BIO_printf(bio_err,"Memory allocation failure\n");
2233                         goto err;
2234                         }
2235
2236                 for (i=0; i<DB_NUMBER; i++)
2237                         {
2238                         irow[i]=row[i];
2239                         row[i]=NULL;
2240                         }
2241                 irow[DB_NUMBER]=NULL;
2242
2243                 if (!TXT_DB_insert(db,irow))
2244                         {
2245                         BIO_printf(bio_err,"failed to update database\n");
2246                         BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2247                         goto err;
2248                         }
2249
2250                 /* Revoke Certificate */
2251                 ok = do_revoke(x509,db);
2252
2253                 goto err;
2254
2255                 }
2256         else if (index_name_cmp(row,rrow))
2257                 {
2258                 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2259                            row[DB_name]);
2260                 goto err;
2261                 }
2262         else if (rrow[DB_type][0]=='R')
2263                 {
2264                 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2265                            row[DB_serial]);
2266                 goto err;
2267                 }
2268         else
2269                 {
2270                 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2271                 revtm = ASN1_UTCTIME_new();
2272                 revtm=X509_gmtime_adj(revtm,0);
2273                 rrow[DB_type][0]='R';
2274                 rrow[DB_type][1]='\0';
2275                 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2276                 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2277                 rrow[DB_rev_date][revtm->length]='\0';
2278                 ASN1_UTCTIME_free(revtm);
2279                 }
2280         ok=1;
2281 err:
2282         for (i=0; i<DB_NUMBER; i++)
2283                 {
2284                 if (row[i] != NULL) 
2285                         OPENSSL_free(row[i]);
2286                 }
2287         return(ok);
2288 }
2289