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