Add information on 0.9.6a (in a form such that the list can be
[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 <ctype.h>
65 #include <sys/types.h>
66 #include <sys/stat.h>
67 #include "apps.h"
68 #include <openssl/conf.h>
69 #include <openssl/bio.h>
70 #include <openssl/err.h>
71 #include <openssl/bn.h>
72 #include <openssl/txt_db.h>
73 #include <openssl/evp.h>
74 #include <openssl/x509.h>
75 #include <openssl/x509v3.h>
76 #include <openssl/objects.h>
77 #include <openssl/ocsp.h>
78 #include <openssl/pem.h>
79 #include <openssl/engine.h>
80
81 #ifdef OPENSSL_SYS_WINDOWS
82 #define strcasecmp _stricmp
83 #else
84 #include <strings.h>
85 #endif
86
87 #ifndef W_OK
88 #  ifdef OPENSSL_SYS_VMS
89 #    if defined(__DECC)
90 #      include <unistd.h>
91 #    else
92 #      include <unixlib.h>
93 #    endif
94 #  else
95 #    include <sys/file.h>
96 #  endif
97 #endif
98
99 #ifndef W_OK
100 #  define F_OK 0
101 #  define X_OK 1
102 #  define W_OK 2
103 #  define R_OK 4
104 #endif
105
106 #undef PROG
107 #define PROG ca_main
108
109 #define BASE_SECTION    "ca"
110 #define CONFIG_FILE "openssl.cnf"
111
112 #define ENV_DEFAULT_CA          "default_ca"
113
114 #define ENV_DIR                 "dir"
115 #define ENV_CERTS               "certs"
116 #define ENV_CRL_DIR             "crl_dir"
117 #define ENV_CA_DB               "CA_DB"
118 #define ENV_NEW_CERTS_DIR       "new_certs_dir"
119 #define ENV_CERTIFICATE         "certificate"
120 #define ENV_SERIAL              "serial"
121 #define ENV_CRL                 "crl"
122 #define ENV_PRIVATE_KEY         "private_key"
123 #define ENV_RANDFILE            "RANDFILE"
124 #define ENV_DEFAULT_DAYS        "default_days"
125 #define ENV_DEFAULT_STARTDATE   "default_startdate"
126 #define ENV_DEFAULT_ENDDATE     "default_enddate"
127 #define ENV_DEFAULT_CRL_DAYS    "default_crl_days"
128 #define ENV_DEFAULT_CRL_HOURS   "default_crl_hours"
129 #define ENV_DEFAULT_MD          "default_md"
130 #define ENV_PRESERVE            "preserve"
131 #define ENV_POLICY              "policy"
132 #define ENV_EXTENSIONS          "x509_extensions"
133 #define ENV_CRLEXT              "crl_extensions"
134 #define ENV_MSIE_HACK           "msie_hack"
135 #define ENV_NAMEOPT             "name_opt"
136 #define ENV_CERTOPT             "cert_opt"
137 #define ENV_EXTCOPY             "copy_extensions"
138
139 #define ENV_DATABASE            "database"
140
141 #define DB_type         0
142 #define DB_exp_date     1
143 #define DB_rev_date     2
144 #define DB_serial       3       /* index - unique */
145 #define DB_file         4       
146 #define DB_name         5       /* index - unique for active */
147 #define DB_NUMBER       6
148
149 #define DB_TYPE_REV     'R'
150 #define DB_TYPE_EXP     'E'
151 #define DB_TYPE_VAL     'V'
152
153 /* Additional revocation information types */
154
155 #define REV_NONE                0       /* No addditional information */
156 #define REV_CRL_REASON          1       /* Value is CRL reason code */
157 #define REV_HOLD                2       /* Value is hold instruction */
158 #define REV_KEY_COMPROMISE      3       /* Value is cert key compromise time */
159 #define REV_CA_COMPROMISE       4       /* Value is CA key compromise time */
160
161 static char *ca_usage[]={
162 "usage: ca args\n",
163 "\n",
164 " -verbose        - Talk alot while doing things\n",
165 " -config file    - A config file\n",
166 " -name arg       - The particular CA definition to use\n",
167 " -gencrl         - Generate a new CRL\n",
168 " -crldays days   - Days is when the next CRL is due\n",
169 " -crlhours hours - Hours is when the next CRL is due\n",
170 " -startdate YYMMDDHHMMSSZ  - certificate validity notBefore\n",
171 " -enddate YYMMDDHHMMSSZ    - certificate validity notAfter (overrides -days)\n",
172 " -days arg       - number of days to certify the certificate for\n",
173 " -md arg         - md to use, one of md2, md5, sha or sha1\n",
174 " -policy arg     - The CA 'policy' to support\n",
175 " -keyfile arg    - private key file\n",
176 " -keyform arg    - private key file format (PEM or ENGINE)\n",
177 " -key arg        - key to decode the private key if it is encrypted\n",
178 " -cert file      - The CA certificate\n",
179 " -in file        - The input PEM encoded certificate request(s)\n",
180 " -out file       - Where to put the output file(s)\n",
181 " -outdir dir     - Where to put output certificates\n",
182 " -infiles ....   - The last argument, requests to process\n",
183 " -spkac file     - File contains DN and signed public key and challenge\n",
184 " -ss_cert file   - File contains a self signed cert to sign\n",
185 " -preserveDN     - Don't re-order the DN\n",
186 " -batch          - Don't ask questions\n",
187 " -msie_hack      - msie modifications to handle all those universal strings\n",
188 " -revoke file    - Revoke a certificate (given in file)\n",
189 " -subj arg       - Use arg instead of request's subject\n",
190 " -extensions ..  - Extension section (override value in config file)\n",
191 " -extfile file   - Configuration file with X509v3 extentions to add\n",
192 " -crlexts ..     - CRL extension section (override value in config file)\n",
193 " -engine e       - use engine e, possibly a hardware device.\n",
194 " -status serial  - Shows certificate status given the serial number\n",
195 " -updatedb       - Updates db for expired certificates\n",
196 NULL
197 };
198
199 #ifdef EFENCE
200 extern int EF_PROTECT_FREE;
201 extern int EF_PROTECT_BELOW;
202 extern int EF_ALIGNMENT;
203 #endif
204
205 static void lookup_fail(char *name,char *tag);
206 static unsigned long index_serial_hash(const char **a);
207 static int index_serial_cmp(const char **a, const char **b);
208 static unsigned long index_name_hash(const char **a);
209 static int index_name_qual(char **a);
210 static int index_name_cmp(const char **a,const char **b);
211 static BIGNUM *load_serial(char *serialfile);
212 static int save_serial(char *serialfile, BIGNUM *serial);
213 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
214                    const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
215                    BIGNUM *serial, char *subj, char *startdate,char *enddate,
216                    int days, int batch, char *ext_sect, LHASH *conf,int verbose,
217                    unsigned long certopt, unsigned long nameopt, int default_op,
218                    int ext_copy);
219 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
220                         const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
221                         TXT_DB *db, BIGNUM *serial, char *subj, char *startdate,
222                         char *enddate, int days, int batch, char *ext_sect,
223                         LHASH *conf,int verbose, unsigned long certopt,
224                         unsigned long nameopt, int default_op, int ext_copy);
225 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
226                          const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
227                          TXT_DB *db, BIGNUM *serial,char *subj, char *startdate,
228                          char *enddate, int days, char *ext_sect,LHASH *conf,
229                          int verbose, unsigned long certopt, unsigned long nameopt,
230                          int default_op, int ext_copy);
231 static int fix_data(int nid, int *type);
232 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
233 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
234         STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj,
235         char *startdate, char *enddate, int days, int batch, int verbose,
236         X509_REQ *req, char *ext_sect, LHASH *conf,
237         unsigned long certopt, unsigned long nameopt, int default_op,
238         int ext_copy);
239 static X509_NAME *do_subject(char *subject);
240 static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval);
241 static int get_certificate_status(const char *ser_status, TXT_DB *db);
242 static int do_updatedb(TXT_DB *db);
243 static int check_time_format(char *str);
244 char *make_revocation_str(int rev_type, char *rev_arg);
245 int make_revoked(X509_REVOKED *rev, char *str);
246 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
247 static LHASH *conf=NULL;
248 static LHASH *extconf=NULL;
249 static char *section=NULL;
250
251 static int preserve=0;
252 static int msie_hack=0;
253
254 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
255 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
256 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
257 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
258
259
260 int MAIN(int, char **);
261
262 int MAIN(int argc, char **argv)
263         {
264         ENGINE *e = NULL;
265         char *key=NULL,*passargin=NULL;
266         int total=0;
267         int total_done=0;
268         int badops=0;
269         int ret=1;
270         int req=0;
271         int verbose=0;
272         int gencrl=0;
273         int dorevoke=0;
274         int doupdatedb=0;
275         long crldays=0;
276         long crlhours=0;
277         long errorline= -1;
278         char *configfile=NULL;
279         char *md=NULL;
280         char *policy=NULL;
281         char *keyfile=NULL;
282         char *certfile=NULL;
283         int keyform=FORMAT_PEM;
284         char *infile=NULL;
285         char *spkac_file=NULL;
286         char *ss_cert_file=NULL;
287         char *ser_status=NULL;
288         EVP_PKEY *pkey=NULL;
289         int output_der = 0;
290         char *outfile=NULL;
291         char *outdir=NULL;
292         char *serialfile=NULL;
293         char *extensions=NULL;
294         char *extfile=NULL;
295         char *subj=NULL;
296         char *crl_ext=NULL;
297         int rev_type = REV_NONE;
298         char *rev_arg = NULL;
299         BIGNUM *serial=NULL;
300         char *startdate=NULL;
301         char *enddate=NULL;
302         int days=0;
303         int batch=0;
304         int notext=0;
305         unsigned long nameopt = 0, certopt = 0;
306         int default_op = 1;
307         int ext_copy = EXT_COPY_NONE;
308         X509 *x509=NULL;
309         X509 *x=NULL;
310         BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
311         char *dbfile=NULL;
312         TXT_DB *db=NULL;
313         X509_CRL *crl=NULL;
314         X509_CRL_INFO *ci=NULL;
315         X509_REVOKED *r=NULL;
316         char **pp,*p,*f;
317         int i,j;
318         long l;
319         const EVP_MD *dgst=NULL;
320         STACK_OF(CONF_VALUE) *attribs=NULL;
321         STACK_OF(X509) *cert_sk=NULL;
322 #undef BSIZE
323 #define BSIZE 256
324         MS_STATIC char buf[3][BSIZE];
325         char *randfile=NULL;
326         char *engine = NULL;
327
328 #ifdef EFENCE
329 EF_PROTECT_FREE=1;
330 EF_PROTECT_BELOW=1;
331 EF_ALIGNMENT=0;
332 #endif
333
334         apps_startup();
335
336         conf = NULL;
337         key = NULL;
338         section = NULL;
339
340         preserve=0;
341         msie_hack=0;
342         if (bio_err == NULL)
343                 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
344                         BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
345
346         argc--;
347         argv++;
348         while (argc >= 1)
349                 {
350                 if      (strcmp(*argv,"-verbose") == 0)
351                         verbose=1;
352                 else if (strcmp(*argv,"-config") == 0)
353                         {
354                         if (--argc < 1) goto bad;
355                         configfile= *(++argv);
356                         }
357                 else if (strcmp(*argv,"-name") == 0)
358                         {
359                         if (--argc < 1) goto bad;
360                         section= *(++argv);
361                         }
362                 else if (strcmp(*argv,"-subj") == 0)
363                         {
364                         if (--argc < 1) goto bad;
365                         subj= *(++argv);
366                         /* preserve=1; */
367                         }
368                 else if (strcmp(*argv,"-startdate") == 0)
369                         {
370                         if (--argc < 1) goto bad;
371                         startdate= *(++argv);
372                         }
373                 else if (strcmp(*argv,"-enddate") == 0)
374                         {
375                         if (--argc < 1) goto bad;
376                         enddate= *(++argv);
377                         }
378                 else if (strcmp(*argv,"-days") == 0)
379                         {
380                         if (--argc < 1) goto bad;
381                         days=atoi(*(++argv));
382                         }
383                 else if (strcmp(*argv,"-md") == 0)
384                         {
385                         if (--argc < 1) goto bad;
386                         md= *(++argv);
387                         }
388                 else if (strcmp(*argv,"-policy") == 0)
389                         {
390                         if (--argc < 1) goto bad;
391                         policy= *(++argv);
392                         }
393                 else if (strcmp(*argv,"-keyfile") == 0)
394                         {
395                         if (--argc < 1) goto bad;
396                         keyfile= *(++argv);
397                         }
398                 else if (strcmp(*argv,"-keyform") == 0)
399                         {
400                         if (--argc < 1) goto bad;
401                         keyform=str2fmt(*(++argv));
402                         }
403                 else if (strcmp(*argv,"-passin") == 0)
404                         {
405                         if (--argc < 1) goto bad;
406                         passargin= *(++argv);
407                         }
408                 else if (strcmp(*argv,"-key") == 0)
409                         {
410                         if (--argc < 1) goto bad;
411                         key= *(++argv);
412                         }
413                 else if (strcmp(*argv,"-cert") == 0)
414                         {
415                         if (--argc < 1) goto bad;
416                         certfile= *(++argv);
417                         }
418                 else if (strcmp(*argv,"-in") == 0)
419                         {
420                         if (--argc < 1) goto bad;
421                         infile= *(++argv);
422                         req=1;
423                         }
424                 else if (strcmp(*argv,"-out") == 0)
425                         {
426                         if (--argc < 1) goto bad;
427                         outfile= *(++argv);
428                         }
429                 else if (strcmp(*argv,"-outdir") == 0)
430                         {
431                         if (--argc < 1) goto bad;
432                         outdir= *(++argv);
433                         }
434                 else if (strcmp(*argv,"-notext") == 0)
435                         notext=1;
436                 else if (strcmp(*argv,"-batch") == 0)
437                         batch=1;
438                 else if (strcmp(*argv,"-preserveDN") == 0)
439                         preserve=1;
440                 else if (strcmp(*argv,"-gencrl") == 0)
441                         gencrl=1;
442                 else if (strcmp(*argv,"-msie_hack") == 0)
443                         msie_hack=1;
444                 else if (strcmp(*argv,"-crldays") == 0)
445                         {
446                         if (--argc < 1) goto bad;
447                         crldays= atol(*(++argv));
448                         }
449                 else if (strcmp(*argv,"-crlhours") == 0)
450                         {
451                         if (--argc < 1) goto bad;
452                         crlhours= atol(*(++argv));
453                         }
454                 else if (strcmp(*argv,"-infiles") == 0)
455                         {
456                         argc--;
457                         argv++;
458                         req=1;
459                         break;
460                         }
461                 else if (strcmp(*argv, "-ss_cert") == 0)
462                         {
463                         if (--argc < 1) goto bad;
464                         ss_cert_file = *(++argv);
465                         req=1;
466                         }
467                 else if (strcmp(*argv, "-spkac") == 0)
468                         {
469                         if (--argc < 1) goto bad;
470                         spkac_file = *(++argv);
471                         req=1;
472                         }
473                 else if (strcmp(*argv,"-revoke") == 0)
474                         {
475                         if (--argc < 1) goto bad;
476                         infile= *(++argv);
477                         dorevoke=1;
478                         }
479                 else if (strcmp(*argv,"-extensions") == 0)
480                         {
481                         if (--argc < 1) goto bad;
482                         extensions= *(++argv);
483                         }
484                 else if (strcmp(*argv,"-extfile") == 0)
485                         {
486                         if (--argc < 1) goto bad;
487                         extfile= *(++argv);
488                         }
489                 else if (strcmp(*argv,"-status") == 0)
490                         {
491                         if (--argc < 1) goto bad;
492                         ser_status= *(++argv);
493                         }
494                 else if (strcmp(*argv,"-updatedb") == 0)
495                         {
496                         doupdatedb=1;
497                         }
498                 else if (strcmp(*argv,"-crlexts") == 0)
499                         {
500                         if (--argc < 1) goto bad;
501                         crl_ext= *(++argv);
502                         }
503                 else if (strcmp(*argv,"-crl_reason") == 0)
504                         {
505                         if (--argc < 1) goto bad;
506                         rev_arg = *(++argv);
507                         rev_type = REV_CRL_REASON;
508                         }
509                 else if (strcmp(*argv,"-crl_hold") == 0)
510                         {
511                         if (--argc < 1) goto bad;
512                         rev_arg = *(++argv);
513                         rev_type = REV_HOLD;
514                         }
515                 else if (strcmp(*argv,"-crl_compromise") == 0)
516                         {
517                         if (--argc < 1) goto bad;
518                         rev_arg = *(++argv);
519                         rev_type = REV_KEY_COMPROMISE;
520                         }
521                 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
522                         {
523                         if (--argc < 1) goto bad;
524                         rev_arg = *(++argv);
525                         rev_type = REV_CA_COMPROMISE;
526                         }
527                 else if (strcmp(*argv,"-engine") == 0)
528                         {
529                         if (--argc < 1) goto bad;
530                         engine= *(++argv);
531                         }
532                 else
533                         {
534 bad:
535                         BIO_printf(bio_err,"unknown option %s\n",*argv);
536                         badops=1;
537                         break;
538                         }
539                 argc--;
540                 argv++;
541                 }
542
543         if (badops)
544                 {
545                 for (pp=ca_usage; (*pp != NULL); pp++)
546                         BIO_printf(bio_err,"%s",*pp);
547                 goto err;
548                 }
549
550         ERR_load_crypto_strings();
551
552         if (engine != NULL)
553                 {
554                 if ((e = ENGINE_by_id(engine)) == NULL)
555                         {
556                         BIO_printf(bio_err,"invalid engine \"%s\"\n",
557                                 engine);
558                         goto err;
559                         }
560                 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL))
561                         {
562                         BIO_printf(bio_err,"can't use that engine\n");
563                         goto err;
564                         }
565                 BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
566                 /* Free our "structural" reference. */
567                 ENGINE_free(e);
568                 }
569
570         /*****************************************************************/
571         if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
572         if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
573         if (configfile == NULL)
574                 {
575                 /* We will just use 'buf[0]' as a temporary buffer.  */
576 #ifdef OPENSSL_SYS_VMS
577                 strncpy(buf[0],X509_get_default_cert_area(),
578                         sizeof(buf[0])-1-sizeof(CONFIG_FILE));
579 #else
580                 strncpy(buf[0],X509_get_default_cert_area(),
581                         sizeof(buf[0])-2-sizeof(CONFIG_FILE));
582                 strcat(buf[0],"/");
583 #endif
584                 strcat(buf[0],CONFIG_FILE);
585                 configfile=buf[0];
586                 }
587
588         BIO_printf(bio_err,"Using configuration from %s\n",configfile);
589         if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
590                 {
591                 if (errorline <= 0)
592                         BIO_printf(bio_err,"error loading the config file '%s'\n",
593                                 configfile);
594                 else
595                         BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
596                                 ,errorline,configfile);
597                 goto err;
598                 }
599
600         /* Lets get the config section we are using */
601         if (section == NULL)
602                 {
603                 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
604                 if (section == NULL)
605                         {
606                         lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
607                         goto err;
608                         }
609                 }
610
611         if (conf != NULL)
612                 {
613                 p=CONF_get_string(conf,NULL,"oid_file");
614                 if (p == NULL)
615                         ERR_clear_error();
616                 if (p != NULL)
617                         {
618                         BIO *oid_bio;
619
620                         oid_bio=BIO_new_file(p,"r");
621                         if (oid_bio == NULL) 
622                                 {
623                                 /*
624                                 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
625                                 ERR_print_errors(bio_err);
626                                 */
627                                 ERR_clear_error();
628                                 }
629                         else
630                                 {
631                                 OBJ_create_objects(oid_bio);
632                                 BIO_free(oid_bio);
633                                 }
634                         }
635                 if (!add_oid_section(bio_err,conf)) 
636                         {
637                         ERR_print_errors(bio_err);
638                         goto err;
639                         }
640                 }
641
642         randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
643         if (randfile == NULL)
644                 ERR_clear_error();
645         app_RAND_load_file(randfile, bio_err, 0);
646         
647         in=BIO_new(BIO_s_file());
648         out=BIO_new(BIO_s_file());
649         Sout=BIO_new(BIO_s_file());
650         Cout=BIO_new(BIO_s_file());
651         if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
652                 {
653                 ERR_print_errors(bio_err);
654                 goto err;
655                 }
656
657         /*****************************************************************/
658         /* report status of cert with serial number given on command line */
659         if (ser_status)
660         {
661                 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
662                         {
663                         lookup_fail(section,ENV_DATABASE);
664                         goto err;
665                         }
666                 if (BIO_read_filename(in,dbfile) <= 0)
667                         {
668                         perror(dbfile);
669                         BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
670                         goto err;
671                         }
672                 db=TXT_DB_read(in,DB_NUMBER);
673                 if (db == NULL) goto err;
674
675                 if (!TXT_DB_create_index(db, DB_serial, NULL,
676                                         LHASH_HASH_FN(index_serial_hash),
677                                         LHASH_COMP_FN(index_serial_cmp)))
678                         {
679                         BIO_printf(bio_err,
680                           "error creating serial number index:(%ld,%ld,%ld)\n",
681                                                 db->error,db->arg1,db->arg2);
682                         goto err;
683                         }
684
685                 if (get_certificate_status(ser_status,db) != 1)
686                         BIO_printf(bio_err,"Error verifying serial %s!\n",
687                                  ser_status);
688                 goto err;
689         }
690
691         /*****************************************************************/
692         /* we definitely need a public key, so let's get it */
693
694         if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
695                 section,ENV_PRIVATE_KEY)) == NULL))
696                 {
697                 lookup_fail(section,ENV_PRIVATE_KEY);
698                 goto err;
699                 }
700         if (!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
701                 {
702                 BIO_printf(bio_err,"Error getting password\n");
703                 goto err;
704                 }
705         if (keyform == FORMAT_ENGINE)
706                 {
707                 if (!e)
708                         {
709                         BIO_printf(bio_err,"no engine specified\n");
710                         goto err;
711                         }
712                 pkey = ENGINE_load_private_key(e, keyfile, key);
713                 }
714         else if (keyform == FORMAT_PEM)
715                 {
716                 if (BIO_read_filename(in,keyfile) <= 0)
717                         {
718                         perror(keyfile);
719                         BIO_printf(bio_err,"trying to load CA private key\n");
720                         goto err;
721                         }
722                 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
723                 }
724         else
725                 {
726                 BIO_printf(bio_err,"bad input format specified for key file\n");
727                 goto err;
728                 }
729         if (key) memset(key,0,strlen(key));
730         if (pkey == NULL)
731                 {
732                 BIO_printf(bio_err,"unable to load CA private key\n");
733                 goto err;
734                 }
735
736         /*****************************************************************/
737         /* we need a certificate */
738         if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
739                 section,ENV_CERTIFICATE)) == NULL))
740                 {
741                 lookup_fail(section,ENV_CERTIFICATE);
742                 goto err;
743                 }
744         if (BIO_read_filename(in,certfile) <= 0)
745                 {
746                 perror(certfile);
747                 BIO_printf(bio_err,"trying to load CA certificate\n");
748                 goto err;
749                 }
750         x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
751         if (x509 == NULL)
752                 {
753                 BIO_printf(bio_err,"unable to load CA certificate\n");
754                 goto err;
755                 }
756
757         if (!X509_check_private_key(x509,pkey))
758                 {
759                 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
760                 goto err;
761                 }
762
763         f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
764         if (f == NULL)
765                 ERR_clear_error();
766         if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
767                 preserve=1;
768         f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
769         if (f == NULL)
770                 ERR_clear_error();
771         if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
772                 msie_hack=1;
773
774         f=CONF_get_string(conf,section,ENV_NAMEOPT);
775
776         if (f)
777                 {
778                 if (!set_name_ex(&nameopt, f))
779                         {
780                         BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
781                         goto err;
782                         }
783                 default_op = 0;
784                 }
785         else
786                 ERR_clear_error();
787
788         f=CONF_get_string(conf,section,ENV_CERTOPT);
789
790         if (f)
791                 {
792                 if (!set_cert_ex(&certopt, f))
793                         {
794                         BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
795                         goto err;
796                         }
797                 default_op = 0;
798                 }
799         else
800                 ERR_clear_error();
801
802         f=CONF_get_string(conf,section,ENV_EXTCOPY);
803
804         if (f)
805                 {
806                 if (!set_ext_copy(&ext_copy, f))
807                         {
808                         BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
809                         goto err;
810                         }
811                 }
812         else
813                 ERR_clear_error();
814
815         /*****************************************************************/
816         /* lookup where to write new certificates */
817         if ((outdir == NULL) && (req))
818                 {
819                 struct stat sb;
820
821                 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
822                         == NULL)
823                         {
824                         BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
825                         goto err;
826                         }
827 #ifndef OPENSSL_SYS_VMS
828             /* outdir is a directory spec, but access() for VMS demands a
829                filename.  In any case, stat(), below, will catch the problem
830                if outdir is not a directory spec, and the fopen() or open()
831                will catch an error if there is no write access.
832
833                Presumably, this problem could also be solved by using the DEC
834                C routines to convert the directory syntax to Unixly, and give
835                that to access().  However, time's too short to do that just
836                now.
837             */
838                 if (access(outdir,R_OK|W_OK|X_OK) != 0)
839                         {
840                         BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
841                         perror(outdir);
842                         goto err;
843                         }
844
845                 if (stat(outdir,&sb) != 0)
846                         {
847                         BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
848                         perror(outdir);
849                         goto err;
850                         }
851 #ifdef S_IFDIR
852                 if (!(sb.st_mode & S_IFDIR))
853                         {
854                         BIO_printf(bio_err,"%s need to be a directory\n",outdir);
855                         perror(outdir);
856                         goto err;
857                         }
858 #endif
859 #endif
860                 }
861
862         /*****************************************************************/
863         /* we need to load the database file */
864         if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
865                 {
866                 lookup_fail(section,ENV_DATABASE);
867                 goto err;
868                 }
869         if (BIO_read_filename(in,dbfile) <= 0)
870                 {
871                 perror(dbfile);
872                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
873                 goto err;
874                 }
875         db=TXT_DB_read(in,DB_NUMBER);
876         if (db == NULL) goto err;
877
878         /* Lets check some fields */
879         for (i=0; i<sk_num(db->data); i++)
880                 {
881                 pp=(char **)sk_value(db->data,i);
882                 if ((pp[DB_type][0] != DB_TYPE_REV) &&
883                         (pp[DB_rev_date][0] != '\0'))
884                         {
885                         BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
886                         goto err;
887                         }
888                 if ((pp[DB_type][0] == DB_TYPE_REV) &&
889                         !make_revoked(NULL, pp[DB_rev_date]))
890                         {
891                         BIO_printf(bio_err," in entry %d\n", i+1);
892                         goto err;
893                         }
894                 if (!check_time_format(pp[DB_exp_date]))
895                         {
896                         BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
897                         goto err;
898                         }
899                 p=pp[DB_serial];
900                 j=strlen(p);
901                 if (*p == '-')
902                         {
903                         p++;
904                         j--;
905                         }
906                 if ((j&1) || (j < 2))
907                         {
908                         BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
909                         goto err;
910                         }
911                 while (*p)
912                         {
913                         if (!(  ((*p >= '0') && (*p <= '9')) ||
914                                 ((*p >= 'A') && (*p <= 'F')) ||
915                                 ((*p >= 'a') && (*p <= 'f')))  )
916                                 {
917                                 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);
918                                 goto err;
919                                 }
920                         p++;
921                         }
922                 }
923         if (verbose)
924                 {
925                 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
926 #ifdef OPENSSL_SYS_VMS
927                 {
928                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
929                 out = BIO_push(tmpbio, out);
930                 }
931 #endif
932                 TXT_DB_write(out,db);
933                 BIO_printf(bio_err,"%d entries loaded from the database\n",
934                         db->data->num);
935                 BIO_printf(bio_err,"generating index\n");
936                 }
937         
938         if (!TXT_DB_create_index(db, DB_serial, NULL,
939                         LHASH_HASH_FN(index_serial_hash),
940                         LHASH_COMP_FN(index_serial_cmp)))
941                 {
942                 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
943                 goto err;
944                 }
945
946         if (!TXT_DB_create_index(db, DB_name, index_name_qual,
947                         LHASH_HASH_FN(index_name_hash),
948                         LHASH_COMP_FN(index_name_cmp)))
949                 {
950                 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
951                         db->error,db->arg1,db->arg2);
952                 goto err;
953                 }
954
955         /*****************************************************************/
956         /* Update the db file for expired certificates */
957         if (doupdatedb)
958                 {
959                 if (verbose)
960                         BIO_printf(bio_err, "Updating %s ...\n",
961                                                         dbfile);
962
963                 i = do_updatedb(db);
964                 if (i == -1)
965                         {
966                         BIO_printf(bio_err,"Malloc failure\n");
967                         goto err;
968                         }
969                 else if (i == 0)
970                         {
971                         if (verbose) BIO_printf(bio_err,
972                                         "No entries found to mark expired\n"); 
973                         }
974                 else
975                         {
976                         out = BIO_new(BIO_s_file());
977                         if (out == NULL)
978                                 {
979                                 ERR_print_errors(bio_err);
980                                 goto err;
981                                 }
982
983                         j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
984                         if (j < 0 || j >= sizeof buf[0])
985                                 {
986                                 BIO_printf(bio_err, "file name too long\n");
987                                 goto err;
988                                 }
989                         if (BIO_write_filename(out,buf[0]) <= 0)
990                                 {
991                                 perror(dbfile);
992                                 BIO_printf(bio_err,"unable to open '%s'\n",
993                                                                         dbfile);
994                                 goto err;
995                                 }
996                         j=TXT_DB_write(out,db);
997                         if (j <= 0) goto err;
998                         
999                         BIO_free(out);
1000                         out = NULL;
1001                         j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
1002                         if (j < 0 || j >= sizeof buf[1])
1003                                 {
1004                                 BIO_printf(bio_err, "file name too long\n");
1005                                 goto err;
1006                                 }
1007                         if (rename(dbfile,buf[1]) < 0)
1008                                 {
1009                                 BIO_printf(bio_err,
1010                                                 "unable to rename %s to %s\n",
1011                                                 dbfile, buf[1]);
1012                                 perror("reason");
1013                                 goto err;
1014                                 }
1015                         if (rename(buf[0],dbfile) < 0)
1016                                 {
1017                                 BIO_printf(bio_err,
1018                                                 "unable to rename %s to %s\n",
1019                                                 buf[0],dbfile);
1020                                 perror("reason");
1021                                 rename(buf[1],dbfile);
1022                                 goto err;
1023                                 }
1024                                 
1025                         if (verbose) BIO_printf(bio_err,
1026                                 "Done. %d entries marked as expired\n",i); 
1027                         }
1028                         goto err;
1029                 }
1030
1031         /*****************************************************************/
1032         /* Read extentions config file                                   */
1033         if (extfile)
1034                 {
1035                 if (!(extconf=CONF_load(NULL,extfile,&errorline)))
1036                         {
1037                         if (errorline <= 0)
1038                                 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
1039                                         extfile);
1040                         else
1041                                 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
1042                                         errorline,extfile);
1043                         ret = 1;
1044                         goto err;
1045                         }
1046
1047                 if (verbose)
1048                         BIO_printf(bio_err, "Succesfully loaded extensions file %s\n", extfile);
1049
1050                 /* We can have sections in the ext file */
1051                 if (!extensions && !(extensions = CONF_get_string(extconf, "default", "extensions")))
1052                         extensions = "default";
1053                 }
1054
1055         /*****************************************************************/
1056         if (req || gencrl)
1057                 {
1058                 if (outfile != NULL)
1059                         {
1060                         if (BIO_write_filename(Sout,outfile) <= 0)
1061                                 {
1062                                 perror(outfile);
1063                                 goto err;
1064                                 }
1065                         }
1066                 else
1067                         {
1068                         BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
1069 #ifdef OPENSSL_SYS_VMS
1070                         {
1071                         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1072                         Sout = BIO_push(tmpbio, Sout);
1073                         }
1074 #endif
1075                         }
1076                 }
1077
1078         if (req)
1079                 {
1080                 if ((md == NULL) && ((md=CONF_get_string(conf,
1081                         section,ENV_DEFAULT_MD)) == NULL))
1082                         {
1083                         lookup_fail(section,ENV_DEFAULT_MD);
1084                         goto err;
1085                         }
1086                 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1087                         {
1088                         BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1089                         goto err;
1090                         }
1091                 if (verbose)
1092                         BIO_printf(bio_err,"message digest is %s\n",
1093                                 OBJ_nid2ln(dgst->type));
1094                 if ((policy == NULL) && ((policy=CONF_get_string(conf,
1095                         section,ENV_POLICY)) == NULL))
1096                         {
1097                         lookup_fail(section,ENV_POLICY);
1098                         goto err;
1099                         }
1100                 if (verbose)
1101                         BIO_printf(bio_err,"policy is %s\n",policy);
1102
1103                 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
1104                         == NULL)
1105                         {
1106                         lookup_fail(section,ENV_SERIAL);
1107                         goto err;
1108                         }
1109
1110                 if (!extconf)
1111                         {
1112                         /* no '-extfile' option, so we look for extensions
1113                          * in the main configuration file */
1114                         if (!extensions)
1115                                 {
1116                                 extensions=CONF_get_string(conf,section,
1117                                                                 ENV_EXTENSIONS);
1118                                 if (!extensions)
1119                                         ERR_clear_error();
1120                                 }
1121                         if (extensions)
1122                                 {
1123                                 /* Check syntax of file */
1124                                 X509V3_CTX ctx;
1125                                 X509V3_set_ctx_test(&ctx);
1126                                 X509V3_set_conf_lhash(&ctx, conf);
1127                                 if (!X509V3_EXT_add_conf(conf, &ctx, extensions,
1128                                                                 NULL))
1129                                         {
1130                                         BIO_printf(bio_err,
1131                                         "Error Loading extension section %s\n",
1132                                                                  extensions);
1133                                         ret = 1;
1134                                         goto err;
1135                                         }
1136                                 }
1137                         }
1138
1139                 if (startdate == NULL)
1140                         {
1141                         startdate=CONF_get_string(conf,section,
1142                                 ENV_DEFAULT_STARTDATE);
1143                         if (startdate == NULL)
1144                                 ERR_clear_error();
1145                         }
1146                 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1147                         {
1148                         BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1149                         goto err;
1150                         }
1151                 if (startdate == NULL) startdate="today";
1152
1153                 if (enddate == NULL)
1154                         {
1155                         enddate=CONF_get_string(conf,section,
1156                                 ENV_DEFAULT_ENDDATE);
1157                         if (enddate == NULL)
1158                                 ERR_clear_error();
1159                         }
1160                 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1161                         {
1162                         BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1163                         goto err;
1164                         }
1165
1166                 if (days == 0)
1167                         {
1168                         days=(int)CONF_get_number(conf,section,
1169                                 ENV_DEFAULT_DAYS);
1170                         }
1171                 if (!enddate && (days == 0))
1172                         {
1173                         BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1174                         goto err;
1175                         }
1176
1177                 if ((serial=load_serial(serialfile)) == NULL)
1178                         {
1179                         BIO_printf(bio_err,"error while loading serial number\n");
1180                         goto err;
1181                         }
1182                 if (verbose)
1183                         {
1184                         if ((f=BN_bn2hex(serial)) == NULL) goto err;
1185                         BIO_printf(bio_err,"next serial number is %s\n",f);
1186                         OPENSSL_free(f);
1187                         }
1188
1189                 if ((attribs=CONF_get_section(conf,policy)) == NULL)
1190                         {
1191                         BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1192                         goto err;
1193                         }
1194
1195                 if ((cert_sk=sk_X509_new_null()) == NULL)
1196                         {
1197                         BIO_printf(bio_err,"Memory allocation failure\n");
1198                         goto err;
1199                         }
1200                 if (spkac_file != NULL)
1201                         {
1202                         total++;
1203                         j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1204                                 serial,subj,startdate,enddate, days,extensions,conf,
1205                                 verbose, certopt, nameopt, default_op, ext_copy);
1206                         if (j < 0) goto err;
1207                         if (j > 0)
1208                                 {
1209                                 total_done++;
1210                                 BIO_printf(bio_err,"\n");
1211                                 if (!BN_add_word(serial,1)) goto err;
1212                                 if (!sk_X509_push(cert_sk,x))
1213                                         {
1214                                         BIO_printf(bio_err,"Memory allocation failure\n");
1215                                         goto err;
1216                                         }
1217                                 if (outfile)
1218                                         {
1219                                         output_der = 1;
1220                                         batch = 1;
1221                                         }
1222                                 }
1223                         }
1224                 if (ss_cert_file != NULL)
1225                         {
1226                         total++;
1227                         j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1228                                 db,serial,subj,startdate,enddate,days,batch,
1229                                 extensions,conf,verbose, certopt, nameopt,
1230                                                         default_op, ext_copy);
1231                         if (j < 0) goto err;
1232                         if (j > 0)
1233                                 {
1234                                 total_done++;
1235                                 BIO_printf(bio_err,"\n");
1236                                 if (!BN_add_word(serial,1)) goto err;
1237                                 if (!sk_X509_push(cert_sk,x))
1238                                         {
1239                                         BIO_printf(bio_err,"Memory allocation failure\n");
1240                                         goto err;
1241                                         }
1242                                 }
1243                         }
1244                 if (infile != NULL)
1245                         {
1246                         total++;
1247                         j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1248                                 serial,subj,startdate,enddate,days,batch,
1249                                 extensions,conf,verbose, certopt, nameopt,
1250                                 default_op, ext_copy);
1251                         if (j < 0) goto err;
1252                         if (j > 0)
1253                                 {
1254                                 total_done++;
1255                                 BIO_printf(bio_err,"\n");
1256                                 if (!BN_add_word(serial,1)) goto err;
1257                                 if (!sk_X509_push(cert_sk,x))
1258                                         {
1259                                         BIO_printf(bio_err,"Memory allocation failure\n");
1260                                         goto err;
1261                                         }
1262                                 }
1263                         }
1264                 for (i=0; i<argc; i++)
1265                         {
1266                         total++;
1267                         j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1268                                 serial,subj,startdate,enddate,days,batch,
1269                                 extensions,conf,verbose, certopt, nameopt,
1270                                 default_op, ext_copy);
1271                         if (j < 0) goto err;
1272                         if (j > 0)
1273                                 {
1274                                 total_done++;
1275                                 BIO_printf(bio_err,"\n");
1276                                 if (!BN_add_word(serial,1)) goto err;
1277                                 if (!sk_X509_push(cert_sk,x))
1278                                         {
1279                                         BIO_printf(bio_err,"Memory allocation failure\n");
1280                                         goto err;
1281                                         }
1282                                 }
1283                         }       
1284                 /* we have a stack of newly certified certificates
1285                  * and a data base and serial number that need
1286                  * updating */
1287
1288                 if (sk_X509_num(cert_sk) > 0)
1289                         {
1290                         if (!batch)
1291                                 {
1292                                 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1293                                 (void)BIO_flush(bio_err);
1294                                 buf[0][0]='\0';
1295                                 fgets(buf[0],10,stdin);
1296                                 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1297                                         {
1298                                         BIO_printf(bio_err,"CERTIFICATION CANCELED\n"); 
1299                                         ret=0;
1300                                         goto err;
1301                                         }
1302                                 }
1303
1304                         BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1305
1306                         strncpy(buf[0],serialfile,BSIZE-4);
1307
1308 #ifdef OPENSSL_SYS_VMS
1309                         strcat(buf[0],"-new");
1310 #else
1311                         strcat(buf[0],".new");
1312 #endif
1313
1314                         if (!save_serial(buf[0],serial)) goto err;
1315
1316                         strncpy(buf[1],dbfile,BSIZE-4);
1317
1318 #ifdef OPENSSL_SYS_VMS
1319                         strcat(buf[1],"-new");
1320 #else
1321                         strcat(buf[1],".new");
1322 #endif
1323
1324                         if (BIO_write_filename(out,buf[1]) <= 0)
1325                                 {
1326                                 perror(dbfile);
1327                                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1328                                 goto err;
1329                                 }
1330                         l=TXT_DB_write(out,db);
1331                         if (l <= 0) goto err;
1332                         }
1333         
1334                 if (verbose)
1335                         BIO_printf(bio_err,"writing new certificates\n");
1336                 for (i=0; i<sk_X509_num(cert_sk); i++)
1337                         {
1338                         int k;
1339                         unsigned char *n;
1340
1341                         x=sk_X509_value(cert_sk,i);
1342
1343                         j=x->cert_info->serialNumber->length;
1344                         p=(char *)x->cert_info->serialNumber->data;
1345                         
1346                         strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1347
1348 #ifndef OPENSSL_SYS_VMS
1349                         strcat(buf[2],"/");
1350 #endif
1351
1352                         n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1353                         if (j > 0)
1354                                 {
1355                                 for (k=0; k<j; k++)
1356                                         {
1357                                         sprintf((char *)n,"%02X",(unsigned char)*(p++));
1358                                         n+=2;
1359                                         }
1360                                 }
1361                         else
1362                                 {
1363                                 *(n++)='0';
1364                                 *(n++)='0';
1365                                 }
1366                         *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1367                         *n='\0';
1368                         if (verbose)
1369                                 BIO_printf(bio_err,"writing %s\n",buf[2]);
1370
1371                         if (BIO_write_filename(Cout,buf[2]) <= 0)
1372                                 {
1373                                 perror(buf[2]);
1374                                 goto err;
1375                                 }
1376                         write_new_certificate(Cout,x, 0, notext);
1377                         write_new_certificate(Sout,x, output_der, notext);
1378                         }
1379
1380                 if (sk_X509_num(cert_sk))
1381                         {
1382                         /* Rename the database and the serial file */
1383                         strncpy(buf[2],serialfile,BSIZE-4);
1384
1385 #ifdef OPENSSL_SYS_VMS
1386                         strcat(buf[2],"-old");
1387 #else
1388                         strcat(buf[2],".old");
1389 #endif
1390
1391                         BIO_free(in);
1392                         BIO_free_all(out);
1393                         in=NULL;
1394                         out=NULL;
1395                         if (rename(serialfile,buf[2]) < 0)
1396                                 {
1397                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1398                                         serialfile,buf[2]);
1399                                 perror("reason");
1400                                 goto err;
1401                                 }
1402                         if (rename(buf[0],serialfile) < 0)
1403                                 {
1404                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1405                                         buf[0],serialfile);
1406                                 perror("reason");
1407                                 rename(buf[2],serialfile);
1408                                 goto err;
1409                                 }
1410
1411                         strncpy(buf[2],dbfile,BSIZE-4);
1412
1413 #ifdef OPENSSL_SYS_VMS
1414                         strcat(buf[2],"-old");
1415 #else
1416                         strcat(buf[2],".old");
1417 #endif
1418
1419                         if (rename(dbfile,buf[2]) < 0)
1420                                 {
1421                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1422                                         dbfile,buf[2]);
1423                                 perror("reason");
1424                                 goto err;
1425                                 }
1426                         if (rename(buf[1],dbfile) < 0)
1427                                 {
1428                                 BIO_printf(bio_err,"unable to rename %s to %s\n",
1429                                         buf[1],dbfile);
1430                                 perror("reason");
1431                                 rename(buf[2],dbfile);
1432                                 goto err;
1433                                 }
1434                         BIO_printf(bio_err,"Data Base Updated\n");
1435                         }
1436                 }
1437         
1438         /*****************************************************************/
1439         if (gencrl)
1440                 {
1441                 int crl_v2 = 0;
1442                 if (!crl_ext)
1443                         {
1444                         crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1445                         if (!crl_ext)
1446                                 ERR_clear_error();
1447                         }
1448                 if (crl_ext)
1449                         {
1450                         /* Check syntax of file */
1451                         X509V3_CTX ctx;
1452                         X509V3_set_ctx_test(&ctx);
1453                         X509V3_set_conf_lhash(&ctx, conf);
1454                         if (!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL))
1455                                 {
1456                                 BIO_printf(bio_err,
1457                                  "Error Loading CRL extension section %s\n",
1458                                                                  crl_ext);
1459                                 ret = 1;
1460                                 goto err;
1461                                 }
1462                         }
1463
1464                 if (!crldays && !crlhours)
1465                         {
1466                         crldays=CONF_get_number(conf,section,
1467                                 ENV_DEFAULT_CRL_DAYS);
1468                         crlhours=CONF_get_number(conf,section,
1469                                 ENV_DEFAULT_CRL_HOURS);
1470                         }
1471                 if ((crldays == 0) && (crlhours == 0))
1472                         {
1473                         BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1474                         goto err;
1475                         }
1476
1477                 if (verbose) BIO_printf(bio_err,"making CRL\n");
1478                 if ((crl=X509_CRL_new()) == NULL) goto err;
1479                 ci=crl->crl;
1480                 X509_NAME_free(ci->issuer);
1481                 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1482                 if (ci->issuer == NULL) goto err;
1483
1484                 X509_gmtime_adj(ci->lastUpdate,0);
1485                 if (ci->nextUpdate == NULL)
1486                         ci->nextUpdate=ASN1_UTCTIME_new();
1487                 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1488
1489                 for (i=0; i<sk_num(db->data); i++)
1490                         {
1491                         pp=(char **)sk_value(db->data,i);
1492                         if (pp[DB_type][0] == DB_TYPE_REV)
1493                                 {
1494                                 if ((r=X509_REVOKED_new()) == NULL) goto err;
1495                                 j = make_revoked(r, pp[DB_rev_date]);
1496                                 if (!j) goto err;
1497                                 if (j == 2) crl_v2 = 1;
1498                                 if (!BN_hex2bn(&serial, pp[DB_serial]))
1499                                         goto err;
1500                                 r->serialNumber = BN_to_ASN1_INTEGER(serial, r->serialNumber);
1501                                 BN_free(serial);
1502                                 serial = NULL;
1503                                 if (!r->serialNumber)
1504                                         goto err;
1505                                 X509_CRL_add0_revoked(crl,r);
1506                                 }
1507                         }
1508                 /* sort the data so it will be written in serial
1509                  * number order */
1510                 sk_X509_REVOKED_sort(ci->revoked);
1511                 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1512                         {
1513                         r=sk_X509_REVOKED_value(ci->revoked,i);
1514                         r->sequence=i;
1515                         }
1516
1517                 /* we now have a CRL */
1518                 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1519                 if (md != NULL)
1520                         {
1521                         if ((dgst=EVP_get_digestbyname(md)) == NULL)
1522                                 {
1523                                 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1524                                 goto err;
1525                                 }
1526                         }
1527                 else
1528                         {
1529 #ifndef OPENSSL_NO_DSA
1530                         if (pkey->type == EVP_PKEY_DSA) 
1531                                 dgst=EVP_dss1();
1532                         else
1533 #endif
1534                                 dgst=EVP_md5();
1535                         }
1536
1537                 /* Add any extensions asked for */
1538
1539                 if (crl_ext)
1540                         {
1541                         X509V3_CTX crlctx;
1542                         if (ci->version == NULL)
1543                                 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1544                         X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1545                         X509V3_set_conf_lhash(&crlctx, conf);
1546
1547                         if (!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1548                                 crl_ext, crl)) goto err;
1549                         }
1550                 if (crl_ext || crl_v2)
1551                         {
1552                         if (ci->version == NULL)
1553                                 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1554                         ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1555                         }
1556
1557                 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1558
1559                 PEM_write_bio_X509_CRL(Sout,crl);
1560                 }
1561         /*****************************************************************/
1562         if (dorevoke)
1563                 {
1564                 if (infile == NULL) 
1565                         {
1566                         BIO_printf(bio_err,"no input files\n");
1567                         goto err;
1568                         }
1569                 else
1570                         {
1571                         X509 *revcert;
1572                         if (BIO_read_filename(in,infile) <= 0)
1573                                 {
1574                                 perror(infile);
1575                                 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1576                                 goto err;
1577                                 }
1578                         revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1579                         if (revcert == NULL)
1580                                 {
1581                                 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1582                                 goto err;
1583                                 }
1584                         j=do_revoke(revcert,db, rev_type, rev_arg);
1585                         if (j <= 0) goto err;
1586                         X509_free(revcert);
1587
1588                         strncpy(buf[0],dbfile,BSIZE-4);
1589                         strcat(buf[0],".new");
1590                         if (BIO_write_filename(out,buf[0]) <= 0)
1591                                 {
1592                                 perror(dbfile);
1593                                 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1594                                 goto err;
1595                                 }
1596                         j=TXT_DB_write(out,db);
1597                         if (j <= 0) goto err;
1598                         strncpy(buf[1],dbfile,BSIZE-4);
1599                         strcat(buf[1],".old");
1600                         if (rename(dbfile,buf[1]) < 0)
1601                                 {
1602                                 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1603                                 perror("reason");
1604                                 goto err;
1605                                 }
1606                         if (rename(buf[0],dbfile) < 0)
1607                                 {
1608                                 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1609                                 perror("reason");
1610                                 rename(buf[1],dbfile);
1611                                 goto err;
1612                                 }
1613                         BIO_printf(bio_err,"Data Base Updated\n"); 
1614                         }
1615                 }
1616         /*****************************************************************/
1617         ret=0;
1618 err:
1619         BIO_free_all(Cout);
1620         BIO_free_all(Sout);
1621         BIO_free_all(out);
1622         BIO_free(in);
1623
1624         sk_X509_pop_free(cert_sk,X509_free);
1625
1626         if (ret) ERR_print_errors(bio_err);
1627         app_RAND_write_file(randfile, bio_err);
1628         BN_free(serial);
1629         TXT_DB_free(db);
1630         EVP_PKEY_free(pkey);
1631         X509_free(x509);
1632         X509_CRL_free(crl);
1633         CONF_free(conf);
1634         OBJ_cleanup();
1635         EXIT(ret);
1636         }
1637
1638 static void lookup_fail(char *name, char *tag)
1639         {
1640         BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1641         }
1642
1643 static unsigned long index_serial_hash(const char **a)
1644         {
1645         const char *n;
1646
1647         n=a[DB_serial];
1648         while (*n == '0') n++;
1649         return(lh_strhash(n));
1650         }
1651
1652 static int index_serial_cmp(const char **a, const char **b)
1653         {
1654         const char *aa,*bb;
1655
1656         for (aa=a[DB_serial]; *aa == '0'; aa++);
1657         for (bb=b[DB_serial]; *bb == '0'; bb++);
1658         return(strcmp(aa,bb));
1659         }
1660
1661 static unsigned long index_name_hash(const char **a)
1662         { return(lh_strhash(a[DB_name])); }
1663
1664 static int index_name_qual(char **a)
1665         { return(a[0][0] == 'V'); }
1666
1667 static int index_name_cmp(const char **a, const char **b)
1668         { return(strcmp(a[DB_name],
1669              b[DB_name])); }
1670
1671 static BIGNUM *load_serial(char *serialfile)
1672         {
1673         BIO *in=NULL;
1674         BIGNUM *ret=NULL;
1675         MS_STATIC char buf[1024];
1676         ASN1_INTEGER *ai=NULL;
1677
1678         if ((in=BIO_new(BIO_s_file())) == NULL)
1679                 {
1680                 ERR_print_errors(bio_err);
1681                 goto err;
1682                 }
1683
1684         if (BIO_read_filename(in,serialfile) <= 0)
1685                 {
1686                 perror(serialfile);
1687                 goto err;
1688                 }
1689         ai=ASN1_INTEGER_new();
1690         if (ai == NULL) goto err;
1691         if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1692                 {
1693                 BIO_printf(bio_err,"unable to load number from %s\n",
1694                         serialfile);
1695                 goto err;
1696                 }
1697         ret=ASN1_INTEGER_to_BN(ai,NULL);
1698         if (ret == NULL)
1699                 {
1700                 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1701                 goto err;
1702                 }
1703 err:
1704         if (in != NULL) BIO_free(in);
1705         if (ai != NULL) ASN1_INTEGER_free(ai);
1706         return(ret);
1707         }
1708
1709 static int save_serial(char *serialfile, BIGNUM *serial)
1710         {
1711         BIO *out;
1712         int ret=0;
1713         ASN1_INTEGER *ai=NULL;
1714
1715         out=BIO_new(BIO_s_file());
1716         if (out == NULL)
1717                 {
1718                 ERR_print_errors(bio_err);
1719                 goto err;
1720                 }
1721         if (BIO_write_filename(out,serialfile) <= 0)
1722                 {
1723                 perror(serialfile);
1724                 goto err;
1725                 }
1726
1727         if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1728                 {
1729                 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1730                 goto err;
1731                 }
1732         i2a_ASN1_INTEGER(out,ai);
1733         BIO_puts(out,"\n");
1734         ret=1;
1735 err:
1736         if (out != NULL) BIO_free_all(out);
1737         if (ai != NULL) ASN1_INTEGER_free(ai);
1738         return(ret);
1739         }
1740
1741 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1742              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1743              BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
1744              int batch, char *ext_sect, LHASH *lconf, int verbose,
1745              unsigned long certopt, unsigned long nameopt, int default_op,
1746              int ext_copy)
1747         {
1748         X509_REQ *req=NULL;
1749         BIO *in=NULL;
1750         EVP_PKEY *pktmp=NULL;
1751         int ok= -1,i;
1752
1753         in=BIO_new(BIO_s_file());
1754
1755         if (BIO_read_filename(in,infile) <= 0)
1756                 {
1757                 perror(infile);
1758                 goto err;
1759                 }
1760         if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1761                 {
1762                 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1763                         infile);
1764                 goto err;
1765                 }
1766         if (verbose)
1767                 X509_REQ_print(bio_err,req);
1768
1769         BIO_printf(bio_err,"Check that the request matches the signature\n");
1770
1771         if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1772                 {
1773                 BIO_printf(bio_err,"error unpacking public key\n");
1774                 goto err;
1775                 }
1776         i=X509_REQ_verify(req,pktmp);
1777         EVP_PKEY_free(pktmp);
1778         if (i < 0)
1779                 {
1780                 ok=0;
1781                 BIO_printf(bio_err,"Signature verification problems....\n");
1782                 goto err;
1783                 }
1784         if (i == 0)
1785                 {
1786                 ok=0;
1787                 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1788                 goto err;
1789                 }
1790         else
1791                 BIO_printf(bio_err,"Signature ok\n");
1792
1793         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate, enddate,
1794                 days,batch,verbose,req,ext_sect,lconf,
1795                 certopt, nameopt, default_op, ext_copy);
1796
1797 err:
1798         if (req != NULL) X509_REQ_free(req);
1799         if (in != NULL) BIO_free(in);
1800         return(ok);
1801         }
1802
1803 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1804              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1805              BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
1806              int batch, char *ext_sect, LHASH *lconf, int verbose,
1807              unsigned long certopt, unsigned long nameopt, int default_op,
1808              int ext_copy)
1809         {
1810         X509 *req=NULL;
1811         X509_REQ *rreq=NULL;
1812         BIO *in=NULL;
1813         EVP_PKEY *pktmp=NULL;
1814         int ok= -1,i;
1815
1816         in=BIO_new(BIO_s_file());
1817
1818         if (BIO_read_filename(in,infile) <= 0)
1819                 {
1820                 perror(infile);
1821                 goto err;
1822                 }
1823         if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1824                 {
1825                 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1826                 goto err;
1827                 }
1828         if (verbose)
1829                 X509_print(bio_err,req);
1830
1831         BIO_printf(bio_err,"Check that the request matches the signature\n");
1832
1833         if ((pktmp=X509_get_pubkey(req)) == NULL)
1834                 {
1835                 BIO_printf(bio_err,"error unpacking public key\n");
1836                 goto err;
1837                 }
1838         i=X509_verify(req,pktmp);
1839         EVP_PKEY_free(pktmp);
1840         if (i < 0)
1841                 {
1842                 ok=0;
1843                 BIO_printf(bio_err,"Signature verification problems....\n");
1844                 goto err;
1845                 }
1846         if (i == 0)
1847                 {
1848                 ok=0;
1849                 BIO_printf(bio_err,"Signature did not match the certificate\n");
1850                 goto err;
1851                 }
1852         else
1853                 BIO_printf(bio_err,"Signature ok\n");
1854
1855         if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1856                 goto err;
1857
1858         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,days,
1859                 batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1860                         ext_copy);
1861
1862 err:
1863         if (rreq != NULL) X509_REQ_free(rreq);
1864         if (req != NULL) X509_free(req);
1865         if (in != NULL) BIO_free(in);
1866         return(ok);
1867         }
1868
1869 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1870              STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1871              char *startdate, char *enddate, int days, int batch, int verbose,
1872              X509_REQ *req, char *ext_sect, LHASH *lconf,
1873              unsigned long certopt, unsigned long nameopt, int default_op,
1874              int ext_copy)
1875         {
1876         X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1877         ASN1_UTCTIME *tm,*tmptm;
1878         ASN1_STRING *str,*str2;
1879         ASN1_OBJECT *obj;
1880         X509 *ret=NULL;
1881         X509_CINF *ci;
1882         X509_NAME_ENTRY *ne;
1883         X509_NAME_ENTRY *tne,*push;
1884         EVP_PKEY *pktmp;
1885         int ok= -1,i,j,last,nid;
1886         char *p;
1887         CONF_VALUE *cv;
1888         char *row[DB_NUMBER],**rrow,**irow=NULL;
1889         char buf[25];
1890
1891         tmptm=ASN1_UTCTIME_new();
1892         if (tmptm == NULL)
1893                 {
1894                 BIO_printf(bio_err,"malloc error\n");
1895                 return(0);
1896                 }
1897
1898         for (i=0; i<DB_NUMBER; i++)
1899                 row[i]=NULL;
1900
1901         if (subj)
1902                 {
1903                 X509_NAME *n = do_subject(subj);
1904
1905                 if (!n)
1906                         {
1907                         ERR_print_errors(bio_err);
1908                         goto err;
1909                         }
1910                 X509_REQ_set_subject_name(req,n);
1911                 req->req_info->enc.modified = 1;
1912                 X509_NAME_free(n);
1913                 }
1914
1915         if (default_op)
1916                 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1917         name=X509_REQ_get_subject_name(req);
1918         for (i=0; i<X509_NAME_entry_count(name); i++)
1919                 {
1920                 ne= X509_NAME_get_entry(name,i);
1921                 str=X509_NAME_ENTRY_get_data(ne);
1922                 obj=X509_NAME_ENTRY_get_object(ne);
1923
1924                 if (msie_hack)
1925                         {
1926                         /* assume all type should be strings */
1927                         nid=OBJ_obj2nid(ne->object);
1928
1929                         if (str->type == V_ASN1_UNIVERSALSTRING)
1930                                 ASN1_UNIVERSALSTRING_to_string(str);
1931
1932                         if ((str->type == V_ASN1_IA5STRING) &&
1933                                 (nid != NID_pkcs9_emailAddress))
1934                                 str->type=V_ASN1_T61STRING;
1935
1936                         if ((nid == NID_pkcs9_emailAddress) &&
1937                                 (str->type == V_ASN1_PRINTABLESTRING))
1938                                 str->type=V_ASN1_IA5STRING;
1939                         }
1940
1941                 /* check some things */
1942                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1943                         (str->type != V_ASN1_IA5STRING))
1944                         {
1945                         BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1946                         goto err;
1947                         }
1948                 j=ASN1_PRINTABLE_type(str->data,str->length);
1949                 if (    ((j == V_ASN1_T61STRING) &&
1950                          (str->type != V_ASN1_T61STRING)) ||
1951                         ((j == V_ASN1_IA5STRING) &&
1952                          (str->type == V_ASN1_PRINTABLESTRING)))
1953                         {
1954                         BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1955                         goto err;
1956                         }
1957
1958                 if (default_op)
1959                         old_entry_print(bio_err, obj, str);
1960                 }
1961
1962         /* Ok, now we check the 'policy' stuff. */
1963         if ((subject=X509_NAME_new()) == NULL)
1964                 {
1965                 BIO_printf(bio_err,"Memory allocation failure\n");
1966                 goto err;
1967                 }
1968
1969         /* take a copy of the issuer name before we mess with it. */
1970         CAname=X509_NAME_dup(x509->cert_info->subject);
1971         if (CAname == NULL) goto err;
1972         str=str2=NULL;
1973
1974         for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1975                 {
1976                 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1977                 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1978                         {
1979                         BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1980                         goto err;
1981                         }
1982                 obj=OBJ_nid2obj(j);
1983
1984                 last= -1;
1985                 for (;;)
1986                         {
1987                         /* lookup the object in the supplied name list */
1988                         j=X509_NAME_get_index_by_OBJ(name,obj,last);
1989                         if (j < 0)
1990                                 {
1991                                 if (last != -1) break;
1992                                 tne=NULL;
1993                                 }
1994                         else
1995                                 {
1996                                 tne=X509_NAME_get_entry(name,j);
1997                                 }
1998                         last=j;
1999
2000                         /* depending on the 'policy', decide what to do. */
2001                         push=NULL;
2002                         if (strcmp(cv->value,"optional") == 0)
2003                                 {
2004                                 if (tne != NULL)
2005                                         push=tne;
2006                                 }
2007                         else if (strcmp(cv->value,"supplied") == 0)
2008                                 {
2009                                 if (tne == NULL)
2010                                         {
2011                                         BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
2012                                         goto err;
2013                                         }
2014                                 else
2015                                         push=tne;
2016                                 }
2017                         else if (strcmp(cv->value,"match") == 0)
2018                                 {
2019                                 int last2;
2020
2021                                 if (tne == NULL)
2022                                         {
2023                                         BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
2024                                         goto err;
2025                                         }
2026
2027                                 last2= -1;
2028
2029 again2:
2030                                 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
2031                                 if ((j < 0) && (last2 == -1))
2032                                         {
2033                                         BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
2034                                         goto err;
2035                                         }
2036                                 if (j >= 0)
2037                                         {
2038                                         push=X509_NAME_get_entry(CAname,j);
2039                                         str=X509_NAME_ENTRY_get_data(tne);
2040                                         str2=X509_NAME_ENTRY_get_data(push);
2041                                         last2=j;
2042                                         if (ASN1_STRING_cmp(str,str2) != 0)
2043                                                 goto again2;
2044                                         }
2045                                 if (j < 0)
2046                                         {
2047                                         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));
2048                                         goto err;
2049                                         }
2050                                 }
2051                         else
2052                                 {
2053                                 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2054                                 goto err;
2055                                 }
2056
2057                         if (push != NULL)
2058                                 {
2059                                 if (!X509_NAME_add_entry(subject,push, -1, 0))
2060                                         {
2061                                         if (push != NULL)
2062                                                 X509_NAME_ENTRY_free(push);
2063                                         BIO_printf(bio_err,"Memory allocation failure\n");
2064                                         goto err;
2065                                         }
2066                                 }
2067                         if (j < 0) break;
2068                         }
2069                 }
2070
2071         if (preserve)
2072                 {
2073                 X509_NAME_free(subject);
2074                 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
2075                 if (subject == NULL) goto err;
2076                 }
2077
2078         if (verbose)
2079                 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2080
2081         row[DB_name]=X509_NAME_oneline(subject,NULL,0);
2082         row[DB_serial]=BN_bn2hex(serial);
2083         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2084                 {
2085                 BIO_printf(bio_err,"Memory allocation failure\n");
2086                 goto err;
2087                 }
2088
2089         rrow=TXT_DB_get_by_index(db,DB_name,row);
2090         if (rrow != NULL)
2091                 {
2092                 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2093                         row[DB_name]);
2094                 }
2095         else
2096                 {
2097                 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2098                 if (rrow != NULL)
2099                         {
2100                         BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2101                                 row[DB_serial]);
2102                         BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
2103                         }
2104                 }
2105
2106         if (rrow != NULL)
2107                 {
2108                 BIO_printf(bio_err,
2109                         "The matching entry has the following details\n");
2110                 if (rrow[DB_type][0] == 'E')
2111                         p="Expired";
2112                 else if (rrow[DB_type][0] == 'R')
2113                         p="Revoked";
2114                 else if (rrow[DB_type][0] == 'V')
2115                         p="Valid";
2116                 else
2117                         p="\ninvalid type, Data base error\n";
2118                 BIO_printf(bio_err,"Type          :%s\n",p);;
2119                 if (rrow[DB_type][0] == 'R')
2120                         {
2121                         p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2122                         BIO_printf(bio_err,"Was revoked on:%s\n",p);
2123                         }
2124                 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2125                 BIO_printf(bio_err,"Expires on    :%s\n",p);
2126                 p=rrow[DB_serial]; if (p == NULL) p="undef";
2127                 BIO_printf(bio_err,"Serial Number :%s\n",p);
2128                 p=rrow[DB_file]; if (p == NULL) p="undef";
2129                 BIO_printf(bio_err,"File name     :%s\n",p);
2130                 p=rrow[DB_name]; if (p == NULL) p="undef";
2131                 BIO_printf(bio_err,"Subject Name  :%s\n",p);
2132                 ok= -1; /* This is now a 'bad' error. */
2133                 goto err;
2134                 }
2135
2136         /* We are now totally happy, lets make and sign the certificate */
2137         if (verbose)
2138                 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2139
2140         if ((ret=X509_new()) == NULL) goto err;
2141         ci=ret->cert_info;
2142
2143 #ifdef X509_V3
2144         /* Make it an X509 v3 certificate. */
2145         if (!X509_set_version(x509,2)) goto err;
2146 #endif
2147
2148         if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2149                 goto err;
2150         if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2151                 goto err;
2152
2153         if (strcmp(startdate,"today") == 0)
2154                 X509_gmtime_adj(X509_get_notBefore(ret),0);
2155         else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2156
2157         if (enddate == NULL)
2158                 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2159         else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2160
2161         if (!X509_set_subject_name(ret,subject)) goto err;
2162
2163         pktmp=X509_REQ_get_pubkey(req);
2164         i = X509_set_pubkey(ret,pktmp);
2165         EVP_PKEY_free(pktmp);
2166         if (!i) goto err;
2167
2168         /* Lets add the extensions, if there are any */
2169         if (ext_sect)
2170                 {
2171                 X509V3_CTX ctx;
2172                 if (ci->version == NULL)
2173                         if ((ci->version=ASN1_INTEGER_new()) == NULL)
2174                                 goto err;
2175                 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2176
2177                 /* Free the current entries if any, there should not
2178                  * be any I believe */
2179                 if (ci->extensions != NULL)
2180                         sk_X509_EXTENSION_pop_free(ci->extensions,
2181                                                    X509_EXTENSION_free);
2182
2183                 ci->extensions = NULL;
2184
2185                 /* Initialize the context structure */
2186                 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2187
2188                 if (extconf)
2189                         {
2190                         if (verbose)
2191                                 BIO_printf(bio_err, "Extra configuration file found\n");
2192  
2193                         /* Use the extconf configuration db LHASH */
2194                         X509V3_set_conf_lhash(&ctx, extconf);
2195  
2196                         /* Test the structure (needed?) */
2197                         /* X509V3_set_ctx_test(&ctx); */
2198
2199                         /* Adds exts contained in the configuration file */
2200                         if (!X509V3_EXT_add_conf(extconf, &ctx, ext_sect,ret))
2201                                 {
2202                                 BIO_printf(bio_err,
2203                                     "ERROR: adding extensions in section %s\n",
2204                                                                 ext_sect);
2205                                 ERR_print_errors(bio_err);
2206                                 goto err;
2207                                 }
2208                         if (verbose)
2209                                 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2210                         }
2211                 else if (ext_sect)
2212                         {
2213                         /* We found extensions to be set from config file */
2214                         X509V3_set_conf_lhash(&ctx, lconf);
2215
2216                         if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret))
2217                                 {
2218                                 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2219                                 ERR_print_errors(bio_err);
2220                                 goto err;
2221                                 }
2222
2223                         if (verbose) 
2224                                 BIO_printf(bio_err, "Successfully added extensions from config\n");
2225                         }
2226                 }
2227
2228         /* Copy extensions from request (if any) */
2229
2230         if (!copy_extensions(ret, req, ext_copy))
2231                 {
2232                 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2233                 ERR_print_errors(bio_err);
2234                 goto err;
2235                 }
2236
2237
2238         if (!default_op)
2239                 {
2240                 BIO_printf(bio_err, "Certificate Details:\n");
2241                 /* Never print signature details because signature not present */
2242                 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2243                 X509_print_ex(bio_err, ret, nameopt, certopt); 
2244                 }
2245
2246         BIO_printf(bio_err,"Certificate is to be certified until ");
2247         ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2248         if (days) BIO_printf(bio_err," (%d days)",days);
2249         BIO_printf(bio_err, "\n");
2250
2251         if (!batch)
2252                 {
2253
2254                 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2255                 (void)BIO_flush(bio_err);
2256                 buf[0]='\0';
2257                 fgets(buf,sizeof(buf)-1,stdin);
2258                 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2259                         {
2260                         BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2261                         ok=0;
2262                         goto err;
2263                         }
2264                 }
2265
2266
2267 #ifndef OPENSSL_NO_DSA
2268         if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2269         pktmp=X509_get_pubkey(ret);
2270         if (EVP_PKEY_missing_parameters(pktmp) &&
2271                 !EVP_PKEY_missing_parameters(pkey))
2272                 EVP_PKEY_copy_parameters(pktmp,pkey);
2273         EVP_PKEY_free(pktmp);
2274 #endif
2275
2276         if (!X509_sign(ret,pkey,dgst))
2277                 goto err;
2278
2279         /* We now just add it to the database */
2280         row[DB_type]=(char *)OPENSSL_malloc(2);
2281
2282         tm=X509_get_notAfter(ret);
2283         row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2284         memcpy(row[DB_exp_date],tm->data,tm->length);
2285         row[DB_exp_date][tm->length]='\0';
2286
2287         row[DB_rev_date]=NULL;
2288
2289         /* row[DB_serial] done already */
2290         row[DB_file]=(char *)OPENSSL_malloc(8);
2291         /* row[DB_name] done already */
2292
2293         if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2294                 (row[DB_file] == NULL))
2295                 {
2296                 BIO_printf(bio_err,"Memory allocation failure\n");
2297                 goto err;
2298                 }
2299         strcpy(row[DB_file],"unknown");
2300         row[DB_type][0]='V';
2301         row[DB_type][1]='\0';
2302
2303         if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2304                 {
2305                 BIO_printf(bio_err,"Memory allocation failure\n");
2306                 goto err;
2307                 }
2308
2309         for (i=0; i<DB_NUMBER; i++)
2310                 {
2311                 irow[i]=row[i];
2312                 row[i]=NULL;
2313                 }
2314         irow[DB_NUMBER]=NULL;
2315
2316         if (!TXT_DB_insert(db,irow))
2317                 {
2318                 BIO_printf(bio_err,"failed to update database\n");
2319                 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2320                 goto err;
2321                 }
2322         ok=1;
2323 err:
2324         for (i=0; i<DB_NUMBER; i++)
2325                 if (row[i] != NULL) OPENSSL_free(row[i]);
2326
2327         if (CAname != NULL)
2328                 X509_NAME_free(CAname);
2329         if (subject != NULL)
2330                 X509_NAME_free(subject);
2331         if (tmptm != NULL)
2332                 ASN1_UTCTIME_free(tmptm);
2333         if (ok <= 0)
2334                 {
2335                 if (ret != NULL) X509_free(ret);
2336                 ret=NULL;
2337                 }
2338         else
2339                 *xret=ret;
2340         return(ok);
2341         }
2342
2343 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2344         {
2345
2346         if (output_der)
2347                 {
2348                 (void)i2d_X509_bio(bp,x);
2349                 return;
2350                 }
2351 #if 0
2352         /* ??? Not needed since X509_print prints all this stuff anyway */
2353         f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2354         BIO_printf(bp,"issuer :%s\n",f);
2355
2356         f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2357         BIO_printf(bp,"subject:%s\n",f);
2358
2359         BIO_puts(bp,"serial :");
2360         i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2361         BIO_puts(bp,"\n\n");
2362 #endif
2363         if (!notext)X509_print(bp,x);
2364         PEM_write_bio_X509(bp,x);
2365         }
2366
2367 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2368              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2369              BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
2370              char *ext_sect, LHASH *lconf, int verbose, unsigned long certopt,
2371              unsigned long nameopt, int default_op, int ext_copy)
2372         {
2373         STACK_OF(CONF_VALUE) *sk=NULL;
2374         LHASH *parms=NULL;
2375         X509_REQ *req=NULL;
2376         CONF_VALUE *cv=NULL;
2377         NETSCAPE_SPKI *spki = NULL;
2378         X509_REQ_INFO *ri;
2379         char *type,*buf;
2380         EVP_PKEY *pktmp=NULL;
2381         X509_NAME *n=NULL;
2382         X509_NAME_ENTRY *ne=NULL;
2383         int ok= -1,i,j;
2384         long errline;
2385         int nid;
2386
2387         /*
2388          * Load input file into a hash table.  (This is just an easy
2389          * way to read and parse the file, then put it into a convenient
2390          * STACK format).
2391          */
2392         parms=CONF_load(NULL,infile,&errline);
2393         if (parms == NULL)
2394                 {
2395                 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2396                 ERR_print_errors(bio_err);
2397                 goto err;
2398                 }
2399
2400         sk=CONF_get_section(parms, "default");
2401         if (sk_CONF_VALUE_num(sk) == 0)
2402                 {
2403                 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2404                 CONF_free(parms);
2405                 goto err;
2406                 }
2407
2408         /*
2409          * Now create a dummy X509 request structure.  We don't actually
2410          * have an X509 request, but we have many of the components
2411          * (a public key, various DN components).  The idea is that we
2412          * put these components into the right X509 request structure
2413          * and we can use the same code as if you had a real X509 request.
2414          */
2415         req=X509_REQ_new();
2416         if (req == NULL)
2417                 {
2418                 ERR_print_errors(bio_err);
2419                 goto err;
2420                 }
2421
2422         /*
2423          * Build up the subject name set.
2424          */
2425         ri=req->req_info;
2426         n = ri->subject;
2427
2428         for (i = 0; ; i++)
2429                 {
2430                 if (sk_CONF_VALUE_num(sk) <= i) break;
2431
2432                 cv=sk_CONF_VALUE_value(sk,i);
2433                 type=cv->name;
2434                 /* Skip past any leading X. X: X, etc to allow for
2435                  * multiple instances
2436                  */
2437                 for (buf = cv->name; *buf ; buf++)
2438                         if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2439                                 {
2440                                 buf++;
2441                                 if (*buf) type = buf;
2442                                 break;
2443                                 }
2444
2445                 buf=cv->value;
2446                 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2447                         {
2448                         if (strcmp(type, "SPKAC") == 0)
2449                                 {
2450                                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2451                                 if (spki == NULL)
2452                                         {
2453                                         BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2454                                         ERR_print_errors(bio_err);
2455                                         goto err;
2456                                         }
2457                                 }
2458                         continue;
2459                         }
2460
2461                 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2462                 if (fix_data(nid, &j) == 0)
2463                         {
2464                         BIO_printf(bio_err,
2465                                 "invalid characters in string %s\n",buf);
2466                         goto err;
2467                         }
2468
2469                 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2470                         (unsigned char *)buf,
2471                         strlen(buf))) == NULL)
2472                         goto err;
2473
2474                 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2475                 }
2476         if (spki == NULL)
2477                 {
2478                 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2479                         infile);
2480                 goto err;
2481                 }
2482
2483         /*
2484          * Now extract the key from the SPKI structure.
2485          */
2486
2487         BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2488
2489         if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2490                 {
2491                 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2492                 goto err;
2493                 }
2494
2495         j = NETSCAPE_SPKI_verify(spki, pktmp);
2496         if (j <= 0)
2497                 {
2498                 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2499                 goto err;
2500                 }
2501         BIO_printf(bio_err,"Signature ok\n");
2502
2503         X509_REQ_set_pubkey(req,pktmp);
2504         EVP_PKEY_free(pktmp);
2505         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,
2506                    days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2507                         ext_copy);
2508 err:
2509         if (req != NULL) X509_REQ_free(req);
2510         if (parms != NULL) CONF_free(parms);
2511         if (spki != NULL) NETSCAPE_SPKI_free(spki);
2512         if (ne != NULL) X509_NAME_ENTRY_free(ne);
2513
2514         return(ok);
2515         }
2516
2517 static int fix_data(int nid, int *type)
2518         {
2519         if (nid == NID_pkcs9_emailAddress)
2520                 *type=V_ASN1_IA5STRING;
2521         if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2522                 *type=V_ASN1_T61STRING;
2523         if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2524                 *type=V_ASN1_T61STRING;
2525         if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2526                 return(0);
2527         if (nid == NID_pkcs9_unstructuredName)
2528                 *type=V_ASN1_IA5STRING;
2529         return(1);
2530         }
2531
2532 static int check_time_format(char *str)
2533         {
2534         ASN1_UTCTIME tm;
2535
2536         tm.data=(unsigned char *)str;
2537         tm.length=strlen(str);
2538         tm.type=V_ASN1_UTCTIME;
2539         return(ASN1_UTCTIME_check(&tm));
2540         }
2541
2542 static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2543         {
2544         ASN1_UTCTIME *tm=NULL;
2545         char *row[DB_NUMBER],**rrow,**irow;
2546         char *rev_str = NULL;
2547         BIGNUM *bn = NULL;
2548         int ok=-1,i;
2549
2550         for (i=0; i<DB_NUMBER; i++)
2551                 row[i]=NULL;
2552         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2553         bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2554         row[DB_serial]=BN_bn2hex(bn);
2555         BN_free(bn);
2556         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2557                 {
2558                 BIO_printf(bio_err,"Memory allocation failure\n");
2559                 goto err;
2560                 }
2561         /* We have to lookup by serial number because name lookup
2562          * skips revoked certs
2563          */
2564         rrow=TXT_DB_get_by_index(db,DB_serial,row);
2565         if (rrow == NULL)
2566                 {
2567                 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2568
2569                 /* We now just add it to the database */
2570                 row[DB_type]=(char *)OPENSSL_malloc(2);
2571
2572                 tm=X509_get_notAfter(x509);
2573                 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2574                 memcpy(row[DB_exp_date],tm->data,tm->length);
2575                 row[DB_exp_date][tm->length]='\0';
2576
2577                 row[DB_rev_date]=NULL;
2578
2579                 /* row[DB_serial] done already */
2580                 row[DB_file]=(char *)OPENSSL_malloc(8);
2581
2582                 /* row[DB_name] done already */
2583
2584                 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2585                         (row[DB_file] == NULL))
2586                         {
2587                         BIO_printf(bio_err,"Memory allocation failure\n");
2588                         goto err;
2589                         }
2590                 strcpy(row[DB_file],"unknown");
2591                 row[DB_type][0]='V';
2592                 row[DB_type][1]='\0';
2593
2594                 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2595                         {
2596                         BIO_printf(bio_err,"Memory allocation failure\n");
2597                         goto err;
2598                         }
2599
2600                 for (i=0; i<DB_NUMBER; i++)
2601                         {
2602                         irow[i]=row[i];
2603                         row[i]=NULL;
2604                         }
2605                 irow[DB_NUMBER]=NULL;
2606
2607                 if (!TXT_DB_insert(db,irow))
2608                         {
2609                         BIO_printf(bio_err,"failed to update database\n");
2610                         BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2611                         goto err;
2612                         }
2613
2614                 /* Revoke Certificate */
2615                 ok = do_revoke(x509,db, type, value);
2616
2617                 goto err;
2618
2619                 }
2620         else if (index_name_cmp((const char **)row,(const char **)rrow))
2621                 {
2622                 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2623                            row[DB_name]);
2624                 goto err;
2625                 }
2626         else if (rrow[DB_type][0]=='R')
2627                 {
2628                 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2629                            row[DB_serial]);
2630                 goto err;
2631                 }
2632         else
2633                 {
2634                 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2635                 rev_str = make_revocation_str(type, value);
2636                 if (!rev_str)
2637                         {
2638                         BIO_printf(bio_err, "Error in revocation arguments\n");
2639                         goto err;
2640                         }
2641                 rrow[DB_type][0]='R';
2642                 rrow[DB_type][1]='\0';
2643                 rrow[DB_rev_date] = rev_str;
2644                 }
2645         ok=1;
2646 err:
2647         for (i=0; i<DB_NUMBER; i++)
2648                 {
2649                 if (row[i] != NULL) 
2650                         OPENSSL_free(row[i]);
2651                 }
2652         return(ok);
2653         }
2654
2655 static int get_certificate_status(const char *serial, TXT_DB *db)
2656         {
2657         char *row[DB_NUMBER],**rrow;
2658         int ok=-1,i;
2659
2660         /* Free Resources */
2661         for (i=0; i<DB_NUMBER; i++)
2662                 row[i]=NULL;
2663
2664         /* Malloc needed char spaces */
2665         row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2666         if (row[DB_serial] == NULL)
2667                 {
2668                 BIO_printf(bio_err,"Malloc failure\n");
2669                 goto err;
2670                 }
2671
2672         if (strlen(serial) % 2)
2673                 {
2674                 /* Set the first char to 0 */;
2675                 row[DB_serial][0]='0';
2676
2677                 /* Copy String from serial to row[DB_serial] */
2678                 memcpy(row[DB_serial]+1, serial, strlen(serial));
2679                 row[DB_serial][strlen(serial)+1]='\0';
2680                 }
2681         else
2682                 {
2683                 /* Copy String from serial to row[DB_serial] */
2684                 memcpy(row[DB_serial], serial, strlen(serial));
2685                 row[DB_serial][strlen(serial)]='\0';
2686                 }
2687                         
2688         /* Make it Upper Case */
2689         for (i=0; row[DB_serial][i] != '\0'; i++)
2690                 row[DB_serial][i] = toupper(row[DB_serial][i]);
2691         
2692
2693         ok=1;
2694
2695         /* Search for the certificate */
2696         rrow=TXT_DB_get_by_index(db,DB_serial,row);
2697         if (rrow == NULL)
2698                 {
2699                 BIO_printf(bio_err,"Serial %s not present in db.\n",
2700                                  row[DB_serial]);
2701                 ok=-1;
2702                 goto err;
2703                 }
2704         else if (rrow[DB_type][0]=='V')
2705                 {
2706                 BIO_printf(bio_err,"%s=Valid (%c)\n",
2707                         row[DB_serial], rrow[DB_type][0]);
2708                 goto err;
2709                 }
2710         else if (rrow[DB_type][0]=='R')
2711                 {
2712                 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2713                         row[DB_serial], rrow[DB_type][0]);
2714                 goto err;
2715                 }
2716         else if (rrow[DB_type][0]=='E')
2717                 {
2718                 BIO_printf(bio_err,"%s=Expired (%c)\n",
2719                         row[DB_serial], rrow[DB_type][0]);
2720                 goto err;
2721                 }
2722         else if (rrow[DB_type][0]=='S')
2723                 {
2724                 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2725                         row[DB_serial], rrow[DB_type][0]);
2726                 goto err;
2727                 }
2728         else
2729                 {
2730                 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2731                         row[DB_serial], rrow[DB_type][0]);
2732                 ok=-1;
2733                 }
2734 err:
2735         for (i=0; i<DB_NUMBER; i++)
2736                 {
2737                 if (row[i] != NULL)
2738                         OPENSSL_free(row[i]);
2739                 }
2740         return(ok);
2741         }
2742
2743 static int do_updatedb (TXT_DB *db)
2744         {
2745         ASN1_UTCTIME    *a_tm = NULL;
2746         int i, cnt = 0;
2747         int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */ 
2748         char **rrow, *a_tm_s;
2749
2750         a_tm = ASN1_UTCTIME_new();
2751
2752         /* get actual time and make a string */
2753         a_tm = X509_gmtime_adj(a_tm, 0);
2754         a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2755         if (a_tm_s == NULL)
2756                 {
2757                 cnt = -1;
2758                 goto err;
2759                 }
2760
2761         memcpy(a_tm_s, a_tm->data, a_tm->length);
2762         a_tm_s[a_tm->length] = '\0';
2763
2764         if (strncmp(a_tm_s, "49", 2) <= 0)
2765                 a_y2k = 1;
2766         else
2767                 a_y2k = 0;
2768
2769         for (i = 0; i < sk_num(db->data); i++)
2770                 {
2771                 rrow = (char **) sk_value(db->data, i);
2772
2773                 if (rrow[DB_type][0] == 'V')
2774                         {
2775                         /* ignore entries that are not valid */
2776                         if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2777                                 db_y2k = 1;
2778                         else
2779                                 db_y2k = 0;
2780
2781                         if (db_y2k == a_y2k)
2782                                 {
2783                                 /* all on the same y2k side */
2784                                 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2785                                         {
2786                                         rrow[DB_type][0]  = 'E';
2787                                         rrow[DB_type][1]  = '\0';
2788                                         cnt++;
2789
2790                                         BIO_printf(bio_err, "%s=Expired\n",
2791                                                         rrow[DB_serial]);
2792                                         }
2793                                 }
2794                         else if (db_y2k < a_y2k)
2795                                 {
2796                                 rrow[DB_type][0]  = 'E';
2797                                 rrow[DB_type][1]  = '\0';
2798                                 cnt++;
2799
2800                                 BIO_printf(bio_err, "%s=Expired\n",
2801                                                         rrow[DB_serial]);
2802                                 }
2803
2804                         }
2805                 }
2806
2807 err:
2808
2809         ASN1_UTCTIME_free(a_tm);
2810         OPENSSL_free(a_tm_s);
2811
2812         return (cnt);
2813         }
2814
2815 static char *crl_reasons[] = {
2816         /* CRL reason strings */
2817         "unspecified",
2818         "keyCompromise",
2819         "CACompromise",
2820         "affiliationChanged",
2821         "superseded", 
2822         "cessationOfOperation",
2823         "certificateHold",
2824         "removeFromCRL",
2825         /* Additional pseudo reasons */
2826         "holdInstruction",
2827         "keyTime",
2828         "CAkeyTime"
2829 };
2830
2831 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2832
2833 /* Given revocation information convert to a DB string.
2834  * The format of the string is:
2835  * revtime[,reason,extra]. Where 'revtime' is the
2836  * revocation time (the current time). 'reason' is the
2837  * optional CRL reason and 'extra' is any additional
2838  * argument
2839  */
2840
2841 char *make_revocation_str(int rev_type, char *rev_arg)
2842         {
2843         char *reason = NULL, *other = NULL, *str;
2844         ASN1_OBJECT *otmp;
2845         ASN1_UTCTIME *revtm = NULL;
2846         int i;
2847         switch (rev_type)
2848                 {
2849         case REV_NONE:
2850                 break;
2851
2852         case REV_CRL_REASON:
2853                 for (i = 0; i < 8; i++)
2854                         {
2855                         if (!strcasecmp(rev_arg, crl_reasons[i]))
2856                                 {
2857                                 reason = crl_reasons[i];
2858                                 break;
2859                                 }
2860                         }
2861                 if (reason == NULL)
2862                         {
2863                         BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2864                         return NULL;
2865                         }
2866                 break;
2867
2868         case REV_HOLD:
2869                 /* Argument is an OID */
2870
2871                 otmp = OBJ_txt2obj(rev_arg, 0);
2872                 ASN1_OBJECT_free(otmp);
2873
2874                 if (otmp == NULL)
2875                         {
2876                         BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2877                         return NULL;
2878                         }
2879
2880                 reason = "holdInstruction";
2881                 other = rev_arg;
2882                 break;
2883                 
2884         case REV_KEY_COMPROMISE:
2885         case REV_CA_COMPROMISE:
2886
2887                 /* Argument is the key compromise time  */
2888                 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2889                         {       
2890                         BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2891                         return NULL;
2892                         }
2893                 other = rev_arg;
2894                 if (rev_type == REV_KEY_COMPROMISE)
2895                         reason = "keyTime";
2896                 else 
2897                         reason = "CAkeyTime";
2898
2899                 break;
2900
2901                 }
2902
2903         revtm = X509_gmtime_adj(NULL, 0);
2904
2905         i = revtm->length + 1;
2906
2907         if (reason) i += strlen(reason) + 1;
2908         if (other) i += strlen(other) + 1;
2909
2910         str = OPENSSL_malloc(i);
2911
2912         if (!str) return NULL;
2913
2914         strcpy(str, (char *)revtm->data);
2915         if (reason)
2916                 {
2917                 strcat(str, ",");
2918                 strcat(str, reason);
2919                 }
2920         if (other)
2921                 {
2922                 strcat(str, ",");
2923                 strcat(str, other);
2924                 }
2925         ASN1_UTCTIME_free(revtm);
2926         return str;
2927         }
2928
2929 /* Convert revocation field to X509_REVOKED entry 
2930  * return code:
2931  * 0 error
2932  * 1 OK
2933  * 2 OK and some extensions added (i.e. V2 CRL)
2934  */
2935
2936 int make_revoked(X509_REVOKED *rev, char *str)
2937         {
2938         char *tmp = NULL;
2939         char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2940         int reason_code = -1;
2941         int i, ret = 0;
2942         ASN1_OBJECT *hold = NULL;
2943         ASN1_GENERALIZEDTIME *comp_time = NULL;
2944         ASN1_ENUMERATED *rtmp = NULL;
2945         tmp = BUF_strdup(str);
2946
2947         p = strchr(tmp, ',');
2948
2949         rtime_str = tmp;
2950
2951         if (p)
2952                 {
2953                 *p = '\0';
2954                 p++;
2955                 reason_str = p;
2956                 p = strchr(p, ',');
2957                 if (p)
2958                         {
2959                         *p = '\0';
2960                         arg_str = p + 1;
2961                         }
2962                 }
2963
2964         if (rev && !ASN1_UTCTIME_set_string(rev->revocationDate, rtime_str))
2965                 {
2966                 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
2967                 goto err;
2968                 }
2969         if (reason_str)
2970                 {
2971                 for (i = 0; i < NUM_REASONS; i++)
2972                         {
2973                         if(!strcasecmp(reason_str, crl_reasons[i]))
2974                                 {
2975                                 reason_code = i;
2976                                 break;
2977                                 }
2978                         }
2979                 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
2980                         {
2981                         BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
2982                         goto err;
2983                         }
2984
2985                 if (reason_code == 7)
2986                         reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2987                 else if (reason_code == 8)              /* Hold instruction */
2988                         {
2989                         if (!arg_str)
2990                                 {       
2991                                 BIO_printf(bio_err, "missing hold instruction\n");
2992                                 goto err;
2993                                 }
2994                         reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2995                         hold = OBJ_txt2obj(arg_str, 0);
2996
2997                         if (!hold)
2998                                 {
2999                                 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3000                                 goto err;
3001                                 }
3002                         }
3003                 else if ((reason_code == 9) || (reason_code == 10))
3004                         {
3005                         if (!arg_str)
3006                                 {       
3007                                 BIO_printf(bio_err, "missing compromised time\n");
3008                                 goto err;
3009                                 }
3010                         comp_time = ASN1_GENERALIZEDTIME_new();
3011                         if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3012                                 {       
3013                                 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3014                                 goto err;
3015                                 }
3016                         if (reason_code == 9)
3017                                 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3018                         else
3019                                 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3020                         }
3021                 }
3022
3023         if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
3024                 {
3025                 rtmp = ASN1_ENUMERATED_new();
3026                 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
3027                         goto err;
3028                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
3029                         goto err;
3030                 }
3031
3032         if (rev && comp_time)
3033                 {
3034                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3035                         goto err;
3036                 }
3037         if (rev && hold)
3038                 {
3039                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3040                         goto err;
3041                 }
3042
3043         if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3044                 ret = 2;
3045         else ret = 1;
3046
3047         err:
3048
3049         if (tmp) OPENSSL_free(tmp);
3050         ASN1_OBJECT_free(hold);
3051         ASN1_GENERALIZEDTIME_free(comp_time);
3052         ASN1_ENUMERATED_free(rtmp);
3053
3054         return ret;
3055         }
3056
3057 static X509_NAME *do_subject(char *subject)
3058         {
3059         X509_NAME *n = NULL;
3060
3061         int i, nid, ne_num=0;
3062
3063         char *ne_name = NULL;
3064         char *ne_value = NULL;
3065
3066         char *tmp = NULL;
3067         char *p[2];
3068
3069         char *str_list[256];
3070        
3071         p[0] = ",/";
3072         p[1] = "=";
3073
3074         n = X509_NAME_new();
3075
3076         tmp = strtok(subject, p[0]);
3077         while((tmp != NULL) && (ne_num < (sizeof str_list/sizeof *str_list)))
3078                 {
3079                 char *token = tmp;
3080
3081                 while (token[0] == ' ')
3082                         token++;
3083                 str_list[ne_num] = token;
3084
3085                 tmp = strtok(NULL, p[0]);
3086                 ne_num++;
3087                 }
3088
3089         for (i = 0; i < ne_num; i++)
3090                 {
3091                 ne_name  = strtok(str_list[i], p[1]);
3092                 ne_value = strtok(NULL, p[1]);
3093
3094                 if ((nid=OBJ_txt2nid(ne_name)) == NID_undef)
3095                         {
3096                         BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_name);
3097                         continue;
3098                         }
3099
3100                 if (ne_value == NULL)
3101                         {
3102                         BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_name);
3103                         continue;
3104                         }
3105
3106                 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, (unsigned char*)ne_value, -1,-1,0))
3107                         {
3108                         X509_NAME_free(n);
3109                         return NULL;
3110                         }
3111                 }
3112
3113         return n;
3114         }
3115
3116
3117 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3118         {
3119         char buf[25],*pbuf, *p;
3120         int j;
3121         j=i2a_ASN1_OBJECT(bp,obj);
3122         pbuf=buf;
3123         for (j=22-j; j>0; j--)
3124                 *(pbuf++)=' ';
3125         *(pbuf++)=':';
3126         *(pbuf++)='\0';
3127         BIO_puts(bp,buf);
3128
3129         if (str->type == V_ASN1_PRINTABLESTRING)
3130                 BIO_printf(bp,"PRINTABLE:'");
3131         else if (str->type == V_ASN1_T61STRING)
3132                 BIO_printf(bp,"T61STRING:'");
3133         else if (str->type == V_ASN1_IA5STRING)
3134                 BIO_printf(bp,"IA5STRING:'");
3135         else if (str->type == V_ASN1_UNIVERSALSTRING)
3136                 BIO_printf(bp,"UNIVERSALSTRING:'");
3137         else
3138                 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3139                         
3140         p=(char *)str->data;
3141         for (j=str->length; j>0; j--)
3142                 {
3143                 if ((*p >= ' ') && (*p <= '~'))
3144                         BIO_printf(bp,"%c",*p);
3145                 else if (*p & 0x80)
3146                         BIO_printf(bp,"\\0x%02X",*p);
3147                 else if ((unsigned char)*p == 0xf7)
3148                         BIO_printf(bp,"^?");
3149                 else    BIO_printf(bp,"^%c",*p+'@');
3150                 p++;
3151                 }
3152         BIO_printf(bp,"'\n");
3153         return 1;
3154         }