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