[openssl] master update

dev at ddvo.net dev at ddvo.net
Thu Nov 11 19:19:45 UTC 2021


The branch master has been updated
       via  00cf3a2d30fc7642bf9f816a7c545115985a8c0c (commit)
       via  adbd77f6d7cc4efb7b4bde483036fab8e48ce870 (commit)
      from  b0c1214e1e82bc4c98eadd11d368b4ba9ffa202c (commit)


- Log -----------------------------------------------------------------
commit 00cf3a2d30fc7642bf9f816a7c545115985a8c0c
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Aug 24 09:31:53 2021 +0200

    25-test_req.t: Add systematic SKID+AKID tests for self-issued (incl. self-signed) certs
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/16342)

commit adbd77f6d7cc4efb7b4bde483036fab8e48ce870
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Tue Aug 17 23:13:28 2021 +0200

    X509: Fix handling of AKID and SKID extensions according to configuration
    
    Fixes #16300
    
    Reviewed-by: Viktor Dukhovni <viktor at openssl.org>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/16342)

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

Summary of changes:
 apps/ca.c                   |  11 +++-
 apps/include/apps.h         |   1 +
 apps/lib/apps.c             |  20 ++++--
 apps/pkcs12.c               |   2 +-
 apps/req.c                  |   4 +-
 apps/x509.c                 |   4 ++
 crypto/x509/v3_akid.c       |  13 ++--
 crypto/x509/v3_conf.c       |  18 ++++-
 doc/man5/x509v3_config.pod  |   1 +
 test/certs/ext-check.csr    |  23 ++-----
 test/recipes/25-test_req.t  | 157 +++++++++++++++++++++++++++++++++++++-------
 test/recipes/tconversion.pl |   3 +-
 12 files changed, 199 insertions(+), 58 deletions(-)

diff --git a/apps/ca.c b/apps/ca.c
index 24883615ed..1e77bf50c5 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1709,7 +1709,16 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
 
     /* Initialize the context structure */
     X509V3_set_ctx(&ext_ctx, selfsign ? ret : x509,
-                   ret, req, NULL, X509V3_CTX_REPLACE);
+                   ret, NULL /* no need to give req, needed info is in ret */,
+                   NULL, X509V3_CTX_REPLACE);
+    /* prepare fallback for AKID, but only if issuer cert equals subject cert */
+    if (selfsign) {
+        if (!X509V3_set_issuer_pkey(&ext_ctx, pkey))
+            goto end;
+        if (!cert_matches_key(ret, pkey))
+            BIO_printf(bio_err,
+                       "Warning: Signature key and public key of cert do not match\n");
+    }
 
     /* Lets add the extensions, if there are any */
     if (ext_sect) {
diff --git a/apps/include/apps.h b/apps/include/apps.h
index 9d5db16600..6018a83ca4 100644
--- a/apps/include/apps.h
+++ b/apps/include/apps.h
@@ -247,6 +247,7 @@ int x509_req_ctrl_string(X509_REQ *x, const char *value);
 int init_gen_str(EVP_PKEY_CTX **pctx,
                  const char *algname, ENGINE *e, int do_param,
                  OSSL_LIB_CTX *libctx, const char *propq);
+int cert_matches_key(const X509 *cert, const EVP_PKEY *pkey);
 int do_X509_sign(X509 *x, EVP_PKEY *pkey, const char *md,
                  STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx);
 int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts);
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index b15abac857..82eeaea249 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -2224,8 +2224,8 @@ static int adapt_keyid_ext(X509 *cert, X509V3_CTX *ext_ctx,
     idx = X509v3_get_ext_by_OBJ(exts, X509_EXTENSION_get_object(new_ext), -1);
     if (idx >= 0) {
         X509_EXTENSION *found_ext = X509v3_get_ext(exts, idx);
-        ASN1_OCTET_STRING *data = X509_EXTENSION_get_data(found_ext);
-        int disabled = ASN1_STRING_length(data) <= 2; /* config said "none" */
+        ASN1_OCTET_STRING *encoded = X509_EXTENSION_get_data(found_ext);
+        int disabled = ASN1_STRING_length(encoded) <= 2; /* indicating "none" */
 
         if (disabled) {
             X509_delete_ext(cert, idx);
@@ -2239,6 +2239,16 @@ static int adapt_keyid_ext(X509 *cert, X509V3_CTX *ext_ctx,
     return rv;
 }
 
+int cert_matches_key(const X509 *cert, const EVP_PKEY *pkey)
+{
+    int match;
+
+    ERR_set_mark();
+    match = X509_check_private_key(cert, pkey);
+    ERR_pop_to_mark();
+    return match;
+}
+
 /* Ensure RFC 5280 compliance, adapt keyIDs as needed, and sign the cert info */
 int do_X509_sign(X509 *cert, EVP_PKEY *pkey, const char *md,
                  STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx)
@@ -2254,16 +2264,14 @@ int do_X509_sign(X509 *cert, EVP_PKEY *pkey, const char *md,
             goto end;
 
         /*
-         * Add default SKID before such that default AKID can make use of it
+         * Add default SKID before AKID such that AKID can make use of it
          * in case the certificate is self-signed
          */
         /* Prevent X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER */
         if (!adapt_keyid_ext(cert, ext_ctx, "subjectKeyIdentifier", "hash", 1))
             goto end;
         /* Prevent X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER */
-        ERR_set_mark();
-        self_sign = X509_check_private_key(cert, pkey);
-        ERR_pop_to_mark();
+        self_sign = cert_matches_key(cert, pkey);
         if (!adapt_keyid_ext(cert, ext_ctx, "authorityKeyIdentifier",
                              "keyid, issuer", !self_sign))
             goto end;
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index dcb173f201..acc45c405a 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -555,7 +555,7 @@ int pkcs12_main(int argc, char **argv)
                 /* Look for matching private key */
                 for (i = 0; i < sk_X509_num(certs); i++) {
                     x = sk_X509_value(certs, i);
-                    if (X509_check_private_key(x, key)) {
+                    if (cert_matches_key(x, key)) {
                         ee_cert = x;
                         /* Zero keyid and alias */
                         X509_keyid_set1(ee_cert, NULL, 0);
diff --git a/apps/req.c b/apps/req.c
index 7997ea7649..274f839902 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -838,11 +838,9 @@ int req_main(int argc, char **argv)
             if (CAcert == NULL) {
                 if (!X509V3_set_issuer_pkey(&ext_ctx, issuer_key))
                     goto end;
-                ERR_set_mark();
-                if (!X509_check_private_key(new_x509, issuer_key))
+                if (!cert_matches_key(new_x509, issuer_key))
                     BIO_printf(bio_err,
                                "Warning: Signature key and public key of cert do not match\n");
-                ERR_pop_to_mark();
             }
             X509V3_set_nconf(&ext_ctx, req_conf);
 
diff --git a/apps/x509.c b/apps/x509.c
index b88fb4f5ea..ff95821bab 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -810,6 +810,10 @@ int x509_main(int argc, char **argv)
             goto end;
         if (!x509toreq && !reqfile && !newcert && !self_signed(ctx, x))
             goto end;
+    } else {
+        if (privkey != NULL && !cert_matches_key(x, privkey))
+            BIO_printf(bio_err,
+                       "Warning: Signature key and public key of cert do not match\n");
     }
 
     if (sno != NULL && !X509_set_serialNumber(x, sno))
diff --git a/crypto/x509/v3_akid.c b/crypto/x509/v3_akid.c
index 43b515f50c..59ea439edd 100644
--- a/crypto/x509/v3_akid.c
+++ b/crypto/x509/v3_akid.c
@@ -161,8 +161,13 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
          */
         i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1);
         if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL
-            && !(same_issuer && !ss))
+            && !(same_issuer && !ss)) {
             ikeyid = X509V3_EXT_d2i(ext);
+            if (ASN1_STRING_length(ikeyid) == 0) /* indicating "none" */ {
+                ASN1_OCTET_STRING_free(ikeyid);
+                ikeyid = NULL;
+            }
+        }
         if (ikeyid == NULL && same_issuer && ctx->issuer_pkey != NULL) {
             /* generate fallback AKID, emulating s2i_skey_id(..., "hash") */
             X509_PUBKEY *pubkey = NULL;
@@ -171,15 +176,13 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
                 ikeyid = ossl_x509_pubkey_hash(pubkey);
             X509_PUBKEY_free(pubkey);
         }
-        if ((keyid == 2 || issuer == 0)
-            && (ikeyid == NULL
-                || ASN1_STRING_length(ikeyid) <= 2) /* indicating "none" */) {
+        if (keyid == 2 && ikeyid == NULL) {
             ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
             goto err;
         }
     }
 
-    if (issuer == 2 || (issuer == 1 && ikeyid == NULL)) {
+    if (issuer == 2 || (issuer == 1 && !ss && ikeyid == NULL)) {
         isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert));
         serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert));
         if (isname == NULL || serial == NULL) {
diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c
index 1c11d671b2..b95c652468 100644
--- a/crypto/x509/v3_conf.c
+++ b/crypto/x509/v3_conf.c
@@ -311,13 +311,27 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
 {
     X509_EXTENSION *ext;
     STACK_OF(CONF_VALUE) *nval;
-    CONF_VALUE *val;
-    int i;
+    const CONF_VALUE *val;
+    int i, akid = -1, skid = -1;
 
     if ((nval = NCONF_get_section(conf, section)) == NULL)
         return 0;
     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
         val = sk_CONF_VALUE_value(nval, i);
+        if (strcmp(val->name, "authorityKeyIdentifier") == 0)
+            akid = i;
+        else if (strcmp(val->name, "subjectKeyIdentifier") == 0)
+            skid = i;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (skid > akid && akid >= 0) {
+            /* make sure SKID is handled before AKID */
+            if (i == akid)
+                val = sk_CONF_VALUE_value(nval, skid);
+            else if (i == skid)
+                val = sk_CONF_VALUE_value(nval, akid);
+        }
         if ((ext = X509V3_EXT_nconf_int(conf, ctx, val->section,
                                         val->name, val->value)) == NULL)
             return 0;
diff --git a/doc/man5/x509v3_config.pod b/doc/man5/x509v3_config.pod
index 2a3afee27f..0114b45505 100644
--- a/doc/man5/x509v3_config.pod
+++ b/doc/man5/x509v3_config.pod
@@ -208,6 +208,7 @@ If B<always> is present but no value can be obtained, an error is returned.
 If B<issuer> is present, and in addition it has the option B<always> specified
 or B<keyid> is not present,
 then the issuer DN and serial number are copied from the issuer certificate.
+If this fails, an error is returned.
 
 Examples:
 
diff --git a/test/certs/ext-check.csr b/test/certs/ext-check.csr
index ee974e05ce..a5ca888156 100644
--- a/test/certs/ext-check.csr
+++ b/test/certs/ext-check.csr
@@ -1,18 +1,9 @@
 -----BEGIN CERTIFICATE REQUEST-----
-MIICzTCCAbcCAQAwVDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
-ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDENMAsGA1UEAwwEdGVz
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvdj9Ix
-sogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOzn1k5
-0DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/Wl9rF
-QtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0lYW5I
-NvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAcZGh7
-r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9CLNN
-sUcCAwEAAaA2MBYGCSqGSIb3DQEJAjEJDAdDb21wYW55MBwGCSqGSIb3DQEJDjEP
-MA0wCwYDVR0PBAQDAgeAMAsGCSqGSIb3DQEBCwOCAQEAYd4B+FkWRuVVDPYfrN8P
-UdZbLTggUGrpdhRibnoAsLNQ3cCS90OsCq5FLD6TVUCNb1gnp15Jp1WChQSyD3zC
-jb8VgivDeDOuk08Zy2Fl2+QvuwyQ9hKTAOTdAmP/bapAi7zniElSTP6BZ8vyEtuP
-FCEWJ5UjhvUYbZOG5WIHxhT+24CtYH3iHNir4OlDbsYrUBKEmQZIDj6WC01UT+4U
-/up2xKq1Y+rOUv2Xy3K9O/U1W/3AF7IvcDyd7+qQTGD8U2X3efzZYOffhTN+9Rvn
-5t82CnHLjFn4Co43RBiOcbjSDbvtaghtDiYB2tSUuqafHiuAJKx6zAm0Y2FR8X+z
-gg==
+MIIBJzCBsgIBADAPMQ0wCwYDVQQDDAR0ZXN0MHwwDQYJKoZIhvcNAQEBBQADawAw
+aAJhALntqSk2YVnhNalAikA2tuSOvHUKVSJlqjKmzlUPI+gQFyBWxtyQdwepI87t
+l8EW1in2IiOeN49W+OtVOlBiMxwqi/BcBltTbbSrlRpoSKOH6V7zIXvfsqjwWsDi
+37V1xQIDAQABoB4wHAYJKoZIhvcNAQkOMQ8wDTALBgNVHQ8EBAMCB4AwDQYJKoZI
+hvcNAQELBQADYQCu+Qad0pgxIY8PUo6pvg8nNruEyrk/0/weL+sPZxEv0hSrIaGo
+ZaVGcPGi67oidiUyM2eMwDUUz3UmPA4oHNGRCddnTMISDxynLEM55CUECLFxXhP+
+8dJsKuJ9jbdasn4=
 -----END CERTIFICATE REQUEST-----
diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t
index 235b53c61c..c1587b76d7 100644
--- a/test/recipes/25-test_req.t
+++ b/test/recipes/25-test_req.t
@@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
 
 setup("test_req");
 
-plan tests => 43;
+plan tests => 91;
 
 require_ok(srctop_file('test', 'recipes', 'tconversion.pl'));
 
@@ -37,7 +37,7 @@ $ENV{MSYS2_ARG_CONV_EXCL} = "/CN=";
 
 # Check for duplicate -addext parameters, and one "working" case.
 my @addext_args = ( "openssl", "req", "-new", "-out", "testreq.pem",
-                    "-key",  srctop_file("test", "certs", "ee-key.pem"),
+                    "-key",  srctop_file(@certs, "ee-key.pem"),
     "-config", srctop_file("test", "test.cnf"), @req_new );
 my $val = "subjectAltName=DNS:example.com";
 my $val2 = " " . $val;
@@ -298,7 +298,7 @@ subtest "generating certificate requests" => sub {
     plan tests => 2;
 
     ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"),
-                "-key", srctop_file("test", "certs", "ee-key.pem"),
+                "-key", srctop_file(@certs, "ee-key.pem"),
                 @req_new, "-out", "testreq.pem"])),
        "Generating request");
 
@@ -415,36 +415,150 @@ sub strict_verify {
 my @v3_ca = ("-addext", "basicConstraints = critical,CA:true",
              "-addext", "keyUsage = keyCertSign");
 my $SKID_AKID = "subjectKeyIdentifier,authorityKeyIdentifier";
-my $cert = "self-signed_v1_CA_no_KIDs.pem";
+
+# # SKID
+
+my $cert = "self-signed_v3_CA_hash_SKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "subjectKeyIdentifier = hash");
+has_SKID($cert, 1); # explicit hash SKID
+
+$cert = "self-signed_v3_CA_no_SKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "subjectKeyIdentifier = none");
+cert_ext_has_n_different_lines($cert, 0, $SKID_AKID); # no SKID and no AKID
+#TODO strict_verify($cert, 0);
+
+$cert = "self-signed_v3_CA_given_SKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "subjectKeyIdentifier = 45");
+cert_contains($cert, "Subject Key Identifier: 45 ", 1); # given SKID
+strict_verify($cert, 1);
+
+# AKID of self-signed certs
+
+$cert = "self-signed_v1_CA_no_KIDs.pem";
 generate_cert($cert);
 cert_ext_has_n_different_lines($cert, 0, $SKID_AKID); # no SKID and no AKID
 #TODO strict_verify($cert, 1); # self-signed v1 root cert should be accepted as CA
 
-$ca_cert = "self-signed_v3_CA_default_SKID.pem";
+$ca_cert = "self-signed_v3_CA_default_SKID.pem"; # will also be used below
 generate_cert($ca_cert, @v3_ca);
-has_SKID($ca_cert, 1);
-has_AKID($ca_cert, 0);
+has_SKID($ca_cert, 1); # default SKID
+has_AKID($ca_cert, 0); # no default AKID
 strict_verify($ca_cert, 1);
 
-$cert = "self-signed_v3_CA_no_SKID.pem";
-generate_cert($cert, @v3_ca, "-addext", "subjectKeyIdentifier = none");
-cert_ext_has_n_different_lines($cert, 0, $SKID_AKID); # no SKID and no AKID
-#TODO strict_verify($cert, 0);
+$cert = "self-signed_v3_CA_no_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = none");
+has_AKID($cert, 0); # forced no AKID
 
-$cert = "self-signed_v3_CA_both_KIDs.pem";
-generate_cert($cert, @v3_ca, "-addext", "subjectKeyIdentifier = hash",
-            "-addext", "authorityKeyIdentifier = keyid:always");
-cert_ext_has_n_different_lines($cert, 3, $SKID_AKID); # SKID == AKID
+$cert = "self-signed_v3_CA_explicit_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid");
+has_AKID($cert, 0); # for self-signed cert, AKID suppressed and not forced
+
+$cert = "self-signed_v3_CA_forced_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid:always");
+cert_ext_has_n_different_lines($cert, 3, $SKID_AKID); # forced AKID, AKID == SKID
 strict_verify($cert, 1);
 
+$cert = "self-signed_v3_CA_issuer_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = issuer");
+has_AKID($cert, 0); # suppressed AKID since not forced
+
+$cert = "self-signed_v3_CA_forced_issuer_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = issuer:always");
+cert_contains($cert, "Authority Key Identifier: DirName:/CN=CA serial:", 1); # forced issuer AKID
+
+$cert = "self-signed_v3_CA_nonforced_keyid_issuer_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid, issuer");
+has_AKID($cert, 0); # AKID not present because not forced and cert self-signed
+
+$cert = "self-signed_v3_CA_keyid_forced_issuer_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid, issuer:always");
+cert_contains($cert, "Authority Key Identifier: DirName:/CN=CA serial:", 1); # issuer AKID forced, with keyid not forced
+
+$cert = "self-signed_v3_CA_forced_keyid_issuer_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid:always, issuer");
+has_AKID($cert, 1); # AKID with keyid forced
+cert_contains($cert, "Authority Key Identifier: DirName:/CN=CA serial:", 0); # no issuer AKID
+
+$cert = "self-signed_v3_CA_forced_keyid_forced_issuer_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid:always, issuer:always");
+cert_contains($cert, "Authority Key Identifier: keyid(:[0-9A-Fa-f]{2})+ DirName:/CN=CA serial:", 1); # AKID with keyid and issuer forced
+
 $cert = "self-signed_v3_EE_wrong_keyUsage.pem";
 generate_cert($cert, "-addext", "keyUsage = keyCertSign");
 #TODO strict_verify($cert, 1); # should be accepted because RFC 5280 does not apply
 
-$cert = "v3_EE_default_KIDs.pem";
+# AKID of self-issued but not self-signed certs
+
+$cert = "self-issued_x509_v3_CA_default_KIDs.pem";
+ok(run(app([("openssl", "x509", "-copy_extensions", "copy",
+             "-req", "-in", srctop_file(@certs, "ext-check.csr"),
+             "-key", srctop_file(@certs, "ca-key.pem"),
+             "-force_pubkey", srctop_file("test", "testrsapub.pem"),
+             "-out", $cert)])), "generate using x509: $cert");
+cert_contains($cert, "Issuer: CN=test .*? Subject: CN=test", 1);
+cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
+strict_verify($cert, 1);
+
+$cert = "self-issued_v3_CA_default_KIDs.pem";
+generate_cert($cert, "-addext", "keyUsage = dataEncipherment",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+cert_contains($cert, "Issuer: CN=CA .*? Subject: CN=CA", 1);
+cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
+strict_verify($cert, 1);
+
+$cert = "self-issued_v3_CA_no_AKID.pem";
+generate_cert($cert, "-addext", "authorityKeyIdentifier = none",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+has_AKID($cert, 0);
+strict_verify($cert, 1);
+
+$cert = "self-issued_v3_CA_explicit_AKID.pem";
+generate_cert($cert, "-addext", "authorityKeyIdentifier = keyid",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
+strict_verify($cert, 1);
+
+$cert = "self-issued_v3_CA_forced_AKID.pem";
+generate_cert($cert, "-addext", "authorityKeyIdentifier = keyid:always",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
+
+$cert = "self-issued_v3_CA_issuer_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = issuer",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+cert_contains($cert, "Authority Key Identifier: DirName:/CN=CA serial:", 1); # just issuer AKID
+
+$cert = "self-issued_v3_CA_forced_issuer_AKID.pem";
+generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = issuer:always",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+cert_contains($cert, "Authority Key Identifier: DirName:/CN=CA serial:", 1); # just issuer AKID
+
+$cert = "self-issued_v3_CA_keyid_issuer_AKID.pem";
+generate_cert($cert, "-addext", "authorityKeyIdentifier = keyid, issuer",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID, not forced
+
+$cert = "self-issued_v3_CA_keyid_forced_issuer_AKID.pem";
+generate_cert($cert, "-addext", "authorityKeyIdentifier = keyid, issuer:always",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+cert_ext_has_n_different_lines($cert, 6, $SKID_AKID); # SKID != AKID, with forced issuer
+
+$cert = "self-issued_v3_CA_forced_keyid_and_issuer_AKID.pem";
+generate_cert($cert, "-addext", "authorityKeyIdentifier = keyid:always, issuer:always",
+    "-in", srctop_file(@certs, "x509-check.csr"));
+cert_ext_has_n_different_lines($cert, 6, $SKID_AKID); # SKID != AKID, both forced
+
+# AKID of not self-issued certs
+
+$cert = "regular_v3_EE_default_KIDs.pem";
 generate_cert($cert, "-addext", "keyUsage = dataEncipherment");
 cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
 strict_verify($cert, 1, $ca_cert);
+$cert = "regular_v3_EE_copied_exts_default_KIDs.pem";
+generate_cert($cert, "-copy_extensions", "copy",
+              "-in", srctop_file(@certs, "ext-check.csr"));
+cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
+strict_verify($cert, 1);
 
 $cert = "v3_EE_no_AKID.pem";
 generate_cert($cert, "-addext", "authorityKeyIdentifier = none");
@@ -452,16 +566,13 @@ has_SKID($cert, 1);
 has_AKID($cert, 0);
 strict_verify($cert, 0, $ca_cert);
 
-$cert = "self-issued_v3_EE_default_KIDs.pem";
-generate_cert($cert, "-addext", "keyUsage = dataEncipherment",
-    "-in", srctop_file(@certs, "x509-check.csr"));
-cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
-strict_verify($cert, 1);
 
-my $cert = "self-signed_CA_no_keyUsage.pem";
+# Key Usage
+
+$cert = "self-signed_CA_no_keyUsage.pem";
 generate_cert($cert, "-in", srctop_file(@certs, "ext-check.csr"));
 has_keyUsage($cert, 0);
-my $cert = "self-signed_CA_with_keyUsages.pem";
+$cert = "self-signed_CA_with_keyUsages.pem";
 generate_cert($cert, "-in", srctop_file(@certs, "ext-check.csr"),
     "-copy_extensions", "copy");
 has_keyUsage($cert, 1);
diff --git a/test/recipes/tconversion.pl b/test/recipes/tconversion.pl
index 87b037b34d..f60954c0ba 100644
--- a/test/recipes/tconversion.pl
+++ b/test/recipes/tconversion.pl
@@ -114,6 +114,7 @@ sub file_contains {
     open(DATA, $_) or return 0;
     $_= join('', <DATA>);
     close(DATA);
+    s/\s+/ /g; # take multiple whitespace (including newline) as single space
     return m/$pattern/ ? 1 : 0;
 }
 
@@ -125,7 +126,7 @@ sub cert_contains {
     my $out = "cert_contains.out";
     run(app(["openssl", "x509", "-noout", "-text", "-in", $cert, "-out", $out]));
     is(file_contains($out, $pattern), $expected, ($name ? "$name: " : "").
-       "$cert should ".($expected ? "" : "not ")."contain $pattern");
+       "$cert should ".($expected ? "" : "not ")."contain: \"$pattern\"");
     # not unlinking $out
 }
 


More information about the openssl-commits mailing list