On VMS, stdout may very well lead to a file that is written to in a
[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 #ifdef VMS
694                 {
695                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
696                 out = BIO_push(tmpbio, out);
697                 }
698 #endif
699                 TXT_DB_write(out,db);
700                 BIO_printf(bio_err,"%d entries loaded from the database\n",
701                         db->data->num);
702                 BIO_printf(bio_err,"generating index\n");
703                 }
704         
705         if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
706                 index_serial_cmp))
707                 {
708                 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
709                 goto err;
710                 }
711
712         if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
713                 index_name_cmp))
714                 {
715                 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
716                         db->error,db->arg1,db->arg2);
717                 goto err;
718                 }
719
720         /*****************************************************************/
721         if (req || gencrl)
722                 {
723                 if (outfile != NULL)
724                         {
725
726                         if (BIO_write_filename(Sout,outfile) <= 0)
727                                 {
728                                 perror(outfile);
729                                 goto err;
730                                 }
731                         }
732                 else
733                         {
734                         BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
735 #ifdef VMS
736                         {
737                         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
738                         Sout = BIO_push(tmpbio, Sout);
739                         }
740 #endif
741                         }
742                 }
743
744         if (req)
745                 {
746                 if ((md == NULL) && ((md=CONF_get_string(conf,
747                         section,ENV_DEFAULT_MD)) == NULL))
748                         {
749                         lookup_fail(section,ENV_DEFAULT_MD);
750                         goto err;
751                         }
752                 if ((dgst=EVP_get_digestbyname(md)) == NULL)
753                         {
754                         BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
755                         goto err;
756                         }
757                 if (verbose)
758                         BIO_printf(bio_err,"message digest is %s\n",
759                                 OBJ_nid2ln(dgst->type));
760                 if ((policy == NULL) && ((policy=CONF_get_string(conf,
761                         section,ENV_POLICY)) == NULL))
762                         {
763                         lookup_fail(section,ENV_POLICY);
764                         goto err;
765                         }
766                 if (verbose)
767                         BIO_printf(bio_err,"policy is %s\n",policy);
768
769                 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
770                         == NULL)
771                         {
772                         lookup_fail(section,ENV_SERIAL);
773                         goto err;
774                         }
775                 if(!extensions)
776                         extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
777                 if(extensions) {
778                         /* Check syntax of file */
779                         X509V3_CTX ctx;
780                         X509V3_set_ctx_test(&ctx);
781                         X509V3_set_conf_lhash(&ctx, conf);
782                         if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
783                                 BIO_printf(bio_err,
784                                  "Error Loading extension section %s\n",
785                                                                  extensions);
786                                 ret = 1;
787                                 goto err;
788                         }
789                 }
790
791                 if (startdate == NULL)
792                         {
793                         startdate=CONF_get_string(conf,section,
794                                 ENV_DEFAULT_STARTDATE);
795                         }
796                 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
797                         {
798                         BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
799                         goto err;
800                         }
801                 if (startdate == NULL) startdate="today";
802
803                 if (enddate == NULL)
804                         {
805                         enddate=CONF_get_string(conf,section,
806                                 ENV_DEFAULT_ENDDATE);
807                         }
808                 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
809                         {
810                         BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
811                         goto err;
812                         }
813
814                 if (days == 0)
815                         {
816                         days=(int)CONF_get_number(conf,section,
817                                 ENV_DEFAULT_DAYS);
818                         }
819                 if (!enddate && (days == 0))
820                         {
821                         BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
822                         goto err;
823                         }
824
825                 if ((serial=load_serial(serialfile)) == NULL)
826                         {
827                         BIO_printf(bio_err,"error while loading serial number\n");
828                         goto err;
829                         }
830                 if (verbose)
831                         {
832                         if ((f=BN_bn2hex(serial)) == NULL) goto err;
833                         BIO_printf(bio_err,"next serial number is %s\n",f);
834                         OPENSSL_free(f);
835                         }
836
837                 if ((attribs=CONF_get_section(conf,policy)) == NULL)
838                         {
839                         BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
840                         goto err;
841                         }
842
843                 if ((cert_sk=sk_X509_new_null()) == NULL)
844                         {
845                         BIO_printf(bio_err,"Memory allocation failure\n");
846                         goto err;
847                         }
848                 if (spkac_file != NULL)
849                         {
850                         total++;
851                         j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
852                                 serial,startdate,enddate, days,extensions,conf,
853                                 verbose);
854                         if (j < 0) goto err;
855                         if (j > 0)
856                                 {
857                                 total_done++;
858                                 BIO_printf(bio_err,"\n");
859                                 if (!BN_add_word(serial,1)) goto err;
860                                 if (!sk_X509_push(cert_sk,x))
861                                         {
862                                         BIO_printf(bio_err,"Memory allocation failure\n");
863                                         goto err;
864                                         }
865                                 if (outfile)
866                                         {
867                                         output_der = 1;
868                                         batch = 1;
869                                         }
870                                 }
871                         }
872                 if (ss_cert_file != NULL)
873                         {
874                         total++;
875                         j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
876                                 db,serial,startdate,enddate,days,batch,
877                                 extensions,conf,verbose);
878                         if (j < 0) goto err;
879                         if (j > 0)
880                                 {
881                                 total_done++;
882                                 BIO_printf(bio_err,"\n");
883                                 if (!BN_add_word(serial,1)) goto err;
884                                 if (!sk_X509_push(cert_sk,x))
885                                         {
886                                         BIO_printf(bio_err,"Memory allocation failure\n");
887                                         goto err;
888                                         }
889                                 }
890                         }
891                 if (infile != NULL)
892                         {
893                         total++;
894                         j=certify(&x,infile,pkey,x509,dgst,attribs,db,
895                                 serial,startdate,enddate,days,batch,
896                                 extensions,conf,verbose);
897                         if (j < 0) goto err;
898                         if (j > 0)
899                                 {
900                                 total_done++;
901                                 BIO_printf(bio_err,"\n");
902                                 if (!BN_add_word(serial,1)) goto err;
903                                 if (!sk_X509_push(cert_sk,x))
904                                         {
905                                         BIO_printf(bio_err,"Memory allocation failure\n");
906                                         goto err;
907                                         }
908                                 }
909                         }
910                 for (i=0; i<argc; i++)
911                         {
912                         total++;
913                         j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
914                                 serial,startdate,enddate,days,batch,
915                                 extensions,conf,verbose);
916                         if (j < 0) goto err;
917                         if (j > 0)
918                                 {
919                                 total_done++;
920                                 BIO_printf(bio_err,"\n");
921                                 if (!BN_add_word(serial,1)) goto err;
922                                 if (!sk_X509_push(cert_sk,x))
923                                         {
924                                         BIO_printf(bio_err,"Memory allocation failure\n");
925                                         goto err;
926                                         }
927                                 }
928                         }       
929                 /* we have a stack of newly certified certificates
930                  * and a data base and serial number that need
931                  * updating */
932
933                 if (sk_X509_num(cert_sk) > 0)
934                         {
935                         if (!batch)
936                                 {
937                                 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
938                                 (void)BIO_flush(bio_err);
939                                 buf[0][0]='\0';
940                                 fgets(buf[0],10,stdin);
941                                 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
942                                         {
943                                         BIO_printf(bio_err,"CERTIFICATION CANCELED\n"); 
944                                         ret=0;
945                                         goto err;
946                                         }
947                                 }
948
949                         BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
950
951                         strncpy(buf[0],serialfile,BSIZE-4);
952
953 #ifdef VMS
954                         strcat(buf[0],"-new");
955 #else
956                         strcat(buf[0],".new");
957 #endif
958
959                         if (!save_serial(buf[0],serial)) goto err;
960
961                         strncpy(buf[1],dbfile,BSIZE-4);
962
963 #ifdef VMS
964                         strcat(buf[1],"-new");
965 #else
966                         strcat(buf[1],".new");
967 #endif
968
969                         if (BIO_write_filename(out,buf[1]) <= 0)
970                                 {
971                                 perror(dbfile);
972                                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
973                                 goto err;
974                                 }
975                         l=TXT_DB_write(out,db);
976                         if (l <= 0) goto err;
977                         }
978         
979                 if (verbose)
980                         BIO_printf(bio_err,"writing new certificates\n");
981                 for (i=0; i<sk_X509_num(cert_sk); i++)
982                         {
983                         int k;
984                         unsigned char *n;
985
986                         x=sk_X509_value(cert_sk,i);
987
988                         j=x->cert_info->serialNumber->length;
989                         p=(char *)x->cert_info->serialNumber->data;
990                         
991                         strncpy(buf[2],outdir,BSIZE-(j*2)-6);
992
993 #ifndef VMS
994                         strcat(buf[2],"/");
995 #endif
996
997                         n=(unsigned char *)&(buf[2][strlen(buf[2])]);
998                         if (j > 0)
999                                 {
1000                                 for (k=0; k<j; k++)
1001                                         {
1002                                         sprintf((char *)n,"%02X",(unsigned char)*(p++));
1003                                         n+=2;
1004                                         }
1005                                 }
1006                         else
1007                                 {
1008                                 *(n++)='0';
1009                                 *(n++)='0';
1010                                 }
1011                         *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1012                         *n='\0';
1013                         if (verbose)
1014                                 BIO_printf(bio_err,"writing %s\n",buf[2]);
1015
1016                         if (BIO_write_filename(Cout,buf[2]) <= 0)
1017                                 {
1018                                 perror(buf[2]);
1019                                 goto err;
1020                                 }
1021                         write_new_certificate(Cout,x, 0, notext);
1022                         write_new_certificate(Sout,x, output_der, notext);
1023                         }
1024
1025                 if (sk_X509_num(cert_sk))
1026                         {
1027                         /* Rename the database and the serial file */
1028                         strncpy(buf[2],serialfile,BSIZE-4);
1029
1030 #ifdef VMS
1031                         strcat(buf[2],"-old");
1032 #else
1033                         strcat(buf[2],".old");
1034 #endif
1035
1036                         BIO_free(in);
1037                         BIO_free_all(out);
1038                         in=NULL;
1039                         out=NULL;
1040                         if (rename(serialfile,buf[2]) < 0)
1041                                 {
1042                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1043                                         serialfile,buf[2]);
1044                                 perror("reason");
1045                                 goto err;
1046                                 }
1047                         if (rename(buf[0],serialfile) < 0)
1048                                 {
1049                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1050                                         buf[0],serialfile);
1051                                 perror("reason");
1052                                 rename(buf[2],serialfile);
1053                                 goto err;
1054                                 }
1055
1056                         strncpy(buf[2],dbfile,BSIZE-4);
1057
1058 #ifdef VMS
1059                         strcat(buf[2],"-old");
1060 #else
1061                         strcat(buf[2],".old");
1062 #endif
1063
1064                         if (rename(dbfile,buf[2]) < 0)
1065                                 {
1066                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1067                                         dbfile,buf[2]);
1068                                 perror("reason");
1069                                 goto err;
1070                                 }
1071                         if (rename(buf[1],dbfile) < 0)
1072                                 {
1073                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1074                                         buf[1],dbfile);
1075                                 perror("reason");
1076                                 rename(buf[2],dbfile);
1077                                 goto err;
1078                                 }
1079                         BIO_printf(bio_err,"Data Base Updated\n");
1080                         }
1081                 }
1082         
1083         /*****************************************************************/
1084         if (gencrl)
1085                 {
1086                 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1087                 if(crl_ext) {
1088                         /* Check syntax of file */
1089                         X509V3_CTX ctx;
1090                         X509V3_set_ctx_test(&ctx);
1091                         X509V3_set_conf_lhash(&ctx, conf);
1092                         if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1093                                 BIO_printf(bio_err,
1094                                  "Error Loading CRL extension section %s\n",
1095                                                                  crl_ext);
1096                                 ret = 1;
1097                                 goto err;
1098                         }
1099                 }
1100                 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1101
1102                 if (!crldays && !crlhours)
1103                         {
1104                         crldays=CONF_get_number(conf,section,
1105                                 ENV_DEFAULT_CRL_DAYS);
1106                         crlhours=CONF_get_number(conf,section,
1107                                 ENV_DEFAULT_CRL_HOURS);
1108                         }
1109                 if ((crldays == 0) && (crlhours == 0))
1110                         {
1111                         BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1112                         goto err;
1113                         }
1114
1115                 if (verbose) BIO_printf(bio_err,"making CRL\n");
1116                 if ((crl=X509_CRL_new()) == NULL) goto err;
1117                 ci=crl->crl;
1118                 X509_NAME_free(ci->issuer);
1119                 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1120                 if (ci->issuer == NULL) goto err;
1121
1122                 X509_gmtime_adj(ci->lastUpdate,0);
1123                 if (ci->nextUpdate == NULL)
1124                         ci->nextUpdate=ASN1_UTCTIME_new();
1125                 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1126
1127                 for (i=0; i<sk_num(db->data); i++)
1128                         {
1129                         pp=(char **)sk_value(db->data,i);
1130                         if (pp[DB_type][0] == DB_TYPE_REV)
1131                                 {
1132                                 if ((r=X509_REVOKED_new()) == NULL) goto err;
1133                                 ASN1_STRING_set((ASN1_STRING *)
1134                                         r->revocationDate,
1135                                         (unsigned char *)pp[DB_rev_date],
1136                                         strlen(pp[DB_rev_date]));
1137                                 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1138
1139                                 (void)BIO_reset(hex);
1140                                 if (!BIO_puts(hex,pp[DB_serial]))
1141                                         goto err;
1142                                 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1143                                         buf[0],BSIZE)) goto err;
1144
1145                                 sk_X509_REVOKED_push(ci->revoked,r);
1146                                 }
1147                         }
1148                 /* sort the data so it will be written in serial
1149                  * number order */
1150                 sk_X509_REVOKED_sort(ci->revoked);
1151                 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1152                         {
1153                         r=sk_X509_REVOKED_value(ci->revoked,i);
1154                         r->sequence=i;
1155                         }
1156
1157                 /* we now have a CRL */
1158                 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1159                 if (md != NULL)
1160                         {
1161                         if ((dgst=EVP_get_digestbyname(md)) == NULL)
1162                                 {
1163                                 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1164                                 goto err;
1165                                 }
1166                         }
1167                 else
1168                     {
1169 #ifndef NO_DSA
1170                     if (pkey->type == EVP_PKEY_DSA) 
1171                         dgst=EVP_dss1();
1172                     else
1173 #endif
1174                         dgst=EVP_md5();
1175                     }
1176
1177                 /* Add any extensions asked for */
1178
1179                 if(crl_ext) {
1180                     X509V3_CTX crlctx;
1181                     if (ci->version == NULL)
1182                     if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1183                     ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1184                     X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1185                     X509V3_set_conf_lhash(&crlctx, conf);
1186
1187                     if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1188                                                  crl_ext, crl)) goto err;
1189                 }
1190
1191                 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1192
1193                 PEM_write_bio_X509_CRL(Sout,crl);
1194                 }
1195         /*****************************************************************/
1196         if (dorevoke)
1197                 {
1198                 if (infile == NULL) 
1199                         {
1200                         BIO_printf(bio_err,"no input files\n");
1201                         goto err;
1202                         }
1203                 else
1204                         {
1205                         X509 *revcert;
1206                         if (BIO_read_filename(in,infile) <= 0)
1207                                 {
1208                                 perror(infile);
1209                                 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1210                                 goto err;
1211                                 }
1212                         revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1213                         if (revcert == NULL)
1214                                 {
1215                                 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1216                                 goto err;
1217                                 }
1218                         j=do_revoke(revcert,db);
1219                         if (j <= 0) goto err;
1220                         X509_free(revcert);
1221
1222                         strncpy(buf[0],dbfile,BSIZE-4);
1223                         strcat(buf[0],".new");
1224                         if (BIO_write_filename(out,buf[0]) <= 0)
1225                                 {
1226                                 perror(dbfile);
1227                                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1228                                 goto err;
1229                                 }
1230                         j=TXT_DB_write(out,db);
1231                         if (j <= 0) goto err;
1232                         strncpy(buf[1],dbfile,BSIZE-4);
1233                         strcat(buf[1],".old");
1234                         if (rename(dbfile,buf[1]) < 0)
1235                                 {
1236                                 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1237                                 perror("reason");
1238                                 goto err;
1239                                 }
1240                         if (rename(buf[0],dbfile) < 0)
1241                                 {
1242                                 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1243                                 perror("reason");
1244                                 rename(buf[1],dbfile);
1245                                 goto err;
1246                                 }
1247                         BIO_printf(bio_err,"Data Base Updated\n"); 
1248                         }
1249                 }
1250         /*****************************************************************/
1251         ret=0;
1252 err:
1253         BIO_free(hex);
1254         BIO_free_all(Cout);
1255         BIO_free_all(Sout);
1256         BIO_free_all(out);
1257         BIO_free(in);
1258
1259         sk_X509_pop_free(cert_sk,X509_free);
1260
1261         if (ret) ERR_print_errors(bio_err);
1262         app_RAND_write_file(randfile, bio_err);
1263         BN_free(serial);
1264         TXT_DB_free(db);
1265         EVP_PKEY_free(pkey);
1266         X509_free(x509);
1267         X509_CRL_free(crl);
1268         CONF_free(conf);
1269         OBJ_cleanup();
1270         EXIT(ret);
1271         }
1272
1273 static void lookup_fail(char *name, char *tag)
1274         {
1275         BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1276         }
1277
1278 static unsigned long index_serial_hash(char **a)
1279         {
1280         char *n;
1281
1282         n=a[DB_serial];
1283         while (*n == '0') n++;
1284         return(lh_strhash(n));
1285         }
1286
1287 static int index_serial_cmp(char **a, char **b)
1288         {
1289         char *aa,*bb;
1290
1291         for (aa=a[DB_serial]; *aa == '0'; aa++);
1292         for (bb=b[DB_serial]; *bb == '0'; bb++);
1293         return(strcmp(aa,bb));
1294         }
1295
1296 static unsigned long index_name_hash(char **a)
1297         { return(lh_strhash(a[DB_name])); }
1298
1299 static int index_name_qual(char **a)
1300         { return(a[0][0] == 'V'); }
1301
1302 static int index_name_cmp(char **a, char **b)
1303         { return(strcmp(a[DB_name],
1304              b[DB_name])); }
1305
1306 static BIGNUM *load_serial(char *serialfile)
1307         {
1308         BIO *in=NULL;
1309         BIGNUM *ret=NULL;
1310         MS_STATIC char buf[1024];
1311         ASN1_INTEGER *ai=NULL;
1312
1313         if ((in=BIO_new(BIO_s_file())) == NULL)
1314                 {
1315                 ERR_print_errors(bio_err);
1316                 goto err;
1317                 }
1318
1319         if (BIO_read_filename(in,serialfile) <= 0)
1320                 {
1321                 perror(serialfile);
1322                 goto err;
1323                 }
1324         ai=ASN1_INTEGER_new();
1325         if (ai == NULL) goto err;
1326         if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1327                 {
1328                 BIO_printf(bio_err,"unable to load number from %s\n",
1329                         serialfile);
1330                 goto err;
1331                 }
1332         ret=ASN1_INTEGER_to_BN(ai,NULL);
1333         if (ret == NULL)
1334                 {
1335                 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1336                 goto err;
1337                 }
1338 err:
1339         if (in != NULL) BIO_free(in);
1340         if (ai != NULL) ASN1_INTEGER_free(ai);
1341         return(ret);
1342         }
1343
1344 static int save_serial(char *serialfile, BIGNUM *serial)
1345         {
1346         BIO *out;
1347         int ret=0;
1348         ASN1_INTEGER *ai=NULL;
1349
1350         out=BIO_new(BIO_s_file());
1351         if (out == NULL)
1352                 {
1353                 ERR_print_errors(bio_err);
1354                 goto err;
1355                 }
1356         if (BIO_write_filename(out,serialfile) <= 0)
1357                 {
1358                 perror(serialfile);
1359                 goto err;
1360                 }
1361
1362         if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1363                 {
1364                 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1365                 goto err;
1366                 }
1367         i2a_ASN1_INTEGER(out,ai);
1368         BIO_puts(out,"\n");
1369         ret=1;
1370 err:
1371         if (out != NULL) BIO_free_all(out);
1372         if (ai != NULL) ASN1_INTEGER_free(ai);
1373         return(ret);
1374         }
1375
1376 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1377              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1378              BIGNUM *serial, char *startdate, char *enddate, int days,
1379              int batch, char *ext_sect, LHASH *lconf, int verbose)
1380         {
1381         X509_REQ *req=NULL;
1382         BIO *in=NULL;
1383         EVP_PKEY *pktmp=NULL;
1384         int ok= -1,i;
1385
1386         in=BIO_new(BIO_s_file());
1387
1388         if (BIO_read_filename(in,infile) <= 0)
1389                 {
1390                 perror(infile);
1391                 goto err;
1392                 }
1393         if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1394                 {
1395                 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1396                         infile);
1397                 goto err;
1398                 }
1399         if (verbose)
1400                 X509_REQ_print(bio_err,req);
1401
1402         BIO_printf(bio_err,"Check that the request matches the signature\n");
1403
1404         if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1405                 {
1406                 BIO_printf(bio_err,"error unpacking public key\n");
1407                 goto err;
1408                 }
1409         i=X509_REQ_verify(req,pktmp);
1410         EVP_PKEY_free(pktmp);
1411         if (i < 0)
1412                 {
1413                 ok=0;
1414                 BIO_printf(bio_err,"Signature verification problems....\n");
1415                 goto err;
1416                 }
1417         if (i == 0)
1418                 {
1419                 ok=0;
1420                 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1421                 goto err;
1422                 }
1423         else
1424                 BIO_printf(bio_err,"Signature ok\n");
1425
1426         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1427                 days,batch,verbose,req,ext_sect,lconf);
1428
1429 err:
1430         if (req != NULL) X509_REQ_free(req);
1431         if (in != NULL) BIO_free(in);
1432         return(ok);
1433         }
1434
1435 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1436              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1437              BIGNUM *serial, char *startdate, char *enddate, int days,
1438              int batch, char *ext_sect, LHASH *lconf, int verbose)
1439         {
1440         X509 *req=NULL;
1441         X509_REQ *rreq=NULL;
1442         BIO *in=NULL;
1443         EVP_PKEY *pktmp=NULL;
1444         int ok= -1,i;
1445
1446         in=BIO_new(BIO_s_file());
1447
1448         if (BIO_read_filename(in,infile) <= 0)
1449                 {
1450                 perror(infile);
1451                 goto err;
1452                 }
1453         if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1454                 {
1455                 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1456                 goto err;
1457                 }
1458         if (verbose)
1459                 X509_print(bio_err,req);
1460
1461         BIO_printf(bio_err,"Check that the request matches the signature\n");
1462
1463         if ((pktmp=X509_get_pubkey(req)) == NULL)
1464                 {
1465                 BIO_printf(bio_err,"error unpacking public key\n");
1466                 goto err;
1467                 }
1468         i=X509_verify(req,pktmp);
1469         EVP_PKEY_free(pktmp);
1470         if (i < 0)
1471                 {
1472                 ok=0;
1473                 BIO_printf(bio_err,"Signature verification problems....\n");
1474                 goto err;
1475                 }
1476         if (i == 0)
1477                 {
1478                 ok=0;
1479                 BIO_printf(bio_err,"Signature did not match the certificate\n");
1480                 goto err;
1481                 }
1482         else
1483                 BIO_printf(bio_err,"Signature ok\n");
1484
1485         if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1486                 goto err;
1487
1488         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1489                 batch,verbose,rreq,ext_sect,lconf);
1490
1491 err:
1492         if (rreq != NULL) X509_REQ_free(rreq);
1493         if (req != NULL) X509_free(req);
1494         if (in != NULL) BIO_free(in);
1495         return(ok);
1496         }
1497
1498 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1499              STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1500              char *startdate, char *enddate, int days, int batch, int verbose,
1501              X509_REQ *req, char *ext_sect, LHASH *lconf)
1502         {
1503         X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1504         ASN1_UTCTIME *tm,*tmptm;
1505         ASN1_STRING *str,*str2;
1506         ASN1_OBJECT *obj;
1507         X509 *ret=NULL;
1508         X509_CINF *ci;
1509         X509_NAME_ENTRY *ne;
1510         X509_NAME_ENTRY *tne,*push;
1511         EVP_PKEY *pktmp;
1512         int ok= -1,i,j,last,nid;
1513         char *p;
1514         CONF_VALUE *cv;
1515         char *row[DB_NUMBER],**rrow,**irow=NULL;
1516         char buf[25],*pbuf;
1517
1518         tmptm=ASN1_UTCTIME_new();
1519         if (tmptm == NULL)
1520                 {
1521                 BIO_printf(bio_err,"malloc error\n");
1522                 return(0);
1523                 }
1524
1525         for (i=0; i<DB_NUMBER; i++)
1526                 row[i]=NULL;
1527
1528         BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1529         name=X509_REQ_get_subject_name(req);
1530         for (i=0; i<X509_NAME_entry_count(name); i++)
1531                 {
1532                 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1533                 obj=X509_NAME_ENTRY_get_object(ne);
1534                 j=i2a_ASN1_OBJECT(bio_err,obj);
1535                 str=X509_NAME_ENTRY_get_data(ne);
1536                 pbuf=buf;
1537                 for (j=22-j; j>0; j--)
1538                         *(pbuf++)=' ';
1539                 *(pbuf++)=':';
1540                 *(pbuf++)='\0';
1541                 BIO_puts(bio_err,buf);
1542
1543                 if (msie_hack)
1544                         {
1545                         /* assume all type should be strings */
1546                         nid=OBJ_obj2nid(ne->object);
1547
1548                         if (str->type == V_ASN1_UNIVERSALSTRING)
1549                                 ASN1_UNIVERSALSTRING_to_string(str);
1550
1551                         if ((str->type == V_ASN1_IA5STRING) &&
1552                                 (nid != NID_pkcs9_emailAddress))
1553                                 str->type=V_ASN1_T61STRING;
1554
1555                         if ((nid == NID_pkcs9_emailAddress) &&
1556                                 (str->type == V_ASN1_PRINTABLESTRING))
1557                                 str->type=V_ASN1_IA5STRING;
1558                         }
1559
1560                 if (str->type == V_ASN1_PRINTABLESTRING)
1561                         BIO_printf(bio_err,"PRINTABLE:'");
1562                 else if (str->type == V_ASN1_T61STRING)
1563                         BIO_printf(bio_err,"T61STRING:'");
1564                 else if (str->type == V_ASN1_IA5STRING)
1565                         BIO_printf(bio_err,"IA5STRING:'");
1566                 else if (str->type == V_ASN1_UNIVERSALSTRING)
1567                         BIO_printf(bio_err,"UNIVERSALSTRING:'");
1568                 else
1569                         BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1570
1571                 /* check some things */
1572                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1573                         (str->type != V_ASN1_IA5STRING))
1574                         {
1575                         BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1576                         goto err;
1577                         }
1578                 j=ASN1_PRINTABLE_type(str->data,str->length);
1579                 if (    ((j == V_ASN1_T61STRING) &&
1580                          (str->type != V_ASN1_T61STRING)) ||
1581                         ((j == V_ASN1_IA5STRING) &&
1582                          (str->type == V_ASN1_PRINTABLESTRING)))
1583                         {
1584                         BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1585                         goto err;
1586                         }
1587                         
1588                 p=(char *)str->data;
1589                 for (j=str->length; j>0; j--)
1590                         {
1591                         if ((*p >= ' ') && (*p <= '~'))
1592                                 BIO_printf(bio_err,"%c",*p);
1593                         else if (*p & 0x80)
1594                                 BIO_printf(bio_err,"\\0x%02X",*p);
1595                         else if ((unsigned char)*p == 0xf7)
1596                                 BIO_printf(bio_err,"^?");
1597                         else    BIO_printf(bio_err,"^%c",*p+'@');
1598                         p++;
1599                         }
1600                 BIO_printf(bio_err,"'\n");
1601                 }
1602
1603         /* Ok, now we check the 'policy' stuff. */
1604         if ((subject=X509_NAME_new()) == NULL)
1605                 {
1606                 BIO_printf(bio_err,"Memory allocation failure\n");
1607                 goto err;
1608                 }
1609
1610         /* take a copy of the issuer name before we mess with it. */
1611         CAname=X509_NAME_dup(x509->cert_info->subject);
1612         if (CAname == NULL) goto err;
1613         str=str2=NULL;
1614
1615         for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1616                 {
1617                 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1618                 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1619                         {
1620                         BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1621                         goto err;
1622                         }
1623                 obj=OBJ_nid2obj(j);
1624
1625                 last= -1;
1626                 for (;;)
1627                         {
1628                         /* lookup the object in the supplied name list */
1629                         j=X509_NAME_get_index_by_OBJ(name,obj,last);
1630                         if (j < 0)
1631                                 {
1632                                 if (last != -1) break;
1633                                 tne=NULL;
1634                                 }
1635                         else
1636                                 {
1637                                 tne=X509_NAME_get_entry(name,j);
1638                                 }
1639                         last=j;
1640
1641                         /* depending on the 'policy', decide what to do. */
1642                         push=NULL;
1643                         if (strcmp(cv->value,"optional") == 0)
1644                                 {
1645                                 if (tne != NULL)
1646                                         push=tne;
1647                                 }
1648                         else if (strcmp(cv->value,"supplied") == 0)
1649                                 {
1650                                 if (tne == NULL)
1651                                         {
1652                                         BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1653                                         goto err;
1654                                         }
1655                                 else
1656                                         push=tne;
1657                                 }
1658                         else if (strcmp(cv->value,"match") == 0)
1659                                 {
1660                                 int last2;
1661
1662                                 if (tne == NULL)
1663                                         {
1664                                         BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1665                                         goto err;
1666                                         }
1667
1668                                 last2= -1;
1669
1670 again2:
1671                                 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1672                                 if ((j < 0) && (last2 == -1))
1673                                         {
1674                                         BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1675                                         goto err;
1676                                         }
1677                                 if (j >= 0)
1678                                         {
1679                                         push=X509_NAME_get_entry(CAname,j);
1680                                         str=X509_NAME_ENTRY_get_data(tne);
1681                                         str2=X509_NAME_ENTRY_get_data(push);
1682                                         last2=j;
1683                                         if (ASN1_STRING_cmp(str,str2) != 0)
1684                                                 goto again2;
1685                                         }
1686                                 if (j < 0)
1687                                         {
1688                                         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));
1689                                         goto err;
1690                                         }
1691                                 }
1692                         else
1693                                 {
1694                                 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1695                                 goto err;
1696                                 }
1697
1698                         if (push != NULL)
1699                                 {
1700                                 if (!X509_NAME_add_entry(subject,push, -1, 0))
1701                                         {
1702                                         if (push != NULL)
1703                                                 X509_NAME_ENTRY_free(push);
1704                                         BIO_printf(bio_err,"Memory allocation failure\n");
1705                                         goto err;
1706                                         }
1707                                 }
1708                         if (j < 0) break;
1709                         }
1710                 }
1711
1712         if (preserve)
1713                 {
1714                 X509_NAME_free(subject);
1715                 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1716                 if (subject == NULL) goto err;
1717                 }
1718
1719         if (verbose)
1720                 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1721
1722         row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1723         row[DB_serial]=BN_bn2hex(serial);
1724         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1725                 {
1726                 BIO_printf(bio_err,"Memory allocation failure\n");
1727                 goto err;
1728                 }
1729
1730         rrow=TXT_DB_get_by_index(db,DB_name,row);
1731         if (rrow != NULL)
1732                 {
1733                 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1734                         row[DB_name]);
1735                 }
1736         else
1737                 {
1738                 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1739                 if (rrow != NULL)
1740                         {
1741                         BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1742                                 row[DB_serial]);
1743                         BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1744                         }
1745                 }
1746
1747         if (rrow != NULL)
1748                 {
1749                 BIO_printf(bio_err,
1750                         "The matching entry has the following details\n");
1751                 if (rrow[DB_type][0] == 'E')
1752                         p="Expired";
1753                 else if (rrow[DB_type][0] == 'R')
1754                         p="Revoked";
1755                 else if (rrow[DB_type][0] == 'V')
1756                         p="Valid";
1757                 else
1758                         p="\ninvalid type, Data base error\n";
1759                 BIO_printf(bio_err,"Type          :%s\n",p);;
1760                 if (rrow[DB_type][0] == 'R')
1761                         {
1762                         p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1763                         BIO_printf(bio_err,"Was revoked on:%s\n",p);
1764                         }
1765                 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1766                 BIO_printf(bio_err,"Expires on    :%s\n",p);
1767                 p=rrow[DB_serial]; if (p == NULL) p="undef";
1768                 BIO_printf(bio_err,"Serial Number :%s\n",p);
1769                 p=rrow[DB_file]; if (p == NULL) p="undef";
1770                 BIO_printf(bio_err,"File name     :%s\n",p);
1771                 p=rrow[DB_name]; if (p == NULL) p="undef";
1772                 BIO_printf(bio_err,"Subject Name  :%s\n",p);
1773                 ok= -1; /* This is now a 'bad' error. */
1774                 goto err;
1775                 }
1776
1777         /* We are now totally happy, lets make and sign the certificate */
1778         if (verbose)
1779                 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1780
1781         if ((ret=X509_new()) == NULL) goto err;
1782         ci=ret->cert_info;
1783
1784 #ifdef X509_V3
1785         /* Make it an X509 v3 certificate. */
1786         if (!X509_set_version(x509,2)) goto err;
1787 #endif
1788
1789         if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1790                 goto err;
1791         if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1792                 goto err;
1793
1794         BIO_printf(bio_err,"Certificate is to be certified until ");
1795         if (strcmp(startdate,"today") == 0)
1796                 X509_gmtime_adj(X509_get_notBefore(ret),0);
1797         else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1798
1799         if (enddate == NULL)
1800                 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1801         else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1802
1803         ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1804         if(days) BIO_printf(bio_err," (%d days)",days);
1805         BIO_printf(bio_err, "\n");
1806
1807         if (!X509_set_subject_name(ret,subject)) goto err;
1808
1809         pktmp=X509_REQ_get_pubkey(req);
1810         i = X509_set_pubkey(ret,pktmp);
1811         EVP_PKEY_free(pktmp);
1812         if (!i) goto err;
1813
1814         /* Lets add the extensions, if there are any */
1815         if (ext_sect)
1816                 {
1817                 X509V3_CTX ctx;
1818                 if (ci->version == NULL)
1819                         if ((ci->version=ASN1_INTEGER_new()) == NULL)
1820                                 goto err;
1821                 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1822
1823                 /* Free the current entries if any, there should not
1824                  * be any I believe */
1825                 if (ci->extensions != NULL)
1826                         sk_X509_EXTENSION_pop_free(ci->extensions,
1827                                                    X509_EXTENSION_free);
1828
1829                 ci->extensions = NULL;
1830
1831                 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1832                 X509V3_set_conf_lhash(&ctx, lconf);
1833
1834                 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1835
1836                 }
1837
1838
1839         if (!batch)
1840                 {
1841                 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1842                 (void)BIO_flush(bio_err);
1843                 buf[0]='\0';
1844                 fgets(buf,sizeof(buf)-1,stdin);
1845                 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1846                         {
1847                         BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1848                         ok=0;
1849                         goto err;
1850                         }
1851                 }
1852
1853
1854 #ifndef NO_DSA
1855         if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1856         pktmp=X509_get_pubkey(ret);
1857         if (EVP_PKEY_missing_parameters(pktmp) &&
1858                 !EVP_PKEY_missing_parameters(pkey))
1859                 EVP_PKEY_copy_parameters(pktmp,pkey);
1860         EVP_PKEY_free(pktmp);
1861 #endif
1862
1863         if (!X509_sign(ret,pkey,dgst))
1864                 goto err;
1865
1866         /* We now just add it to the database */
1867         row[DB_type]=(char *)OPENSSL_malloc(2);
1868
1869         tm=X509_get_notAfter(ret);
1870         row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1871         memcpy(row[DB_exp_date],tm->data,tm->length);
1872         row[DB_exp_date][tm->length]='\0';
1873
1874         row[DB_rev_date]=NULL;
1875
1876         /* row[DB_serial] done already */
1877         row[DB_file]=(char *)OPENSSL_malloc(8);
1878         /* row[DB_name] done already */
1879
1880         if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1881                 (row[DB_file] == NULL))
1882                 {
1883                 BIO_printf(bio_err,"Memory allocation failure\n");
1884                 goto err;
1885                 }
1886         strcpy(row[DB_file],"unknown");
1887         row[DB_type][0]='V';
1888         row[DB_type][1]='\0';
1889
1890         if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1891                 {
1892                 BIO_printf(bio_err,"Memory allocation failure\n");
1893                 goto err;
1894                 }
1895
1896         for (i=0; i<DB_NUMBER; i++)
1897                 {
1898                 irow[i]=row[i];
1899                 row[i]=NULL;
1900                 }
1901         irow[DB_NUMBER]=NULL;
1902
1903         if (!TXT_DB_insert(db,irow))
1904                 {
1905                 BIO_printf(bio_err,"failed to update database\n");
1906                 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1907                 goto err;
1908                 }
1909         ok=1;
1910 err:
1911         for (i=0; i<DB_NUMBER; i++)
1912                 if (row[i] != NULL) OPENSSL_free(row[i]);
1913
1914         if (CAname != NULL)
1915                 X509_NAME_free(CAname);
1916         if (subject != NULL)
1917                 X509_NAME_free(subject);
1918         if (tmptm != NULL)
1919                 ASN1_UTCTIME_free(tmptm);
1920         if (ok <= 0)
1921                 {
1922                 if (ret != NULL) X509_free(ret);
1923                 ret=NULL;
1924                 }
1925         else
1926                 *xret=ret;
1927         return(ok);
1928         }
1929
1930 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1931         {
1932
1933         if (output_der)
1934                 {
1935                 (void)i2d_X509_bio(bp,x);
1936                 return;
1937                 }
1938 #if 0
1939         /* ??? Not needed since X509_print prints all this stuff anyway */
1940         f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1941         BIO_printf(bp,"issuer :%s\n",f);
1942
1943         f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1944         BIO_printf(bp,"subject:%s\n",f);
1945
1946         BIO_puts(bp,"serial :");
1947         i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1948         BIO_puts(bp,"\n\n");
1949 #endif
1950         if(!notext)X509_print(bp,x);
1951         PEM_write_bio_X509(bp,x);
1952         }
1953
1954 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1955              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1956              BIGNUM *serial, char *startdate, char *enddate, int days,
1957              char *ext_sect, LHASH *lconf, int verbose)
1958         {
1959         STACK_OF(CONF_VALUE) *sk=NULL;
1960         LHASH *parms=NULL;
1961         X509_REQ *req=NULL;
1962         CONF_VALUE *cv=NULL;
1963         NETSCAPE_SPKI *spki = NULL;
1964         X509_REQ_INFO *ri;
1965         char *type,*buf;
1966         EVP_PKEY *pktmp=NULL;
1967         X509_NAME *n=NULL;
1968         X509_NAME_ENTRY *ne=NULL;
1969         int ok= -1,i,j;
1970         long errline;
1971         int nid;
1972
1973         /*
1974          * Load input file into a hash table.  (This is just an easy
1975          * way to read and parse the file, then put it into a convenient
1976          * STACK format).
1977          */
1978         parms=CONF_load(NULL,infile,&errline);
1979         if (parms == NULL)
1980                 {
1981                 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
1982                 ERR_print_errors(bio_err);
1983                 goto err;
1984                 }
1985
1986         sk=CONF_get_section(parms, "default");
1987         if (sk_CONF_VALUE_num(sk) == 0)
1988                 {
1989                 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
1990                 CONF_free(parms);
1991                 goto err;
1992                 }
1993
1994         /*
1995          * Now create a dummy X509 request structure.  We don't actually
1996          * have an X509 request, but we have many of the components
1997          * (a public key, various DN components).  The idea is that we
1998          * put these components into the right X509 request structure
1999          * and we can use the same code as if you had a real X509 request.
2000          */
2001         req=X509_REQ_new();
2002         if (req == NULL)
2003                 {
2004                 ERR_print_errors(bio_err);
2005                 goto err;
2006                 }
2007
2008         /*
2009          * Build up the subject name set.
2010          */
2011         ri=req->req_info;
2012         n = ri->subject;
2013
2014         for (i = 0; ; i++)
2015                 {
2016                 if (sk_CONF_VALUE_num(sk) <= i) break;
2017
2018                 cv=sk_CONF_VALUE_value(sk,i);
2019                 type=cv->name;
2020                 /* Skip past any leading X. X: X, etc to allow for
2021                  * multiple instances
2022                  */
2023                 for(buf = cv->name; *buf ; buf++)
2024                         if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2025                                         buf++;
2026                                         if(*buf) type = buf;
2027                                         break;
2028                 }
2029
2030                 buf=cv->value;
2031                 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2032                         {
2033                         if (strcmp(type, "SPKAC") == 0)
2034                                 {
2035                                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2036                                 if (spki == NULL)
2037                                         {
2038                                         BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2039                                         ERR_print_errors(bio_err);
2040                                         goto err;
2041                                         }
2042                                 }
2043                         continue;
2044                         }
2045
2046                 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2047                 if (fix_data(nid, &j) == 0)
2048                         {
2049                         BIO_printf(bio_err,
2050                                 "invalid characters in string %s\n",buf);
2051                         goto err;
2052                         }
2053
2054                 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2055                         (unsigned char *)buf,
2056                         strlen(buf))) == NULL)
2057                         goto err;
2058
2059                 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2060                 }
2061         if (spki == NULL)
2062                 {
2063                 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2064                         infile);
2065                 goto err;
2066                 }
2067
2068         /*
2069          * Now extract the key from the SPKI structure.
2070          */
2071
2072         BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2073
2074         if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2075                 {
2076                 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2077                 goto err;
2078                 }
2079
2080         j = NETSCAPE_SPKI_verify(spki, pktmp);
2081         if (j <= 0)
2082                 {
2083                 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2084                 goto err;
2085                 }
2086         BIO_printf(bio_err,"Signature ok\n");
2087
2088         X509_REQ_set_pubkey(req,pktmp);
2089         EVP_PKEY_free(pktmp);
2090         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2091                    days,1,verbose,req,ext_sect,lconf);
2092 err:
2093         if (req != NULL) X509_REQ_free(req);
2094         if (parms != NULL) CONF_free(parms);
2095         if (spki != NULL) NETSCAPE_SPKI_free(spki);
2096         if (ne != NULL) X509_NAME_ENTRY_free(ne);
2097
2098         return(ok);
2099         }
2100
2101 static int fix_data(int nid, int *type)
2102         {
2103         if (nid == NID_pkcs9_emailAddress)
2104                 *type=V_ASN1_IA5STRING;
2105         if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2106                 *type=V_ASN1_T61STRING;
2107         if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2108                 *type=V_ASN1_T61STRING;
2109         if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2110                 return(0);
2111         if (nid == NID_pkcs9_unstructuredName)
2112                 *type=V_ASN1_IA5STRING;
2113         return(1);
2114         }
2115
2116 static int check_time_format(char *str)
2117         {
2118         ASN1_UTCTIME tm;
2119
2120         tm.data=(unsigned char *)str;
2121         tm.length=strlen(str);
2122         tm.type=V_ASN1_UTCTIME;
2123         return(ASN1_UTCTIME_check(&tm));
2124         }
2125
2126 static int do_revoke(X509 *x509, TXT_DB *db)
2127 {
2128         ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2129         char *row[DB_NUMBER],**rrow,**irow;
2130         BIGNUM *bn = NULL;
2131         int ok=-1,i;
2132
2133         for (i=0; i<DB_NUMBER; i++)
2134                 row[i]=NULL;
2135         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2136         bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2137         row[DB_serial]=BN_bn2hex(bn);
2138         BN_free(bn);
2139         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2140                 {
2141                 BIO_printf(bio_err,"Memory allocation failure\n");
2142                 goto err;
2143                 }
2144         /* We have to lookup by serial number because name lookup
2145          * skips revoked certs
2146          */
2147         rrow=TXT_DB_get_by_index(db,DB_serial,row);
2148         if (rrow == NULL)
2149                 {
2150                 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2151
2152                 /* We now just add it to the database */
2153                 row[DB_type]=(char *)OPENSSL_malloc(2);
2154
2155                 tm=X509_get_notAfter(x509);
2156                 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2157                 memcpy(row[DB_exp_date],tm->data,tm->length);
2158                 row[DB_exp_date][tm->length]='\0';
2159
2160                 row[DB_rev_date]=NULL;
2161
2162                 /* row[DB_serial] done already */
2163                 row[DB_file]=(char *)OPENSSL_malloc(8);
2164
2165                 /* row[DB_name] done already */
2166
2167                 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2168                         (row[DB_file] == NULL))
2169                         {
2170                         BIO_printf(bio_err,"Memory allocation failure\n");
2171                         goto err;
2172                         }
2173                 strcpy(row[DB_file],"unknown");
2174                 row[DB_type][0]='V';
2175                 row[DB_type][1]='\0';
2176
2177                 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2178                         {
2179                         BIO_printf(bio_err,"Memory allocation failure\n");
2180                         goto err;
2181                         }
2182
2183                 for (i=0; i<DB_NUMBER; i++)
2184                         {
2185                         irow[i]=row[i];
2186                         row[i]=NULL;
2187                         }
2188                 irow[DB_NUMBER]=NULL;
2189
2190                 if (!TXT_DB_insert(db,irow))
2191                         {
2192                         BIO_printf(bio_err,"failed to update database\n");
2193                         BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2194                         goto err;
2195                         }
2196
2197                 /* Revoke Certificate */
2198                 ok = do_revoke(x509,db);
2199
2200                 goto err;
2201
2202                 }
2203         else if (index_name_cmp(row,rrow))
2204                 {
2205                 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2206                            row[DB_name]);
2207                 goto err;
2208                 }
2209         else if (rrow[DB_type][0]=='R')
2210                 {
2211                 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2212                            row[DB_serial]);
2213                 goto err;
2214                 }
2215         else
2216                 {
2217                 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2218                 revtm = ASN1_UTCTIME_new();
2219                 revtm=X509_gmtime_adj(revtm,0);
2220                 rrow[DB_type][0]='R';
2221                 rrow[DB_type][1]='\0';
2222                 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2223                 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2224                 rrow[DB_rev_date][revtm->length]='\0';
2225                 ASN1_UTCTIME_free(revtm);
2226                 }
2227         ok=1;
2228 err:
2229         for (i=0; i<DB_NUMBER; i++)
2230                 {
2231                 if (row[i] != NULL) 
2232                         OPENSSL_free(row[i]);
2233                 }
2234         return(ok);
2235 }
2236