This is an automated email from the ASF dual-hosted git repository. dsoumis pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 722464b256cde6104fcf26e5efd707e9ae9e37fa Author: Dimitris Soumis <[email protected]> AuthorDate: Fri Mar 27 20:46:19 2026 +0200 Move generateKeystore() from TesterSupport to independent TesterKeystoreGenerator class --- .../tomcat/util/net/TestLargeClientHello.java | 2 +- .../tomcat/util/net/TesterKeystoreGenerator.java | 103 +++++++++++++++++++++ test/org/apache/tomcat/util/net/TesterSupport.java | 76 --------------- 3 files changed, 104 insertions(+), 77 deletions(-) diff --git a/test/org/apache/tomcat/util/net/TestLargeClientHello.java b/test/org/apache/tomcat/util/net/TestLargeClientHello.java index c476fe0a24..43370f9c54 100644 --- a/test/org/apache/tomcat/util/net/TestLargeClientHello.java +++ b/test/org/apache/tomcat/util/net/TestLargeClientHello.java @@ -41,7 +41,7 @@ public class TestLargeClientHello extends TomcatBaseTest { // https://bz.apache.org/bugzilla/show_bug.cgi?id=67938 @Test public void testLargeClientHelloWithSessionResumption() throws Exception { - File keystoreFile = TesterSupport.generateKeystore("localhost", "tomcat", + File keystoreFile = TesterKeystoreGenerator.generateKeystore("localhost", "tomcat", new String[]{"localhost", "*.localhost"}, (keyPair, certBuilder) -> { JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); diff --git a/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java b/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java new file mode 100644 index 0000000000..9fd4affde6 --- /dev/null +++ b/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tomcat.util.net; + +import java.io.File; +import java.io.FileOutputStream; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Date; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; + +public final class TesterKeystoreGenerator { + + private TesterKeystoreGenerator() {} + + @FunctionalInterface + public interface CertificateExtensionsCustomizer { + void customize(KeyPair keyPair, X509v3CertificateBuilder certBuilder) + throws Exception; + } + + /** + * 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. + * + * @return a temporary keystore file with password {@link TesterSupport#JKS_PASS} + * + * @throws Exception if certificate generation or keystore creation fails + */ + public static File generateKeystore(String cn, String alias, 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(System.currentTimeMillis()); + long oneDay = 86400000L; + Date notBefore = new Date(System.currentTimeMillis() - oneDay); + Date notAfter = new Date(System.currentTimeMillis() + 365L * oneDay); + + X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(subject, serial, notBefore, notAfter, + subject, keyPair.getPublic()); + + if (sanNames != null && sanNames.length > 0) { + GeneralName[] generalNames = new GeneralName[sanNames.length]; + for (int i = 0; i < sanNames.length; i++) { + generalNames[i] = new GeneralName(GeneralName.dNSName, sanNames[i]); + } + certBuilder.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(generalNames)); + } + + if (customizer != null) { + customizer.customize(keyPair, certBuilder); + } + + ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(keyPair.getPrivate()); + X509Certificate certificate = new JcaX509CertificateConverter().getCertificate(certBuilder.build(signer)); + + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + ks.setKeyEntry(alias, keyPair.getPrivate(), TesterSupport.JKS_PASS.toCharArray(), new X509Certificate[] { certificate }); + + 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/TesterSupport.java b/test/org/apache/tomcat/util/net/TesterSupport.java index 31a1c73240..9c3e0d2095 100644 --- a/test/org/apache/tomcat/util/net/TesterSupport.java +++ b/test/org/apache/tomcat/util/net/TesterSupport.java @@ -18,15 +18,11 @@ package org.apache.tomcat.util.net; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.math.BigInteger; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -40,7 +36,6 @@ import java.security.cert.PKIXRevocationChecker; import java.security.cert.TrustAnchor; import java.security.cert.X509CertSelector; import java.security.cert.X509Certificate; -import java.util.Date; import java.util.EnumSet; import java.util.Enumeration; import java.util.HashSet; @@ -84,15 +79,6 @@ import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type; import org.apache.tomcat.util.net.jsse.JSSEImplementation; import org.apache.tomcat.util.net.openssl.OpenSSLImplementation; import org.apache.tomcat.util.net.openssl.OpenSSLStatus; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; public final class TesterSupport { @@ -426,68 +412,6 @@ public final class TesterSupport { new X500Principal(lastRequestedIssuers[0].getName())); } - @FunctionalInterface - public interface CertificateExtensionsCustomizer { - void customize(KeyPair keyPair, X509v3CertificateBuilder certBuilder) - throws Exception; - } - - /** - * 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. - * - * @return a temporary keystore file with password {@link #JKS_PASS} - * - * @throws Exception if certificate generation or keystore creation fails - */ - public static File generateKeystore(String cn, String alias, 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(System.currentTimeMillis()); - long oneDay = 86400000L; - Date notBefore = new Date(System.currentTimeMillis() - oneDay); - Date notAfter = new Date(System.currentTimeMillis() + 365L * oneDay); - - X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(subject, serial, notBefore, notAfter, - subject, keyPair.getPublic()); - - if (sanNames != null && sanNames.length > 0) { - GeneralName[] generalNames = new GeneralName[sanNames.length]; - for (int i = 0; i < sanNames.length; i++) { - generalNames[i] = new GeneralName(GeneralName.dNSName, sanNames[i]); - } - certBuilder.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(generalNames)); - } - - if (customizer != null) { - customizer.customize(keyPair, certBuilder); - } - - ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(keyPair.getPrivate()); - X509Certificate certificate = new JcaX509CertificateConverter().getCertificate(certBuilder.build(signer)); - - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(null, null); - ks.setKeyEntry(alias, keyPair.getPrivate(), JKS_PASS.toCharArray(), new X509Certificate[] { certificate }); - - File keystoreFile = File.createTempFile("test-cert-", ".jks"); - keystoreFile.deleteOnExit(); - try (FileOutputStream fos = new FileOutputStream(keystoreFile)) { - ks.store(fos, JKS_PASS.toCharArray()); - } - - return keystoreFile; - } - - public static final byte DATA = (byte)33; public static class SimpleServlet extends HttpServlet { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
