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