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