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