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]