APPS: Remove unnecessary NULL check of uri in load_cert_pass()
[openssl.git] / apps / lib / apps.c
index 3a9521f67e4539b7cd7ac763bb58f94d07a72143..6fd27c3665a744ca40b1dff81795b758ab27bd1f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -29,6 +29,7 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/pem.h>
+#include <openssl/store.h>
 #include <openssl/pkcs12.h>
 #include <openssl/ui.h>
 #include <openssl/safestack.h>
@@ -57,6 +58,17 @@ static int WIN32_rename(const char *from, const char *to);
 
 #define PASS_SOURCE_SIZE_MAX 4
 
+DEFINE_STACK_OF(CONF)
+DEFINE_STACK_OF(CONF_VALUE)
+DEFINE_STACK_OF(X509)
+DEFINE_STACK_OF(X509_CRL)
+DEFINE_STACK_OF(X509_INFO)
+DEFINE_STACK_OF(X509_EXTENSION)
+DEFINE_STACK_OF(X509_POLICY_NODE)
+DEFINE_STACK_OF(GENERAL_NAME)
+DEFINE_STACK_OF(DIST_POINT)
+DEFINE_STACK_OF_STRING()
+
 typedef struct {
     const char *name;
     unsigned long flag;
@@ -198,6 +210,24 @@ int wrap_password_callback(char *buf, int bufsiz, int verify, void *userdata)
 
 static char *app_get_pass(const char *arg, int keepbio);
 
+char *get_passwd(const char *pass, const char *desc)
+{
+    char *result = NULL;
+
+    if (desc == NULL)
+        desc = "<unknown>";
+    if (!app_passwd(pass, NULL, &result, NULL))
+        BIO_printf(bio_err, "Error getting password for %s\n", desc);
+    if (pass != NULL && result == NULL) {
+        BIO_printf(bio_err,
+                   "Trying plain input string (better precede with 'pass:')\n");
+        result = OPENSSL_strdup(pass);
+        if (result == NULL)
+            BIO_printf(bio_err, "Out of memory getting password for %s\n", desc);
+    }
+    return result;
+}
+
 int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2)
 {
     int same = arg1 != NULL && arg2 != NULL && strcmp(arg1, arg2) == 0;
@@ -401,276 +431,158 @@ int add_oid_section(CONF *conf)
     return 1;
 }
 
-static int load_pkcs12(BIO *in, const char *desc,
-                       pem_password_cb *pem_cb, PW_CB_DATA *cb_data,
-                       EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
+X509 *load_cert_pass(const char *uri, int maybe_stdin,
+                     const char *pass, const char *desc)
 {
-    const char *pass;
-    char tpass[PEM_BUFSIZE];
-    int len, ret = 0;
-    PKCS12 *p12;
-    p12 = d2i_PKCS12_bio(in, NULL);
-    if (p12 == NULL) {
-        BIO_printf(bio_err, "Error loading PKCS12 file for %s\n", desc);
-        goto die;
-    }
-    /* See if an empty password will do */
-    if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) {
-        pass = "";
-    } else {
-        if (pem_cb == NULL)
-            pem_cb = (pem_password_cb *)password_callback;
-        len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
-        if (len < 0) {
-            BIO_printf(bio_err, "Passphrase callback error for %s\n", desc);
-            goto die;
-        }
-        if (len < PEM_BUFSIZE)
-            tpass[len] = 0;
-        if (!PKCS12_verify_mac(p12, tpass, len)) {
-            BIO_printf(bio_err,
-                       "Mac verify error (wrong password?) in PKCS12 file for %s\n",
-                       desc);
-            goto die;
-        }
-        pass = tpass;
+    X509 *cert = NULL;
+
+    if (desc == NULL)
+        desc = "certificate";
+    (void)load_key_cert_crl(uri, maybe_stdin, pass, desc, NULL, &cert, NULL);
+    if (cert == NULL) {
+        BIO_printf(bio_err, "Unable to load %s\n", desc);
+        ERR_print_errors(bio_err);
     }
-    ret = PKCS12_parse(p12, pass, pkey, cert, ca);
- die:
-    PKCS12_free(p12);
-    return ret;
+    return cert;
 }
 
-X509 *load_cert(const char *file, int format, const char *cert_descrip)
+/* the format parameter is meanwhile not needed anymore and thus ignored */
+X509 *load_cert(const char *uri, int format, const char *desc)
 {
-    X509 *x = NULL;
-    BIO *cert;
-
-    if (format == FORMAT_HTTP) {
-#if !defined(OPENSSL_NO_SOCK)
-        x = X509_load_http(file, NULL, NULL, 0 /* timeout */);
-#endif
-        return x;
-    }
+    return load_cert_pass(uri, 1, NULL, desc);
+}
 
-    if (file == NULL) {
-        unbuffer(stdin);
-        cert = dup_bio_in(format);
-    } else {
-        cert = bio_open_default(file, 'r', format);
-    }
-    if (cert == NULL)
-        goto end;
+/* the format parameter is meanwhile not needed anymore and thus ignored */
+X509_CRL *load_crl(const char *uri, int format, const char *desc)
+{
+    X509_CRL *crl = NULL;
 
-    if (format == FORMAT_ASN1) {
-        x = d2i_X509_bio(cert, NULL);
-    } else if (format == FORMAT_PEM) {
-        x = PEM_read_bio_X509_AUX(cert, NULL,
-                                  (pem_password_cb *)password_callback, NULL);
-    } else if (format == FORMAT_PKCS12) {
-        if (!load_pkcs12(cert, cert_descrip, NULL, NULL, NULL, &x, NULL))
-            goto end;
-    } else {
-        BIO_printf(bio_err, "bad input format specified for %s\n", cert_descrip);
-        goto end;
-    }
- end:
-    if (x == NULL) {
-        BIO_printf(bio_err, "unable to load certificate\n");
+    if (desc == NULL)
+        desc = "CRL";
+    (void)load_key_cert_crl(uri, 0, NULL, desc, NULL, NULL, &crl);
+    if (crl == NULL) {
+        BIO_printf(bio_err, "Unable to load %s\n", desc);
         ERR_print_errors(bio_err);
     }
-    BIO_free(cert);
-    return x;
+    return crl;
 }
 
-X509_CRL *load_crl(const char *infile, int format)
+X509_REQ *load_csr(const char *file, int format, const char *desc)
 {
-    X509_CRL *x = NULL;
-    BIO *in = NULL;
-
-    if (format == FORMAT_HTTP) {
-#if !defined(OPENSSL_NO_SOCK)
-        x = X509_CRL_load_http(infile, NULL, NULL, 0 /* timeout */);
-#endif
-        return x;
-    }
+    X509_REQ *req = NULL;
+    BIO *in;
 
-    in = bio_open_default(infile, 'r', format);
+    if (desc == NULL)
+        desc = "CSR";
+    in = bio_open_default(file, 'r', format);
     if (in == NULL)
         goto end;
-    if (format == FORMAT_ASN1) {
-        x = d2i_X509_CRL_bio(in, NULL);
-    } else if (format == FORMAT_PEM) {
-        x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
-    } else {
-        BIO_printf(bio_err, "bad input format specified for input crl\n");
-        goto end;
-    }
-    if (x == NULL) {
-        BIO_printf(bio_err, "unable to load CRL\n");
-        ERR_print_errors(bio_err);
-        goto end;
-    }
+
+    if (format == FORMAT_ASN1)
+        req = d2i_X509_REQ_bio(in, NULL);
+    else if (format == FORMAT_PEM)
+        req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
+    else
+        print_format_error(format, OPT_FMT_PEMDER);
 
  end:
+    if (req == NULL) {
+        BIO_printf(bio_err, "Unable to load %s\n", desc);
+        ERR_print_errors(bio_err);
+    }
     BIO_free(in);
-    return x;
+    return req;
+}
+
+void cleanse(char *str)
+{
+    if (str != NULL)
+        OPENSSL_cleanse(str, strlen(str));
 }
 
-EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
-                   const char *pass, ENGINE *e, const char *key_descrip)
+void clear_free(char *str)
+{
+    if (str != NULL)
+        OPENSSL_clear_free(str, strlen(str));
+}
+
+EVP_PKEY *load_key(const char *uri, int format, int may_stdin,
+                   const char *pass, ENGINE *e, const char *desc)
 {
-    BIO *key = NULL;
     EVP_PKEY *pkey = NULL;
-    PW_CB_DATA cb_data;
 
-    cb_data.password = pass;
-    cb_data.prompt_info = file;
+    if (desc == NULL)
+        desc = "private key";
 
-    if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
-        BIO_printf(bio_err, "no keyfile specified\n");
-        goto end;
-    }
     if (format == FORMAT_ENGINE) {
         if (e == NULL) {
-            BIO_printf(bio_err, "no engine specified\n");
+            BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
         } else {
 #ifndef OPENSSL_NO_ENGINE
+            PW_CB_DATA cb_data;
+
+            cb_data.password = pass;
+            cb_data.prompt_info = uri;
             if (ENGINE_init(e)) {
-                pkey = ENGINE_load_private_key(e, file,
+                pkey = ENGINE_load_private_key(e, uri,
                                                (UI_METHOD *)get_ui_method(),
                                                &cb_data);
                 ENGINE_finish(e);
             }
             if (pkey == NULL) {
-                BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip);
+                BIO_printf(bio_err, "Cannot load %s from engine\n", desc);
                 ERR_print_errors(bio_err);
             }
 #else
-            BIO_printf(bio_err, "engines not supported\n");
+            BIO_printf(bio_err, "Engines not supported for loading %s\n", desc);
 #endif
         }
-        goto end;
-    }
-    if (file == NULL && maybe_stdin) {
-        unbuffer(stdin);
-        key = dup_bio_in(format);
     } else {
-        key = bio_open_default(file, 'r', format);
-    }
-    if (key == NULL)
-        goto end;
-    if (format == FORMAT_ASN1) {
-        pkey = d2i_PrivateKey_bio(key, NULL);
-    } else if (format == FORMAT_PEM) {
-        pkey = PEM_read_bio_PrivateKey(key, NULL, wrap_password_callback, &cb_data);
-    } else if (format == FORMAT_PKCS12) {
-        if (!load_pkcs12(key, key_descrip, wrap_password_callback, &cb_data,
-                         &pkey, NULL, NULL))
-            goto end;
-#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
-    } else if (format == FORMAT_MSBLOB) {
-        pkey = b2i_PrivateKey_bio(key);
-    } else if (format == FORMAT_PVK) {
-        pkey = b2i_PVK_bio(key, wrap_password_callback, &cb_data);
-#endif
-    } else {
-        BIO_printf(bio_err, "bad input format specified for key file\n");
-        goto end;
+        (void)load_key_cert_crl(uri, may_stdin, pass, desc, &pkey, NULL, NULL);
     }
- end:
-    BIO_free(key);
+
     if (pkey == NULL) {
-        BIO_printf(bio_err, "unable to load %s\n", key_descrip);
+        BIO_printf(bio_err, "Unable to load %s\n", desc);
         ERR_print_errors(bio_err);
     }
     return pkey;
 }
 
-EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
-                      const char *pass, ENGINE *e, const char *key_descrip)
+EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
+                      const char *pass, ENGINE *e, const char *desc)
 {
-    BIO *key = NULL;
     EVP_PKEY *pkey = NULL;
-    PW_CB_DATA cb_data;
 
-    cb_data.password = pass;
-    cb_data.prompt_info = file;
+    if (desc == NULL)
+        desc = "public key";
 
-    if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
-        BIO_printf(bio_err, "no keyfile specified\n");
-        goto end;
-    }
     if (format == FORMAT_ENGINE) {
         if (e == NULL) {
-            BIO_printf(bio_err, "no engine specified\n");
+            BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
         } else {
 #ifndef OPENSSL_NO_ENGINE
-            pkey = ENGINE_load_public_key(e, file, (UI_METHOD *)get_ui_method(),
+            PW_CB_DATA cb_data;
+
+            cb_data.password = pass;
+            cb_data.prompt_info = uri;
+            pkey = ENGINE_load_public_key(e, uri, (UI_METHOD *)get_ui_method(),
                                           &cb_data);
             if (pkey == NULL) {
-                BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip);
+                BIO_printf(bio_err, "Cannot load %s from engine\n", desc);
                 ERR_print_errors(bio_err);
             }
 #else
-            BIO_printf(bio_err, "engines not supported\n");
+            BIO_printf(bio_err, "Engines not supported for loading %s\n", desc);
 #endif
         }
-        goto end;
-    }
-    if (file == NULL && maybe_stdin) {
-        unbuffer(stdin);
-        key = dup_bio_in(format);
     } else {
-        key = bio_open_default(file, 'r', format);
+        (void)load_key_cert_crl(uri, maybe_stdin, pass, desc, &pkey,
+                                NULL, NULL);
     }
-    if (key == NULL)
-        goto end;
-    if (format == FORMAT_ASN1) {
-        pkey = d2i_PUBKEY_bio(key, NULL);
-    } else if (format == FORMAT_ASN1RSA) {
-#ifndef OPENSSL_NO_RSA
-        RSA *rsa;
-        rsa = d2i_RSAPublicKey_bio(key, NULL);
-        if (rsa) {
-            pkey = EVP_PKEY_new();
-            if (pkey != NULL)
-                EVP_PKEY_set1_RSA(pkey, rsa);
-            RSA_free(rsa);
-        } else
-#else
-        BIO_printf(bio_err, "RSA keys not supported\n");
-#endif
-            pkey = NULL;
-    } else if (format == FORMAT_PEMRSA) {
-#ifndef OPENSSL_NO_RSA
-        RSA *rsa;
-        rsa = PEM_read_bio_RSAPublicKey(key, NULL,
-                                        (pem_password_cb *)password_callback,
-                                        &cb_data);
-        if (rsa != NULL) {
-            pkey = EVP_PKEY_new();
-            if (pkey != NULL)
-                EVP_PKEY_set1_RSA(pkey, rsa);
-            RSA_free(rsa);
-        } else
-#else
-        BIO_printf(bio_err, "RSA keys not supported\n");
-#endif
-            pkey = NULL;
-    } else if (format == FORMAT_PEM) {
-        pkey = PEM_read_bio_PUBKEY(key, NULL,
-                                   (pem_password_cb *)password_callback,
-                                   &cb_data);
-#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
-    } else if (format == FORMAT_MSBLOB) {
-        pkey = b2i_PublicKey_bio(key);
-#endif
+    if (pkey == NULL) {
+        BIO_printf(bio_err, "Unable to load %s\n", desc);
+        ERR_print_errors(bio_err);
     }
- end:
-    BIO_free(key);
-    if (pkey == NULL)
-        BIO_printf(bio_err, "unable to load %s\n", key_descrip);
     return pkey;
 }
 
@@ -690,7 +602,7 @@ static int load_certs_crls(const char *file, int format,
     cb_data.prompt_info = file;
 
     if (format != FORMAT_PEM) {
-        BIO_printf(bio_err, "bad input format specified for %s\n", desc);
+        BIO_printf(bio_err, "Bad input format specified for %s\n", desc);
         return 0;
     }
 
@@ -749,23 +661,30 @@ static int load_certs_crls(const char *file, int format,
             sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
             *pcrls = NULL;
         }
-        BIO_printf(bio_err, "unable to load %s\n",
-                   pcerts ? "certificates" : "CRLs");
-        ERR_print_errors(bio_err);
+        BIO_printf(bio_err, "Unable to load %s\n", desc != NULL ? desc :
+                   pcerts != NULL ? "certificates" : "CRLs");
     }
     return rv;
 }
 
+void app_bail_out(char *fmt, ...)
+{
+    va_list args;
+
+    va_start(args, fmt);
+    BIO_vprintf(bio_err, fmt, args);
+    va_end(args);
+    ERR_print_errors(bio_err);
+    exit(1);
+}
+
 void* app_malloc(int sz, const char *what)
 {
     void *vp = OPENSSL_malloc(sz);
 
-    if (vp == NULL) {
-        BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n",
-                opt_getprog(), sz, what);
-        ERR_print_errors(bio_err);
-        exit(1);
-    }
+    if (vp == NULL)
+        app_bail_out("%s: Could not allocate %d bytes for %s\n",
+                     opt_getprog(), sz, what);
     return vp;
 }
 
@@ -787,6 +706,102 @@ int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format,
     return load_certs_crls(file, format, pass, desc, NULL, crls);
 }
 
+/*
+ * Load those types of credentials for which the result pointer is not NULL.
+ * Reads from stdio if uri is NULL and maybe_stdin is nonzero.
+ * For each type the first credential found in the store is loaded.
+ * May yield partial result even if rv == 0.
+ */
+int load_key_cert_crl(const char *uri, int maybe_stdin,
+                      const char *pass, const char *desc,
+                      EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl)
+{
+    PW_CB_DATA uidata;
+    OSSL_STORE_CTX *ctx = NULL;
+    int ret = 0;
+    /* TODO make use of the engine reference 'eng' when loading pkeys */
+
+    if (ppkey != NULL)
+        *ppkey = NULL;
+    if (pcert != NULL)
+        *pcert = NULL;
+    if (pcrl != NULL)
+        *pcrl = NULL;
+
+    if (desc == NULL)
+        desc = "key/certificate/CRL";
+    uidata.password = pass;
+    uidata.prompt_info = uri;
+
+    if (uri == NULL) {
+        BIO *bio;
+
+        if (!maybe_stdin) {
+            BIO_printf(bio_err, "No filename or uri specified for loading %s\n",
+                       desc);
+            goto end;
+        }
+        unbuffer(stdin);
+        bio = BIO_new_fp(stdin, 0);
+        if (bio != NULL)
+            ctx = OSSL_STORE_attach(bio, NULL, "file", NULL,
+                                    get_ui_method(), &uidata, NULL, NULL);
+        uri = "<stdin>";
+    } else {
+        ctx = OSSL_STORE_open(uri, get_ui_method(), &uidata, NULL, NULL);
+    }
+    if (ctx == NULL) {
+        BIO_printf(bio_err, "Could not open file or uri %s for loading %s\n",
+                   uri, desc);
+        goto end;
+    }
+
+    for (;;) {
+        OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
+        int type = info == NULL ? 0 : OSSL_STORE_INFO_get_type(info);
+        const char *infostr =
+            info == NULL ? NULL : OSSL_STORE_INFO_type_string(type);
+        int err = 0;
+
+        if (info == NULL) {
+            if (OSSL_STORE_eof(ctx))
+                ret = 1;
+            break;
+        }
+
+        switch (type) {
+        case OSSL_STORE_INFO_PKEY:
+            if (ppkey != NULL && *ppkey == NULL)
+                err = ((*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) == NULL);
+            break;
+        case OSSL_STORE_INFO_CERT:
+            if (pcert != NULL && *pcert == NULL)
+                err = ((*pcert = OSSL_STORE_INFO_get1_CERT(info)) == NULL);
+            break;
+        case OSSL_STORE_INFO_CRL:
+            if (pcrl != NULL && *pcrl == NULL)
+                err = ((*pcrl = OSSL_STORE_INFO_get1_CRL(info)) == NULL);
+            break;
+        default:
+            /* skip any other type */
+            break;
+        }
+        OSSL_STORE_INFO_free(info);
+        if (err) {
+            BIO_printf(bio_err, "Could not read %s of %s from %s\n",
+                       infostr, desc, uri);
+            break;
+        }
+    }
+
+ end:
+    OSSL_STORE_close(ctx);
+    if (!ret)
+        ERR_print_errors(bio_err);
+    return ret;
+}
+
+
 #define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
 /* Return error for unknown extensions */
 #define X509V3_EXT_DEFAULT              0
@@ -968,7 +983,7 @@ static int set_table_opts(unsigned long *flags, const char *arg,
     return 0;
 }
 
-void print_name(BIO *out, const char *title, X509_NAME *nm,
+void print_name(BIO *out, const char *title, const X509_NAME *nm,
                 unsigned long lflags)
 {
     char *buf;
@@ -1083,6 +1098,7 @@ X509_STORE *setup_verify(const char *CAfile, int noCAfile,
     ERR_clear_error();
     return store;
  end:
+    ERR_print_errors(bio_err);
     X509_STORE_free(store);
     return NULL;
 }
@@ -1103,36 +1119,35 @@ static ENGINE *try_load_engine(const char *engine)
 }
 #endif
 
-ENGINE *setup_engine(const char *engine, int debug)
+ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug)
 {
     ENGINE *e = NULL;
 
 #ifndef OPENSSL_NO_ENGINE
-    if (engine != NULL) {
-        if (strcmp(engine, "auto") == 0) {
-            BIO_printf(bio_err, "enabling auto ENGINE support\n");
+    if (id != NULL) {
+        if (strcmp(id, "auto") == 0) {
+            BIO_printf(bio_err, "Enabling auto ENGINE support\n");
             ENGINE_register_all_complete();
             return NULL;
         }
-        if ((e = ENGINE_by_id(engine)) == NULL
-            && (e = try_load_engine(engine)) == NULL) {
-            BIO_printf(bio_err, "invalid engine \"%s\"\n", engine);
+        if ((e = ENGINE_by_id(id)) == NULL
+            && (e = try_load_engine(id)) == NULL) {
+            BIO_printf(bio_err, "Invalid engine \"%s\"\n", id);
             ERR_print_errors(bio_err);
             return NULL;
         }
-        if (debug) {
-            ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0);
-        }
-        ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, (void *)get_ui_method(),
-                        0, 1);
-        if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
-            BIO_printf(bio_err, "can't use that engine\n");
+        if (debug)
+            (void)ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0);
+        if (!ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0,
+                             (void *)get_ui_method(), 0, 1)
+                || !ENGINE_set_default(e, methods)) {
+            BIO_printf(bio_err, "Cannot use engine \"%s\"\n", ENGINE_get_id(e));
             ERR_print_errors(bio_err);
             ENGINE_free(e);
             return NULL;
         }
 
-        BIO_printf(bio_err, "engine \"%s\" set.\n", ENGINE_get_id(e));
+        BIO_printf(bio_err, "Engine \"%s\" set.\n", ENGINE_get_id(e));
     }
 #endif
     return e;
@@ -1211,14 +1226,13 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai)
             BIO_printf(bio_err, "Out of memory\n");
     } else {
         if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
-            BIO_printf(bio_err, "unable to load number from %s\n",
+            BIO_printf(bio_err, "Unable to load number from %s\n",
                        serialfile);
             goto err;
         }
         ret = ASN1_INTEGER_to_BN(ai, NULL);
         if (ret == NULL) {
-            BIO_printf(bio_err,
-                       "error converting number from bin to BIGNUM\n");
+            BIO_printf(bio_err, "Error converting number from bin to BIGNUM\n");
             goto err;
         }
     }
@@ -1228,6 +1242,7 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai)
         ai = NULL;
     }
  err:
+    ERR_print_errors(bio_err);
     BIO_free(in);
     ASN1_INTEGER_free(ai);
     return ret;
@@ -1247,7 +1262,7 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial
     else
         j = strlen(serialfile) + strlen(suffix) + 1;
     if (j >= BSIZE) {
-        BIO_printf(bio_err, "file name too long\n");
+        BIO_printf(bio_err, "File name too long\n");
         goto err;
     }
 
@@ -1262,7 +1277,6 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial
     }
     out = BIO_new_file(buf[0], "w");
     if (out == NULL) {
-        ERR_print_errors(bio_err);
         goto err;
     }
 
@@ -1278,6 +1292,8 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial
         ai = NULL;
     }
  err:
+    if (!ret)
+        ERR_print_errors(bio_err);
     BIO_free_all(out);
     ASN1_INTEGER_free(ai);
     return ret;
@@ -1294,7 +1310,7 @@ int rotate_serial(const char *serialfile, const char *new_suffix,
     if (i > j)
         j = i;
     if (j + 1 >= BSIZE) {
-        BIO_printf(bio_err, "file name too long\n");
+        BIO_printf(bio_err, "File name too long\n");
         goto err;
     }
 #ifndef OPENSSL_SYS_VMS
@@ -1310,19 +1326,20 @@ int rotate_serial(const char *serialfile, const char *new_suffix,
 #endif
         ) {
         BIO_printf(bio_err,
-                   "unable to rename %s to %s\n", serialfile, buf[1]);
+                   "Unable to rename %s to %s\n", serialfile, buf[1]);
         perror("reason");
         goto err;
     }
     if (rename(buf[0], serialfile) < 0) {
         BIO_printf(bio_err,
-                   "unable to rename %s to %s\n", buf[0], serialfile);
+                   "Unable to rename %s to %s\n", buf[0], serialfile);
         perror("reason");
         rename(buf[1], serialfile);
         goto err;
     }
     return 1;
  err:
+    ERR_print_errors(bio_err);
     return 0;
 }
 
@@ -1363,17 +1380,14 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
 #endif
 
     in = BIO_new_file(dbfile, "r");
-    if (in == NULL) {
-        ERR_print_errors(bio_err);
+    if (in == NULL)
         goto err;
-    }
 
 #ifndef OPENSSL_NO_POSIX_IO
     BIO_get_fp(in, &dbfp);
     if (fstat(fileno(dbfp), &dbst) == -1) {
         ERR_raise_data(ERR_LIB_SYS, errno,
                        "calling fstat(%s)", dbfile);
-        ERR_print_errors(bio_err);
         goto err;
     }
 #endif
@@ -1410,6 +1424,7 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
 #endif
 
  err:
+    ERR_print_errors(bio_err);
     NCONF_free(dbattr_conf);
     TXT_DB_free(tmpdb);
     BIO_free_all(in);
@@ -1425,20 +1440,23 @@ int index_index(CA_DB *db)
                              LHASH_HASH_FN(index_serial),
                              LHASH_COMP_FN(index_serial))) {
         BIO_printf(bio_err,
-                   "error creating serial number index:(%ld,%ld,%ld)\n",
+                   "Error creating serial number index:(%ld,%ld,%ld)\n",
                    db->db->error, db->db->arg1, db->db->arg2);
-        return 0;
+        goto err;
     }
 
     if (db->attributes.unique_subject
         && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
                                 LHASH_HASH_FN(index_name),
                                 LHASH_COMP_FN(index_name))) {
-        BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
+        BIO_printf(bio_err, "Error creating name index:(%ld,%ld,%ld)\n",
                    db->db->error, db->db->arg1, db->db->arg2);
-        return 0;
+        goto err;
     }
     return 1;
+ err:
+    ERR_print_errors(bio_err);
+    return 0;
 }
 
 int save_index(const char *dbfile, const char *suffix, CA_DB *db)
@@ -1449,7 +1467,7 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db)
 
     j = strlen(dbfile) + strlen(suffix);
     if (j + 6 >= BSIZE) {
-        BIO_printf(bio_err, "file name too long\n");
+        BIO_printf(bio_err, "File name too long\n");
         goto err;
     }
 #ifndef OPENSSL_SYS_VMS
@@ -1464,7 +1482,7 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db)
     out = BIO_new_file(buf[0], "w");
     if (out == NULL) {
         perror(dbfile);
-        BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
+        BIO_printf(bio_err, "Unable to open '%s'\n", dbfile);
         goto err;
     }
     j = TXT_DB_write(out, db->db);
@@ -1475,7 +1493,7 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db)
     out = BIO_new_file(buf[1], "w");
     if (out == NULL) {
         perror(buf[2]);
-        BIO_printf(bio_err, "unable to open '%s'\n", buf[2]);
+        BIO_printf(bio_err, "Unable to open '%s'\n", buf[2]);
         goto err;
     }
     BIO_printf(out, "unique_subject = %s\n",
@@ -1484,6 +1502,7 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db)
 
     return 1;
  err:
+    ERR_print_errors(bio_err);
     return 0;
 }
 
@@ -1498,7 +1517,7 @@ int rotate_index(const char *dbfile, const char *new_suffix,
     if (i > j)
         j = i;
     if (j + 6 >= BSIZE) {
-        BIO_printf(bio_err, "file name too long\n");
+        BIO_printf(bio_err, "File name too long\n");
         goto err;
     }
 #ifndef OPENSSL_SYS_VMS
@@ -1519,12 +1538,12 @@ int rotate_index(const char *dbfile, const char *new_suffix,
         && errno != ENOTDIR
 #endif
         ) {
-        BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]);
+        BIO_printf(bio_err, "Unable to rename %s to %s\n", dbfile, buf[1]);
         perror("reason");
         goto err;
     }
     if (rename(buf[0], dbfile) < 0) {
-        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[0], dbfile);
+        BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[0], dbfile);
         perror("reason");
         rename(buf[1], dbfile);
         goto err;
@@ -1534,14 +1553,14 @@ int rotate_index(const char *dbfile, const char *new_suffix,
         && errno != ENOTDIR
 #endif
         ) {
-        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]);
+        BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[4], buf[3]);
         perror("reason");
         rename(dbfile, buf[0]);
         rename(buf[1], dbfile);
         goto err;
     }
     if (rename(buf[2], buf[4]) < 0) {
-        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[2], buf[4]);
+        BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[2], buf[4]);
         perror("reason");
         rename(buf[3], buf[4]);
         rename(dbfile, buf[0]);
@@ -1550,6 +1569,7 @@ int rotate_index(const char *dbfile, const char *new_suffix,
     }
     return 1;
  err:
+    ERR_print_errors(bio_err);
     return 0;
 }
 
@@ -1640,7 +1660,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
             }
             if (*cp == '\\' && *++cp == '\0') {
                 BIO_printf(bio_err,
-                           "%s: escape character at end of string\n",
+                           "%s: Escape character at end of string\n",
                            opt_getprog());
                 goto err;
             }
@@ -1889,18 +1909,18 @@ static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
         DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
         urlptr = get_dp_url(dp);
         if (urlptr)
-            return load_crl(urlptr, FORMAT_HTTP);
+            return load_crl(urlptr, FORMAT_HTTP, "CRL via CDP");
     }
     return NULL;
 }
 
 /*
- * Example of downloading CRLs from CRLDP: not usable for real world as it
- * always downloads, doesn't support non-blocking I/O and doesn't cache
- * anything.
+ * Example of downloading CRLs from CRLDP:
+ * not usable for real world as it always downloads and doesn't cache anything.
  */
 
-static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm)
+static STACK_OF(X509_CRL) *crls_http_cb(const X509_STORE_CTX *ctx,
+                                        const X509_NAME *nm)
 {
     X509 *x;
     STACK_OF(X509_CRL) *crls = NULL;
@@ -1989,7 +2009,7 @@ BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
     } else if (!connect && !detail) { /* disconnecting after error */
         const char *hint = tls_error_hint();
         if (hint != NULL)
-            ERR_add_error_data(1, hint);
+            ERR_add_error_data(2, " : ", hint);
         /*
          * If we pop sbio and BIO_free() it this may lead to libssl double free.
          * Rely on BIO_free_all() done by OSSL_HTTP_transfer() in http_client.c
@@ -1999,7 +2019,7 @@ BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
 }
 
 ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
-                              const char *proxy_port, SSL_CTX *ssl_ctx,
+                              const char *no_proxy, SSL_CTX *ssl_ctx,
                               const STACK_OF(CONF_VALUE) *headers,
                               long timeout, const char *expected_content_type,
                               const ASN1_ITEM *it)
@@ -2028,7 +2048,7 @@ ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
     info.use_proxy = proxy != NULL;
     info.timeout = timeout;
     info.ssl_ctx = ssl_ctx;
-    resp = OSSL_HTTP_get_asn1(url, proxy, proxy_port,
+    resp = OSSL_HTTP_get_asn1(url, proxy, no_proxy,
                               NULL, NULL, app_http_tls_cb, &info,
                               headers, 0 /* maxline */, 0 /* max_resp_len */,
                               timeout, expected_content_type, it);
@@ -2041,7 +2061,7 @@ ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
 
 ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
                                const char *path, const char *proxy,
-                               const char *proxy_port, SSL_CTX *ssl_ctx,
+                               const char *no_proxy, SSL_CTX *ssl_ctx,
                                const STACK_OF(CONF_VALUE) *headers,
                                const char *content_type,
                                ASN1_VALUE *req, const ASN1_ITEM *req_it,
@@ -2055,7 +2075,7 @@ ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
     info.timeout = timeout;
     info.ssl_ctx = ssl_ctx;
     return OSSL_HTTP_post_asn1(host, port, path, ssl_ctx != NULL,
-                               proxy, proxy_port,
+                               proxy, no_proxy,
                                NULL, NULL, app_http_tls_cb, &info,
                                headers, content_type, req, req_it,
                                0 /* maxline */,
@@ -2214,40 +2234,6 @@ double app_tminterval(int stop, int usertime)
     return ret;
 }
 
-#elif defined(OPENSSL_SYSTEM_VMS)
-# include <time.h>
-# include <times.h>
-
-double app_tminterval(int stop, int usertime)
-{
-    static clock_t tmstart;
-    double ret = 0;
-    clock_t now;
-# ifdef __TMS
-    struct tms rus;
-
-    now = times(&rus);
-    if (usertime)
-        now = rus.tms_utime;
-# else
-    if (usertime)
-        now = clock();          /* sum of user and kernel times */
-    else {
-        struct timeval tv;
-        gettimeofday(&tv, NULL);
-        now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK +
-                        (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK)
-            );
-    }
-# endif
-    if (stop == TM_START)
-        tmstart = now;
-    else
-        ret = (now - tmstart) / (double)(CLK_TCK);
-
-    return ret;
-}
-
 #elif defined(_SC_CLK_TCK)      /* by means of unistd.h */
 # include <sys/times.h>
 
@@ -2690,6 +2676,7 @@ OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts,
     size_t sz = (size_t)sk_OPENSSL_STRING_num(opts);
     size_t params_n;
     char *opt = "", *stmp, *vtmp = NULL;
+    int found = 1;
 
     if (opts == NULL)
         return NULL;
@@ -2708,7 +2695,7 @@ OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts,
         /* Skip over the separator so that vmtp points to the value */
         vtmp++;
         if (!OSSL_PARAM_allocate_from_text(&params[params_n], paramdefs,
-                                           stmp, vtmp, strlen(vtmp), NULL))
+                                           stmp, vtmp, strlen(vtmp), &found))
             goto err;
         OPENSSL_free(stmp);
     }
@@ -2716,7 +2703,8 @@ OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts,
     return params;
 err:
     OPENSSL_free(stmp);
-    BIO_printf(bio_err, "Parameter error '%s'\n", opt);
+    BIO_printf(bio_err, "Parameter %s '%s'\n", found ? "error" : "unknown",
+               opt);
     ERR_print_errors(bio_err);
     app_params_free(params);
     return NULL;