[openssl] master update

dev at ddvo.net dev at ddvo.net
Thu Dec 10 14:21:32 UTC 2020


The branch master has been updated
       via  1a683b80dc9ad4dcbf206a0617364a9d614a9883 (commit)
       via  98ba251fe6f49fc2ee310f6e559c3431922fa16d (commit)
       via  8ca661abd78b0e0c45340100169c4b47c0290142 (commit)
       via  f902716f24ab13a02ab501fde9428f996fd4b0cd (commit)
       via  374f72cedd2f26d197c208ae56571fd2123fe9ce (commit)
       via  9c3a52f2a27729490f86f1ff6cc51b9e98115729 (commit)
       via  6c9515b763aa19f11cfdc1d06cab338ae1ed5363 (commit)
       via  d858e743a9efa9d6282fdb84f3160b485bafc866 (commit)
       via  e9701a0141313d2c7008c6ee6d821ba80b3a14d9 (commit)
       via  7c051ecce4ca9cd65f802fbf4fc469755859a036 (commit)
      from  bca7ad6efd0e1e828033cae2440d83322bf3dc01 (commit)


- Log -----------------------------------------------------------------
commit 1a683b80dc9ad4dcbf206a0617364a9d614a9883
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Dec 7 19:37:46 2020 +0100

    apps/{ca,req,x509}.c: Improve diag and doc mostly on X.509 extensions, fix multiple instances
    
    This includes a general correction in the code (now using the X509V3_CTX_REPLACE flag)
    and adding a prominent clarification in the documentation:
    
        If multiple entries are processed for the same extension name,
        later entries override earlier ones with the same name.
    
    This is due to an RFC 5280 requirement - the intro of its section 4.2 says:
    
        A certificate MUST NOT include more than one instance of a particular extension.
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit 98ba251fe6f49fc2ee310f6e559c3431922fa16d
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Dec 7 18:25:10 2020 +0100

    openssl_hexstr2buf_sep(): Prevent misleading 'malloc failure' errors on short input
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit 8ca661abd78b0e0c45340100169c4b47c0290142
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Dec 7 17:45:09 2020 +0100

    v2i_AUTHORITY_KEYID(): Correct out-of-memory behavior and avoid mem leaks
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit f902716f24ab13a02ab501fde9428f996fd4b0cd
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Dec 7 13:28:39 2020 +0100

    X509V3_EXT_add_nconf_sk(): Improve description and use of 'sk' arg, which may be NULL
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit 374f72cedd2f26d197c208ae56571fd2123fe9ce
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Dec 7 13:25:34 2020 +0100

    openssl-ca.pod.in: Clarify the -extensions/-crlexts options vs. x509_extensions/crl_extensions
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit 9c3a52f2a27729490f86f1ff6cc51b9e98115729
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Fri Dec 4 12:42:24 2020 +0100

    apps/x509.c: Factor out common aspects of X509 signing
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit 6c9515b763aa19f11cfdc1d06cab338ae1ed5363
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Fri Dec 4 11:09:29 2020 +0100

    apps/{req,x509,ca}.c: Cleanup: move shared X509{,_REQ,_CRL} code to apps/lib/apps.c
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit d858e743a9efa9d6282fdb84f3160b485bafc866
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Fri Dec 4 11:01:08 2020 +0100

    apps/{req,x509,ca}.c: Clean up code setting X.509 cert version v3
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit e9701a0141313d2c7008c6ee6d821ba80b3a14d9
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Fri Dec 4 09:26:25 2020 +0100

    x509v3_config.pod: Clarify semantics of subjectKeyIdentifier and authorityKeyIdentifier
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

commit 7c051ecce4ca9cd65f802fbf4fc469755859a036
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Thu Dec 3 17:09:20 2020 +0100

    apps/req.c: Improve diagnostics on multiple/overriding X.509 extensions defined via -reqext option
    
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13614)

-----------------------------------------------------------------------

Summary of changes:
 apps/ca.c                   |  76 ++++++++++-----------
 apps/lib/apps.c             | 146 +++++++++++++++++++++++++++++++++++++++
 apps/req.c                  | 162 ++++----------------------------------------
 apps/x509.c                 |  96 ++++++++++----------------
 crypto/cpt_err.c            |   2 +
 crypto/err/openssl.txt      |   1 +
 crypto/o_str.c              |   7 +-
 crypto/x509/v3_akey.c       |  19 +++---
 crypto/x509/v3_conf.c       |   6 +-
 doc/man1/openssl-ca.pod.in  |  12 ++--
 doc/man5/x509v3_config.pod  |  42 +++++++-----
 include/crypto/cryptoerr.h  |   2 +-
 include/openssl/cryptoerr.h |   1 +
 test/recipes/25-test_x509.t |   2 +-
 14 files changed, 290 insertions(+), 284 deletions(-)

diff --git a/apps/ca.c b/apps/ca.c
index 0f21b4fa1c..82b008cbce 100755
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -138,7 +138,7 @@ static int make_revoked(X509_REVOKED *rev, const char *str);
 static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str);
 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
 
-static CONF *extconf = NULL;
+static CONF *extfile_conf = NULL;
 static int preserve = 0;
 static int msie_hack = 0;
 
@@ -761,7 +761,7 @@ end_of_options:
     /*****************************************************************/
     /* Read extensions config file                                   */
     if (extfile) {
-        if ((extconf = app_load_config(extfile)) == NULL) {
+        if ((extfile_conf = app_load_config(extfile)) == NULL) {
             ret = 1;
             goto end;
         }
@@ -772,7 +772,7 @@ end_of_options:
 
         /* We can have sections in the ext file */
         if (extensions == NULL) {
-            extensions = NCONF_get_string(extconf, "default", "extensions");
+            extensions = NCONF_get_string(extfile_conf, "default", "extensions");
             if (extensions == NULL)
                 extensions = "default";
         }
@@ -836,7 +836,20 @@ end_of_options:
                 goto end;
         }
 
-        if (extconf == NULL) {
+        if (extfile_conf != NULL) {
+            /* Check syntax of extfile */
+            X509V3_CTX ctx;
+
+            X509V3_set_ctx_test(&ctx);
+            X509V3_set_nconf(&ctx, extfile_conf);
+            if (!X509V3_EXT_add_nconf(extfile_conf, &ctx, extensions, NULL)) {
+                BIO_printf(bio_err,
+                           "Error checking certificate extensions from extfile section %s\n",
+                           extensions);
+                ret = 1;
+                goto end;
+            }
+        } else {
             /*
              * no '-extfile' option, so we look for extensions in the main
              * configuration file
@@ -847,13 +860,13 @@ end_of_options:
                     ERR_clear_error();
             }
             if (extensions != NULL) {
-                /* Check syntax of file */
+                /* Check syntax of config file section */
                 X509V3_CTX ctx;
                 X509V3_set_ctx_test(&ctx);
                 X509V3_set_nconf(&ctx, conf);
                 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) {
                     BIO_printf(bio_err,
-                               "Error Loading extension section %s\n",
+                               "Error checking certificate extension config section %s\n",
                                extensions);
                     ret = 1;
                     goto end;
@@ -1131,7 +1144,7 @@ end_of_options:
             X509V3_set_nconf(&ctx, conf);
             if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) {
                 BIO_printf(bio_err,
-                           "Error Loading CRL extension section %s\n", crl_ext);
+                           "Error checking CRL extension section %s\n", crl_ext);
                 ret = 1;
                 goto end;
             }
@@ -1220,8 +1233,11 @@ end_of_options:
             X509V3_set_nconf(&crlctx, conf);
 
             if (crl_ext != NULL)
-                if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl))
+                if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl)) {
+                    BIO_printf(bio_err,
+                               "Error adding CRL extensions from section %s\n", crl_ext);
                     goto end;
+                }
             if (crlnumberfile != NULL) {
                 tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
                 if (!tmpser)
@@ -1312,7 +1328,7 @@ end_of_options:
     X509_free(x509);
     X509_CRL_free(crl);
     NCONF_free(conf);
-    NCONF_free(extconf);
+    NCONF_free(extfile_conf);
     release_engine(e);
     return ret;
 }
@@ -1650,12 +1666,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
     if ((ret = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL)
         goto end;
 
-#ifdef X509_V3
-    /* Make it an X509 v3 certificate. */
-    if (!X509_set_version(ret, 2))
-        goto end;
-#endif
-
     if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
         goto end;
     if (selfsign) {
@@ -1687,28 +1697,23 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
 
     /* Lets add the extensions, if there are any */
     if (ext_sect) {
-        X509V3_CTX ctx;
+        X509V3_CTX ext_ctx;
 
         /* Initialize the context structure */
-        if (selfsign)
-            X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
-        else
-            X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
+        X509V3_set_ctx(&ext_ctx, selfsign ? ret : x509,
+                       ret, req, NULL, X509V3_CTX_REPLACE);
 
-        if (extconf != NULL) {
+        if (extfile_conf != NULL) {
             if (verbose)
                 BIO_printf(bio_err, "Extra configuration file found\n");
 
-            /* Use the extconf configuration db LHASH */
-            X509V3_set_nconf(&ctx, extconf);
-
-            /* Test the structure (needed?) */
-            /* X509V3_set_ctx_test(&ctx); */
+            /* Use the extfile_conf configuration db LHASH */
+            X509V3_set_nconf(&ext_ctx, extfile_conf);
 
             /* Adds exts contained in the configuration file */
-            if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) {
+            if (!X509V3_EXT_add_nconf(extfile_conf, &ext_ctx, ext_sect, ret)) {
                 BIO_printf(bio_err,
-                           "ERROR: adding extensions in section %s\n",
+                           "Error adding certificate extensions from extfile section %s\n",
                            ext_sect);
                 goto end;
             }
@@ -1717,11 +1722,11 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                            "Successfully added extensions from file.\n");
         } else if (ext_sect) {
             /* We found extensions to be set from config file */
-            X509V3_set_nconf(&ctx, lconf);
+            X509V3_set_nconf(&ext_ctx, lconf);
 
-            if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
+            if (!X509V3_EXT_add_nconf(lconf, &ext_ctx, ext_sect, ret)) {
                 BIO_printf(bio_err,
-                           "ERROR: adding extensions in section %s\n",
+                           "Error adding certificate extensions from config section %s\n",
                            ext_sect);
                 goto end;
             }
@@ -1739,15 +1744,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
         goto end;
     }
 
-    {
-        const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(ret);
-
-        if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0)
-            /* Make it an X509 v3 certificate. */
-            if (!X509_set_version(ret, 2))
-                goto end;
-    }
-
     if (verbose)
         BIO_printf(bio_err,
                    "The subject name appears to be ok, checking data base for clashes\n");
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index 699802044d..703518ce8c 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -1906,6 +1906,152 @@ void print_cert_checks(BIO *bio, X509 *x,
     }
 }
 
+static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts)
+{
+    int i;
+
+    if (opts == NULL)
+        return 1;
+
+    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+        char *opt = sk_OPENSSL_STRING_value(opts, i);
+        if (pkey_ctrl_string(pkctx, opt) <= 0) {
+            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
+            ERR_print_errors(bio_err);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts)
+{
+    int i;
+
+    if (opts == NULL)
+        return 1;
+
+    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+        char *opt = sk_OPENSSL_STRING_value(opts, i);
+        if (x509_ctrl_string(x, opt) <= 0) {
+            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
+            ERR_print_errors(bio_err);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts)
+{
+    int i;
+
+    if (opts == NULL)
+        return 1;
+
+    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+        char *opt = sk_OPENSSL_STRING_value(opts, i);
+        if (x509_req_ctrl_string(x, opt) <= 0) {
+            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
+            ERR_print_errors(bio_err);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
+                        const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
+{
+    EVP_PKEY_CTX *pkctx = NULL;
+    int def_nid;
+
+    if (ctx == NULL)
+        return 0;
+    /*
+     * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
+     * for this algorithm.
+     */
+    if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2
+            && def_nid == NID_undef) {
+        /* The signing algorithm requires there to be no digest */
+        md = NULL;
+    }
+    return EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)
+        && do_pkey_ctx_init(pkctx, sigopts);
+}
+
+/* Ensure RFC 5280 compliance and then sign the certificate info */
+int do_X509_sign(X509 *cert, EVP_PKEY *pkey, const EVP_MD *md,
+                 STACK_OF(OPENSSL_STRING) *sigopts)
+{
+    const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert);
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    int rv = 0;
+
+    if (sk_X509_EXTENSION_num(exts /* may be NULL */) > 0) {
+        /* Prevent X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 */
+        if (!X509_set_version(cert, 2)) /* Make sure cert is X509 v3 */
+            goto end;
+
+        /* TODO any further measures for ensuring default RFC 5280 compliance */
+    }
+
+    if (mctx != NULL && do_sign_init(mctx, pkey, md, sigopts) > 0)
+        rv = (X509_sign_ctx(cert, mctx) > 0);
+ end:
+    EVP_MD_CTX_free(mctx);
+    return rv;
+}
+
+/* Sign the certificate request info */
+int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
+                     STACK_OF(OPENSSL_STRING) *sigopts)
+{
+    int rv = 0;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+
+    if (do_sign_init(mctx, pkey, md, sigopts) > 0)
+        rv = (X509_REQ_sign_ctx(x, mctx) > 0);
+    EVP_MD_CTX_free(mctx);
+    return rv;
+}
+
+/* Sign the CRL info */
+int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
+                     STACK_OF(OPENSSL_STRING) *sigopts)
+{
+    int rv = 0;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+
+    if (do_sign_init(mctx, pkey, md, sigopts) > 0)
+        rv = (X509_CRL_sign_ctx(x, mctx) > 0);
+    EVP_MD_CTX_free(mctx);
+    return rv;
+}
+
+int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts)
+{
+    int rv = 0;
+
+    if (do_x509_init(x, vfyopts) > 0)
+        rv = (X509_verify(x, pkey) > 0);
+    return rv;
+}
+
+int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
+                       STACK_OF(OPENSSL_STRING) *vfyopts)
+{
+    int rv = 0;
+
+    if (do_x509_req_init(x, vfyopts) > 0)
+        rv = (X509_REQ_verify(x, pkey) > 0);
+    return rv;
+}
+
 /* Get first http URL from a DIST_POINT structure */
 
 static const char *get_dp_url(DIST_POINT *dp)
diff --git a/apps/req.c b/apps/req.c
index 41a78593b0..ad79866a5a 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -426,9 +426,11 @@ int req_main(int argc, char **argv)
                     goto end;
             }
             i = duplicated(addexts, p);
-            if (i == 1)
+            if (i == 1) {
+                BIO_printf(bio_err, "Duplicate extension: %s\n", p);
                 goto opthelp;
-            if (i < 0 || BIO_printf(addext_bio, "%s\n", opt_arg()) < 0)
+            }
+            if (i < 0 || BIO_printf(addext_bio, "%s\n", p) < 0)
                 goto end;
             break;
         case OPT_EXTENSIONS:
@@ -471,7 +473,7 @@ int req_main(int argc, char **argv)
     if (addext_bio != NULL) {
         if (verbose)
             BIO_printf(bio_err,
-                       "Using additional configuration from command line\n");
+                       "Using additional configuration from -addext options\n");
         if ((addext_conf = app_load_config_bio(addext_bio, NULL)) == NULL)
             goto end;
     }
@@ -523,7 +525,7 @@ int req_main(int argc, char **argv)
         X509V3_set_nconf(&ctx, req_conf);
         if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
             BIO_printf(bio_err,
-                       "Error Loading extension section %s\n", extensions);
+                       "Error checking x509 extension section %s\n", extensions);
             goto end;
         }
     }
@@ -533,7 +535,7 @@ int req_main(int argc, char **argv)
         X509V3_set_ctx_test(&ctx);
         X509V3_set_nconf(&ctx, addext_conf);
         if (!X509V3_EXT_add_nconf(addext_conf, &ctx, "default", NULL)) {
-            BIO_printf(bio_err, "Error Loading command line extensions\n");
+            BIO_printf(bio_err, "Error checking extensions defined using -addext\n");
             goto end;
         }
     }
@@ -581,7 +583,7 @@ int req_main(int argc, char **argv)
         X509V3_set_nconf(&ctx, req_conf);
         if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
             BIO_printf(bio_err,
-                       "Error Loading request extension section %s\n",
+                       "Error checking request extension section %s\n",
                        req_exts);
             goto end;
         }
@@ -659,7 +661,7 @@ int req_main(int argc, char **argv)
         EVP_PKEY_CTX_set_app_data(genctx, bio_err);
 
         if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
-            BIO_puts(bio_err, "Error Generating Key\n");
+            BIO_puts(bio_err, "Error generating key\n");
             goto end;
         }
 
@@ -742,9 +744,6 @@ int req_main(int argc, char **argv)
                 goto end;
 
             /* Set version to V3 */
-            if ((extensions != NULL || addext_conf != NULL)
-                && !X509_set_version(x509ss, 2))
-                goto end;
             if (serial != NULL) {
                 if (!X509_set_serialNumber(x509ss, serial))
                     goto end;
@@ -770,21 +769,21 @@ int req_main(int argc, char **argv)
 
             /* Set up V3 context struct */
 
-            X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
+            X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, X509V3_CTX_REPLACE);
             X509V3_set_nconf(&ext_ctx, req_conf);
 
             /* Add extensions */
             if (extensions != NULL && !X509V3_EXT_add_nconf(req_conf,
                                                             &ext_ctx, extensions,
                                                             x509ss)) {
-                BIO_printf(bio_err, "Error Loading extension section %s\n",
+                BIO_printf(bio_err, "Error adding x509 extensions from section %s\n",
                            extensions);
                 goto end;
             }
             if (addext_conf != NULL
                 && !X509V3_EXT_add_nconf(addext_conf, &ext_ctx, "default",
                                          x509ss)) {
-                BIO_printf(bio_err, "Error Loading command line extensions\n");
+                BIO_printf(bio_err, "Error adding extensions defined via -addext\n");
                 goto end;
             }
 
@@ -814,14 +813,14 @@ int req_main(int argc, char **argv)
             if (req_exts != NULL
                 && !X509V3_EXT_REQ_add_nconf(req_conf, &ext_ctx,
                                              req_exts, req)) {
-                BIO_printf(bio_err, "Error Loading extension section %s\n",
+                BIO_printf(bio_err, "Error adding request extensions from section %s\n",
                            req_exts);
                 goto end;
             }
             if (addext_conf != NULL
                 && !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx, "default",
                                              req)) {
-                BIO_printf(bio_err, "Error Loading command line extensions\n");
+                BIO_printf(bio_err, "Error adding extensions defined via -addext\n");
                 goto end;
             }
             i = do_X509_REQ_sign(req, pkey, digest, sigopts);
@@ -1627,136 +1626,3 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx)
     (void)BIO_flush(b);
     return 1;
 }
-
-static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts)
-{
-    int i;
-
-    if (opts == NULL)
-        return 1;
-
-    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
-        char *opt = sk_OPENSSL_STRING_value(opts, i);
-        if (pkey_ctrl_string(pkctx, opt) <= 0) {
-            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
-            ERR_print_errors(bio_err);
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
-static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts)
-{
-    int i;
-
-    if (opts == NULL)
-        return 1;
-
-    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
-        char *opt = sk_OPENSSL_STRING_value(opts, i);
-        if (x509_ctrl_string(x, opt) <= 0) {
-            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
-            ERR_print_errors(bio_err);
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
-static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts)
-{
-    int i;
-
-    if (opts == NULL)
-        return 1;
-
-    for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
-        char *opt = sk_OPENSSL_STRING_value(opts, i);
-        if (x509_req_ctrl_string(x, opt) <= 0) {
-            BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
-            ERR_print_errors(bio_err);
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
-static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
-                        const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
-{
-    EVP_PKEY_CTX *pkctx = NULL;
-    int def_nid;
-
-    if (ctx == NULL)
-        return 0;
-    /*
-     * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
-     * for this algorithm.
-     */
-    if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) == 2
-            && def_nid == NID_undef) {
-        /* The signing algorithm requires there to be no digest */
-        md = NULL;
-    }
-    return EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)
-        && do_pkey_ctx_init(pkctx, sigopts);
-}
-
-int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
-                 STACK_OF(OPENSSL_STRING) *sigopts)
-{
-    int rv = 0;
-    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-
-    if (do_sign_init(mctx, pkey, md, sigopts) > 0)
-        rv = (X509_sign_ctx(x, mctx) > 0);
-    EVP_MD_CTX_free(mctx);
-    return rv;
-}
-
-int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
-                     STACK_OF(OPENSSL_STRING) *sigopts)
-{
-    int rv = 0;
-    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-
-    if (do_sign_init(mctx, pkey, md, sigopts) > 0)
-        rv = (X509_REQ_sign_ctx(x, mctx) > 0);
-    EVP_MD_CTX_free(mctx);
-    return rv;
-}
-
-int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts)
-{
-    int rv = 0;
-
-    if (do_x509_init(x, vfyopts) > 0)
-        rv = (X509_verify(x, pkey) > 0);
-    return rv;
-}
-
-int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
-                       STACK_OF(OPENSSL_STRING) *vfyopts)
-{
-    int rv = 0;
-
-    if (do_x509_req_init(x, vfyopts) > 0)
-        rv = (X509_REQ_verify(x, pkey) > 0);
-    return rv;
-}
-
-int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
-                     STACK_OF(OPENSSL_STRING) *sigopts)
-{
-    int rv = 0;
-    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-
-    if (do_sign_init(mctx, pkey, md, sigopts) > 0)
-        rv = (X509_CRL_sign_ctx(x, mctx) > 0);
-    EVP_MD_CTX_free(mctx);
-    return rv;
-}
diff --git a/apps/x509.c b/apps/x509.c
index ad627f4558..8cd84f5afe 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -33,7 +33,7 @@
 #define DEF_DAYS        30
 
 static int callb(int ok, X509_STORE_CTX *ctx);
-static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey,
+static int sign(X509 *x, EVP_PKEY *pkey, X509 *issuer,
                 STACK_OF(OPENSSL_STRING) *sigopts,
                 int days, int clrext,
                 const EVP_MD *digest, CONF *conf, const char *section,
@@ -465,7 +465,7 @@ int x509_main(int argc, char **argv)
                     goto opthelp;
                 checkoffset = (time_t)temp;
                 if ((intmax_t)checkoffset != temp) {
-                    BIO_printf(bio_err, "%s: checkend time out of range %s\n",
+                    BIO_printf(bio_err, "%s: Checkend time out of range %s\n",
                                prog, opt_arg());
                     goto opthelp;
                 }
@@ -536,11 +536,11 @@ int x509_main(int argc, char **argv)
         CAkeyfile = CAfile;
     } else if (CA_flag && CAkeyfile == NULL) {
         BIO_printf(bio_err,
-                   "need to specify a CAkey if using the CA command\n");
+                   "Need to specify a CAkey if using the CA command\n");
         goto end;
     } else if (!CA_flag && CAkeyfile != NULL) {
         BIO_printf(bio_err,
-                   "ignoring -CAkey option since no -CA option is given\n");
+                   "Ignoring -CAkey option since no -CA option is given\n");
     }
 
     if (extfile != NULL) {
@@ -558,7 +558,7 @@ int x509_main(int argc, char **argv)
         X509V3_set_nconf(&ctx2, extconf);
         if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
             BIO_printf(bio_err,
-                       "Error Loading extension section %s\n", extsect);
+                       "Error checking extension section %s\n", extsect);
             ERR_print_errors(bio_err);
             goto end;
         }
@@ -572,7 +572,7 @@ int x509_main(int argc, char **argv)
             goto end;
 
         if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
-            BIO_printf(bio_err, "error unpacking public key\n");
+            BIO_printf(bio_err, "Error unpacking public key\n");
             goto end;
         }
         i = do_X509_REQ_verify(req, pkey, vfyopts);
@@ -807,7 +807,7 @@ int x509_main(int argc, char **argv)
                     fdig = EVP_sha1();
 
                 if (!X509_digest(x, fdig, md, &n)) {
-                    BIO_printf(bio_err, "out of memory\n");
+                    BIO_printf(bio_err, "Out of memory\n");
                     goto end;
                 }
                 BIO_printf(out, "%s Fingerprint=",
@@ -820,19 +820,20 @@ int x509_main(int argc, char **argv)
 
             /* should be in the library */
             else if (sign_flag == i && x509req == 0) {
-                BIO_printf(bio_err, "Getting Private key\n");
                 if (Upkey == NULL) {
                     Upkey = load_key(keyfile, keyformat, 0,
                                      passin, e, "private key");
                     if (Upkey == NULL)
                         goto end;
                 }
-
-                if (!sign(x, Upkey, fkey, sigopts, days, clrext, digest,
-                          extconf, extsect, preserve_dates))
+                if (fkey == NULL && !X509_set_pubkey(x, Upkey))
+                    goto end;
+                if (!sign(x, Upkey, x /* self-issuing */, sigopts, days, clrext,
+                          digest, extconf, extsect, preserve_dates)) {
+                    ERR_print_errors(bio_err);
                     goto end;
+                }
             } else if (CA_flag == i) {
-                BIO_printf(bio_err, "Getting CA Private Key\n");
                 if (CAkeyfile != NULL) {
                     CApkey = load_key(CAkeyfile, CAkeyformat,
                                       0, passin, e, "CA private key");
@@ -848,9 +849,8 @@ int x509_main(int argc, char **argv)
             } else if (x509req == i) {
                 EVP_PKEY *pk;
 
-                BIO_printf(bio_err, "Getting request Private Key\n");
                 if (keyfile == NULL) {
-                    BIO_printf(bio_err, "no request key file specified\n");
+                    BIO_printf(bio_err, "No request key file specified\n");
                     goto end;
                 } else {
                     pk = load_key(keyfile, keyformat, 0,
@@ -859,8 +859,6 @@ int x509_main(int argc, char **argv)
                         goto end;
                 }
 
-                BIO_printf(bio_err, "Generating certificate request\n");
-
                 rq = X509_to_X509_REQ(x, pk, digest);
                 EVP_PKEY_free(pk);
                 if (rq == NULL) {
@@ -908,11 +906,11 @@ int x509_main(int argc, char **argv)
         else
             i = PEM_write_bio_X509(out, x);
     } else {
-        BIO_printf(bio_err, "bad output format specified for outfile\n");
+        BIO_printf(bio_err, "Bad output format specified for outfile\n");
         goto end;
     }
     if (!i) {
-        BIO_printf(bio_err, "unable to write certificate\n");
+        BIO_printf(bio_err, "Unable to write certificate\n");
         ERR_print_errors(bio_err);
         goto end;
     }
@@ -962,7 +960,7 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile,
         goto end;
 
     if (!BN_add_word(serial, 1)) {
-        BIO_printf(bio_err, "add_word failure\n");
+        BIO_printf(bio_err, "Serial number increment failure\n");
         goto end;
     }
 
@@ -1019,30 +1017,13 @@ static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *diges
         goto end;
     }
 
-    if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
-        goto end;
     if (!X509_set_serialNumber(x, bs))
         goto end;
 
-    if (!preserve_dates && !set_cert_times(x, NULL, NULL, days))
+    if (!sign(x, pkey, xca, sigopts, days, clrext, digest,
+              conf, section, preserve_dates))
         goto end;
 
-    if (clrext) {
-        while (X509_get_ext_count(x) > 0)
-            X509_delete_ext(x, 0);
-    }
-
-    if (conf != NULL) {
-        X509V3_CTX ctx2;
-        X509_set_version(x, 2); /* version 3 certificate */
-        X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
-        X509V3_set_nconf(&ctx2, conf);
-        if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
-            goto end;
-    }
-
-    if (!do_X509_sign(x, pkey, digest, sigopts))
-        goto end;
     ret = 1;
  end:
     X509_STORE_CTX_free(xsc);
@@ -1073,50 +1054,47 @@ static int callb(int ok, X509_STORE_CTX *ctx)
      */
     if (ok) {
         BIO_printf(bio_err,
-                   "error with certificate to be certified - should be self-signed\n");
+                   "Error with certificate to be certified - should be self-signed\n");
         return 0;
     } else {
         err_cert = X509_STORE_CTX_get_current_cert(ctx);
         print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
         BIO_printf(bio_err,
-                   "error with certificate - error %d at depth %d\n%s\n", err,
+                   "Error with certificate - error %d at depth %d\n%s\n", err,
                    X509_STORE_CTX_get_error_depth(ctx),
                    X509_verify_cert_error_string(err));
         return 1;
     }
 }
 
-/* self-issue; self-sign unless a forced public key (fkey) is given */
-static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey,
+static int sign(X509 *x, EVP_PKEY *pkey, X509 *issuer,
                 STACK_OF(OPENSSL_STRING) *sigopts,
                 int days, int clrext,
                 const EVP_MD *digest, CONF *conf, const char *section,
                 int preserve_dates)
 {
-    if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
-        goto err;
+    if (!X509_set_issuer_name(x, X509_get_subject_name(issuer)))
+        return 0;
+
     if (!preserve_dates && !set_cert_times(x, NULL, NULL, days))
-        goto err;
-    if (fkey == NULL && !X509_set_pubkey(x, pkey))
-        goto err;
+        return 0;
+
     if (clrext) {
         while (X509_get_ext_count(x) > 0)
             X509_delete_ext(x, 0);
     }
     if (conf != NULL) {
-        X509V3_CTX ctx;
-        X509_set_version(x, 2); /* version 3 certificate */
-        X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
-        X509V3_set_nconf(&ctx, conf);
-        if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
-            goto err;
+        X509V3_CTX ext_ctx;
+
+        X509V3_set_ctx(&ext_ctx, issuer, x, NULL, NULL, X509V3_CTX_REPLACE);
+        X509V3_set_nconf(&ext_ctx, conf);
+        if (!X509V3_EXT_add_nconf(conf, &ext_ctx, section, x)) {
+            BIO_printf(bio_err,
+                       "Error adding extensions from section %s\n", section);
+            return 0;
+        }
     }
-    if (!do_X509_sign(x, pkey, digest, sigopts))
-        goto err;
-    return 1;
- err:
-    ERR_print_errors(bio_err);
-    return 0;
+    return do_X509_sign(x, pkey, digest, sigopts);
 }
 
 static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c
index 7aa5416720..65fb429c58 100644
--- a/crypto/cpt_err.c
+++ b/crypto/cpt_err.c
@@ -21,6 +21,8 @@ static const ERR_STRING_DATA CRYPTO_str_reasons[] = {
     "conflicting names"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED),
     "fips mode not supported"},
+    {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_HEX_STRING_TOO_SHORT),
+    "hex string too short"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ILLEGAL_HEX_DIGIT),
     "illegal hex digit"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_DATA_SPACE),
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 273400e3c4..60f343eb7d 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2318,6 +2318,7 @@ CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method
 CRYPTO_R_BAD_ALGORITHM_NAME:117:bad algorithm name
 CRYPTO_R_CONFLICTING_NAMES:118:conflicting names
 CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported
+CRYPTO_R_HEX_STRING_TOO_SHORT:121:hex string too short
 CRYPTO_R_ILLEGAL_HEX_DIGIT:102:illegal hex digit
 CRYPTO_R_INSUFFICIENT_DATA_SPACE:106:insufficient data space
 CRYPTO_R_INSUFFICIENT_PARAM_SIZE:107:insufficient param size
diff --git a/crypto/o_str.c b/crypto/o_str.c
index 142ac4ba44..dbecf4841c 100644
--- a/crypto/o_str.c
+++ b/crypto/o_str.c
@@ -187,7 +187,12 @@ unsigned char *openssl_hexstr2buf_sep(const char *str, long *buflen,
     unsigned char *buf;
     size_t buf_n, tmp_buflen;
 
-    buf_n = strlen(str) >> 1;
+    buf_n = strlen(str);
+    if (buf_n <= 1) {
+        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_HEX_STRING_TOO_SHORT);
+        return NULL;
+    }
+    buf_n /= 2;
     if ((buf = OPENSSL_malloc(buf_n)) == NULL) {
         ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
         return NULL;
diff --git a/crypto/x509/v3_akey.c b/crypto/x509/v3_akey.c
index 21ea1e4c75..96e415aeb1 100644
--- a/crypto/x509/v3_akey.c
+++ b/crypto/x509/v3_akey.c
@@ -87,7 +87,10 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
     ASN1_INTEGER *serial = NULL;
     X509_EXTENSION *ext;
     X509 *cert;
-    AUTHORITY_KEYID *akeyid;
+    AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new();
+
+    if (akeyid == NULL)
+        goto err;
 
     for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
         cnf = sk_CONF_VALUE_value(values, i);
@@ -102,15 +105,15 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
         } else {
             ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION,
                            "name=%s", cnf->name);
-            return NULL;
+            goto err;
         }
     }
 
     if (!ctx || !ctx->issuer_cert) {
         if (ctx && (ctx->flags == CTX_TEST))
-            return AUTHORITY_KEYID_new();
+            return akeyid;
         ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
-        return NULL;
+        goto err;
     }
 
     cert = ctx->issuer_cert;
@@ -119,9 +122,9 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
         i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
         if ((i >= 0) && (ext = X509_get_ext(cert, i)))
             ikeyid = X509V3_EXT_d2i(ext);
-        if (keyid == 2 && !ikeyid) {
+        if ((keyid == 2 || issuer == 0) && ikeyid == NULL) {
             ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
-            return NULL;
+            goto err;
         }
     }
 
@@ -134,9 +137,6 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
         }
     }
 
-    if ((akeyid = AUTHORITY_KEYID_new()) == NULL)
-        goto err;
-
     if (isname) {
         if ((gens = sk_GENERAL_NAME_new_null()) == NULL
             || (gen = GENERAL_NAME_new()) == NULL
@@ -162,5 +162,6 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
     X509_NAME_free(isname);
     ASN1_INTEGER_free(serial);
     ASN1_OCTET_STRING_free(ikeyid);
+    AUTHORITY_KEYID_free(akeyid);
     return NULL;
 }
diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c
index 47b626659c..1f424325a0 100644
--- a/crypto/x509/v3_conf.c
+++ b/crypto/x509/v3_conf.c
@@ -305,7 +305,7 @@ static void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext)
 
 /*
  * This is the main function: add a bunch of extensions based on a config
- * file section to an extension STACK.
+ * file section to an extension STACK. Just check in case sk == NULL.
  */
 
 int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
@@ -323,9 +323,9 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
         if ((ext = X509V3_EXT_nconf_int(conf, ctx, val->section,
                                         val->name, val->value)) == NULL)
             return 0;
-        if (ctx->flags == X509V3_CTX_REPLACE)
-            delete_ext(*sk, ext);
         if (sk != NULL) {
+            if (ctx->flags == X509V3_CTX_REPLACE)
+                delete_ext(*sk, ext);
             if (X509v3_add_ext(sk, ext, -1) == NULL) {
                 X509_EXTENSION_free(ext);
                 return 0;
diff --git a/doc/man1/openssl-ca.pod.in b/doc/man1/openssl-ca.pod.in
index 8442c4450b..68da77d349 100644
--- a/doc/man1/openssl-ca.pod.in
+++ b/doc/man1/openssl-ca.pod.in
@@ -271,10 +271,10 @@ and all certificates will be certified automatically.
 
 The section of the configuration file containing certificate extensions
 to be added when a certificate is issued (defaults to B<x509_extensions>
-unless the B<-extfile> option is used). If no extension section is
-present then, a V1 certificate is created. If the extension section
-is present (even if it is empty), then a V3 certificate is created. See the
-L<x509v3_config(5)> manual page for details of the
+unless the B<-extfile> option is used).
+If no X.509 extensions are specified then a V1 certificate is created,
+else a V3 certificate is created.
+See the L<x509v3_config(5)> manual page for details of the
 extension section format.
 
 =item B<-extfile> I<file>
@@ -540,11 +540,11 @@ present, it must contain a valid CRL number.
 
 =item B<x509_extensions>
 
-The same as B<-extensions>.
+A fallback to the B<-extensions> option.
 
 =item B<crl_extensions>
 
-The same as B<-crlexts>.
+A fallback to the B<-crlexts> option.
 
 =item B<preserve>
 
diff --git a/doc/man5/x509v3_config.pod b/doc/man5/x509v3_config.pod
index 953b0268cd..cf08f78695 100644
--- a/doc/man5/x509v3_config.pod
+++ b/doc/man5/x509v3_config.pod
@@ -7,8 +7,9 @@ x509v3_config - X509 V3 certificate extension configuration format
 =head1 DESCRIPTION
 
 Several OpenSSL commands can add extensions to a certificate or
-certificate request based on the contents of a configuration file.
-The syntax of this file is described in L<config(5)>.
+certificate request based on the contents of a configuration file
+and CLI options such as B<-addext>.
+The syntax of configuration files is described in L<config(5)>.
 The commands typically have an option to specify the name of the configuration
 file, and a section within that file; see the documentation of the
 individual command for details.
@@ -22,6 +23,9 @@ Each entry in the extension section takes the form:
 
 If B<critical> is present then the extension will be marked as critical.
 
+If multiple entries are processed for the same extension name,
+later entries override earlier ones with the same name.
+
 The format of B<values> depends on the value of B<name>, many have a
 type-value pairing where the type and value are separated by a colon.
 There are four main types of extension:
@@ -164,11 +168,14 @@ Examples:
 
 =head2 Subject Key Identifier
 
-This is a string extension with one of two legal values. If it is the word
-B<hash>, then OpenSSL will follow the process in RFC 5280 to calculate the
-hash value.
-Otherwise, the value should be a hex string to output directly, however, this
-is strongly discouraged.
+This SKID extension is a string with one of two legal values.
+If it is the word B<hash>, then OpenSSL will follow
+the process specified in RFC 5280 section 4.2.1.2. (1):
+The keyIdentifier is composed of the 160-bit SHA-1 hash of the value of the BIT
+STRING subjectPublicKey (excluding the tag, length, and number of unused bits).
+
+Otherwise, the value must be a hex string (possibly with C<:> separating bytes)
+to output directly, however, this is strongly discouraged.
 
 Example:
 
@@ -176,16 +183,19 @@ Example:
 
 =head2 Authority Key Identifier
 
-This extension has two options, B<keyid> and B<issuer>. Either or both
-can have the value B<always>, indicated by putting a colon between
-the option and its value.
+The AKID extension specification may have the value B<keyid> or B<issuer>
+or both of them, separated by C<,>.
+Either or both can have the option B<always>,
+indicated by putting a colon C<:> between the value and this opton.
+
+If B<keyid> is present, an attempt is made to copy the subject key identifier
+(SKID) from the issuer certificate, which is the default behavior.
+If this fails and the option B<always> is present, an error is returned.
+For self-issued certs the specification for the SKID must be given before.
 
-If B<keyid> is present, than an attempt is made to copy the subject key
-identifier from the parent certificate. If the value B<always> is present,
-then an error can be returned if the option fails.  If B<issuer> is present,
-an attempt is made to copy the issuer and serial number from the parent
-certificate. This is done if the B<keyid> option fails, or if B<issuer>
-has B<always> specified.
+If B<issuer> is present and no B<keyid> has been added
+or it has the option B<always> specified, then
+the issuer DN and serial number are copied from the issuer certificate.
 
 Examples:
 
diff --git a/include/crypto/cryptoerr.h b/include/crypto/cryptoerr.h
index 81af1ed558..419ca1aac1 100644
--- a/include/crypto/cryptoerr.h
+++ b/include/crypto/cryptoerr.h
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-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
diff --git a/include/openssl/cryptoerr.h b/include/openssl/cryptoerr.h
index 971ae122b9..c7371124aa 100644
--- a/include/openssl/cryptoerr.h
+++ b/include/openssl/cryptoerr.h
@@ -78,6 +78,7 @@
 # define CRYPTO_R_BAD_ALGORITHM_NAME                      117
 # define CRYPTO_R_CONFLICTING_NAMES                       118
 # define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED                 101
+# define CRYPTO_R_HEX_STRING_TOO_SHORT                    121
 # define CRYPTO_R_ILLEGAL_HEX_DIGIT                       102
 # define CRYPTO_R_INSUFFICIENT_DATA_SPACE                 106
 # define CRYPTO_R_INSUFFICIENT_PARAM_SIZE                 107
diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t
index 54fbe78e96..19ff335f82 100644
--- a/test/recipes/25-test_x509.t
+++ b/test/recipes/25-test_x509.t
@@ -126,7 +126,7 @@ sub test_errors { # actually tests diagnostics of OSSL_STORE
 
 # 3 tests for non-existence of spurious OSSL_STORE ASN.1 parse error output.
 # This requires provoking a failure exit of the app after reading input files.
-ok(test_errors("bad output format", "root-cert.pem", '-outform', 'http'),
+ok(test_errors("Bad output format", "root-cert.pem", '-outform', 'http'),
    "load root-cert errors");
 ok(test_errors("RC2-40-CBC", "v3-certs-RC2.p12", '-passin', 'pass:v3-certs'),
    "load v3-certs-RC2 no asn1 errors"); # error msg should mention "RC2-40-CBC"


More information about the openssl-commits mailing list