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