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