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