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

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


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 1c975c8c4a Fix test when running on APR
1c975c8c4a is described below

commit 1c975c8c4a7cb275ae7f2c1e69d907ef925deba2
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Mar 31 15:27:38 2026 +0100

    Fix test when running on APR
---
 .../tomcat/util/net/TestLargeClientHello.java      | 60 +++++++++++----------
 ...nerator.java => TesterCredentialGenerator.java} | 61 +++++++++++++++++++---
 2 files changed, 85 insertions(+), 36 deletions(-)

diff --git a/test/org/apache/tomcat/util/net/TestLargeClientHello.java 
b/test/org/apache/tomcat/util/net/TestLargeClientHello.java
index fecb52a692..21ca1919f4 100644
--- a/test/org/apache/tomcat/util/net/TestLargeClientHello.java
+++ b/test/org/apache/tomcat/util/net/TestLargeClientHello.java
@@ -17,7 +17,6 @@
 
 package org.apache.tomcat.util.net;
 
-import java.io.File;
 import java.util.Arrays;
 import java.util.logging.Level;
 
@@ -30,6 +29,7 @@ import org.junit.Test;
 import org.apache.catalina.Context;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.util.net.TesterCredentialGenerator.TesterCredential;
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.DERUTF8String;
 import org.bouncycastle.asn1.x509.BasicConstraints;
@@ -42,23 +42,21 @@ public class TestLargeClientHello extends TomcatBaseTest {
     // https://bz.apache.org/bugzilla/show_bug.cgi?id=67938
     @Test
     public void testLargeClientHelloWithSessionResumption() throws Exception {
-        File keystoreFile = 
TesterKeystoreGenerator.generateKeystore("localhost", "tomcat",
-            new String[]{"localhost", "*.localhost"},
-                (keyPair, certBuilder) -> {
-                JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
-                certBuilder.addExtension(Extension.subjectKeyIdentifier, false,
-                        
extUtils.createSubjectKeyIdentifier(keyPair.getPublic()));
-                certBuilder.addExtension(Extension.authorityKeyIdentifier, 
false,
-                        
extUtils.createAuthorityKeyIdentifier(keyPair.getPublic()));
-                certBuilder.addExtension(Extension.basicConstraints, true,
-                    new BasicConstraints(true));
-                certBuilder.addExtension(Extension.keyUsage, false,
-                    new KeyUsage(KeyUsage.digitalSignature | 
KeyUsage.keyEncipherment));
-                char[] padding = new char[16922];
-                Arrays.fill(padding, 'x');
-                certBuilder.addExtension(new ASN1ObjectIdentifier("2.999"), 
false,
-                    new DERUTF8String(new String(padding)));
-            });
+        TesterCredential credential = 
TesterCredentialGenerator.generateCredential("localhost", "tomcat",
+                new String[] { "localhost", "*.localhost" }, (keyPair, 
certBuilder) -> {
+                    JcaX509ExtensionUtils extUtils = new 
JcaX509ExtensionUtils();
+                    certBuilder.addExtension(Extension.subjectKeyIdentifier, 
false,
+                            
extUtils.createSubjectKeyIdentifier(keyPair.getPublic()));
+                    certBuilder.addExtension(Extension.authorityKeyIdentifier, 
false,
+                            
extUtils.createAuthorityKeyIdentifier(keyPair.getPublic()));
+                    certBuilder.addExtension(Extension.basicConstraints, true, 
new BasicConstraints(true));
+                    certBuilder.addExtension(Extension.keyUsage, false,
+                            new KeyUsage(KeyUsage.digitalSignature | 
KeyUsage.keyEncipherment));
+                    char[] padding = new char[16922];
+                    Arrays.fill(padding, 'x');
+                    certBuilder.addExtension(new 
ASN1ObjectIdentifier("2.999"), false,
+                            new DERUTF8String(new String(padding)));
+                });
 
         Tomcat tomcat = getTomcatInstance();
 
@@ -66,28 +64,32 @@ public class TestLargeClientHello extends TomcatBaseTest {
         Tomcat.addServlet(ctx, "hello", new HelloWorldServlet());
         ctx.addServletMappingDecoded("/", "hello");
 
-        TesterSupport.initSsl(tomcat, keystoreFile.getAbsolutePath(), null, 
null, false);
+        TesterSupport.initSsl(tomcat, 
credential.getKeystore().getAbsolutePath(),
+                credential.getCertificate().getAbsolutePath(), 
credential.getKey().getAbsolutePath(), false);
 
-        try (LogCapture nioCapture = attachLogCapture(Level.FINE,
-            "org.apache.tomcat.util.net.SecureNioChannel");
-             LogCapture nio2Capture = attachLogCapture(Level.FINE,
-                 "org.apache.tomcat.util.net.SecureNio2Channel")) {
+        try (LogCapture nioCapture = attachLogCapture(Level.FINE, 
"org.apache.tomcat.util.net.SecureNioChannel");
+                LogCapture nio2Capture = attachLogCapture(Level.FINE, 
"org.apache.tomcat.util.net.SecureNio2Channel")) {
 
             tomcat.start();
 
             SSLContext sc = 
SSLContext.getInstance(Constants.SSL_PROTO_TLSv1_3);
-            sc.init(null, new TrustManager[]{new 
TesterSupport.TrustAllCerts()}, null);
+            sc.init(null, new TrustManager[] { new 
TesterSupport.TrustAllCerts() }, null);
             
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
 
             String url = "https://localhost:"; + getPort() + "/";
             Assert.assertTrue(getUrl(url).toString().contains("Hello World"));
             Assert.assertTrue(getUrl(url).toString().contains("Hello World"));
 
-            Assert.assertTrue(nioCapture.containsText(
-                    
TomcatBaseTest.getKeyFromPropertiesFile("org.apache.tomcat.util.net",
-                    "channel.nio.ssl.handshakeUnwrapBufferUnderflow")) || 
nio2Capture.containsText(
-                
TomcatBaseTest.getKeyFromPropertiesFile("org.apache.tomcat.util.net",
-                    "channel.nio.ssl.handshakeUnwrapBufferUnderflow")));
+            /*
+             * We don't have the same visibility into the internal processing 
for the handshake with APR so for APR the
+             * test is simply to ensure that the handshake required by 
getUrl() above does not fail.
+             */
+            Assert.assertTrue(nioCapture
+                    
.containsText(TomcatBaseTest.getKeyFromPropertiesFile("org.apache.tomcat.util.net",
+                            "channel.nio.ssl.handshakeUnwrapBufferUnderflow")) 
||
+                    
nio2Capture.containsText(TomcatBaseTest.getKeyFromPropertiesFile("org.apache.tomcat.util.net",
+                            "channel.nio.ssl.handshakeUnwrapBufferUnderflow")) 
||
+                    
"org.apache.coyote.http11.Http11AprProtocol".equals(System.getProperty("tomcat.test.protocol")));
         }
 
     }
diff --git a/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java 
b/test/org/apache/tomcat/util/net/TesterCredentialGenerator.java
similarity index 66%
rename from test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java
rename to test/org/apache/tomcat/util/net/TesterCredentialGenerator.java
index 9fd4affde6..8fc2cd64c9 100644
--- a/test/org/apache/tomcat/util/net/TesterKeystoreGenerator.java
+++ b/test/org/apache/tomcat/util/net/TesterCredentialGenerator.java
@@ -19,11 +19,13 @@ package org.apache.tomcat.util.net;
 
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.FileWriter;
 import java.math.BigInteger;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.cert.X509Certificate;
+import java.util.Base64;
 import java.util.Date;
 
 import org.bouncycastle.asn1.x500.X500Name;
@@ -36,9 +38,9 @@ import 
org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
 import org.bouncycastle.operator.ContentSigner;
 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 
-public final class TesterKeystoreGenerator {
+public final class TesterCredentialGenerator {
 
-    private TesterKeystoreGenerator() {}
+    private TesterCredentialGenerator() {}
 
     @FunctionalInterface
     public interface CertificateExtensionsCustomizer {
@@ -47,18 +49,18 @@ public final class TesterKeystoreGenerator {
     }
 
     /**
-     * Generate a temporary JKS keystore containing a self-signed RSA 
certificate.
+     * Generate a temporary credential using 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}
+     *  @return a temporary set of credential files with password {@link 
TesterSupport#JKS_PASS}
      *
-     *  @throws Exception if certificate generation or keystore creation fails
+     *  @throws Exception if credential creation fails
      */
-    public static File generateKeystore(String cn, String alias, String[] 
sanNames,
+    public static TesterCredential generateCredential(String cn, String alias, 
String[] sanNames,
                                         CertificateExtensionsCustomizer 
customizer) throws Exception {
         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
         kpg.initialize(4096);
@@ -88,6 +90,7 @@ public final class TesterKeystoreGenerator {
         ContentSigner signer = new 
JcaContentSignerBuilder("SHA256withRSA").build(keyPair.getPrivate());
         X509Certificate certificate = new 
JcaX509CertificateConverter().getCertificate(certBuilder.build(signer));
 
+        // Create the keystore from the key and certificate
         KeyStore ks = KeyStore.getInstance("JKS");
         ks.load(null, null);
         ks.setKeyEntry(alias, keyPair.getPrivate(), 
TesterSupport.JKS_PASS.toCharArray(), new X509Certificate[] { certificate });
@@ -98,6 +101,50 @@ public final class TesterKeystoreGenerator {
             ks.store(fos, TesterSupport.JKS_PASS.toCharArray());
         }
 
-        return keystoreFile;
+        // Create the key file
+        File keyFile = File.createTempFile("test-key-", ".key");
+        keyFile.deleteOnExit();
+        try (FileWriter fw = new FileWriter(keyFile)) {
+            fw.write("-----BEGIN PRIVATE KEY-----\n");
+            
fw.write(Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()));
+            fw.write("\n-----END PRIVATE KEY-----");
+        }
+
+        // Create the certificate file
+        File certificateFile = File.createTempFile("test-certificate-", 
".cert");
+        certificateFile.deleteOnExit();
+        try (FileWriter fw = new FileWriter(certificateFile)) {
+            fw.write("-----BEGIN CERTIFICATE-----\n");
+            
fw.write(Base64.getEncoder().encodeToString(certificate.getEncoded()));
+            fw.write("\n-----END CERTIFICATE-----");
+        }
+
+        return new TesterCredential(keystoreFile, keyFile, certificateFile);
+    }
+
+
+    public static class TesterCredential {
+
+        private final File keystore;
+        private final File key;
+        private final File certificate;
+
+        public TesterCredential(File keystore, File key, File certificate) {
+            this.keystore = keystore;
+            this.key = key;
+            this.certificate = certificate;
+        }
+
+        public File getKeystore() {
+            return keystore;
+        }
+
+        public File getKey() {
+            return key;
+        }
+
+        public File getCertificate() {
+            return certificate;
+        }
     }
 }


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

Reply via email to