Fix use before assignment
[openssl.git] / apps / ca.c
index 0e7bfdcbe32b36dfe3f20e90aba10f2906716374..1fb7b08f87084dc858e5cea485be65117520f43e 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1,58 +1,10 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
  *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
  */
 
 /* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
 
 /* Additional revocation information types */
 
-#define REV_NONE                0 /* No addditional information */
+#define REV_NONE                0 /* No additional information */
 #define REV_CRL_REASON          1 /* Value is CRL reason code */
 #define REV_HOLD                2 /* Value is hold instruction */
 #define REV_KEY_COMPROMISE      3 /* Value is cert key compromise time */
 #define REV_CA_COMPROMISE       4 /* Value is CA key compromise time */
 
-static void lookup_fail(const char *name, const char *tag);
-static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+static char *lookup_conf(const CONF *conf, const char *group, const char *tag);
+
+static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
                    const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
                    STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-                   BIGNUM *serial, char *subj, unsigned long chtype,
-                   int multirdn, int email_dn, char *startdate, char *enddate,
-                   long days, int batch, char *ext_sect, CONF *conf,
+                   BIGNUM *serial, const char *subj, unsigned long chtype,
+                   int multirdn, int email_dn, const char *startdate,
+                   const char *enddate,
+                   long days, int batch, const char *ext_sect, CONF *conf,
                    int verbose, unsigned long certopt, unsigned long nameopt,
                    int default_op, int ext_copy, int selfsign);
-static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
                         const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-                        BIGNUM *serial, char *subj, unsigned long chtype,
-                        int multirdn, int email_dn, char *startdate,
-                        char *enddate, long days, int batch, char *ext_sect,
+                        BIGNUM *serial, const char *subj, unsigned long chtype,
+                        int multirdn, int email_dn, const char *startdate,
+                        const char *enddate, long days, int batch, const char *ext_sect,
                         CONF *conf, int verbose, unsigned long certopt,
                         unsigned long nameopt, int default_op, int ext_copy);
-static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey,
+static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
                          X509 *x509, const EVP_MD *dgst,
                          STACK_OF(OPENSSL_STRING) *sigopts,
                          STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-                         BIGNUM *serial, char *subj, unsigned long chtype,
-                         int multirdn, int email_dn, char *startdate,
-                         char *enddate, long days, char *ext_sect, CONF *conf,
+                         BIGNUM *serial, const char *subj, unsigned long chtype,
+                         int multirdn, int email_dn, const char *startdate,
+                         const char *enddate, long days, const char *ext_sect, CONF *conf,
                          int verbose, unsigned long certopt,
                          unsigned long nameopt, int default_op, int ext_copy);
-static void write_new_certificate(BIO *bp, X509 *x, int output_der,
-                                  int notext);
+static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                    const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
                    STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
-                   char *subj, unsigned long chtype, int multirdn,
-                   int email_dn, char *startdate, char *enddate, long days,
-                   int batch, int verbose, X509_REQ *req, char *ext_sect,
+                   const char *subj, unsigned long chtype, int multirdn,
+                   int email_dn, const char *startdate, const char *enddate, long days,
+                   int batch, int verbose, X509_REQ *req, const char *ext_sect,
                    CONF *conf, unsigned long certopt, unsigned long nameopt,
                    int default_op, int ext_copy, int selfsign);
 static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
@@ -179,11 +132,9 @@ static int do_updatedb(CA_DB *db);
 static int check_time_format(const char *str);
 char *make_revocation_str(int rev_type, char *rev_arg);
 int make_revoked(X509_REVOKED *rev, const char *str);
-static int old_entry_print(ASN1_OBJECT *obj, ASN1_STRING *str);
+static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str);
 
-static CONF *conf = NULL;
 static CONF *extconf = NULL;
-static char *section = NULL;
 static int preserve = 0;
 static int msie_hack = 0;
 
@@ -209,7 +160,7 @@ OPTIONS ca_options[] = {
     {"subj", OPT_SUBJ, 's', "Use arg instead of request's subject"},
     {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
     {"create_serial", OPT_CREATE_SERIAL, '-',
-    "If reading serial fails, create a new random serial"},
+     "If reading serial fails, create a new random serial"},
     {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
      "Enable support for multivalued RDNs"},
     {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
@@ -244,7 +195,8 @@ OPTIONS ca_options[] = {
     {"spkac", OPT_SPKAC, '<',
      "File contains DN and signed public key and challenge"},
     {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"},
-    {"valid", OPT_VALID, 's'},
+    {"valid", OPT_VALID, 's',
+     "Add a Valid(not-revoked) DB entry about a cert (given in file)"},
     {"extensions", OPT_EXTENSIONS, 's',
      "Extension section (override value in config file)"},
     {"extfile", OPT_EXTFILE, '<',
@@ -268,10 +220,11 @@ OPTIONS ca_options[] = {
 
 int ca_main(int argc, char **argv)
 {
+    CONF *conf = NULL;
     ENGINE *e = NULL;
     BIGNUM *crlnumber = NULL, *serial = NULL;
     EVP_PKEY *pkey = NULL;
-    BIO *in = NULL, *out = NULL, *Sout = NULL, *Cout = NULL;
+    BIO *in = NULL, *out = NULL, *Sout = NULL;
     ASN1_INTEGER *tmpser;
     ASN1_TIME *tmptm;
     CA_DB *db = NULL;
@@ -281,15 +234,15 @@ int ca_main(int argc, char **argv)
     STACK_OF(X509) *cert_sk = NULL;
     X509_CRL *crl = NULL;
     const EVP_MD *dgst = NULL;
-    char *configfile = default_config_file;
+    char *configfile = default_config_file, *section = NULL;
     char *md = NULL, *policy = NULL, *keyfile = NULL;
-    char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL;
-    char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL;
-    char *extensions = NULL, *extfile = NULL, *key = NULL, *passinarg = NULL;
+    char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL, *key = NULL;
+    const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL;
+    const char *extensions = NULL, *extfile = NULL, *passinarg = NULL;
     char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
-    char *serialfile = NULL, *startdate = NULL, *subj = NULL;
-    char *prog, *enddate = NULL, *tmp_email_dn = NULL;
-    char *dbfile = NULL, *f, *randfile = NULL, *tofree = NULL;
+    const char *serialfile = NULL, *subj = NULL;
+    char *prog, *startdate = NULL, *enddate = NULL;
+    char *dbfile = NULL, *f, *randfile = NULL;
     char buf[3][BSIZE];
     char *const *pp;
     const char *p;
@@ -304,46 +257,41 @@ int ca_main(int argc, char **argv)
     X509_REVOKED *r = NULL;
     OPTION_CHOICE o;
 
-    conf = NULL;
-    section = NULL;
-    preserve = 0;
-    msie_hack = 0;
-
     prog = opt_init(argc, argv, ca_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
-            case OPT_EOF:
-            case OPT_ERR:
+        case OPT_EOF:
+        case OPT_ERR:
 opthelp:
-                BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-                goto end;
-            case OPT_HELP:
-                opt_help(ca_options);
-                ret = 0;
-                goto end;
-            case OPT_IN:
-                req = 1;
-                infile = opt_arg();
-                break;
-            case OPT_OUT:
-                outfile = opt_arg();
-                break;
-            case OPT_VERBOSE:
-                verbose = 1;
-                break;
-            case OPT_CONFIG:
-                configfile = opt_arg();
-                break;
-            case OPT_NAME:
-                section = opt_arg();
-                break;
-            case OPT_SUBJ:
-                subj = opt_arg();
-                /* preserve=1; */
-                break;
-            case OPT_UTF8:
-                chtype = MBSTRING_UTF8;
-                break;
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(ca_options);
+            ret = 0;
+            goto end;
+        case OPT_IN:
+            req = 1;
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_VERBOSE:
+            verbose = 1;
+            break;
+        case OPT_CONFIG:
+            configfile = opt_arg();
+            break;
+        case OPT_NAME:
+            section = opt_arg();
+            break;
+        case OPT_SUBJ:
+            subj = opt_arg();
+            /* preserve=1; */
+            break;
+        case OPT_UTF8:
+            chtype = MBSTRING_UTF8;
+            break;
         case OPT_CREATE_SERIAL:
             create_ser = 1;
             break;
@@ -481,22 +429,16 @@ end_of_options:
     argv = opt_rest();
 
     BIO_printf(bio_err, "Using configuration from %s\n", configfile);
-    /* We already loaded the default config file */
-    if (configfile != default_config_file) {
-        if ((conf = app_load_config(configfile)) == NULL)
-            goto end;
-        if (!app_load_modules(conf))
-            goto end;
-    }
+
+    if ((conf = app_load_config(configfile)) == NULL)
+        goto end;
+    if (configfile != default_config_file && !app_load_modules(conf))
+        goto end;
 
     /* Lets get the config section we are using */
-    if (section == NULL) {
-        section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_CA);
-        if (section == NULL) {
-            lookup_fail(BASE_SECTION, ENV_DEFAULT_CA);
-            goto end;
-        }
-    }
+    if (section == NULL
+        && (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL)
+        goto end;
 
     if (conf != NULL) {
         p = NCONF_get_string(conf, NULL, "oid_file");
@@ -552,13 +494,13 @@ end_of_options:
     } else
         ERR_clear_error();
 
-        /*****************************************************************/
+    /*****************************************************************/
     /* report status of cert with serial number given on command line */
     if (ser_status) {
-        if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) {
-            lookup_fail(section, ENV_DATABASE);
+        dbfile = lookup_conf(conf, section, ENV_DATABASE);
+        if (dbfile == NULL)
             goto end;
-        }
+
         db = load_index(dbfile, &db_attr);
         if (db == NULL)
             goto end;
@@ -571,16 +513,13 @@ end_of_options:
         goto end;
     }
 
-        /*****************************************************************/
+    /*****************************************************************/
     /* we definitely need a private key, so let's get it */
 
-    if ((keyfile == NULL) && ((keyfile = NCONF_get_string(conf,
-                                                          section,
-                                                          ENV_PRIVATE_KEY)) ==
-                              NULL)) {
-        lookup_fail(section, ENV_PRIVATE_KEY);
+    if (keyfile == NULL
+        && (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL)
         goto end;
-    }
+
     if (!key) {
         free_key = 1;
         if (!app_passwd(passinarg, NULL, &key, NULL)) {
@@ -596,16 +535,13 @@ end_of_options:
         goto end;
     }
 
-        /*****************************************************************/
+    /*****************************************************************/
     /* we need a certificate */
     if (!selfsign || spkac_file || ss_cert_file || gencrl) {
-        if ((certfile == NULL)
-            && ((certfile = NCONF_get_string(conf,
-                                             section,
-                                             ENV_CERTIFICATE)) == NULL)) {
-            lookup_fail(section, ENV_CERTIFICATE);
+        if (certfile == NULL
+            && (certfile = lookup_conf(conf, section, ENV_CERTIFICATE)) == NULL)
             goto end;
-        }
+
         x509 = load_cert(certfile, FORMAT_PEM, "CA certificate");
         if (x509 == NULL)
             goto end;
@@ -664,12 +600,12 @@ end_of_options:
     } else
         ERR_clear_error();
 
-        /*****************************************************************/
+    /*****************************************************************/
     /* lookup where to write new certificates */
     if ((outdir == NULL) && (req)) {
 
-        if ((outdir = NCONF_get_string(conf, section, ENV_NEW_CERTS_DIR))
-            == NULL) {
+        outdir = NCONF_get_string(conf, section, ENV_NEW_CERTS_DIR);
+        if (outdir == NULL) {
             BIO_printf(bio_err,
                        "there needs to be defined a directory for new certificate to be placed in\n");
             goto end;
@@ -690,12 +626,12 @@ end_of_options:
 #endif
     }
 
-        /*****************************************************************/
+    /*****************************************************************/
     /* we need to load the database file */
-    if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) {
-        lookup_fail(section, ENV_DATABASE);
+    dbfile = lookup_conf(conf, section, ENV_DATABASE);
+    if (dbfile == NULL)
         goto end;
-    }
+
     db = load_index(dbfile, &db_attr);
     if (db == NULL)
         goto end;
@@ -748,7 +684,7 @@ end_of_options:
     if (!index_index(db))
         goto end;
 
-        /*****************************************************************/
+    /*****************************************************************/
     /* Update the db file for expired certificates */
     if (doupdatedb) {
         if (verbose)
@@ -787,10 +723,11 @@ end_of_options:
                        extfile);
 
         /* We can have sections in the ext file */
-        if (!extensions
-            && !(extensions =
-                 NCONF_get_string(extconf, "default", "extensions")))
-            extensions = "default";
+        if (extensions == NULL) {
+            extensions = NCONF_get_string(extconf, "default", "extensions");
+            if (extensions == NULL)
+                extensions = "default";
+        }
     }
 
     /*****************************************************************/
@@ -801,12 +738,9 @@ end_of_options:
             goto end;
     }
 
-    if ((md == NULL) && ((md = NCONF_get_string(conf,
-                                                section,
-                                                ENV_DEFAULT_MD)) == NULL)) {
-        lookup_fail(section, ENV_DEFAULT_MD);
+    if (md == NULL
+        && (md = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL)
         goto end;
-    }
 
     if (strcmp(md, "default") == 0) {
         int def_nid;
@@ -822,31 +756,26 @@ end_of_options:
     }
 
     if (req) {
-        if ((email_dn == 1) && ((tmp_email_dn = NCONF_get_string(conf,
-                                                                 section,
-                                                                 ENV_DEFAULT_EMAIL_DN))
-                                != NULL)) {
-            if (strcmp(tmp_email_dn, "no") == 0)
+        if (email_dn == 1) {
+            char *tmp_email_dn = NULL;
+
+            tmp_email_dn = NCONF_get_string(conf, section, ENV_DEFAULT_EMAIL_DN);
+            if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0)
                 email_dn = 0;
         }
         if (verbose)
             BIO_printf(bio_err, "message digest is %s\n",
                        OBJ_nid2ln(EVP_MD_type(dgst)));
-        if ((policy == NULL) && ((policy = NCONF_get_string(conf,
-                                                            section,
-                                                            ENV_POLICY)) ==
-                                 NULL)) {
-            lookup_fail(section, ENV_POLICY);
+        if (policy == NULL
+            && (policy = lookup_conf(conf, section, ENV_POLICY)) == NULL)
             goto end;
-        }
+
         if (verbose)
             BIO_printf(bio_err, "policy is %s\n", policy);
 
-        if ((serialfile = NCONF_get_string(conf, section, ENV_SERIAL))
-            == NULL) {
-            lookup_fail(section, ENV_SERIAL);
+        serialfile = lookup_conf(conf, section, ENV_SERIAL);
+        if (serialfile == NULL)
             goto end;
-        }
 
         if (!extconf) {
             /*
@@ -1053,14 +982,14 @@ end_of_options:
         if (verbose)
             BIO_printf(bio_err, "writing new certificates\n");
         for (i = 0; i < sk_X509_num(cert_sk); i++) {
-            ASN1_INTEGER *serialNumber = X509_get_serialNumber(x);
+            BIO *Cout = NULL;
+            X509 *xi = sk_X509_value(cert_sk, i);
+            ASN1_INTEGER *serialNumber = X509_get_serialNumber(xi);
             int k;
             char *n;
 
-            x = sk_X509_value(cert_sk, i);
-
             j = ASN1_STRING_length(serialNumber);
-            p = (const char *)ASN1_STRING_data(serialNumber);
+            p = (const char *)ASN1_STRING_get0_data(serialNumber);
 
             if (strlen(outdir) >= (size_t)(j ? BSIZE - j * 2 - 6 : BSIZE - 8)) {
                 BIO_printf(bio_err, "certificate file name too long\n");
@@ -1100,8 +1029,9 @@ end_of_options:
                 perror(buf[2]);
                 goto end;
             }
-            write_new_certificate(Cout, x, 0, notext);
-            write_new_certificate(Sout, x, output_der, notext);
+            write_new_certificate(Cout, xi, 0, notext);
+            write_new_certificate(Sout, xi, output_der, notext);
+            BIO_free_all(Cout);
         }
 
         if (sk_X509_num(cert_sk)) {
@@ -1116,7 +1046,7 @@ end_of_options:
         }
     }
 
-        /*****************************************************************/
+    /*****************************************************************/
     if (gencrl) {
         int crl_v2 = 0;
         if (!crl_ext) {
@@ -1171,13 +1101,13 @@ end_of_options:
         if (tmptm == NULL)
             goto end;
         X509_gmtime_adj(tmptm, 0);
-        X509_CRL_set_lastUpdate(crl, tmptm);
+        X509_CRL_set1_lastUpdate(crl, tmptm);
         if (!X509_time_adj_ex(tmptm, crldays, crlhours * 60 * 60 + crlsec,
                               NULL)) {
             BIO_puts(bio_err, "error setting CRL nextUpdate\n");
             goto end;
         }
-        X509_CRL_set_nextUpdate(crl, tmptm);
+        X509_CRL_set1_nextUpdate(crl, tmptm);
 
         ASN1_TIME_free(tmptm);
 
@@ -1257,7 +1187,7 @@ end_of_options:
                 goto end;
 
     }
-        /*****************************************************************/
+    /*****************************************************************/
     if (dorevoke) {
         if (infile == NULL) {
             BIO_printf(bio_err, "no input files\n");
@@ -1283,11 +1213,9 @@ end_of_options:
             BIO_printf(bio_err, "Data Base Updated\n");
         }
     }
-        /*****************************************************************/
+    /*****************************************************************/
     ret = 0;
  end:
-    OPENSSL_free(tofree);
-    BIO_free_all(Cout);
     BIO_free_all(Sout);
     BIO_free_all(out);
     BIO_free_all(in);
@@ -1307,20 +1235,25 @@ end_of_options:
     X509_CRL_free(crl);
     NCONF_free(conf);
     NCONF_free(extconf);
+    release_engine(e);
     return (ret);
 }
 
-static void lookup_fail(const char *name, const char *tag)
+static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
 {
-    BIO_printf(bio_err, "variable lookup failed for %s::%s\n", name, tag);
+    char *entry = NCONF_get_string(conf, section, tag);
+    if (entry == NULL)
+        BIO_printf(bio_err, "variable lookup failed for %s::%s\n", section, tag);
+    return entry;
 }
 
-static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
                    const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
                    STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-                   BIGNUM *serial, char *subj, unsigned long chtype,
-                   int multirdn, int email_dn, char *startdate, char *enddate,
-                   long days, int batch, char *ext_sect, CONF *lconf,
+                   BIGNUM *serial, const char *subj, unsigned long chtype,
+                   int multirdn, int email_dn, const char *startdate,
+                   const char *enddate,
+                   long days, int batch, const char *ext_sect, CONF *lconf,
                    int verbose, unsigned long certopt, unsigned long nameopt,
                    int default_op, int ext_copy, int selfsign)
 {
@@ -1382,12 +1315,12 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
     return (ok);
 }
 
-static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
+static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
                         const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-                        BIGNUM *serial, char *subj, unsigned long chtype,
-                        int multirdn, int email_dn, char *startdate,
-                        char *enddate, long days, int batch, char *ext_sect,
+                        BIGNUM *serial, const char *subj, unsigned long chtype,
+                        int multirdn, int email_dn, const char *startdate,
+                        const char *enddate, long days, int batch, const char *ext_sect,
                         CONF *lconf, int verbose, unsigned long certopt,
                         unsigned long nameopt, int default_op, int ext_copy)
 {
@@ -1437,15 +1370,15 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                    const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
                    STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
-                   char *subj, unsigned long chtype, int multirdn,
-                   int email_dn, char *startdate, char *enddate, long days,
-                   int batch, int verbose, X509_REQ *req, char *ext_sect,
+                   const char *subj, unsigned long chtype, int multirdn,
+                   int email_dn, const char *startdate, const char *enddate, long days,
+                   int batch, int verbose, X509_REQ *req, const char *ext_sect,
                    CONF *lconf, unsigned long certopt, unsigned long nameopt,
                    int default_op, int ext_copy, int selfsign)
 {
     X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject =
         NULL;
-    ASN1_UTCTIME *tm, *tmptm;
+    const ASN1_TIME *tm;
     ASN1_STRING *str, *str2;
     ASN1_OBJECT *obj;
     X509 *ret = NULL;
@@ -1460,12 +1393,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
     OPENSSL_STRING *rrow = NULL;
     char buf[25];
 
-    tmptm = ASN1_UTCTIME_new();
-    if (tmptm == NULL) {
-        BIO_printf(bio_err, "malloc error\n");
-        return (0);
-    }
-
     for (i = 0; i < DB_NUMBER; i++)
         row[i] = NULL;
 
@@ -1601,7 +1528,8 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                 j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);
                 if ((j < 0) && (last2 == -1)) {
                     BIO_printf(bio_err,
-                               "The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",
+                               "The %s field does not exist in the CA certificate,\n"
+                               "the 'policy' is misconfigured\n",
                                cv->name);
                     goto end;
                 }
@@ -1615,7 +1543,8 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                 }
                 if (j < 0) {
                     BIO_printf(bio_err,
-                               "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",
+                               "The %s field is different between\n"
+                               "CA certificate (%s) and the request (%s)\n",
                                cv->name,
                                ((str2 == NULL) ? "NULL" : (char *)str2->data),
                                ((str == NULL) ? "NULL" : (char *)str->data));
@@ -1770,17 +1699,12 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
             goto end;
     }
 
-    if (strcmp(startdate, "today") == 0)
-        X509_gmtime_adj(X509_get_notBefore(ret), 0);
-    else
-        ASN1_TIME_set_string(X509_get_notBefore(ret), startdate);
+    if (!set_cert_times(ret, startdate, enddate, days))
+        goto end;
 
-    if (enddate == NULL)
-        X509_time_adj_ex(X509_get_notAfter(ret), days, 0, NULL);
-    else {
+    if (enddate != NULL) {
         int tdays;
-        ASN1_TIME_set_string(X509_get_notAfter(ret), enddate);
-        ASN1_TIME_diff(&tdays, NULL, NULL, X509_get_notAfter(ret));
+        ASN1_TIME_diff(&tdays, NULL, NULL, X509_get0_notAfter(ret));
         days = tdays;
     }
 
@@ -1866,7 +1790,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
     }
 
     BIO_printf(bio_err, "Certificate is to be certified until ");
-    ASN1_TIME_print(bio_err, X509_get_notAfter(ret));
+    ASN1_TIME_print(bio_err, X509_get0_notAfter(ret));
     if (days)
         BIO_printf(bio_err, " (%ld days)", days);
     BIO_printf(bio_err, "\n");
@@ -1899,7 +1823,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
 
     /* We now just add it to the database */
     row[DB_type] = OPENSSL_strdup("V");
-    tm = X509_get_notAfter(ret);
+    tm = X509_get0_notAfter(ret);
     row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");
     memcpy(row[DB_exp_date], tm->data, tm->length);
     row[DB_exp_date][tm->length] = '\0';
@@ -1934,7 +1858,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
     X509_NAME_free(subject);
     if (dn_subject != subject)
         X509_NAME_free(dn_subject);
-    ASN1_UTCTIME_free(tmptm);
     if (ok <= 0)
         X509_free(ret);
     else
@@ -1955,13 +1878,13 @@ static void write_new_certificate(BIO *bp, X509 *x, int output_der,
     PEM_write_bio_X509(bp, x);
 }
 
-static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey,
+static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
                          X509 *x509, const EVP_MD *dgst,
                          STACK_OF(OPENSSL_STRING) *sigopts,
                          STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-                         BIGNUM *serial, char *subj, unsigned long chtype,
-                         int multirdn, int email_dn, char *startdate,
-                         char *enddate, long days, char *ext_sect,
+                         BIGNUM *serial, const char *subj, unsigned long chtype,
+                         int multirdn, int email_dn, const char *startdate,
+                         const char *enddate, long days, const char *ext_sect,
                          CONF *lconf, int verbose, unsigned long certopt,
                          unsigned long nameopt, int default_op, int ext_copy)
 {
@@ -1993,7 +1916,6 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey,
     sk = CONF_get_section(parms, "default");
     if (sk_CONF_VALUE_num(sk) == 0) {
         BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
-        CONF_free(parms);
         goto end;
     }
 
@@ -2099,7 +2021,7 @@ static int check_time_format(const char *str)
 
 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
 {
-    ASN1_UTCTIME *tm = NULL;
+    const ASN1_TIME *tm = NULL;
     char *row[DB_NUMBER], **rrow, **irow;
     char *rev_str = NULL;
     BIGNUM *bn = NULL;
@@ -2132,7 +2054,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
 
         /* We now just add it to the database */
         row[DB_type] = OPENSSL_strdup("V");
-        tm = X509_get_notAfter(x509);
+        tm = X509_get0_notAfter(x509);
         row[DB_exp_date] = app_malloc(tm->length + 1, "row exp_data");
         memcpy(row[DB_exp_date], tm->data, tm->length);
         row[DB_exp_date][tm->length] = '\0';
@@ -2194,27 +2116,28 @@ static int get_certificate_status(const char *serial, CA_DB *db)
 {
     char *row[DB_NUMBER], **rrow;
     int ok = -1, i;
+    size_t serial_len = strlen(serial);
 
     /* Free Resources */
     for (i = 0; i < DB_NUMBER; i++)
         row[i] = NULL;
 
     /* Malloc needed char spaces */
-    row[DB_serial] = app_malloc(strlen(serial) + 2, "row serial#");
+    row[DB_serial] = app_malloc(serial_len + 2, "row serial#");
 
-    if (strlen(serial) % 2) {
+    if (serial_len % 2) {
         /*
          * Set the first char to 0
          */ ;
         row[DB_serial][0] = '0';
 
         /* Copy String from serial to row[DB_serial] */
-        memcpy(row[DB_serial] + 1, serial, strlen(serial));
-        row[DB_serial][strlen(serial) + 1] = '\0';
+        memcpy(row[DB_serial] + 1, serial, serial_len);
+        row[DB_serial][serial_len + 1] = '\0';
     } else {
         /* Copy String from serial to row[DB_serial] */
-        memcpy(row[DB_serial], serial, strlen(serial));
-        row[DB_serial][strlen(serial)] = '\0';
+        memcpy(row[DB_serial], serial, serial_len);
+        row[DB_serial][serial_len] = '\0';
     }
 
     /* Make it Upper Case */
@@ -2270,7 +2193,7 @@ static int do_updatedb(CA_DB *db)
 
     /* get actual time and make a string */
     a_tm = X509_gmtime_adj(a_tm, 0);
-    a_tm_s = (char *)app_malloc(a_tm->length + 1, "time string");
+    a_tm_s = app_malloc(a_tm->length + 1, "time string");
 
     memcpy(a_tm_s, a_tm->data, a_tm->length);
     a_tm_s[a_tm->length] = '\0';
@@ -2342,7 +2265,8 @@ static const char *crl_reasons[] = {
 
 char *make_revocation_str(int rev_type, char *rev_arg)
 {
-    char *other = NULL, *str;
+    char *str;
+    const char *other = NULL;
     const char *reason = NULL;
     ASN1_OBJECT *otmp;
     ASN1_UTCTIME *revtm = NULL;
@@ -2487,10 +2411,12 @@ int make_revoked(X509_REVOKED *rev, const char *str)
     return ret;
 }
 
-static int old_entry_print(ASN1_OBJECT *obj, ASN1_STRING *str)
+static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str)
 {
-    char buf[25], *pbuf, *p;
+    char buf[25], *pbuf;
+    const char *p;
     int j;
+
     j = i2a_ASN1_OBJECT(bio_err, obj);
     pbuf = buf;
     for (j = 22 - j; j > 0; j--)
@@ -2510,7 +2436,7 @@ static int old_entry_print(ASN1_OBJECT *obj, ASN1_STRING *str)
     else
         BIO_printf(bio_err, "ASN.1 %2d:'", str->type);
 
-    p = (char *)str->data;
+    p = (const char *)str->data;
     for (j = str->length; j > 0; j--) {
         if ((*p >= ' ') && (*p <= '~'))
             BIO_printf(bio_err, "%c", *p);