Import OpenSSL-0.9.8i.
[dragonfly.git] / crypto / openssl-0.9.7e / 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                         goto err;
947                 }
948
949         /*****************************************************************/
950         /* Read extentions config file                                   */
951         if (extfile)
952                 {
953                 extconf = NCONF_new(NULL);
954                 if (NCONF_load(extconf,extfile,&errorline) <= 0)
955                         {
956                         if (errorline <= 0)
957                                 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
958                                         extfile);
959                         else
960                                 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
961                                         errorline,extfile);
962                         ret = 1;
963                         goto err;
964                         }
965
966                 if (verbose)
967                         BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
968
969                 /* We can have sections in the ext file */
970                 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
971                         extensions = "default";
972                 }
973
974         /*****************************************************************/
975         if (req || gencrl)
976                 {
977                 if (outfile != NULL)
978                         {
979                         if (BIO_write_filename(Sout,outfile) <= 0)
980                                 {
981                                 perror(outfile);
982                                 goto err;
983                                 }
984                         }
985                 else
986                         {
987                         BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
988 #ifdef OPENSSL_SYS_VMS
989                         {
990                         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
991                         Sout = BIO_push(tmpbio, Sout);
992                         }
993 #endif
994                         }
995                 }
996
997         if (req)
998                 {
999                 if ((md == NULL) && ((md=NCONF_get_string(conf,
1000                         section,ENV_DEFAULT_MD)) == NULL))
1001                         {
1002                         lookup_fail(section,ENV_DEFAULT_MD);
1003                         goto err;
1004                         }
1005                 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1006                         section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1007                         {
1008                         if(strcmp(tmp_email_dn,"no") == 0)
1009                                 email_dn=0;
1010                         }
1011                 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1012                         {
1013                         BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1014                         goto err;
1015                         }
1016                 if (verbose)
1017                         BIO_printf(bio_err,"message digest is %s\n",
1018                                 OBJ_nid2ln(dgst->type));
1019                 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1020                         section,ENV_POLICY)) == NULL))
1021                         {
1022                         lookup_fail(section,ENV_POLICY);
1023                         goto err;
1024                         }
1025                 if (verbose)
1026                         BIO_printf(bio_err,"policy is %s\n",policy);
1027
1028                 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1029                         == NULL)
1030                         {
1031                         lookup_fail(section,ENV_SERIAL);
1032                         goto err;
1033                         }
1034
1035                 if (!extconf)
1036                         {
1037                         /* no '-extfile' option, so we look for extensions
1038                          * in the main configuration file */
1039                         if (!extensions)
1040                                 {
1041                                 extensions=NCONF_get_string(conf,section,
1042                                                                 ENV_EXTENSIONS);
1043                                 if (!extensions)
1044                                         ERR_clear_error();
1045                                 }
1046                         if (extensions)
1047                                 {
1048                                 /* Check syntax of file */
1049                                 X509V3_CTX ctx;
1050                                 X509V3_set_ctx_test(&ctx);
1051                                 X509V3_set_nconf(&ctx, conf);
1052                                 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1053                                                                 NULL))
1054                                         {
1055                                         BIO_printf(bio_err,
1056                                         "Error Loading extension section %s\n",
1057                                                                  extensions);
1058                                         ret = 1;
1059                                         goto err;
1060                                         }
1061                                 }
1062                         }
1063
1064                 if (startdate == NULL)
1065                         {
1066                         startdate=NCONF_get_string(conf,section,
1067                                 ENV_DEFAULT_STARTDATE);
1068                         if (startdate == NULL)
1069                                 ERR_clear_error();
1070                         }
1071                 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1072                         {
1073                         BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1074                         goto err;
1075                         }
1076                 if (startdate == NULL) startdate="today";
1077
1078                 if (enddate == NULL)
1079                         {
1080                         enddate=NCONF_get_string(conf,section,
1081                                 ENV_DEFAULT_ENDDATE);
1082                         if (enddate == NULL)
1083                                 ERR_clear_error();
1084                         }
1085                 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1086                         {
1087                         BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1088                         goto err;
1089                         }
1090
1091                 if (days == 0)
1092                         {
1093                         if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1094                                 days = 0;
1095                         }
1096                 if (!enddate && (days == 0))
1097                         {
1098                         BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1099                         goto err;
1100                         }
1101
1102                 if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL)
1103                         {
1104                         BIO_printf(bio_err,"error while loading serial number\n");
1105                         goto err;
1106                         }
1107                 if (verbose)
1108                         {
1109                         if (BN_is_zero(serial))
1110                                 BIO_printf(bio_err,"next serial number is 00\n");
1111                         else
1112                                 {
1113                                 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1114                                 BIO_printf(bio_err,"next serial number is %s\n",f);
1115                                 OPENSSL_free(f);
1116                                 }
1117                         }
1118
1119                 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1120                         {
1121                         BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1122                         goto err;
1123                         }
1124
1125                 if ((cert_sk=sk_X509_new_null()) == NULL)
1126                         {
1127                         BIO_printf(bio_err,"Memory allocation failure\n");
1128                         goto err;
1129                         }
1130                 if (spkac_file != NULL)
1131                         {
1132                         total++;
1133                         j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1134                                 serial,subj,email_dn,startdate,enddate,days,extensions,
1135                                 conf,verbose,certopt,nameopt,default_op,ext_copy);
1136                         if (j < 0) goto err;
1137                         if (j > 0)
1138                                 {
1139                                 total_done++;
1140                                 BIO_printf(bio_err,"\n");
1141                                 if (!BN_add_word(serial,1)) goto err;
1142                                 if (!sk_X509_push(cert_sk,x))
1143                                         {
1144                                         BIO_printf(bio_err,"Memory allocation failure\n");
1145                                         goto err;
1146                                         }
1147                                 if (outfile)
1148                                         {
1149                                         output_der = 1;
1150                                         batch = 1;
1151                                         }
1152                                 }
1153                         }
1154                 if (ss_cert_file != NULL)
1155                         {
1156                         total++;
1157                         j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1158                                 db,serial,subj,email_dn,startdate,enddate,days,batch,
1159                                 extensions,conf,verbose, certopt, nameopt,
1160                                 default_op, ext_copy, e);
1161                         if (j < 0) goto err;
1162                         if (j > 0)
1163                                 {
1164                                 total_done++;
1165                                 BIO_printf(bio_err,"\n");
1166                                 if (!BN_add_word(serial,1)) goto err;
1167                                 if (!sk_X509_push(cert_sk,x))
1168                                         {
1169                                         BIO_printf(bio_err,"Memory allocation failure\n");
1170                                         goto err;
1171                                         }
1172                                 }
1173                         }
1174                 if (infile != NULL)
1175                         {
1176                         total++;
1177                         j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1178                                 serial,subj,email_dn,startdate,enddate,days,batch,
1179                                 extensions,conf,verbose, certopt, nameopt,
1180                                 default_op, ext_copy);
1181                         if (j < 0) goto err;
1182                         if (j > 0)
1183                                 {
1184                                 total_done++;
1185                                 BIO_printf(bio_err,"\n");
1186                                 if (!BN_add_word(serial,1)) goto err;
1187                                 if (!sk_X509_push(cert_sk,x))
1188                                         {
1189                                         BIO_printf(bio_err,"Memory allocation failure\n");
1190                                         goto err;
1191                                         }
1192                                 }
1193                         }
1194                 for (i=0; i<argc; i++)
1195                         {
1196                         total++;
1197                         j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1198                                 serial,subj,email_dn,startdate,enddate,days,batch,
1199                                 extensions,conf,verbose, certopt, nameopt,
1200                                 default_op, ext_copy);
1201                         if (j < 0) goto err;
1202                         if (j > 0)
1203                                 {
1204                                 total_done++;
1205                                 BIO_printf(bio_err,"\n");
1206                                 if (!BN_add_word(serial,1)) goto err;
1207                                 if (!sk_X509_push(cert_sk,x))
1208                                         {
1209                                         BIO_printf(bio_err,"Memory allocation failure\n");
1210                                         goto err;
1211                                         }
1212                                 }
1213                         }       
1214                 /* we have a stack of newly certified certificates
1215                  * and a data base and serial number that need
1216                  * updating */
1217
1218                 if (sk_X509_num(cert_sk) > 0)
1219                         {
1220                         if (!batch)
1221                                 {
1222                                 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1223                                 (void)BIO_flush(bio_err);
1224                                 buf[0][0]='\0';
1225                                 fgets(buf[0],10,stdin);
1226                                 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1227                                         {
1228                                         BIO_printf(bio_err,"CERTIFICATION CANCELED\n"); 
1229                                         ret=0;
1230                                         goto err;
1231                                         }
1232                                 }
1233
1234                         BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1235
1236                         if (!save_serial(serialfile,"new",serial,NULL)) goto err;
1237
1238                         if (!save_index(dbfile, "new", db)) goto err;
1239                         }
1240         
1241                 if (verbose)
1242                         BIO_printf(bio_err,"writing new certificates\n");
1243                 for (i=0; i<sk_X509_num(cert_sk); i++)
1244                         {
1245                         int k;
1246                         char *n;
1247
1248                         x=sk_X509_value(cert_sk,i);
1249
1250                         j=x->cert_info->serialNumber->length;
1251                         p=(char *)x->cert_info->serialNumber->data;
1252                         
1253                         if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1254                                 {
1255                                 BIO_printf(bio_err,"certificate file name too long\n");
1256                                 goto err;
1257                                 }
1258
1259                         strcpy(buf[2],outdir);
1260
1261 #ifndef OPENSSL_SYS_VMS
1262                         BUF_strlcat(buf[2],"/",sizeof(buf[2]));
1263 #endif
1264
1265                         n=(char *)&(buf[2][strlen(buf[2])]);
1266                         if (j > 0)
1267                                 {
1268                                 for (k=0; k<j; k++)
1269                                         {
1270                                         if (n >= &(buf[2][sizeof(buf[2])]))
1271                                                 break;
1272                                         BIO_snprintf(n,
1273                                                      &buf[2][0] + sizeof(buf[2]) - n,
1274                                                      "%02X",(unsigned char)*(p++));
1275                                         n+=2;
1276                                         }
1277                                 }
1278                         else
1279                                 {
1280                                 *(n++)='0';
1281                                 *(n++)='0';
1282                                 }
1283                         *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1284                         *n='\0';
1285                         if (verbose)
1286                                 BIO_printf(bio_err,"writing %s\n",buf[2]);
1287
1288                         if (BIO_write_filename(Cout,buf[2]) <= 0)
1289                                 {
1290                                 perror(buf[2]);
1291                                 goto err;
1292                                 }
1293                         write_new_certificate(Cout,x, 0, notext);
1294                         write_new_certificate(Sout,x, output_der, notext);
1295                         }
1296
1297                 if (sk_X509_num(cert_sk))
1298                         {
1299                         /* Rename the database and the serial file */
1300                         if (!rotate_serial(serialfile,"new","old")) goto err;
1301
1302                         if (!rotate_index(dbfile,"new","old")) goto err;
1303
1304                         BIO_printf(bio_err,"Data Base Updated\n");
1305                         }
1306                 }
1307         
1308         /*****************************************************************/
1309         if (gencrl)
1310                 {
1311                 int crl_v2 = 0;
1312                 if (!crl_ext)
1313                         {
1314                         crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1315                         if (!crl_ext)
1316                                 ERR_clear_error();
1317                         }
1318                 if (crl_ext)
1319                         {
1320                         /* Check syntax of file */
1321                         X509V3_CTX ctx;
1322                         X509V3_set_ctx_test(&ctx);
1323                         X509V3_set_nconf(&ctx, conf);
1324                         if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1325                                 {
1326                                 BIO_printf(bio_err,
1327                                  "Error Loading CRL extension section %s\n",
1328                                                                  crl_ext);
1329                                 ret = 1;
1330                                 goto err;
1331                                 }
1332                         }
1333
1334                 if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER))
1335                         != NULL)
1336                         if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL)
1337                                 {
1338                                 BIO_printf(bio_err,"error while loading CRL number\n");
1339                                 goto err;
1340                                 }
1341
1342                 if (!crldays && !crlhours)
1343                         {
1344                         if (!NCONF_get_number(conf,section,
1345                                 ENV_DEFAULT_CRL_DAYS, &crldays))
1346                                 crldays = 0;
1347                         if (!NCONF_get_number(conf,section,
1348                                 ENV_DEFAULT_CRL_HOURS, &crlhours))
1349                                 crlhours = 0;
1350                         }
1351                 if ((crldays == 0) && (crlhours == 0))
1352                         {
1353                         BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1354                         goto err;
1355                         }
1356
1357                 if (verbose) BIO_printf(bio_err,"making CRL\n");
1358                 if ((crl=X509_CRL_new()) == NULL) goto err;
1359                 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1360
1361                 tmptm = ASN1_TIME_new();
1362                 if (!tmptm) goto err;
1363                 X509_gmtime_adj(tmptm,0);
1364                 X509_CRL_set_lastUpdate(crl, tmptm);    
1365                 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1366                 X509_CRL_set_nextUpdate(crl, tmptm);    
1367
1368                 ASN1_TIME_free(tmptm);
1369
1370                 for (i=0; i<sk_num(db->db->data); i++)
1371                         {
1372                         pp=(char **)sk_value(db->db->data,i);
1373                         if (pp[DB_type][0] == DB_TYPE_REV)
1374                                 {
1375                                 if ((r=X509_REVOKED_new()) == NULL) goto err;
1376                                 j = make_revoked(r, pp[DB_rev_date]);
1377                                 if (!j) goto err;
1378                                 if (j == 2) crl_v2 = 1;
1379                                 if (!BN_hex2bn(&serial, pp[DB_serial]))
1380                                         goto err;
1381                                 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1382                                 BN_free(serial);
1383                                 serial = NULL;
1384                                 if (!tmpser)
1385                                         goto err;
1386                                 X509_REVOKED_set_serialNumber(r, tmpser);
1387                                 ASN1_INTEGER_free(tmpser);
1388                                 X509_CRL_add0_revoked(crl,r);
1389                                 }
1390                         }
1391
1392                 /* sort the data so it will be written in serial
1393                  * number order */
1394                 X509_CRL_sort(crl);
1395
1396                 /* we now have a CRL */
1397                 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1398                 if (md != NULL)
1399                         {
1400                         if ((dgst=EVP_get_digestbyname(md)) == NULL)
1401                                 {
1402                                 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1403                                 goto err;
1404                                 }
1405                         }
1406                 else
1407                         {
1408 #ifndef OPENSSL_NO_DSA
1409                         if (pkey->type == EVP_PKEY_DSA) 
1410                                 dgst=EVP_dss1();
1411                         else
1412 #endif
1413                                 dgst=EVP_md5();
1414                         }
1415
1416                 /* Add any extensions asked for */
1417
1418                 if (crl_ext || crlnumberfile != NULL)
1419                         {
1420                         X509V3_CTX crlctx;
1421                         X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1422                         X509V3_set_nconf(&crlctx, conf);
1423
1424                         if (crl_ext)
1425                                 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1426                                         crl_ext, crl)) goto err;
1427                         if (crlnumberfile != NULL)
1428                                 {
1429                                 tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
1430                                 if (!tmpser) goto err;
1431                                 X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
1432                                 ASN1_INTEGER_free(tmpser);
1433                                 crl_v2 = 1;
1434                                 if (!BN_add_word(crlnumber,1)) goto err;
1435                                 }
1436                         }
1437                 if (crl_ext || crl_v2)
1438                         {
1439                         if (!X509_CRL_set_version(crl, 1))
1440                                 goto err; /* version 2 CRL */
1441                         }
1442
1443                 
1444                 if (crlnumberfile != NULL)      /* we have a CRL number that need updating */
1445                         if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
1446
1447                 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1448
1449                 PEM_write_bio_X509_CRL(Sout,crl);
1450
1451                 if (crlnumberfile != NULL)      /* Rename the crlnumber file */
1452                         if (!rotate_serial(crlnumberfile,"new","old")) goto err;
1453
1454                 }
1455         /*****************************************************************/
1456         if (dorevoke)
1457                 {
1458                 if (infile == NULL) 
1459                         {
1460                         BIO_printf(bio_err,"no input files\n");
1461                         goto err;
1462                         }
1463                 else
1464                         {
1465                         X509 *revcert;
1466                         revcert=load_cert(bio_err, infile, FORMAT_PEM,
1467                                 NULL, e, infile);
1468                         if (revcert == NULL)
1469                                 goto err;
1470                         j=do_revoke(revcert,db, rev_type, rev_arg);
1471                         if (j <= 0) goto err;
1472                         X509_free(revcert);
1473
1474                         if (!save_index(dbfile, "new", db)) goto err;
1475
1476                         if (!rotate_index(dbfile, "new", "old")) goto err;
1477
1478                         BIO_printf(bio_err,"Data Base Updated\n"); 
1479                         }
1480                 }
1481         /*****************************************************************/
1482         ret=0;
1483 err:
1484         if(tofree)
1485                 OPENSSL_free(tofree);
1486         BIO_free_all(Cout);
1487         BIO_free_all(Sout);
1488         BIO_free_all(out);
1489         BIO_free_all(in);
1490
1491         if (cert_sk)
1492                 sk_X509_pop_free(cert_sk,X509_free);
1493
1494         if (ret) ERR_print_errors(bio_err);
1495         app_RAND_write_file(randfile, bio_err);
1496         if (free_key && key)
1497                 OPENSSL_free(key);
1498         BN_free(serial);
1499         free_index(db);
1500         EVP_PKEY_free(pkey);
1501         X509_free(x509);
1502         X509_CRL_free(crl);
1503         NCONF_free(conf);
1504         OBJ_cleanup();
1505         apps_shutdown();
1506         OPENSSL_EXIT(ret);
1507         }
1508
1509 static void lookup_fail(char *name, char *tag)
1510         {
1511         BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1512         }
1513
1514 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1515              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1516              BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1517              long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1518              unsigned long certopt, unsigned long nameopt, int default_op,
1519              int ext_copy)
1520         {
1521         X509_REQ *req=NULL;
1522         BIO *in=NULL;
1523         EVP_PKEY *pktmp=NULL;
1524         int ok= -1,i;
1525
1526         in=BIO_new(BIO_s_file());
1527
1528         if (BIO_read_filename(in,infile) <= 0)
1529                 {
1530                 perror(infile);
1531                 goto err;
1532                 }
1533         if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1534                 {
1535                 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1536                         infile);
1537                 goto err;
1538                 }
1539         if (verbose)
1540                 X509_REQ_print(bio_err,req);
1541
1542         BIO_printf(bio_err,"Check that the request matches the signature\n");
1543
1544         if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1545                 {
1546                 BIO_printf(bio_err,"error unpacking public key\n");
1547                 goto err;
1548                 }
1549         i=X509_REQ_verify(req,pktmp);
1550         EVP_PKEY_free(pktmp);
1551         if (i < 0)
1552                 {
1553                 ok=0;
1554                 BIO_printf(bio_err,"Signature verification problems....\n");
1555                 goto err;
1556                 }
1557         if (i == 0)
1558                 {
1559                 ok=0;
1560                 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1561                 goto err;
1562                 }
1563         else
1564                 BIO_printf(bio_err,"Signature ok\n");
1565
1566         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1567                 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1568                 certopt, nameopt, default_op, ext_copy);
1569
1570 err:
1571         if (req != NULL) X509_REQ_free(req);
1572         if (in != NULL) BIO_free(in);
1573         return(ok);
1574         }
1575
1576 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1577              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1578              BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1579              long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1580              unsigned long certopt, unsigned long nameopt, int default_op,
1581              int ext_copy, ENGINE *e)
1582         {
1583         X509 *req=NULL;
1584         X509_REQ *rreq=NULL;
1585         EVP_PKEY *pktmp=NULL;
1586         int ok= -1,i;
1587
1588         if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1589                 goto err;
1590         if (verbose)
1591                 X509_print(bio_err,req);
1592
1593         BIO_printf(bio_err,"Check that the request matches the signature\n");
1594
1595         if ((pktmp=X509_get_pubkey(req)) == NULL)
1596                 {
1597                 BIO_printf(bio_err,"error unpacking public key\n");
1598                 goto err;
1599                 }
1600         i=X509_verify(req,pktmp);
1601         EVP_PKEY_free(pktmp);
1602         if (i < 0)
1603                 {
1604                 ok=0;
1605                 BIO_printf(bio_err,"Signature verification problems....\n");
1606                 goto err;
1607                 }
1608         if (i == 0)
1609                 {
1610                 ok=0;
1611                 BIO_printf(bio_err,"Signature did not match the certificate\n");
1612                 goto err;
1613                 }
1614         else
1615                 BIO_printf(bio_err,"Signature ok\n");
1616
1617         if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1618                 goto err;
1619
1620         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1621                 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1622                 ext_copy);
1623
1624 err:
1625         if (rreq != NULL) X509_REQ_free(rreq);
1626         if (req != NULL) X509_free(req);
1627         return(ok);
1628         }
1629
1630 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1631              STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1632              int email_dn, char *startdate, char *enddate, long days, int batch,
1633              int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1634              unsigned long certopt, unsigned long nameopt, int default_op,
1635              int ext_copy)
1636         {
1637         X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1638         ASN1_UTCTIME *tm,*tmptm;
1639         ASN1_STRING *str,*str2;
1640         ASN1_OBJECT *obj;
1641         X509 *ret=NULL;
1642         X509_CINF *ci;
1643         X509_NAME_ENTRY *ne;
1644         X509_NAME_ENTRY *tne,*push;
1645         EVP_PKEY *pktmp;
1646         int ok= -1,i,j,last,nid;
1647         char *p;
1648         CONF_VALUE *cv;
1649         char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
1650         char buf[25];
1651
1652         tmptm=ASN1_UTCTIME_new();
1653         if (tmptm == NULL)
1654                 {
1655                 BIO_printf(bio_err,"malloc error\n");
1656                 return(0);
1657                 }
1658
1659         for (i=0; i<DB_NUMBER; i++)
1660                 row[i]=NULL;
1661
1662         if (subj)
1663                 {
1664                 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1665
1666                 if (!n)
1667                         {
1668                         ERR_print_errors(bio_err);
1669                         goto err;
1670                         }
1671                 X509_REQ_set_subject_name(req,n);
1672                 req->req_info->enc.modified = 1;
1673                 X509_NAME_free(n);
1674                 }
1675
1676         if (default_op)
1677                 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1678
1679         name=X509_REQ_get_subject_name(req);
1680         for (i=0; i<X509_NAME_entry_count(name); i++)
1681                 {
1682                 ne= X509_NAME_get_entry(name,i);
1683                 str=X509_NAME_ENTRY_get_data(ne);
1684                 obj=X509_NAME_ENTRY_get_object(ne);
1685
1686                 if (msie_hack)
1687                         {
1688                         /* assume all type should be strings */
1689                         nid=OBJ_obj2nid(ne->object);
1690
1691                         if (str->type == V_ASN1_UNIVERSALSTRING)
1692                                 ASN1_UNIVERSALSTRING_to_string(str);
1693
1694                         if ((str->type == V_ASN1_IA5STRING) &&
1695                                 (nid != NID_pkcs9_emailAddress))
1696                                 str->type=V_ASN1_T61STRING;
1697
1698                         if ((nid == NID_pkcs9_emailAddress) &&
1699                                 (str->type == V_ASN1_PRINTABLESTRING))
1700                                 str->type=V_ASN1_IA5STRING;
1701                         }
1702
1703                 /* If no EMAIL is wanted in the subject */
1704                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1705                         continue;
1706
1707                 /* check some things */
1708                 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1709                         (str->type != V_ASN1_IA5STRING))
1710                         {
1711                         BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1712                         goto err;
1713                         }
1714                 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1715                         {
1716                         j=ASN1_PRINTABLE_type(str->data,str->length);
1717                         if (    ((j == V_ASN1_T61STRING) &&
1718                                  (str->type != V_ASN1_T61STRING)) ||
1719                                 ((j == V_ASN1_IA5STRING) &&
1720                                  (str->type == V_ASN1_PRINTABLESTRING)))
1721                                 {
1722                                 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1723                                 goto err;
1724                                 }
1725                         }
1726
1727                 if (default_op)
1728                         old_entry_print(bio_err, obj, str);
1729                 }
1730
1731         /* Ok, now we check the 'policy' stuff. */
1732         if ((subject=X509_NAME_new()) == NULL)
1733                 {
1734                 BIO_printf(bio_err,"Memory allocation failure\n");
1735                 goto err;
1736                 }
1737
1738         /* take a copy of the issuer name before we mess with it. */
1739         CAname=X509_NAME_dup(x509->cert_info->subject);
1740         if (CAname == NULL) goto err;
1741         str=str2=NULL;
1742
1743         for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1744                 {
1745                 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1746                 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1747                         {
1748                         BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1749                         goto err;
1750                         }
1751                 obj=OBJ_nid2obj(j);
1752
1753                 last= -1;
1754                 for (;;)
1755                         {
1756                         /* lookup the object in the supplied name list */
1757                         j=X509_NAME_get_index_by_OBJ(name,obj,last);
1758                         if (j < 0)
1759                                 {
1760                                 if (last != -1) break;
1761                                 tne=NULL;
1762                                 }
1763                         else
1764                                 {
1765                                 tne=X509_NAME_get_entry(name,j);
1766                                 }
1767                         last=j;
1768
1769                         /* depending on the 'policy', decide what to do. */
1770                         push=NULL;
1771                         if (strcmp(cv->value,"optional") == 0)
1772                                 {
1773                                 if (tne != NULL)
1774                                         push=tne;
1775                                 }
1776                         else if (strcmp(cv->value,"supplied") == 0)
1777                                 {
1778                                 if (tne == NULL)
1779                                         {
1780                                         BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1781                                         goto err;
1782                                         }
1783                                 else
1784                                         push=tne;
1785                                 }
1786                         else if (strcmp(cv->value,"match") == 0)
1787                                 {
1788                                 int last2;
1789
1790                                 if (tne == NULL)
1791                                         {
1792                                         BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1793                                         goto err;
1794                                         }
1795
1796                                 last2= -1;
1797
1798 again2:
1799                                 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1800                                 if ((j < 0) && (last2 == -1))
1801                                         {
1802                                         BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1803                                         goto err;
1804                                         }
1805                                 if (j >= 0)
1806                                         {
1807                                         push=X509_NAME_get_entry(CAname,j);
1808                                         str=X509_NAME_ENTRY_get_data(tne);
1809                                         str2=X509_NAME_ENTRY_get_data(push);
1810                                         last2=j;
1811                                         if (ASN1_STRING_cmp(str,str2) != 0)
1812                                                 goto again2;
1813                                         }
1814                                 if (j < 0)
1815                                         {
1816                                         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));
1817                                         goto err;
1818                                         }
1819                                 }
1820                         else
1821                                 {
1822                                 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1823                                 goto err;
1824                                 }
1825
1826                         if (push != NULL)
1827                                 {
1828                                 if (!X509_NAME_add_entry(subject,push, -1, 0))
1829                                         {
1830                                         if (push != NULL)
1831                                                 X509_NAME_ENTRY_free(push);
1832                                         BIO_printf(bio_err,"Memory allocation failure\n");
1833                                         goto err;
1834                                         }
1835                                 }
1836                         if (j < 0) break;
1837                         }
1838                 }
1839
1840         if (preserve)
1841                 {
1842                 X509_NAME_free(subject);
1843                 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1844                 subject=X509_NAME_dup(name);
1845                 if (subject == NULL) goto err;
1846                 }
1847
1848         if (verbose)
1849                 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1850
1851         /* Build the correct Subject if no e-mail is wanted in the subject */
1852         /* and add it later on because of the method extensions are added (altName) */
1853          
1854         if (email_dn)
1855                 dn_subject = subject;
1856         else
1857                 {
1858                 X509_NAME_ENTRY *tmpne;
1859                 /* Its best to dup the subject DN and then delete any email
1860                  * addresses because this retains its structure.
1861                  */
1862                 if (!(dn_subject = X509_NAME_dup(subject)))
1863                         {
1864                         BIO_printf(bio_err,"Memory allocation failure\n");
1865                         goto err;
1866                         }
1867                 while((i = X509_NAME_get_index_by_NID(dn_subject,
1868                                         NID_pkcs9_emailAddress, -1)) >= 0)
1869                         {
1870                         tmpne = X509_NAME_get_entry(dn_subject, i);
1871                         X509_NAME_delete_entry(dn_subject, i);
1872                         X509_NAME_ENTRY_free(tmpne);
1873                         }
1874                 }
1875
1876         if (BN_is_zero(serial))
1877                 row[DB_serial]=BUF_strdup("00");
1878         else
1879                 row[DB_serial]=BN_bn2hex(serial);
1880         if (row[DB_serial] == NULL)
1881                 {
1882                 BIO_printf(bio_err,"Memory allocation failure\n");
1883                 goto err;
1884                 }
1885
1886         if (db->attributes.unique_subject)
1887                 {
1888                 rrow=TXT_DB_get_by_index(db->db,DB_name,row);
1889                 if (rrow != NULL)
1890                         {
1891                         BIO_printf(bio_err,
1892                                 "ERROR:There is already a certificate for %s\n",
1893                                 row[DB_name]);
1894                         }
1895                 }
1896         if (rrow == NULL)
1897                 {
1898                 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1899                 if (rrow != NULL)
1900                         {
1901                         BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1902                                 row[DB_serial]);
1903                         BIO_printf(bio_err,"      check the database/serial_file for corruption\n");
1904                         }
1905                 }
1906
1907         if (rrow != NULL)
1908                 {
1909                 BIO_printf(bio_err,
1910                         "The matching entry has the following details\n");
1911                 if (rrow[DB_type][0] == 'E')
1912                         p="Expired";
1913                 else if (rrow[DB_type][0] == 'R')
1914                         p="Revoked";
1915                 else if (rrow[DB_type][0] == 'V')
1916                         p="Valid";
1917                 else
1918                         p="\ninvalid type, Data base error\n";
1919                 BIO_printf(bio_err,"Type          :%s\n",p);;
1920                 if (rrow[DB_type][0] == 'R')
1921                         {
1922                         p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1923                         BIO_printf(bio_err,"Was revoked on:%s\n",p);
1924                         }
1925                 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1926                 BIO_printf(bio_err,"Expires on    :%s\n",p);
1927                 p=rrow[DB_serial]; if (p == NULL) p="undef";
1928                 BIO_printf(bio_err,"Serial Number :%s\n",p);
1929                 p=rrow[DB_file]; if (p == NULL) p="undef";
1930                 BIO_printf(bio_err,"File name     :%s\n",p);
1931                 p=rrow[DB_name]; if (p == NULL) p="undef";
1932                 BIO_printf(bio_err,"Subject Name  :%s\n",p);
1933                 ok= -1; /* This is now a 'bad' error. */
1934                 goto err;
1935                 }
1936
1937         /* We are now totally happy, lets make and sign the certificate */
1938         if (verbose)
1939                 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1940
1941         if ((ret=X509_new()) == NULL) goto err;
1942         ci=ret->cert_info;
1943
1944 #ifdef X509_V3
1945         /* Make it an X509 v3 certificate. */
1946         if (!X509_set_version(ret,2)) goto err;
1947 #endif
1948
1949         if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1950                 goto err;
1951         if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1952                 goto err;
1953
1954         if (strcmp(startdate,"today") == 0)
1955                 X509_gmtime_adj(X509_get_notBefore(ret),0);
1956         else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1957
1958         if (enddate == NULL)
1959                 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1960         else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1961
1962         if (!X509_set_subject_name(ret,subject)) goto err;
1963
1964         pktmp=X509_REQ_get_pubkey(req);
1965         i = X509_set_pubkey(ret,pktmp);
1966         EVP_PKEY_free(pktmp);
1967         if (!i) goto err;
1968
1969         /* Lets add the extensions, if there are any */
1970         if (ext_sect)
1971                 {
1972                 X509V3_CTX ctx;
1973                 if (ci->version == NULL)
1974                         if ((ci->version=ASN1_INTEGER_new()) == NULL)
1975                                 goto err;
1976                 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1977
1978                 /* Free the current entries if any, there should not
1979                  * be any I believe */
1980                 if (ci->extensions != NULL)
1981                         sk_X509_EXTENSION_pop_free(ci->extensions,
1982                                                    X509_EXTENSION_free);
1983
1984                 ci->extensions = NULL;
1985
1986                 /* Initialize the context structure */
1987                 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1988
1989                 if (extconf)
1990                         {
1991                         if (verbose)
1992                                 BIO_printf(bio_err, "Extra configuration file found\n");
1993  
1994                         /* Use the extconf configuration db LHASH */
1995                         X509V3_set_nconf(&ctx, extconf);
1996  
1997                         /* Test the structure (needed?) */
1998                         /* X509V3_set_ctx_test(&ctx); */
1999
2000                         /* Adds exts contained in the configuration file */
2001                         if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2002                                 {
2003                                 BIO_printf(bio_err,
2004                                     "ERROR: adding extensions in section %s\n",
2005                                                                 ext_sect);
2006                                 ERR_print_errors(bio_err);
2007                                 goto err;
2008                                 }
2009                         if (verbose)
2010                                 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2011                         }
2012                 else if (ext_sect)
2013                         {
2014                         /* We found extensions to be set from config file */
2015                         X509V3_set_nconf(&ctx, lconf);
2016
2017                         if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2018                                 {
2019                                 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2020                                 ERR_print_errors(bio_err);
2021                                 goto err;
2022                                 }
2023
2024                         if (verbose) 
2025                                 BIO_printf(bio_err, "Successfully added extensions from config\n");
2026                         }
2027                 }
2028
2029         /* Copy extensions from request (if any) */
2030
2031         if (!copy_extensions(ret, req, ext_copy))
2032                 {
2033                 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2034                 ERR_print_errors(bio_err);
2035                 goto err;
2036                 }
2037
2038         /* Set the right value for the noemailDN option */
2039         if( email_dn == 0 )
2040                 {
2041                 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2042                 }
2043
2044         if (!default_op)
2045                 {
2046                 BIO_printf(bio_err, "Certificate Details:\n");
2047                 /* Never print signature details because signature not present */
2048                 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2049                 X509_print_ex(bio_err, ret, nameopt, certopt); 
2050                 }
2051
2052         BIO_printf(bio_err,"Certificate is to be certified until ");
2053         ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2054         if (days) BIO_printf(bio_err," (%d days)",days);
2055         BIO_printf(bio_err, "\n");
2056
2057         if (!batch)
2058                 {
2059
2060                 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2061                 (void)BIO_flush(bio_err);
2062                 buf[0]='\0';
2063                 fgets(buf,sizeof(buf)-1,stdin);
2064                 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2065                         {
2066                         BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2067                         ok=0;
2068                         goto err;
2069                         }
2070                 }
2071
2072
2073 #ifndef OPENSSL_NO_DSA
2074         if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2075         pktmp=X509_get_pubkey(ret);
2076         if (EVP_PKEY_missing_parameters(pktmp) &&
2077                 !EVP_PKEY_missing_parameters(pkey))
2078                 EVP_PKEY_copy_parameters(pktmp,pkey);
2079         EVP_PKEY_free(pktmp);
2080 #endif
2081
2082         if (!X509_sign(ret,pkey,dgst))
2083                 goto err;
2084
2085         /* We now just add it to the database */
2086         row[DB_type]=(char *)OPENSSL_malloc(2);
2087
2088         tm=X509_get_notAfter(ret);
2089         row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2090         memcpy(row[DB_exp_date],tm->data,tm->length);
2091         row[DB_exp_date][tm->length]='\0';
2092
2093         row[DB_rev_date]=NULL;
2094
2095         /* row[DB_serial] done already */
2096         row[DB_file]=(char *)OPENSSL_malloc(8);
2097         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2098
2099         if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2100                 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2101                 {
2102                 BIO_printf(bio_err,"Memory allocation failure\n");
2103                 goto err;
2104                 }
2105         BUF_strlcpy(row[DB_file],"unknown",8);
2106         row[DB_type][0]='V';
2107         row[DB_type][1]='\0';
2108
2109         if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2110                 {
2111                 BIO_printf(bio_err,"Memory allocation failure\n");
2112                 goto err;
2113                 }
2114
2115         for (i=0; i<DB_NUMBER; i++)
2116                 {
2117                 irow[i]=row[i];
2118                 row[i]=NULL;
2119                 }
2120         irow[DB_NUMBER]=NULL;
2121
2122         if (!TXT_DB_insert(db->db,irow))
2123                 {
2124                 BIO_printf(bio_err,"failed to update database\n");
2125                 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2126                 goto err;
2127                 }
2128         ok=1;
2129 err:
2130         for (i=0; i<DB_NUMBER; i++)
2131                 if (row[i] != NULL) OPENSSL_free(row[i]);
2132
2133         if (CAname != NULL)
2134                 X509_NAME_free(CAname);
2135         if (subject != NULL)
2136                 X509_NAME_free(subject);
2137         if ((dn_subject != NULL) && !email_dn)
2138                 X509_NAME_free(dn_subject);
2139         if (tmptm != NULL)
2140                 ASN1_UTCTIME_free(tmptm);
2141         if (ok <= 0)
2142                 {
2143                 if (ret != NULL) X509_free(ret);
2144                 ret=NULL;
2145                 }
2146         else
2147                 *xret=ret;
2148         return(ok);
2149         }
2150
2151 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2152         {
2153
2154         if (output_der)
2155                 {
2156                 (void)i2d_X509_bio(bp,x);
2157                 return;
2158                 }
2159 #if 0
2160         /* ??? Not needed since X509_print prints all this stuff anyway */
2161         f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2162         BIO_printf(bp,"issuer :%s\n",f);
2163
2164         f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2165         BIO_printf(bp,"subject:%s\n",f);
2166
2167         BIO_puts(bp,"serial :");
2168         i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2169         BIO_puts(bp,"\n\n");
2170 #endif
2171         if (!notext)X509_print(bp,x);
2172         PEM_write_bio_X509(bp,x);
2173         }
2174
2175 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2176              const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2177              BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2178              long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2179              unsigned long nameopt, int default_op, int ext_copy)
2180         {
2181         STACK_OF(CONF_VALUE) *sk=NULL;
2182         LHASH *parms=NULL;
2183         X509_REQ *req=NULL;
2184         CONF_VALUE *cv=NULL;
2185         NETSCAPE_SPKI *spki = NULL;
2186         X509_REQ_INFO *ri;
2187         char *type,*buf;
2188         EVP_PKEY *pktmp=NULL;
2189         X509_NAME *n=NULL;
2190         X509_NAME_ENTRY *ne=NULL;
2191         int ok= -1,i,j;
2192         long errline;
2193         int nid;
2194
2195         /*
2196          * Load input file into a hash table.  (This is just an easy
2197          * way to read and parse the file, then put it into a convenient
2198          * STACK format).
2199          */
2200         parms=CONF_load(NULL,infile,&errline);
2201         if (parms == NULL)
2202                 {
2203                 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2204                 ERR_print_errors(bio_err);
2205                 goto err;
2206                 }
2207
2208         sk=CONF_get_section(parms, "default");
2209         if (sk_CONF_VALUE_num(sk) == 0)
2210                 {
2211                 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2212                 CONF_free(parms);
2213                 goto err;
2214                 }
2215
2216         /*
2217          * Now create a dummy X509 request structure.  We don't actually
2218          * have an X509 request, but we have many of the components
2219          * (a public key, various DN components).  The idea is that we
2220          * put these components into the right X509 request structure
2221          * and we can use the same code as if you had a real X509 request.
2222          */
2223         req=X509_REQ_new();
2224         if (req == NULL)
2225                 {
2226                 ERR_print_errors(bio_err);
2227                 goto err;
2228                 }
2229
2230         /*
2231          * Build up the subject name set.
2232          */
2233         ri=req->req_info;
2234         n = ri->subject;
2235
2236         for (i = 0; ; i++)
2237                 {
2238                 if (sk_CONF_VALUE_num(sk) <= i) break;
2239
2240                 cv=sk_CONF_VALUE_value(sk,i);
2241                 type=cv->name;
2242                 /* Skip past any leading X. X: X, etc to allow for
2243                  * multiple instances
2244                  */
2245                 for (buf = cv->name; *buf ; buf++)
2246                         if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2247                                 {
2248                                 buf++;
2249                                 if (*buf) type = buf;
2250                                 break;
2251                                 }
2252
2253                 buf=cv->value;
2254                 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2255                         {
2256                         if (strcmp(type, "SPKAC") == 0)
2257                                 {
2258                                 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2259                                 if (spki == NULL)
2260                                         {
2261                                         BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2262                                         ERR_print_errors(bio_err);
2263                                         goto err;
2264                                         }
2265                                 }
2266                         continue;
2267                         }
2268
2269                 /*
2270                 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2271                         continue;
2272                 */
2273                 
2274                 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2275                 if (fix_data(nid, &j) == 0)
2276                         {
2277                         BIO_printf(bio_err,
2278                                 "invalid characters in string %s\n",buf);
2279                         goto err;
2280                         }
2281
2282                 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2283                         (unsigned char *)buf,
2284                         strlen(buf))) == NULL)
2285                         goto err;
2286
2287                 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2288                 }
2289         if (spki == NULL)
2290                 {
2291                 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2292                         infile);
2293                 goto err;
2294                 }
2295
2296         /*
2297          * Now extract the key from the SPKI structure.
2298          */
2299
2300         BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2301
2302         if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2303                 {
2304                 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2305                 goto err;
2306                 }
2307
2308         j = NETSCAPE_SPKI_verify(spki, pktmp);
2309         if (j <= 0)
2310                 {
2311                 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2312                 goto err;
2313                 }
2314         BIO_printf(bio_err,"Signature ok\n");
2315
2316         X509_REQ_set_pubkey(req,pktmp);
2317         EVP_PKEY_free(pktmp);
2318         ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2319                    days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2320                         ext_copy);
2321 err:
2322         if (req != NULL) X509_REQ_free(req);
2323         if (parms != NULL) CONF_free(parms);
2324         if (spki != NULL) NETSCAPE_SPKI_free(spki);
2325         if (ne != NULL) X509_NAME_ENTRY_free(ne);
2326
2327         return(ok);
2328         }
2329
2330 static int fix_data(int nid, int *type)
2331         {
2332         if (nid == NID_pkcs9_emailAddress)
2333                 *type=V_ASN1_IA5STRING;
2334         if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2335                 *type=V_ASN1_T61STRING;
2336         if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2337                 *type=V_ASN1_T61STRING;
2338         if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2339                 return(0);
2340         if (nid == NID_pkcs9_unstructuredName)
2341                 *type=V_ASN1_IA5STRING;
2342         return(1);
2343         }
2344
2345 static int check_time_format(char *str)
2346         {
2347         ASN1_UTCTIME tm;
2348
2349         tm.data=(unsigned char *)str;
2350         tm.length=strlen(str);
2351         tm.type=V_ASN1_UTCTIME;
2352         return(ASN1_UTCTIME_check(&tm));
2353         }
2354
2355 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2356         {
2357         ASN1_UTCTIME *tm=NULL;
2358         char *row[DB_NUMBER],**rrow,**irow;
2359         char *rev_str = NULL;
2360         BIGNUM *bn = NULL;
2361         int ok=-1,i;
2362
2363         for (i=0; i<DB_NUMBER; i++)
2364                 row[i]=NULL;
2365         row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2366         bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2367         if (BN_is_zero(bn))
2368                 row[DB_serial]=BUF_strdup("00");
2369         else
2370                 row[DB_serial]=BN_bn2hex(bn);
2371         BN_free(bn);
2372         if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2373                 {
2374                 BIO_printf(bio_err,"Memory allocation failure\n");
2375                 goto err;
2376                 }
2377         /* We have to lookup by serial number because name lookup
2378          * skips revoked certs
2379          */
2380         rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2381         if (rrow == NULL)
2382                 {
2383                 BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2384
2385                 /* We now just add it to the database */
2386                 row[DB_type]=(char *)OPENSSL_malloc(2);
2387
2388                 tm=X509_get_notAfter(x509);
2389                 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2390                 memcpy(row[DB_exp_date],tm->data,tm->length);
2391                 row[DB_exp_date][tm->length]='\0';
2392
2393                 row[DB_rev_date]=NULL;
2394
2395                 /* row[DB_serial] done already */
2396                 row[DB_file]=(char *)OPENSSL_malloc(8);
2397
2398                 /* row[DB_name] done already */
2399
2400                 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2401                         (row[DB_file] == NULL))
2402                         {
2403                         BIO_printf(bio_err,"Memory allocation failure\n");
2404                         goto err;
2405                         }
2406                 BUF_strlcpy(row[DB_file],"unknown",8);
2407                 row[DB_type][0]='V';
2408                 row[DB_type][1]='\0';
2409
2410                 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2411                         {
2412                         BIO_printf(bio_err,"Memory allocation failure\n");
2413                         goto err;
2414                         }
2415
2416                 for (i=0; i<DB_NUMBER; i++)
2417                         {
2418                         irow[i]=row[i];
2419                         row[i]=NULL;
2420                         }
2421                 irow[DB_NUMBER]=NULL;
2422
2423                 if (!TXT_DB_insert(db->db,irow))
2424                         {
2425                         BIO_printf(bio_err,"failed to update database\n");
2426                         BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2427                         goto err;
2428                         }
2429
2430                 /* Revoke Certificate */
2431                 ok = do_revoke(x509,db, type, value);
2432
2433                 goto err;
2434
2435                 }
2436         else if (index_name_cmp((const char **)row,(const char **)rrow))
2437                 {
2438                 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2439                            row[DB_name]);
2440                 goto err;
2441                 }
2442         else if (rrow[DB_type][0]=='R')
2443                 {
2444                 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2445                            row[DB_serial]);
2446                 goto err;
2447                 }
2448         else
2449                 {
2450                 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2451                 rev_str = make_revocation_str(type, value);
2452                 if (!rev_str)
2453                         {
2454                         BIO_printf(bio_err, "Error in revocation arguments\n");
2455                         goto err;
2456                         }
2457                 rrow[DB_type][0]='R';
2458                 rrow[DB_type][1]='\0';
2459                 rrow[DB_rev_date] = rev_str;
2460                 }
2461         ok=1;
2462 err:
2463         for (i=0; i<DB_NUMBER; i++)
2464                 {
2465                 if (row[i] != NULL) 
2466                         OPENSSL_free(row[i]);
2467                 }
2468         return(ok);
2469         }
2470
2471 static int get_certificate_status(const char *serial, CA_DB *db)
2472         {
2473         char *row[DB_NUMBER],**rrow;
2474         int ok=-1,i;
2475
2476         /* Free Resources */
2477         for (i=0; i<DB_NUMBER; i++)
2478                 row[i]=NULL;
2479
2480         /* Malloc needed char spaces */
2481         row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2482         if (row[DB_serial] == NULL)
2483                 {
2484                 BIO_printf(bio_err,"Malloc failure\n");
2485                 goto err;
2486                 }
2487
2488         if (strlen(serial) % 2)
2489                 {
2490                 /* Set the first char to 0 */;
2491                 row[DB_serial][0]='0';
2492
2493                 /* Copy String from serial to row[DB_serial] */
2494                 memcpy(row[DB_serial]+1, serial, strlen(serial));
2495                 row[DB_serial][strlen(serial)+1]='\0';
2496                 }
2497         else
2498                 {
2499                 /* Copy String from serial to row[DB_serial] */
2500                 memcpy(row[DB_serial], serial, strlen(serial));
2501                 row[DB_serial][strlen(serial)]='\0';
2502                 }
2503                         
2504         /* Make it Upper Case */
2505         for (i=0; row[DB_serial][i] != '\0'; i++)
2506                 row[DB_serial][i] = toupper(row[DB_serial][i]);
2507         
2508
2509         ok=1;
2510
2511         /* Search for the certificate */
2512         rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2513         if (rrow == NULL)
2514                 {
2515                 BIO_printf(bio_err,"Serial %s not present in db.\n",
2516                                  row[DB_serial]);
2517                 ok=-1;
2518                 goto err;
2519                 }
2520         else if (rrow[DB_type][0]=='V')
2521                 {
2522                 BIO_printf(bio_err,"%s=Valid (%c)\n",
2523                         row[DB_serial], rrow[DB_type][0]);
2524                 goto err;
2525                 }
2526         else if (rrow[DB_type][0]=='R')
2527                 {
2528                 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2529                         row[DB_serial], rrow[DB_type][0]);
2530                 goto err;
2531                 }
2532         else if (rrow[DB_type][0]=='E')
2533                 {
2534                 BIO_printf(bio_err,"%s=Expired (%c)\n",
2535                         row[DB_serial], rrow[DB_type][0]);
2536                 goto err;
2537                 }
2538         else if (rrow[DB_type][0]=='S')
2539                 {
2540                 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2541                         row[DB_serial], rrow[DB_type][0]);
2542                 goto err;
2543                 }
2544         else
2545                 {
2546                 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2547                         row[DB_serial], rrow[DB_type][0]);
2548                 ok=-1;
2549                 }
2550 err:
2551         for (i=0; i<DB_NUMBER; i++)
2552                 {
2553                 if (row[i] != NULL)
2554                         OPENSSL_free(row[i]);
2555                 }
2556         return(ok);
2557         }
2558
2559 static int do_updatedb (CA_DB *db)
2560         {
2561         ASN1_UTCTIME    *a_tm = NULL;
2562         int i, cnt = 0;
2563         int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */ 
2564         char **rrow, *a_tm_s;
2565
2566         a_tm = ASN1_UTCTIME_new();
2567
2568         /* get actual time and make a string */
2569         a_tm = X509_gmtime_adj(a_tm, 0);
2570         a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2571         if (a_tm_s == NULL)
2572                 {
2573                 cnt = -1;
2574                 goto err;
2575                 }
2576
2577         memcpy(a_tm_s, a_tm->data, a_tm->length);
2578         a_tm_s[a_tm->length] = '\0';
2579
2580         if (strncmp(a_tm_s, "49", 2) <= 0)
2581                 a_y2k = 1;
2582         else
2583                 a_y2k = 0;
2584
2585         for (i = 0; i < sk_num(db->db->data); i++)
2586                 {
2587                 rrow = (char **) sk_value(db->db->data, i);
2588
2589                 if (rrow[DB_type][0] == 'V')
2590                         {
2591                         /* ignore entries that are not valid */
2592                         if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2593                                 db_y2k = 1;
2594                         else
2595                                 db_y2k = 0;
2596
2597                         if (db_y2k == a_y2k)
2598                                 {
2599                                 /* all on the same y2k side */
2600                                 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2601                                         {
2602                                         rrow[DB_type][0]  = 'E';
2603                                         rrow[DB_type][1]  = '\0';
2604                                         cnt++;
2605
2606                                         BIO_printf(bio_err, "%s=Expired\n",
2607                                                         rrow[DB_serial]);
2608                                         }
2609                                 }
2610                         else if (db_y2k < a_y2k)
2611                                 {
2612                                 rrow[DB_type][0]  = 'E';
2613                                 rrow[DB_type][1]  = '\0';
2614                                 cnt++;
2615
2616                                 BIO_printf(bio_err, "%s=Expired\n",
2617                                                         rrow[DB_serial]);
2618                                 }
2619
2620                         }
2621                 }
2622
2623 err:
2624
2625         ASN1_UTCTIME_free(a_tm);
2626         OPENSSL_free(a_tm_s);
2627
2628         return (cnt);
2629         }
2630
2631 static char *crl_reasons[] = {
2632         /* CRL reason strings */
2633         "unspecified",
2634         "keyCompromise",
2635         "CACompromise",
2636         "affiliationChanged",
2637         "superseded", 
2638         "cessationOfOperation",
2639         "certificateHold",
2640         "removeFromCRL",
2641         /* Additional pseudo reasons */
2642         "holdInstruction",
2643         "keyTime",
2644         "CAkeyTime"
2645 };
2646
2647 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2648
2649 /* Given revocation information convert to a DB string.
2650  * The format of the string is:
2651  * revtime[,reason,extra]. Where 'revtime' is the
2652  * revocation time (the current time). 'reason' is the
2653  * optional CRL reason and 'extra' is any additional
2654  * argument
2655  */
2656
2657 char *make_revocation_str(int rev_type, char *rev_arg)
2658         {
2659         char *reason = NULL, *other = NULL, *str;
2660         ASN1_OBJECT *otmp;
2661         ASN1_UTCTIME *revtm = NULL;
2662         int i;
2663         switch (rev_type)
2664                 {
2665         case REV_NONE:
2666                 break;
2667
2668         case REV_CRL_REASON:
2669                 for (i = 0; i < 8; i++)
2670                         {
2671                         if (!strcasecmp(rev_arg, crl_reasons[i]))
2672                                 {
2673                                 reason = crl_reasons[i];
2674                                 break;
2675                                 }
2676                         }
2677                 if (reason == NULL)
2678                         {
2679                         BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2680                         return NULL;
2681                         }
2682                 break;
2683
2684         case REV_HOLD:
2685                 /* Argument is an OID */
2686
2687                 otmp = OBJ_txt2obj(rev_arg, 0);
2688                 ASN1_OBJECT_free(otmp);
2689
2690                 if (otmp == NULL)
2691                         {
2692                         BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2693                         return NULL;
2694                         }
2695
2696                 reason = "holdInstruction";
2697                 other = rev_arg;
2698                 break;
2699                 
2700         case REV_KEY_COMPROMISE:
2701         case REV_CA_COMPROMISE:
2702
2703                 /* Argument is the key compromise time  */
2704                 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2705                         {       
2706                         BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2707                         return NULL;
2708                         }
2709                 other = rev_arg;
2710                 if (rev_type == REV_KEY_COMPROMISE)
2711                         reason = "keyTime";
2712                 else 
2713                         reason = "CAkeyTime";
2714
2715                 break;
2716
2717                 }
2718
2719         revtm = X509_gmtime_adj(NULL, 0);
2720
2721         i = revtm->length + 1;
2722
2723         if (reason) i += strlen(reason) + 1;
2724         if (other) i += strlen(other) + 1;
2725
2726         str = OPENSSL_malloc(i);
2727
2728         if (!str) return NULL;
2729
2730         BUF_strlcpy(str, (char *)revtm->data, i);
2731         if (reason)
2732                 {
2733                 BUF_strlcat(str, ",", i);
2734                 BUF_strlcat(str, reason, i);
2735                 }
2736         if (other)
2737                 {
2738                 BUF_strlcat(str, ",", i);
2739                 BUF_strlcat(str, other, i);
2740                 }
2741         ASN1_UTCTIME_free(revtm);
2742         return str;
2743         }
2744
2745 /* Convert revocation field to X509_REVOKED entry 
2746  * return code:
2747  * 0 error
2748  * 1 OK
2749  * 2 OK and some extensions added (i.e. V2 CRL)
2750  */
2751
2752
2753 int make_revoked(X509_REVOKED *rev, char *str)
2754         {
2755         char *tmp = NULL;
2756         int reason_code = -1;
2757         int i, ret = 0;
2758         ASN1_OBJECT *hold = NULL;
2759         ASN1_GENERALIZEDTIME *comp_time = NULL;
2760         ASN1_ENUMERATED *rtmp = NULL;
2761
2762         ASN1_TIME *revDate = NULL;
2763
2764         i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2765
2766         if (i == 0)
2767                 goto err;
2768
2769         if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2770                 goto err;
2771
2772         if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2773                 {
2774                 rtmp = ASN1_ENUMERATED_new();
2775                 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2776                         goto err;
2777                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2778                         goto err;
2779                 }
2780
2781         if (rev && comp_time)
2782                 {
2783                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2784                         goto err;
2785                 }
2786         if (rev && hold)
2787                 {
2788                 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2789                         goto err;
2790                 }
2791
2792         if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2793                 ret = 2;
2794         else ret = 1;
2795
2796         err:
2797
2798         if (tmp) OPENSSL_free(tmp);
2799         ASN1_OBJECT_free(hold);
2800         ASN1_GENERALIZEDTIME_free(comp_time);
2801         ASN1_ENUMERATED_free(rtmp);
2802         ASN1_TIME_free(revDate);
2803
2804         return ret;
2805         }
2806
2807 /*
2808  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2809  * where characters may be escaped by \
2810  */
2811 X509_NAME *do_subject(char *subject, long chtype)
2812         {
2813         size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
2814         char *buf = OPENSSL_malloc(buflen);
2815         size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2816         char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
2817         char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
2818
2819         char *sp = subject, *bp = buf;
2820         int i, ne_num = 0;
2821
2822         X509_NAME *n = NULL;
2823         int nid;
2824
2825         if (!buf || !ne_types || !ne_values)
2826         {
2827                 BIO_printf(bio_err, "malloc error\n");
2828                 goto error;
2829         }
2830
2831         if (*subject != '/')
2832         {
2833                 BIO_printf(bio_err, "Subject does not start with '/'.\n");
2834                 goto error;
2835         }
2836         sp++; /* skip leading / */
2837
2838         while (*sp)
2839                 {
2840                 /* collect type */
2841                 ne_types[ne_num] = bp;
2842                 while (*sp)
2843                         {
2844                         if (*sp == '\\') /* is there anything to escape in the type...? */
2845                                 {
2846                                 if (*++sp)
2847                                         *bp++ = *sp++;
2848                                 else
2849                                         {
2850                                         BIO_printf(bio_err, "escape character at end of string\n");
2851                                         goto error;
2852                                         }
2853                                 }
2854                         else if (*sp == '=')
2855                                 {
2856                                 sp++;
2857                                 *bp++ = '\0';
2858                                 break;
2859                                 }
2860                         else
2861                                 *bp++ = *sp++;
2862                         }
2863                 if (!*sp)
2864                         {
2865                         BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
2866                         goto error;
2867                         }
2868                 ne_values[ne_num] = bp;
2869                 while (*sp)
2870                         {
2871                         if (*sp == '\\')
2872                                 {
2873                                 if (*++sp)
2874                                         *bp++ = *sp++;
2875                                 else
2876                                         {
2877                                         BIO_printf(bio_err, "escape character at end of string\n");
2878                                         goto error;
2879                                         }
2880                                 }
2881                         else if (*sp == '/')
2882                                 {
2883                                 sp++;
2884                                 break;
2885                                 }
2886                         else
2887                                 *bp++ = *sp++;
2888                         }
2889                 *bp++ = '\0';
2890                 ne_num++;
2891                 }
2892
2893         if (!(n = X509_NAME_new()))
2894                 goto error;
2895
2896         for (i = 0; i < ne_num; i++)
2897                 {
2898                 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
2899                         {
2900                         BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
2901                         continue;
2902                         }
2903
2904                 if (!*ne_values[i])
2905                         {
2906                         BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
2907                         continue;
2908                         }
2909
2910                 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
2911                         goto error;
2912                 }
2913
2914         OPENSSL_free(ne_values);
2915         OPENSSL_free(ne_types);
2916         OPENSSL_free(buf);
2917         return n;
2918
2919 error:
2920         X509_NAME_free(n);
2921         if (ne_values)
2922                 OPENSSL_free(ne_values);
2923         if (ne_types)
2924                 OPENSSL_free(ne_types);
2925         if (buf)
2926                 OPENSSL_free(buf);
2927         return NULL;
2928 }
2929
2930 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2931         {
2932         char buf[25],*pbuf, *p;
2933         int j;
2934         j=i2a_ASN1_OBJECT(bp,obj);
2935         pbuf=buf;
2936         for (j=22-j; j>0; j--)
2937                 *(pbuf++)=' ';
2938         *(pbuf++)=':';
2939         *(pbuf++)='\0';
2940         BIO_puts(bp,buf);
2941
2942         if (str->type == V_ASN1_PRINTABLESTRING)
2943                 BIO_printf(bp,"PRINTABLE:'");
2944         else if (str->type == V_ASN1_T61STRING)
2945                 BIO_printf(bp,"T61STRING:'");
2946         else if (str->type == V_ASN1_IA5STRING)
2947                 BIO_printf(bp,"IA5STRING:'");
2948         else if (str->type == V_ASN1_UNIVERSALSTRING)
2949                 BIO_printf(bp,"UNIVERSALSTRING:'");
2950         else
2951                 BIO_printf(bp,"ASN.1 %2d:'",str->type);
2952                         
2953         p=(char *)str->data;
2954         for (j=str->length; j>0; j--)
2955                 {
2956                 if ((*p >= ' ') && (*p <= '~'))
2957                         BIO_printf(bp,"%c",*p);
2958                 else if (*p & 0x80)
2959                         BIO_printf(bp,"\\0x%02X",*p);
2960                 else if ((unsigned char)*p == 0xf7)
2961                         BIO_printf(bp,"^?");
2962                 else    BIO_printf(bp,"^%c",*p+'@');
2963                 p++;
2964                 }
2965         BIO_printf(bp,"'\n");
2966         return 1;
2967         }
2968
2969 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
2970         {
2971         char *tmp = NULL;
2972         char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2973         int reason_code = -1;
2974         int i, ret = 0;
2975         ASN1_OBJECT *hold = NULL;
2976         ASN1_GENERALIZEDTIME *comp_time = NULL;
2977         tmp = BUF_strdup(str);
2978
2979         p = strchr(tmp, ',');
2980
2981         rtime_str = tmp;
2982
2983         if (p)
2984                 {
2985                 *p = '\0';
2986                 p++;
2987                 reason_str = p;
2988                 p = strchr(p, ',');
2989                 if (p)
2990                         {
2991                         *p = '\0';
2992                         arg_str = p + 1;
2993                         }
2994                 }
2995
2996         if (prevtm)
2997                 {
2998                 *prevtm = ASN1_UTCTIME_new();
2999                 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3000                         {
3001                         BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3002                         goto err;
3003                         }
3004                 }
3005         if (reason_str)
3006                 {
3007                 for (i = 0; i < NUM_REASONS; i++)
3008                         {
3009                         if(!strcasecmp(reason_str, crl_reasons[i]))
3010                                 {
3011                                 reason_code = i;
3012                                 break;
3013                                 }
3014                         }
3015                 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3016                         {
3017                         BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3018                         goto err;
3019                         }
3020
3021                 if (reason_code == 7)
3022                         reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3023                 else if (reason_code == 8)              /* Hold instruction */
3024                         {
3025                         if (!arg_str)
3026                                 {       
3027                                 BIO_printf(bio_err, "missing hold instruction\n");
3028                                 goto err;
3029                                 }
3030                         reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3031                         hold = OBJ_txt2obj(arg_str, 0);
3032
3033                         if (!hold)
3034                                 {
3035                                 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3036                                 goto err;
3037                                 }
3038                         if (phold) *phold = hold;
3039                         }
3040                 else if ((reason_code == 9) || (reason_code == 10))
3041                         {
3042                         if (!arg_str)
3043                                 {       
3044                                 BIO_printf(bio_err, "missing compromised time\n");
3045                                 goto err;
3046                                 }
3047                         comp_time = ASN1_GENERALIZEDTIME_new();
3048                         if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3049                                 {       
3050                                 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3051                                 goto err;
3052                                 }
3053                         if (reason_code == 9)
3054                                 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3055                         else
3056                                 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3057                         }
3058                 }
3059
3060         if (preason) *preason = reason_code;
3061         if (pinvtm) *pinvtm = comp_time;
3062         else ASN1_GENERALIZEDTIME_free(comp_time);
3063
3064         ret = 1;
3065
3066         err:
3067
3068         if (tmp) OPENSSL_free(tmp);
3069         if (!phold) ASN1_OBJECT_free(hold);
3070         if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3071
3072         return ret;
3073         }