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