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