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