This is an automated email from the ASF dual-hosted git repository.

dsoumis pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 61510fbf97208b54132b0c756b8ee1e7f8acd0e8
Author: Dimitris Soumis <[email protected]>
AuthorDate: Thu Oct 29 21:03:25 2026 +0200

    Replace runtime certificate generation with pre-generated fixtures
---
 .../SSLUtilBaseCertificateSelectionTestBase.java   | 164 +++++++++++++++++----
 ...stSSLUtilBaseAutomaticCertificateSelection.java |  36 +++--
 .../TestSSLUtilBaseConfiguredAliasSelection.java   |  82 +++++------
 .../tomcat/util/net/TesterKeystoreGenerator.java   | 133 ++---------------
 .../tomcat/util/net/localhost-rsa-anyauth.jks      | Bin 0 -> 2639 bytes
 .../tomcat/util/net/localhost-rsa-clientauth.jks   | Bin 0 -> 2643 bytes
 .../apache/tomcat/util/net/localhost-rsa-noeku.jks | Bin 0 -> 2757 bytes
 .../tomcat/util/net/localhost-rsa-serverauth.jks   | Bin 0 -> 2644 bytes
 .../tomcat/util/net/localhost-rsa-serverauth2.jks  | Bin 0 -> 2641 bytes
 9 files changed, 207 insertions(+), 208 deletions(-)

diff --git 
a/test/org/apache/tomcat/util/net/SSLUtilBaseCertificateSelectionTestBase.java 
b/test/org/apache/tomcat/util/net/SSLUtilBaseCertificateSelectionTestBase.java
index d2efc36526..3c3522e889 100644
--- 
a/test/org/apache/tomcat/util/net/SSLUtilBaseCertificateSelectionTestBase.java
+++ 
b/test/org/apache/tomcat/util/net/SSLUtilBaseCertificateSelectionTestBase.java
@@ -18,6 +18,8 @@
 package org.apache.tomcat.util.net;
 
 import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
 import java.security.Key;
 import java.security.KeyStore;
 import java.security.KeyStoreSpi;
@@ -28,7 +30,9 @@ import java.security.cert.X509Certificate;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
+import java.util.EnumMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -42,11 +46,6 @@ import org.junit.runners.Parameterized.Parameter;
 
 import org.apache.catalina.startup.TomcatBaseTest;
 import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type;
-import 
org.apache.tomcat.util.net.TesterKeystoreGenerator.CertificateExtensionsCustomizer;
-import org.apache.tomcat.util.net.TesterKeystoreGenerator.KeystoreEntry;
-import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.KeyPurposeId;
 import org.easymock.EasyMock;
 
 /**
@@ -91,19 +90,75 @@ public abstract class 
SSLUtilBaseCertificateSelectionTestBase extends TomcatBase
 
     protected static final String CLIENT_AUTH_EXTENDED_KEY_USAGE_OID = 
"1.3.6.1.5.5.7.3.2";
 
-    @SuppressWarnings("unused")
-    protected static final CertificateExtensionsCustomizer SERVER_AUTH = 
(keyPair, builder) -> builder
-            .addExtension(Extension.extendedKeyUsage, true, new 
ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth));
-    @SuppressWarnings("unused")
-    protected static final CertificateExtensionsCustomizer CLIENT_AUTH = 
(keyPair, builder) -> builder
-            .addExtension(Extension.extendedKeyUsage, true, new 
ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth));
-    @SuppressWarnings("unused")
-    protected static final CertificateExtensionsCustomizer ANY_AUTH = 
(keyPair, builder) -> builder
-            .addExtension(Extension.extendedKeyUsage, true, new 
ExtendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage));
+    private static final String SERVER_AUTH_KEYSTORE = TesterSupport.SSL_DIR + 
"localhost-rsa-serverauth.jks";
+    private static final String SERVER_AUTH_KEYSTORE_2 = TesterSupport.SSL_DIR 
+ "localhost-rsa-serverauth2.jks";
+    private static final String CLIENT_AUTH_KEYSTORE = TesterSupport.SSL_DIR + 
"localhost-rsa-clientauth.jks";
+    private static final String ANY_AUTH_KEYSTORE = TesterSupport.SSL_DIR + 
"localhost-rsa-anyauth.jks";
+    private static final String NO_EKU_KEYSTORE = TesterSupport.SSL_DIR + 
"localhost-rsa-noeku.jks";
+
+    protected enum CertType {
+        SERVER_AUTH,
+        CLIENT_AUTH,
+        ANY_AUTH,
+        NO_EKU
+    }
+
+    private static Map<CertType,List<CertAndKey>> certificatePool;
+
+    private static final class CertAndKey {
+
+        private final PrivateKey key;
+        private final X509Certificate certificate;
+
+        private CertAndKey(PrivateKey key, X509Certificate certificate) {
+            this.key = key;
+            this.certificate = certificate;
+        }
+
+        public PrivateKey key() {
+            return key;
+        }
+
+        public X509Certificate certificate() {
+            return certificate;
+        }
+    }
 
+    /**
+     * An entry to place into a test key store: the alias, which pre-generated 
certificate to use, and whether it is a
+     * private key entry or a trusted (certificate-only) entry.
+     */
+    protected static final class KeystoreEntry {
+
+        private final String alias;
+        private final CertType certType;
+        private final boolean keyEntry;
+
+        protected KeystoreEntry(String alias, CertType certType, boolean 
keyEntry) {
+            this.alias = alias;
+            this.certType = certType;
+            this.keyEntry = keyEntry;
+        }
+
+        protected static KeystoreEntry trusted(String alias) {
+            return new KeystoreEntry(alias, CertType.SERVER_AUTH, false);
+        }
+
+        public String alias() {
+            return alias;
+        }
+
+        public CertType certType() {
+            return certType;
+        }
+
+        public boolean keyEntry() {
+            return keyEntry;
+        }
+    }
 
-    protected static KeystoreEntry key(String alias, 
CertificateExtensionsCustomizer eku) {
-        return KeystoreEntry.key(alias, HOST, eku);
+    protected static KeystoreEntry key(String alias, CertType certType) {
+        return new KeystoreEntry(alias, certType, true);
     }
 
 
@@ -150,8 +205,8 @@ public abstract class 
SSLUtilBaseCertificateSelectionTestBase extends TomcatBase
      * The cut-off date is far enough in the future that every certificate 
qualifies, so the result is exactly the set
      * of certificates the listener monitors for reload.
      */
-    protected Set<X509Certificate> certificatesMonitoredForReload(String 
alias, KeyStore keystore) throws Exception {
-        SSLHostConfigCertificate certificate = registeredCertificate(alias, 
keystore);
+    protected Set<X509Certificate> certificatesMonitoredForReload(KeyStore 
keystore) throws Exception {
+        SSLHostConfigCertificate certificate = registeredCertificate(keystore);
         SSLContext context = sslUtil(certificate).createSSLContext(List.of());
         try {
             certificate.setSslContext(context);
@@ -167,8 +222,8 @@ public abstract class 
SSLUtilBaseCertificateSelectionTestBase extends TomcatBase
      * Builds and registers an SSLContext for the given configured alias and 
key store, then returns the alias the
      * context reports as actually served - which is what the certificate 
logging and reload paths resolve.
      */
-    protected String servedAlias(String alias, KeyStore keystore) throws 
Exception {
-        SSLHostConfigCertificate certificate = registeredCertificate(alias, 
keystore);
+    protected String servedAlias(KeyStore keystore) throws Exception {
+        SSLHostConfigCertificate certificate = registeredCertificate(keystore);
         SSLContext context = sslUtil(certificate).createSSLContext(List.of());
         try {
             certificate.setSslContext(context);
@@ -179,20 +234,76 @@ public abstract class 
SSLUtilBaseCertificateSelectionTestBase extends TomcatBase
     }
 
 
-    private static SSLHostConfigCertificate registeredCertificate(String 
alias, KeyStore keystore) {
+    private static SSLHostConfigCertificate registeredCertificate(KeyStore 
keystore) {
         SSLHostConfig hostConfig = new SSLHostConfig();
         SSLHostConfigCertificate certificate = new 
SSLHostConfigCertificate(hostConfig, Type.UNDEFINED);
         certificate.setCertificateKeystore(keystore);
         certificate.setCertificateKeystoreType("JKS");
         certificate.setCertificateKeystorePassword(TesterSupport.JKS_PASS);
-        if (alias != null) {
-            certificate.setCertificateKeyAlias(alias);
-        }
+        
certificate.setCertificateKeyAlias(SSLUtilBaseCertificateSelectionTestBase.HOST);
         hostConfig.addCertificate(certificate);
         return certificate;
     }
 
 
+    private static synchronized Map<CertType,List<CertAndKey>> 
certificatePool() throws Exception {
+        if (certificatePool == null) {
+            Map<CertType,List<CertAndKey>> pool = new 
EnumMap<>(CertType.class);
+            pool.put(CertType.SERVER_AUTH, List.of(load(SERVER_AUTH_KEYSTORE), 
load(SERVER_AUTH_KEYSTORE_2)));
+            pool.put(CertType.CLIENT_AUTH, 
List.of(load(CLIENT_AUTH_KEYSTORE)));
+            pool.put(CertType.ANY_AUTH, List.of(load(ANY_AUTH_KEYSTORE)));
+            pool.put(CertType.NO_EKU, List.of(load(NO_EKU_KEYSTORE)));
+            certificatePool = pool;
+        }
+        return certificatePool;
+    }
+
+
+    private static CertAndKey load(String keystoreFile) throws Exception {
+        KeyStore keystore = KeyStore.getInstance(new File(keystoreFile), 
TesterSupport.JKS_PASS.toCharArray());
+        String alias = keystore.aliases().nextElement();
+        return new CertAndKey((PrivateKey) keystore.getKey(alias, 
TesterSupport.JKS_PASS.toCharArray()),
+                (X509Certificate) keystore.getCertificate(alias));
+    }
+
+
+    /*
+     * Populates the key store from the pre-generated pool, one certificate 
per entry. Repeated entries of the same
+     * category are given distinct certificates where the pool holds more than 
one (so two server-auth entries in one
+     * store differ, as the duplicate-selection test requires).
+     */
+    private static void populate(KeyStore keystore, KeystoreEntry... entries) 
throws Exception {
+        Map<CertType,Integer> used = new EnumMap<>(CertType.class);
+        for (KeystoreEntry entry : entries) {
+            List<CertAndKey> options = certificatePool().get(entry.certType());
+            CertAndKey chosen = options.get((used.merge(entry.certType(), 1, 
Integer::sum) - 1) % options.size());
+            if (entry.keyEntry()) {
+                keystore.setKeyEntry(entry.alias(), chosen.key(), 
TesterSupport.JKS_PASS.toCharArray(),
+                        new X509Certificate[] { chosen.certificate() });
+            } else {
+                keystore.setCertificateEntry(entry.alias(), 
chosen.certificate());
+            }
+        }
+    }
+
+
+    /*
+     * Writes a temporary JKS file populated from the pool, for the tests that 
configure a certificateKeystoreFile
+     * rather than an in-memory key store.
+     */
+    protected static File keystoreFile(KeystoreEntry... entries) throws 
Exception {
+        KeyStore keystore = KeyStore.getInstance("JKS");
+        keystore.load(null, null);
+        populate(keystore, entries);
+        File file = File.createTempFile("cert-selection-", ".jks");
+        file.deleteOnExit();
+        try (OutputStream os = new FileOutputStream(file)) {
+            keystore.store(os, TesterSupport.JKS_PASS.toCharArray());
+        }
+        return file;
+    }
+
+
     protected static KeyStore orderedKeystore(String malformedAlias, 
KeystoreEntry... entries) throws Exception {
         return orderedKeystore(sunMSCAPIProvider(), "Windows-MY", 
KeyMode.EXPORTABLE, malformedAlias, entries);
     }
@@ -249,8 +360,9 @@ public abstract class 
SSLUtilBaseCertificateSelectionTestBase extends TomcatBase
 
     protected static KeyStore orderedKeystore(Provider provider, String type, 
KeyMode keyMode,
             String malformedAlias, KeystoreEntry... entries) throws Exception {
-        File file = TesterKeystoreGenerator.generateKeystore(List.of(entries));
-        KeyStore delegate = KeyStore.getInstance(file, 
TesterSupport.JKS_PASS.toCharArray());
+        KeyStore delegate = KeyStore.getInstance("JKS");
+        delegate.load(null, null);
+        populate(delegate, entries);
         List<String> aliases = 
Stream.of(entries).map(KeystoreEntry::alias).collect(Collectors.toList());
 
         // JKS type of keystore enumeration order is unspecified.
diff --git 
a/test/org/apache/tomcat/util/net/TestSSLUtilBaseAutomaticCertificateSelection.java
 
b/test/org/apache/tomcat/util/net/TestSSLUtilBaseAutomaticCertificateSelection.java
index 776a60e15e..d868c269bb 100644
--- 
a/test/org/apache/tomcat/util/net/TestSSLUtilBaseAutomaticCertificateSelection.java
+++ 
b/test/org/apache/tomcat/util/net/TestSSLUtilBaseAutomaticCertificateSelection.java
@@ -30,7 +30,6 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type;
-import org.apache.tomcat.util.net.TesterKeystoreGenerator.KeystoreEntry;
 
 /**
  * Tests that, when no {@code certificateKeyAlias} is configured, {@link 
SSLUtilBase#getKeyManagers()} auto-selects the
@@ -43,8 +42,8 @@ public class TestSSLUtilBaseAutomaticCertificateSelection 
extends SSLUtilBaseCer
     @Test
     public void testAutoSelectPrefersServerAuthOverClientAuth() throws 
Exception {
         X509Certificate presented = present(null,
-                key("first", CLIENT_AUTH),
-                key("second", SERVER_AUTH));
+                key("first", CertType.CLIENT_AUTH),
+                key("second", CertType.SERVER_AUTH));
         assertEku(presented, Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -52,8 +51,8 @@ public class TestSSLUtilBaseAutomaticCertificateSelection 
extends SSLUtilBaseCer
     @Test
     public void testAutoSelectAcceptsAnyExtendedKeyUsage() throws Exception {
         X509Certificate presented = present(null,
-                key("first", CLIENT_AUTH),
-                key("any", ANY_AUTH));
+                key("first", CertType.CLIENT_AUTH),
+                key("any", CertType.ANY_AUTH));
         assertEku(presented, Constants.ANY_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -61,8 +60,8 @@ public class TestSSLUtilBaseAutomaticCertificateSelection 
extends SSLUtilBaseCer
     @Test
     public void testAutoSelectAcceptsCertificateWithoutExtendedKeyUsage() 
throws Exception {
         X509Certificate presented = present(null,
-                key("first", CLIENT_AUTH),
-                key("none", null));
+                key("first", CertType.CLIENT_AUTH),
+                key("none", CertType.NO_EKU));
         Assert.assertNull("A certificate with no Extended Key Usage is 
unrestricted and must be selectable",
                 presented.getExtendedKeyUsage());
     }
@@ -71,44 +70,44 @@ public class TestSSLUtilBaseAutomaticCertificateSelection 
extends SSLUtilBaseCer
     @Test
     public void testAutoSelectSkipsTrustedEntries() {
         Assert.assertThrows(IOException.class, () -> present(null,
-                KeystoreEntry.trusted("ca", HOST, SERVER_AUTH),
-                key("key", CLIENT_AUTH)));
+                KeystoreEntry.trusted("ca"),
+                key("key", CertType.CLIENT_AUTH)));
     }
 
 
     @Test
     public void testAutoSelectFailsWhenNoneServerAuth() {
         Assert.assertThrows(IOException.class, () -> present(null,
-                key("first", CLIENT_AUTH),
-                key("second", CLIENT_AUTH)));
+                key("first", CertType.CLIENT_AUTH),
+                key("second", CertType.CLIENT_AUTH)));
     }
 
 
     @Test
     public void testAutoSelectSkipsMalformedExtendedKeyUsage() throws 
Exception {
-        KeyStore keystore = orderedKeystore("malformed", key("malformed", 
CLIENT_AUTH), key("server", SERVER_AUTH));
+        KeyStore keystore = orderedKeystore("malformed", key("malformed", 
CertType.CLIENT_AUTH), key("server", CertType.SERVER_AUTH));
         assertEku(present(null, keystore), 
Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
 
     @Test
     public void testAutoSelectFailsWhenOnlyMalformedExtendedKeyUsage() throws 
Exception {
-        KeyStore keystore = orderedKeystore("malformed", key("malformed", 
CLIENT_AUTH));
+        KeyStore keystore = orderedKeystore("malformed", key("malformed", 
CertType.CLIENT_AUTH));
         Assert.assertThrows(IOException.class, () -> present(null, keystore));
     }
 
 
     @Test
     public void testAutoSelectUsesFirstEligibleKey() throws Exception {
-        KeyStore keystore = orderedKeystore(null, key("client", CLIENT_AUTH), 
key("first", ANY_AUTH),
-                key("second", SERVER_AUTH));
+        KeyStore keystore = orderedKeystore(null, key("client", 
CertType.CLIENT_AUTH), key("first", CertType.ANY_AUTH),
+                key("second", CertType.SERVER_AUTH));
         Assert.assertEquals(keystore.getCertificate("first"), present(null, 
keystore));
     }
 
 
     @Test
     public void testAutoSelectDoesNotSkipKeyReadFailure() throws Exception {
-        KeyStore keystore = orderedKeystore(null, key("first", SERVER_AUTH), 
key("second", SERVER_AUTH));
+        KeyStore keystore = orderedKeystore(null, key("first", 
CertType.SERVER_AUTH), key("second", CertType.SERVER_AUTH));
         SSLHostConfig hostConfig = new SSLHostConfig();
         SSLHostConfigCertificate certificate = new 
SSLHostConfigCertificate(hostConfig, Type.UNDEFINED);
         certificate.setCertificateKeystore(keystore);
@@ -121,7 +120,7 @@ public class TestSSLUtilBaseAutomaticCertificateSelection 
extends SSLUtilBaseCer
 
     @Test
     public void testSSLContextUsesSelectedCertificate() throws Exception {
-        KeyStore keystore = orderedKeystore(null, key("client", CLIENT_AUTH), 
key("server", SERVER_AUTH));
+        KeyStore keystore = orderedKeystore(null, key("client", 
CertType.CLIENT_AUTH), key("server", CertType.SERVER_AUTH));
         SSLContext context = sslUtil(null, 
keystore).createSSLContext(List.of());
         try {
             Assert.assertEquals(keystore.getCertificate("server"), 
context.getCertificateChain("server")[0]);
@@ -133,8 +132,7 @@ public class TestSSLUtilBaseAutomaticCertificateSelection 
extends SSLUtilBaseCer
 
     @Test
     public void testSSLContextLoadsSelectedCertificateFromKeystoreFile() 
throws Exception {
-        File file = TesterKeystoreGenerator.generateKeystore(
-                List.of(key(SSLUtilBase.DEFAULT_KEY_ALIAS, CLIENT_AUTH), 
key("server", SERVER_AUTH)));
+        File file = keystoreFile(key(SSLUtilBase.DEFAULT_KEY_ALIAS, 
CertType.CLIENT_AUTH), key("server", CertType.SERVER_AUTH));
         KeyStore keystore = KeyStore.getInstance(file, 
TesterSupport.JKS_PASS.toCharArray());
         SSLHostConfig hostConfig = new SSLHostConfig();
         SSLHostConfigCertificate certificate = new 
SSLHostConfigCertificate(hostConfig, Type.UNDEFINED);
diff --git 
a/test/org/apache/tomcat/util/net/TestSSLUtilBaseConfiguredAliasSelection.java 
b/test/org/apache/tomcat/util/net/TestSSLUtilBaseConfiguredAliasSelection.java
index 0a8857ad90..fc4a37f02c 100644
--- 
a/test/org/apache/tomcat/util/net/TestSSLUtilBaseConfiguredAliasSelection.java
+++ 
b/test/org/apache/tomcat/util/net/TestSSLUtilBaseConfiguredAliasSelection.java
@@ -28,8 +28,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
-import org.apache.tomcat.util.net.TesterKeystoreGenerator.KeystoreEntry;
-
 /**
  * Tests {@link SSLUtilBase#getKeyManagers()} when a {@code 
certificateKeyAlias} is configured. The configured alias is
  * used even if its certificate is not valid for TLS server authentication, 
except in a SunMSCAPI Windows-MY key store:
@@ -42,8 +40,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection extends 
SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasIsUsedUnchangedWhenNotServerAuth() throws 
Exception {
         X509Certificate presented = present(HOST,
-                key(HOST, CLIENT_AUTH),
-                key("localhost-server", SERVER_AUTH));
+                key(HOST, CertType.CLIENT_AUTH),
+                key("localhost-server", CertType.SERVER_AUTH));
         assertEku(presented, CLIENT_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -51,8 +49,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection extends 
SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasIsUsedWhenServerAuth() throws Exception {
         X509Certificate presented = present(HOST,
-                key(HOST, SERVER_AUTH),
-                key("localhost-client", CLIENT_AUTH));
+                key(HOST, CertType.SERVER_AUTH),
+                key("localhost-client", CertType.CLIENT_AUTH));
         assertEku(presented, Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -60,8 +58,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection extends 
SSLUtilBaseCertific
     @Test
     public void 
testConfiguredAliasUsesNumberedDuplicateWhenBaseNotServerAuth() throws 
Exception {
         X509Certificate presented = present(HOST,
-                key(HOST, CLIENT_AUTH),
-                key(HOST + " (1)", SERVER_AUTH));
+                key(HOST, CertType.CLIENT_AUTH),
+                key(HOST + " (1)", CertType.SERVER_AUTH));
         assertEku(presented, Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -69,8 +67,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection extends 
SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasUnchangedForNonSunMSCAPIStore() throws 
Exception {
         KeyStore keystore = nonSunMSCAPIKeystore(
-                key(HOST, CLIENT_AUTH),
-                key(HOST + " (1)", SERVER_AUTH));
+                key(HOST, CertType.CLIENT_AUTH),
+                key(HOST + " (1)", CertType.SERVER_AUTH));
         X509Certificate presented = present(HOST, keystore);
         Assert.assertEquals(keystore.getCertificate(HOST), presented);
     }
@@ -79,8 +77,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection extends 
SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasKeepsBaseWhenAlreadyServerAuth() throws 
Exception {
         X509Certificate presented = present(HOST,
-                key(HOST, SERVER_AUTH),
-                key(HOST + " (1)", CLIENT_AUTH));
+                key(HOST, CertType.SERVER_AUTH),
+                key(HOST + " (1)", CertType.CLIENT_AUTH));
         assertEku(presented, Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -88,9 +86,9 @@ public class TestSSLUtilBaseConfiguredAliasSelection extends 
SSLUtilBaseCertific
     @Test
     public void 
testConfiguredAliasUsesSecondDuplicateWhenFirstIsNotServerAuth() throws 
Exception {
         X509Certificate presented = present(HOST,
-                key(HOST, CLIENT_AUTH),
-                key(HOST + " (1)", CLIENT_AUTH),
-                key(HOST + " (2)", SERVER_AUTH));
+                key(HOST, CertType.CLIENT_AUTH),
+                key(HOST + " (1)", CertType.CLIENT_AUTH),
+                key(HOST + " (2)", CertType.SERVER_AUTH));
         assertEku(presented, Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -98,9 +96,9 @@ public class TestSSLUtilBaseConfiguredAliasSelection extends 
SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasSelectsFirstOfSeveralServerAuthDuplicates() 
throws Exception {
         KeyStore keystore = orderedKeystore(null,
-                key("tomcat", CLIENT_AUTH),
-                key("tomcat (1)", SERVER_AUTH),
-                key("tomcat (2)", SERVER_AUTH));
+                key("tomcat", CertType.CLIENT_AUTH),
+                key("tomcat (1)", CertType.SERVER_AUTH),
+                key("tomcat (2)", CertType.SERVER_AUTH));
         X509Certificate presented = present("tomcat", keystore);
         Assert.assertEquals(keystore.getCertificate("tomcat (1)"), presented);
     }
@@ -109,9 +107,9 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasSkipsTrustedDuplicateAndUsesNextKeyEntry() 
throws Exception {
         X509Certificate presented = present(HOST,
-                key(HOST, CLIENT_AUTH),
-                KeystoreEntry.trusted(HOST + " (1)", HOST, SERVER_AUTH),
-                key(HOST + " (2)", SERVER_AUTH));
+                key(HOST, CertType.CLIENT_AUTH),
+                KeystoreEntry.trusted(HOST + " (1)"),
+                key(HOST + " (2)", CertType.SERVER_AUTH));
         assertEku(presented, Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -119,8 +117,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void 
testConfiguredAliasFallsBackToBaseWhenNoDuplicateIsServerAuth() throws 
Exception {
         X509Certificate presented = present(HOST,
-                key(HOST, CLIENT_AUTH),
-                key(HOST + " (1)", CLIENT_AUTH));
+                key(HOST, CertType.CLIENT_AUTH),
+                key(HOST + " (1)", CertType.CLIENT_AUTH));
         assertEku(presented, CLIENT_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -128,15 +126,15 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasIgnoresAliasNotMatchingDuplicateFormat() 
throws Exception {
         X509Certificate presented = present(HOST,
-                key(HOST, CLIENT_AUTH),
-                key(HOST + "(1)", SERVER_AUTH));
+                key(HOST, CertType.CLIENT_AUTH),
+                key(HOST + "(1)", CertType.SERVER_AUTH));
         assertEku(presented, CLIENT_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
 
     @Test
     public void testConfiguredAliasWithMalformedExtendedKeyUsageIsUsed() 
throws Exception {
-        KeyStore keystore = orderedKeystore("malformed", key("malformed", 
CLIENT_AUTH), key("server", SERVER_AUTH));
+        KeyStore keystore = orderedKeystore("malformed", key("malformed", 
CertType.CLIENT_AUTH), key("server", CertType.SERVER_AUTH));
         Assert.assertEquals(keystore.getCertificateChain("malformed")[0], 
present("malformed", keystore));
     }
 
@@ -144,21 +142,21 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasUsesNumberedDuplicateWhenBaseIsMalformed() 
throws Exception {
         KeyStore keystore =
-                orderedKeystore("malformed", key("malformed", CLIENT_AUTH), 
key("malformed (1)", SERVER_AUTH));
+                orderedKeystore("malformed", key("malformed", 
CertType.CLIENT_AUTH), key("malformed (1)", CertType.SERVER_AUTH));
         assertEku(present("malformed", keystore), 
Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
 
     @Test
     public void testConfiguredMissingAliasFails() {
-        Assert.assertThrows(IOException.class, () -> present("missing", 
key("server", SERVER_AUTH)));
+        Assert.assertThrows(IOException.class, () -> present("missing", 
key("server", CertType.SERVER_AUTH)));
     }
 
 
     @Test
     public void testConfiguredTrustedAliasFails() {
-        Assert.assertThrows(IOException.class, () -> present("trusted", 
KeystoreEntry.trusted("trusted", HOST, SERVER_AUTH),
-                key("server", SERVER_AUTH)));
+        Assert.assertThrows(IOException.class, () -> present("trusted", 
KeystoreEntry.trusted("trusted"),
+                key("server", CertType.SERVER_AUTH)));
     }
 
 
@@ -172,9 +170,9 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testReloadListenerMonitorsTheServedCertificate() throws 
Exception {
         Assume.assumeTrue("JSSE".equals(connectorName));
-        KeyStore keystore = nonExportableKeystore(key(HOST, CLIENT_AUTH), 
key(HOST + " (1)", SERVER_AUTH));
+        KeyStore keystore = nonExportableKeystore(key(HOST, 
CertType.CLIENT_AUTH), key(HOST + " (1)", CertType.SERVER_AUTH));
 
-        Set<X509Certificate> monitored = certificatesMonitoredForReload(HOST, 
keystore);
+        Set<X509Certificate> monitored = 
certificatesMonitoredForReload(keystore);
 
         X509Certificate served = (X509Certificate) 
keystore.getCertificateChain(HOST + " (1)")[0];
         X509Certificate notServed = (X509Certificate) 
keystore.getCertificateChain(HOST)[0];
@@ -192,8 +190,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testConfiguredTrustedBaseAliasUsesServerAuthDuplicate() throws 
Exception {
         X509Certificate presented = present(HOST,
-                KeystoreEntry.trusted(HOST, HOST, SERVER_AUTH),
-                key(HOST + " (1)", SERVER_AUTH));
+                KeystoreEntry.trusted(HOST),
+                key(HOST + " (1)", CertType.SERVER_AUTH));
         assertEku(presented, Constants.SERVER_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -201,8 +199,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testConfiguredAliasStopsAtGapAndKeepsBase() throws Exception {
         X509Certificate presented = present("tomcat",
-                key("tomcat", CLIENT_AUTH),
-                key("tomcat (2)", SERVER_AUTH));
+                key("tomcat", CertType.CLIENT_AUTH),
+                key("tomcat (2)", CertType.SERVER_AUTH));
         assertEku(presented, CLIENT_AUTH_EXTENDED_KEY_USAGE_OID);
     }
 
@@ -217,9 +215,9 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testReloadResolvesServedCertificateWithOpenSSL() throws 
Exception {
         Assume.assumeTrue(useOpenSSL);
-        KeyStore keystore = orderedKeystore(null, key(HOST, CLIENT_AUTH), 
key(HOST + " (1)", SERVER_AUTH));
+        KeyStore keystore = orderedKeystore(null, key(HOST, 
CertType.CLIENT_AUTH), key(HOST + " (1)", CertType.SERVER_AUTH));
 
-        Set<X509Certificate> monitored = certificatesMonitoredForReload(HOST, 
keystore);
+        Set<X509Certificate> monitored = 
certificatesMonitoredForReload(keystore);
 
         X509Certificate served = (X509Certificate) 
keystore.getCertificateChain(HOST + " (1)")[0];
         X509Certificate notServed = (X509Certificate) 
keystore.getCertificateChain(HOST)[0];
@@ -237,8 +235,8 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testServedAliasIsTheNumberedDuplicate() throws Exception {
         Assume.assumeTrue("JSSE".equals(connectorName));
-        KeyStore keystore = nonExportableKeystore(key(HOST, CLIENT_AUTH), 
key(HOST + " (1)", SERVER_AUTH));
-        Assert.assertEquals(HOST + " (1)", servedAlias(HOST, keystore));
+        KeyStore keystore = nonExportableKeystore(key(HOST, 
CertType.CLIENT_AUTH), key(HOST + " (1)", CertType.SERVER_AUTH));
+        Assert.assertEquals(HOST + " (1)", servedAlias(keystore));
     }
 
 
@@ -251,7 +249,7 @@ public class TestSSLUtilBaseConfiguredAliasSelection 
extends SSLUtilBaseCertific
     @Test
     public void testServedAliasResolvesForOpenSSLWithOriginalKeystore() throws 
Exception {
         Assume.assumeTrue(useOpenSSL);
-        KeyStore keystore = wrappedExportableKeystore(key(HOST, CLIENT_AUTH), 
key(HOST + " (1)", SERVER_AUTH));
-        Assert.assertEquals(HOST + " (1)", servedAlias(HOST, keystore));
+        KeyStore keystore = wrappedExportableKeystore(key(HOST, 
CertType.CLIENT_AUTH), key(HOST + " (1)", CertType.SERVER_AUTH));
+        Assert.assertEquals(HOST + " (1)", servedAlias(keystore));
     }
 }
diff --git a/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java 
b/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java
index 2e94cf8b13..00f1772fcc 100644
--- a/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java
+++ b/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java
@@ -26,8 +26,6 @@ import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.cert.X509Certificate;
 import java.util.Date;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
 
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.asn1.x509.Extension;
@@ -43,8 +41,6 @@ import 
org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 
 public final class TesterKeystoreGenerator {
 
-    private static final AtomicLong SERIAL_COUNTER = new AtomicLong(1);
-
     private TesterKeystoreGenerator() {}
 
     @FunctionalInterface
@@ -54,113 +50,25 @@ public final class TesterKeystoreGenerator {
     }
 
     /**
-     * Generate a temporary JKS keystore containing a single self-signed RSA 
certificate.
+     * Generate a temporary JKS keystore containing a self-signed RSA 
certificate.
      *
-     * @param cn         the Common Name for the certificate subject
-     * @param alias      the keystore alias for the key entry
-     * @param sanNames   DNS Subject Alternative Names to include, or {@code 
null} for none
-     * @param customizer callback to add extensions to the certificate, or 
{@code null} for none
+     * @param cn       the Common Name for the certificate subject
+     * @param alias    the keystore alias for the key entry
+     * @param sanNames DNS Subject Alternative Names to include, or {@code 
null} for none
+     * @param customizer callback to add extensions to the certificate, or 
{@code null} for none.
      *
-     * @return a temporary keystore file with password {@link 
TesterSupport#JKS_PASS}
+     *  @return a temporary keystore file with password {@link  
TesterSupport#JKS_PASS}
      *
-     * @throws Exception if certificate generation or keystore creation fails
+     *  @throws Exception if certificate generation or keystore creation fails
      */
     public static File generateKeystore(String cn, String alias, String[] 
sanNames,
                                         CertificateExtensionsCustomizer 
customizer) throws Exception {
-        CertAndKey generated = generateSelfSignedCertificate(cn, sanNames, 
customizer);
-
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(null, null);
-        ks.setKeyEntry(alias, generated.keyPair().getPrivate(), 
TesterSupport.JKS_PASS.toCharArray(),
-                new X509Certificate[] { generated.certificate() });
-
-        return storeToTempFile(ks);
-    }
-
-    /**
-     * Generate a temporary JKS keystore from an explicit list of entries. 
Each entry has its own Common Name and may be
-     * either a private key entry or a trusted certificate entry, which lets 
tests reproduce stores that mix certificates
-     * with different Subjects and certificate-only (keyless) entries.
-     *
-     * @param entries the entries to add, in order
-     *
-     * @return a temporary keystore file with password {@link 
TesterSupport#JKS_PASS}
-     *
-     * @throws Exception if certificate generation or keystore creation fails
-     */
-    public static File generateKeystore(List<KeystoreEntry> entries) throws 
Exception {
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(null, null);
-
-        for (KeystoreEntry entry : entries) {
-            CertAndKey generated = generateSelfSignedCertificate(entry.cn(), 
null, entry.customizer());
-            if (entry.keyEntry()) {
-                ks.setKeyEntry(entry.alias(), 
generated.keyPair().getPrivate(), TesterSupport.JKS_PASS.toCharArray(),
-                        new X509Certificate[] { generated.certificate() });
-            } else {
-                ks.setCertificateEntry(entry.alias(), generated.certificate());
-            }
-        }
-
-        return storeToTempFile(ks);
-    }
-
-    /**
-     * A single entry for {@link #generateKeystore(List)}.
-     */
-    public static final class KeystoreEntry {
-
-        private final String alias;
-        private final String cn;
-        private final boolean keyEntry;
-        private final CertificateExtensionsCustomizer customizer;
-
-        /**
-         * @param alias      the keystore alias
-         * @param cn         the certificate Subject Common Name
-         * @param keyEntry   {@code true} for a private key entry, {@code 
false} for a trusted certificate entry
-         * @param customizer extensions to add to the certificate, or {@code 
null} for none
-         */
-        public KeystoreEntry(String alias, String cn, boolean keyEntry, 
CertificateExtensionsCustomizer customizer) {
-            this.alias = alias;
-            this.cn = cn;
-            this.keyEntry = keyEntry;
-            this.customizer = customizer;
-        }
-
-        public String alias() {
-            return alias;
-        }
-
-        public String cn() {
-            return cn;
-        }
-
-        public boolean keyEntry() {
-            return keyEntry;
-        }
-
-        public CertificateExtensionsCustomizer customizer() {
-            return customizer;
-        }
-
-        public static KeystoreEntry key(String alias, String cn, 
CertificateExtensionsCustomizer customizer) {
-            return new KeystoreEntry(alias, cn, true, customizer);
-        }
-
-        public static KeystoreEntry trusted(String alias, String cn, 
CertificateExtensionsCustomizer customizer) {
-            return new KeystoreEntry(alias, cn, false, customizer);
-        }
-    }
-
-    private static CertAndKey generateSelfSignedCertificate(String cn, 
String[] sanNames,
-                                                            
CertificateExtensionsCustomizer customizer) throws Exception {
         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
         kpg.initialize(4096);
         KeyPair keyPair = kpg.generateKeyPair();
 
         X500Name subject = new X500Name("CN=" + cn);
-        BigInteger serial = 
BigInteger.valueOf(SERIAL_COUNTER.getAndIncrement());
+        BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());
         long oneDay = 86400000L;
         Date notBefore = new Date(System.currentTimeMillis() - oneDay);
         Date notAfter = new Date(System.currentTimeMillis() + 365L * oneDay);
@@ -182,34 +90,17 @@ public final class TesterKeystoreGenerator {
 
         ContentSigner signer = new 
JcaContentSignerBuilder("SHA256withRSA").build(keyPair.getPrivate());
         X509Certificate certificate = new 
JcaX509CertificateConverter().getCertificate(certBuilder.build(signer));
-        return new CertAndKey(keyPair, certificate);
-    }
-
-    private static final class CertAndKey {
-
-        private final KeyPair keyPair;
-        private final X509Certificate certificate;
 
-        private CertAndKey(KeyPair keyPair, X509Certificate certificate) {
-            this.keyPair = keyPair;
-            this.certificate = certificate;
-        }
-
-        private KeyPair keyPair() {
-            return keyPair;
-        }
-
-        private X509Certificate certificate() {
-            return certificate;
-        }
-    }
+        KeyStore ks = KeyStore.getInstance("JKS");
+        ks.load(null, null);
+        ks.setKeyEntry(alias, keyPair.getPrivate(), 
TesterSupport.JKS_PASS.toCharArray(), new X509Certificate[] { certificate });
 
-    private static File storeToTempFile(KeyStore ks) throws Exception {
         File keystoreFile = File.createTempFile("test-cert-", ".jks");
         keystoreFile.deleteOnExit();
         try (FileOutputStream fos = new FileOutputStream(keystoreFile)) {
             ks.store(fos, TesterSupport.JKS_PASS.toCharArray());
         }
+
         return keystoreFile;
     }
 
diff --git a/test/org/apache/tomcat/util/net/localhost-rsa-anyauth.jks 
b/test/org/apache/tomcat/util/net/localhost-rsa-anyauth.jks
new file mode 100644
index 0000000000..9133e6551b
Binary files /dev/null and 
b/test/org/apache/tomcat/util/net/localhost-rsa-anyauth.jks differ
diff --git a/test/org/apache/tomcat/util/net/localhost-rsa-clientauth.jks 
b/test/org/apache/tomcat/util/net/localhost-rsa-clientauth.jks
new file mode 100644
index 0000000000..5c330f1f8e
Binary files /dev/null and 
b/test/org/apache/tomcat/util/net/localhost-rsa-clientauth.jks differ
diff --git a/test/org/apache/tomcat/util/net/localhost-rsa-noeku.jks 
b/test/org/apache/tomcat/util/net/localhost-rsa-noeku.jks
new file mode 100644
index 0000000000..4cccd21a4b
Binary files /dev/null and 
b/test/org/apache/tomcat/util/net/localhost-rsa-noeku.jks differ
diff --git a/test/org/apache/tomcat/util/net/localhost-rsa-serverauth.jks 
b/test/org/apache/tomcat/util/net/localhost-rsa-serverauth.jks
new file mode 100644
index 0000000000..dae52f78a3
Binary files /dev/null and 
b/test/org/apache/tomcat/util/net/localhost-rsa-serverauth.jks differ
diff --git a/test/org/apache/tomcat/util/net/localhost-rsa-serverauth2.jks 
b/test/org/apache/tomcat/util/net/localhost-rsa-serverauth2.jks
new file mode 100644
index 0000000000..32aa3d834c
Binary files /dev/null and 
b/test/org/apache/tomcat/util/net/localhost-rsa-serverauth2.jks differ


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to