From 5fd51df351484f2c32ac9fd2e8ab94dac4bb550e Mon Sep 17 00:00:00 2001 From: pmeloni Date: Mon, 18 May 2026 17:33:32 +0200 Subject: [PATCH] RESOLVES: RHEL-150714: CVE-2026-24734 Apache Tomcat: Certificate revocation bypass due to improper OCSP response validation --- rhel-150714.patch | 3954 --------------------------------------------- rhel-168081.patch | 34 - sources | 2 +- tomcat.spec | 36 +- 4 files changed, 30 insertions(+), 3996 deletions(-) delete mode 100644 rhel-150714.patch delete mode 100644 rhel-168081.patch diff --git a/rhel-150714.patch b/rhel-150714.patch deleted file mode 100644 index ec1eabb..0000000 --- a/rhel-150714.patch +++ /dev/null @@ -1,3954 +0,0 @@ -diff --git a/java/org/apache/tomcat/util/net/openssl/OpenSSLStatus.java b/java/org/apache/tomcat/util/net/openssl/OpenSSLStatus.java -index 1ad7d3dc84..749813bc38 100644 ---- a/java/org/apache/tomcat/util/net/openssl/OpenSSLStatus.java -+++ b/java/org/apache/tomcat/util/net/openssl/OpenSSLStatus.java -@@ -38,9 +38,10 @@ public class OpenSSLStatus { - private static volatile boolean useOpenSSL = true; - private static volatile boolean instanceCreated = false; - private static volatile long version = 0; -+ private static volatile int majorVersion = 0; -+ private static volatile int minorVersion = 0; - private static volatile Name name = Name.UNKNOWN; - -- - public static boolean isLibraryInitialized() { - return libraryInitialized; - } -@@ -95,6 +96,34 @@ public class OpenSSLStatus { - OpenSSLStatus.version = version; - } - -+ /** -+ * @return the majorVersion -+ */ -+ public static int getMajorVersion() { -+ return majorVersion; -+ } -+ -+ /** -+ * @param majorVersion the majorVersion to set -+ */ -+ public static void setMajorVersion(int majorVersion) { -+ OpenSSLStatus.majorVersion = majorVersion; -+ } -+ -+ /** -+ * @return the minorVersion -+ */ -+ public static int getMinorVersion() { -+ return minorVersion; -+ } -+ -+ /** -+ * @param minorVersion the minorVersion to set -+ */ -+ public static void setMinorVersion(int minorVersion) { -+ OpenSSLStatus.minorVersion = minorVersion; -+ } -+ - /** - * @return the library name - */ -@@ -116,4 +145,18 @@ public class OpenSSLStatus { - return Name.OPENSSL3.equals(name); - } - -+ /** -+ * @return true if running with BoringSSL -+ */ -+ public static boolean isBoringSSL() { -+ return Name.BORINGSSL.equals(name); -+ } -+ -+ /** -+ * @return true if running with LibreSSL < 3.5 -+ */ -+ public static boolean isLibreSSLPre35() { -+ return Name.LIBRESSL.equals(name) && ((majorVersion == 3 && minorVersion < 5) || majorVersion < 3); -+ } -+ - } -diff --git a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java -index bfb9b6f20a..960fa0459f 100644 ---- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java -+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java -@@ -59,6 +59,7 @@ import org.apache.tomcat.util.buf.Asn1Parser; - import org.apache.tomcat.util.http.Method; - import org.apache.tomcat.util.net.Constants; - import org.apache.tomcat.util.net.SSLUtil; -+import org.apache.tomcat.util.net.openssl.OpenSSLStatus; - import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser; - import org.apache.tomcat.util.openssl.SSL_CTX_set_verify$callback; - import org.apache.tomcat.util.openssl.SSL_set_info_callback$cb; -@@ -68,7 +69,7 @@ import org.apache.tomcat.util.openssl.openssl_h_Compatibility; - import org.apache.tomcat.util.res.StringManager; - - /** -- * Implements a {@link SSLEngine} using OpenSSL BIO -+ * Implements a {@link SSLEngine} using OpenSSL BIO - * abstractions. - */ - public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolInfo { -@@ -137,7 +138,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn - private volatile boolean destroyed; - - // Use an invalid cipherSuite until the handshake is completed -- // See https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLEngine.html#getSession() -+ // See https://docs.oracle.com/en/java/javase/21/docs/api/java.base/javax/net/ssl/SSLEngine.html#getSession() - private volatile String version; - private volatile String cipher; - private volatile String applicationProtocol; -@@ -1076,7 +1077,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn - case NONE -> SSL_VERIFY_NONE(); - case REQUIRE -> SSL_VERIFY_FAIL_IF_NO_PEER_CERT(); - case OPTIONAL -> -- certificateVerificationOptionalNoCA ? OpenSSLContext.OPTIONAL_NO_CA : SSL_VERIFY_PEER(); -+ certificateVerificationOptionalNoCA ? OpenSSLContext.OPTIONAL_NO_CA : SSL_VERIFY_PEER(); - }; - // Set int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) callback - int value = switch (mode) { -@@ -1138,6 +1139,9 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn - ok = 1; - openssl_h_Compatibility.SSL_set_verify_result(state.ssl, X509_V_OK()); - } -+ if (ok == 0 && errnum == X509_V_ERR_UNABLE_TO_GET_CRL()) { -+ ok = 1; -+ } - /* - * Expired certificates vs. "expired" CRLs: by default, OpenSSL turns X509_V_ERR_CRL_HAS_EXPIRED into a - * "certificate_expired(45)" SSL alert, but that's not really the message we should convey to the peer (at -@@ -1168,9 +1172,10 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn - if (ocspResponse == V_OCSP_CERTSTATUS_REVOKED()) { - ok = 0; - errnum = X509_STORE_CTX_get_error(x509ctx); -+ X509_STORE_CTX_set_error(x509ctx, X509_V_ERR_CERT_REVOKED()); - } else if (ocspResponse == V_OCSP_CERTSTATUS_UNKNOWN()) { - errnum = X509_STORE_CTX_get_error(x509ctx); -- if (errnum <= 0) { -+ if (errnum != X509_V_ERR_UNABLE_TO_GET_CRL() && (errnum == X509_V_ERR_APPLICATION_VERIFICATION() || errnum != 0)) { - ok = 0; - } - } -@@ -1196,46 +1201,53 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn - // don't do OCSP checking for valid self-issued certs - X509_STORE_CTX_set_error(x509ctx, X509_V_OK()); - } else { -- // If we can't get the issuer, we cannot perform OCSP verification -- MemorySegment issuer = X509_STORE_CTX_get0_current_issuer(x509ctx); -- if (!MemorySegment.NULL.equals(issuer)) { -- // sslutils.c ssl_ocsp_request(x509, issuer, x509ctx); -- int nid = X509_get_ext_by_NID(x509, NID_info_access(), -1); -- if (nid >= 0) { -- try (var localArenal = Arena.ofConfined()) { -- MemorySegment ext = X509_get_ext(x509, nid); -- MemorySegment os = X509_EXTENSION_get_data(ext); -- int length = ASN1_STRING_length(os); -- MemorySegment data = ASN1_STRING_get0_data(os); -- // ocsp_urls = decode_OCSP_url(os); -- byte[] asn1String = -- data.reinterpret(length, localArenal, null).toArray(ValueLayout.JAVA_BYTE); -- Asn1Parser parser = new Asn1Parser(asn1String); -- // Parse the byte sequence -- ArrayList urls = new ArrayList<>(); -- try { -- parseOCSPURLs(parser, urls); -- } catch (Exception e) { -- log.error(sm.getString("engine.ocspParseError"), e); -- } -- if (!urls.isEmpty()) { -- // Use OpenSSL to build OCSP request -- for (String urlString : urls) { -- try { -- URL url = (new URI(urlString)).toURL(); -- ocspResponse = processOCSPRequest(url, issuer, x509, x509ctx, localArenal); -- if (log.isDebugEnabled()) { -- log.debug(sm.getString("engine.ocspResponse", urlString, -- Integer.toString(ocspResponse))); -+ try (var localArena = Arena.ofConfined()) { -+ // If we can't get the issuer, we cannot perform OCSP verification -+ MemorySegment x509IssuerPointer = localArena.allocateFrom(ValueLayout.ADDRESS, MemorySegment.NULL); -+ int res = X509_STORE_CTX_get1_issuer(x509IssuerPointer, x509ctx, x509); -+ if (res > 0) { -+ MemorySegment issuer = MemorySegment.NULL; -+ try { -+ issuer = x509IssuerPointer.get(ValueLayout.ADDRESS, 0); -+ // sslutils.c ssl_ocsp_request(x509, issuer, x509ctx); -+ int nid = X509_get_ext_by_NID(x509, NID_info_access(), -1); -+ if (nid >= 0) { -+ MemorySegment ext = X509_get_ext(x509, nid); -+ MemorySegment os = X509_EXTENSION_get_data(ext); -+ int length = ASN1_STRING_length(os); -+ MemorySegment data = ASN1_STRING_get0_data(os); -+ // ocsp_urls = decode_OCSP_url(os); -+ byte[] asn1String = -+ data.reinterpret(length, localArena, null).toArray(ValueLayout.JAVA_BYTE); -+ Asn1Parser parser = new Asn1Parser(asn1String); -+ // Parse the byte sequence -+ ArrayList urls = new ArrayList<>(); -+ try { -+ parseOCSPURLs(parser, urls); -+ } catch (Exception e) { -+ log.error(sm.getString("engine.ocspParseError"), e); -+ } -+ if (!urls.isEmpty()) { -+ // Use OpenSSL to build OCSP request -+ for (String urlString : urls) { -+ try { -+ URL url = (new URI(urlString)).toURL(); -+ ocspResponse = processOCSPRequest(url, issuer, x509, x509ctx, localArena); -+ if (log.isDebugEnabled()) { -+ log.debug(sm.getString("engine.ocspResponse", urlString, -+ Integer.toString(ocspResponse))); -+ } -+ } catch (MalformedURLException | URISyntaxException e) { -+ log.warn(sm.getString("engine.invalidOCSPURL", urlString)); -+ } -+ if (ocspResponse != V_OCSP_CERTSTATUS_UNKNOWN()) { -+ break; - } -- } catch (MalformedURLException | URISyntaxException e) { -- log.warn(sm.getString("engine.invalidOCSPURL", urlString)); -- } -- if (ocspResponse != V_OCSP_CERTSTATUS_UNKNOWN()) { -- break; - } - } - } -+ } finally { -+ X509_free(issuer); - } - } - } -@@ -1275,6 +1287,9 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn - - private static int processOCSPRequest(URL url, MemorySegment issuer, MemorySegment x509, - MemorySegment /* X509_STORE_CTX */ x509ctx, Arena localArena) { -+ if (OpenSSLStatus.Name.BORINGSSL.equals(OpenSSLStatus.getName())) { -+ return V_OCSP_CERTSTATUS_UNKNOWN(); -+ } - MemorySegment ocspRequest = MemorySegment.NULL; - MemorySegment ocspResponse = MemorySegment.NULL; - MemorySegment id; -@@ -1574,7 +1589,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn - } - - private Principal principal(Certificate[] certs) { -- return ((java.security.cert.X509Certificate) certs[0]).getIssuerX500Principal(); -+ return ((java.security.cert.X509Certificate) certs[0]).getSubjectX500Principal(); - } - - @Override -diff --git a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java -index 7272db9cf2..c1bb2cb664 100644 ---- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java -+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java -@@ -178,6 +178,8 @@ public class OpenSSLLibrary { - initLibrary(); - - OpenSSLStatus.setVersion(OpenSSL_version_num()); -+ OpenSSLStatus.setMajorVersion(openssl_h_Compatibility.MAJOR); -+ OpenSSLStatus.setMinorVersion(openssl_h_Compatibility.MINOR); - if (openssl_h_Compatibility.OPENSSL3) { - OpenSSLStatus.setName(OpenSSLStatus.Name.OPENSSL3); - } else if (openssl_h_Compatibility.OPENSSL) { -diff --git a/java/org/apache/tomcat/util/openssl/openssl_h.java b/java/org/apache/tomcat/util/openssl/openssl_h.java -index 0c2465b633..cbd8a5a0d4 100644 ---- a/java/org/apache/tomcat/util/openssl/openssl_h.java -+++ b/java/org/apache/tomcat/util/openssl/openssl_h.java -@@ -196,6 +196,16 @@ public class openssl_h { - return X509_V_OK; - } - -+ private static final int X509_V_ERR_UNABLE_TO_GET_CRL = (int) 3L; -+ -+ /** -+ * {@snippet lang = c : * #define X509_V_ERR_UNABLE_TO_GET_CRL 3 -+ * } -+ */ -+ public static int X509_V_ERR_UNABLE_TO_GET_CRL() { -+ return X509_V_ERR_UNABLE_TO_GET_CRL; -+ } -+ - private static final int X509_V_ERR_CRL_HAS_EXPIRED = (int) 12L; - - /** -@@ -246,6 +256,16 @@ public class openssl_h { - return X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; - } - -+ private static final int X509_V_ERR_CERT_REVOKED = (int) 23L; -+ -+ /** -+ * {@snippet lang = c : * #define X509_V_ERR_CERT_REVOKED 23 -+ * } -+ */ -+ public static int X509_V_ERR_CERT_REVOKED() { -+ return X509_V_ERR_CERT_REVOKED; -+ } -+ - private static final int X509_V_ERR_CERT_UNTRUSTED = (int) 27L; - - /** -@@ -266,6 +286,46 @@ public class openssl_h { - return X509_V_ERR_APPLICATION_VERIFICATION; - } - -+ private static final int X509_V_ERR_OCSP_RESP_INVALID = (int) 96L; -+ -+ /** -+ * {@snippet lang = c : * #define X509_V_ERR_OCSP_RESP_INVALID 96 -+ * } -+ */ -+ public static int X509_V_ERR_OCSP_RESP_INVALID() { -+ return X509_V_ERR_OCSP_RESP_INVALID; -+ } -+ -+ private static final int X509_V_ERR_OCSP_SIGNATURE_FAILURE = (int) 97L; -+ -+ /** -+ * {@snippet lang = c : * #define X509_V_ERR_OCSP_SIGNATURE_FAILURE 97 -+ * } -+ */ -+ public static int X509_V_ERR_OCSP_SIGNATURE_FAILURE() { -+ return X509_V_ERR_OCSP_SIGNATURE_FAILURE; -+ } -+ -+ private static final int X509_V_ERR_OCSP_NOT_YET_VALID = (int) 98L; -+ -+ /** -+ * {@snippet lang = c : * #define X509_V_ERR_OCSP_NOT_YET_VALID 98 -+ * } -+ */ -+ public static int X509_V_ERR_OCSP_NOT_YET_VALID() { -+ return X509_V_ERR_OCSP_NOT_YET_VALID; -+ } -+ -+ private static final int X509_V_ERR_OCSP_HAS_EXPIRED = (int) 99L; -+ -+ /** -+ * {@snippet lang = c : * #define X509_V_ERR_OCSP_HAS_EXPIRED 99 -+ * } -+ */ -+ public static int X509_V_ERR_OCSP_HAS_EXPIRED() { -+ return X509_V_ERR_OCSP_HAS_EXPIRED; -+ } -+ - private static final int X509_V_FLAG_CRL_CHECK = (int) 4L; - - /** -@@ -3071,6 +3131,66 @@ public class openssl_h { - } - } - -+ private static class X509_STORE_CTX_get0_store { -+ public static final FunctionDescriptor DESC = FunctionDescriptor.of( -+ openssl_h.C_POINTER, -+ openssl_h.C_POINTER -+ ); -+ -+ public static final MemorySegment ADDR = openssl_h.findOrThrow("X509_STORE_CTX_get0_store"); -+ -+ public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); -+ } -+ -+ /** -+ * Function descriptor for: -+ * {@snippet lang=c : -+ * X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx) -+ * } -+ */ -+ public static FunctionDescriptor X509_STORE_CTX_get0_store$descriptor() { -+ return X509_STORE_CTX_get0_store.DESC; -+ } -+ -+ /** -+ * Downcall method handle for: -+ * {@snippet lang=c : -+ * X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx) -+ * } -+ */ -+ public static MethodHandle X509_STORE_CTX_get0_store$handle() { -+ return X509_STORE_CTX_get0_store.HANDLE; -+ } -+ -+ /** -+ * Address for: -+ * {@snippet lang=c : -+ * X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx) -+ * } -+ */ -+ public static MemorySegment X509_STORE_CTX_get0_store$address() { -+ return X509_STORE_CTX_get0_store.ADDR; -+ } -+ -+ /** -+ * {@snippet lang=c : -+ * X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx) -+ * } -+ */ -+ public static MemorySegment X509_STORE_CTX_get0_store(MemorySegment ctx) { -+ var mh$ = X509_STORE_CTX_get0_store.HANDLE; -+ try { -+ if (TRACE_DOWNCALLS) { -+ traceDowncall("X509_STORE_CTX_get0_store", ctx); -+ } -+ return (MemorySegment)mh$.invokeExact(ctx); -+ } catch (Error | RuntimeException ex) { -+ throw ex; -+ } catch (Throwable ex$) { -+ throw new AssertionError("should not reach here", ex$); -+ } -+ } -+ - private static class X509_STORE_CTX_get0_untrusted { - public static final FunctionDescriptor DESC = FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER); - -@@ -3584,52 +3704,52 @@ public class openssl_h { - } - } - -- private static class X509_STORE_CTX_get0_current_issuer { -- public static final FunctionDescriptor DESC = FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER); -+ private static class X509_STORE_CTX_get1_issuer { -+ public static final FunctionDescriptor DESC = FunctionDescriptor.of(openssl_h.C_INT, openssl_h.C_POINTER, openssl_h.C_POINTER, openssl_h.C_POINTER); - -- public static final MemorySegment ADDR = openssl_h.findOrThrow("X509_STORE_CTX_get0_current_issuer"); -+ public static final MemorySegment ADDR = openssl_h.findOrThrow("X509_STORE_CTX_get1_issuer"); - - public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); - } - - /** - * Function descriptor for: -- * {@snippet lang = c : * X509 *X509_STORE_CTX_get0_current_issuer(const X509_STORE_CTX *ctx) -+ * {@snippet lang = c : * int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) - * } - */ -- public static FunctionDescriptor X509_STORE_CTX_get0_current_issuer$descriptor() { -- return X509_STORE_CTX_get0_current_issuer.DESC; -+ public static FunctionDescriptor X509_STORE_CTX_get1_issuer$descriptor() { -+ return X509_STORE_CTX_get1_issuer.DESC; - } - - /** - * Downcall method handle for: -- * {@snippet lang = c : * X509 *X509_STORE_CTX_get0_current_issuer(const X509_STORE_CTX *ctx) -+ * {@snippet lang = c : * int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) - * } - */ -- public static MethodHandle X509_STORE_CTX_get0_current_issuer$handle() { -- return X509_STORE_CTX_get0_current_issuer.HANDLE; -+ public static MethodHandle X509_STORE_CTX_get1_issuer$handle() { -+ return X509_STORE_CTX_get1_issuer.HANDLE; - } - - /** - * Address for: -- * {@snippet lang = c : * X509 *X509_STORE_CTX_get0_current_issuer(const X509_STORE_CTX *ctx) -+ * {@snippet lang = c : * int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) - * } - */ -- public static MemorySegment X509_STORE_CTX_get0_current_issuer$address() { -- return X509_STORE_CTX_get0_current_issuer.ADDR; -+ public static MemorySegment X509_STORE_CTX_get1_issuer$address() { -+ return X509_STORE_CTX_get1_issuer.ADDR; - } - - /** -- * {@snippet lang = c : * X509 *X509_STORE_CTX_get0_current_issuer(const X509_STORE_CTX *ctx) -+ * {@snippet lang = c : * int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) - * } - */ -- public static MemorySegment X509_STORE_CTX_get0_current_issuer(MemorySegment ctx) { -- var mh$ = X509_STORE_CTX_get0_current_issuer.HANDLE; -+ public static int X509_STORE_CTX_get1_issuer(MemorySegment issuer, MemorySegment ctx, MemorySegment x) { -+ var mh$ = X509_STORE_CTX_get1_issuer.HANDLE; - try { - if (TRACE_DOWNCALLS) { -- traceDowncall("X509_STORE_CTX_get0_current_issuer", ctx); -+ traceDowncall("X509_STORE_CTX_get1_issuer", issuer, ctx, x); - } -- return (MemorySegment) mh$.invokeExact(ctx); -+ return (int) mh$.invokeExact(issuer, ctx, x); - } catch (Throwable ex$) { - throw new AssertionError("should not reach here", ex$); - } -@@ -8771,6 +8891,315 @@ public class openssl_h { - } - } - -+ private static class OCSP_resp_get0_certs { -+ public static final FunctionDescriptor DESC = FunctionDescriptor.of( -+ openssl_h.C_POINTER, -+ openssl_h.C_POINTER -+ ); -+ -+ public static final MemorySegment ADDR = openssl_h.findOrThrow("OCSP_resp_get0_certs"); -+ -+ public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); -+ } -+ -+ /** -+ * Function descriptor for: -+ * {@snippet lang=c : -+ * const struct stack_st_X509 *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs) -+ * } -+ */ -+ public static FunctionDescriptor OCSP_resp_get0_certs$descriptor() { -+ return OCSP_resp_get0_certs.DESC; -+ } -+ -+ /** -+ * Downcall method handle for: -+ * {@snippet lang=c : -+ * const struct stack_st_X509 *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs) -+ * } -+ */ -+ public static MethodHandle OCSP_resp_get0_certs$handle() { -+ return OCSP_resp_get0_certs.HANDLE; -+ } -+ -+ /** -+ * Address for: -+ * {@snippet lang=c : -+ * const struct stack_st_X509 *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs) -+ * } -+ */ -+ public static MemorySegment OCSP_resp_get0_certs$address() { -+ return OCSP_resp_get0_certs.ADDR; -+ } -+ -+ /** -+ * {@snippet lang=c : -+ * const struct stack_st_X509 *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs) -+ * } -+ */ -+ public static MemorySegment OCSP_resp_get0_certs(MemorySegment bs) { -+ var mh$ = OCSP_resp_get0_certs.HANDLE; -+ try { -+ if (TRACE_DOWNCALLS) { -+ traceDowncall("OCSP_resp_get0_certs", bs); -+ } -+ return (MemorySegment)mh$.invokeExact(bs); -+ } catch (Error | RuntimeException ex) { -+ throw ex; -+ } catch (Throwable ex$) { -+ throw new AssertionError("should not reach here", ex$); -+ } -+ } -+ -+ private static class OCSP_basic_verify { -+ public static final FunctionDescriptor DESC = FunctionDescriptor.of( -+ openssl_h.C_INT, -+ openssl_h.C_POINTER, -+ openssl_h.C_POINTER, -+ openssl_h.C_POINTER, -+ openssl_h.C_LONG -+ ); -+ -+ public static final MemorySegment ADDR = openssl_h.findOrThrow("OCSP_basic_verify"); -+ -+ public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); -+ } -+ -+ /** -+ * Function descriptor for: -+ * {@snippet lang=c : -+ * int OCSP_basic_verify(OCSP_BASICRESP *bs, struct stack_st_X509 *certs, X509_STORE *st, unsigned long flags) -+ * } -+ */ -+ public static FunctionDescriptor OCSP_basic_verify$descriptor() { -+ return OCSP_basic_verify.DESC; -+ } -+ -+ /** -+ * Downcall method handle for: -+ * {@snippet lang=c : -+ * int OCSP_basic_verify(OCSP_BASICRESP *bs, struct stack_st_X509 *certs, X509_STORE *st, unsigned long flags) -+ * } -+ */ -+ public static MethodHandle OCSP_basic_verify$handle() { -+ return OCSP_basic_verify.HANDLE; -+ } -+ -+ /** -+ * Address for: -+ * {@snippet lang=c : -+ * int OCSP_basic_verify(OCSP_BASICRESP *bs, struct stack_st_X509 *certs, X509_STORE *st, unsigned long flags) -+ * } -+ */ -+ public static MemorySegment OCSP_basic_verify$address() { -+ return OCSP_basic_verify.ADDR; -+ } -+ -+ /** -+ * {@snippet lang=c : -+ * int OCSP_basic_verify(OCSP_BASICRESP *bs, struct stack_st_X509 *certs, X509_STORE *st, unsigned long flags) -+ * } -+ */ -+ public static int OCSP_basic_verify(MemorySegment bs, MemorySegment certs, MemorySegment st, long flags) { -+ var mh$ = OCSP_basic_verify.HANDLE; -+ try { -+ if (TRACE_DOWNCALLS) { -+ traceDowncall("OCSP_basic_verify", bs, certs, st, flags); -+ } -+ return (int)mh$.invokeExact(bs, certs, st, flags); -+ } catch (Error | RuntimeException ex) { -+ throw ex; -+ } catch (Throwable ex$) { -+ throw new AssertionError("should not reach here", ex$); -+ } -+ } -+ -+ private static class OCSP_check_validity { -+ public static final FunctionDescriptor DESC = FunctionDescriptor.of( -+ openssl_h.C_INT, -+ openssl_h.C_POINTER, -+ openssl_h.C_POINTER, -+ openssl_h.C_LONG, -+ openssl_h.C_LONG -+ ); -+ -+ public static final MemorySegment ADDR = openssl_h.findOrThrow("OCSP_check_validity"); -+ -+ public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); -+ } -+ -+ /** -+ * Function descriptor for: -+ * {@snippet lang=c : -+ * int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec) -+ * } -+ */ -+ public static FunctionDescriptor OCSP_check_validity$descriptor() { -+ return OCSP_check_validity.DESC; -+ } -+ -+ /** -+ * Downcall method handle for: -+ * {@snippet lang=c : -+ * int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec) -+ * } -+ */ -+ public static MethodHandle OCSP_check_validity$handle() { -+ return OCSP_check_validity.HANDLE; -+ } -+ -+ /** -+ * Address for: -+ * {@snippet lang=c : -+ * int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec) -+ * } -+ */ -+ public static MemorySegment OCSP_check_validity$address() { -+ return OCSP_check_validity.ADDR; -+ } -+ -+ /** -+ * {@snippet lang=c : -+ * int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec) -+ * } -+ */ -+ public static int OCSP_check_validity(MemorySegment thisupd, MemorySegment nextupd, long sec, long maxsec) { -+ var mh$ = OCSP_check_validity.HANDLE; -+ try { -+ if (TRACE_DOWNCALLS) { -+ traceDowncall("OCSP_check_validity", thisupd, nextupd, sec, maxsec); -+ } -+ return (int)mh$.invokeExact(thisupd, nextupd, sec, maxsec); -+ } catch (Error | RuntimeException ex) { -+ throw ex; -+ } catch (Throwable ex$) { -+ throw new AssertionError("should not reach here", ex$); -+ } -+ } -+ -+ private static class OCSP_request_add1_nonce { -+ public static final FunctionDescriptor DESC = FunctionDescriptor.of( -+ openssl_h.C_INT, -+ openssl_h.C_POINTER, -+ ValueLayout.JAVA_CHAR, -+ openssl_h.C_INT -+ ); -+ -+ public static final MemorySegment ADDR = openssl_h.findOrThrow("OCSP_request_add1_nonce"); -+ -+ public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); -+ } -+ -+ /** -+ * Function descriptor for: -+ * {@snippet lang=c : -+ * int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) -+ * } -+ */ -+ public static FunctionDescriptor OCSP_request_add1_nonce$descriptor() { -+ return OCSP_request_add1_nonce.DESC; -+ } -+ -+ /** -+ * Downcall method handle for: -+ * {@snippet lang=c : -+ * int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) -+ * } -+ */ -+ public static MethodHandle OCSP_request_add1_nonce$handle() { -+ return OCSP_request_add1_nonce.HANDLE; -+ } -+ -+ /** -+ * Address for: -+ * {@snippet lang=c : -+ * int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) -+ * } -+ */ -+ public static MemorySegment OCSP_request_add1_nonce$address() { -+ return OCSP_request_add1_nonce.ADDR; -+ } -+ -+ /** -+ * {@snippet lang=c : -+ * int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) -+ * } -+ */ -+ public static int OCSP_request_add1_nonce(MemorySegment req, char val, int len) { -+ var mh$ = OCSP_request_add1_nonce.HANDLE; -+ try { -+ if (TRACE_DOWNCALLS) { -+ traceDowncall("OCSP_request_add1_nonce", req, val, len); -+ } -+ return (int)mh$.invokeExact(req, val, len); -+ } catch (Error | RuntimeException ex) { -+ throw ex; -+ } catch (Throwable ex$) { -+ throw new AssertionError("should not reach here", ex$); -+ } -+ } -+ -+ private static class OCSP_check_nonce { -+ public static final FunctionDescriptor DESC = FunctionDescriptor.of( -+ openssl_h.C_INT, -+ openssl_h.C_POINTER, -+ openssl_h.C_POINTER -+ ); -+ -+ public static final MemorySegment ADDR = openssl_h.findOrThrow("OCSP_check_nonce"); -+ -+ public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC); -+ } -+ -+ /** -+ * Function descriptor for: -+ * {@snippet lang=c : -+ * int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) -+ * } -+ */ -+ public static FunctionDescriptor OCSP_check_nonce$descriptor() { -+ return OCSP_check_nonce.DESC; -+ } -+ -+ /** -+ * Downcall method handle for: -+ * {@snippet lang=c : -+ * int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) -+ * } -+ */ -+ public static MethodHandle OCSP_check_nonce$handle() { -+ return OCSP_check_nonce.HANDLE; -+ } -+ -+ /** -+ * Address for: -+ * {@snippet lang=c : -+ * int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) -+ * } -+ */ -+ public static MemorySegment OCSP_check_nonce$address() { -+ return OCSP_check_nonce.ADDR; -+ } -+ -+ /** -+ * {@snippet lang=c : -+ * int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) -+ * } -+ */ -+ public static int OCSP_check_nonce(MemorySegment req, MemorySegment bs) { -+ var mh$ = OCSP_check_nonce.HANDLE; -+ try { -+ if (TRACE_DOWNCALLS) { -+ traceDowncall("OCSP_check_nonce", req, bs); -+ } -+ return (int)mh$.invokeExact(req, bs); -+ } catch (Error | RuntimeException ex) { -+ throw ex; -+ } catch (Throwable ex$) { -+ throw new AssertionError("should not reach here", ex$); -+ } -+ } -+ - private static class OCSP_cert_to_id { - public static final FunctionDescriptor DESC = FunctionDescriptor.of(openssl_h.C_POINTER, openssl_h.C_POINTER, - openssl_h.C_POINTER, openssl_h.C_POINTER); -diff --git a/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java b/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java -index 5f513182d1..e75528da40 100644 ---- a/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java -+++ b/java/org/apache/tomcat/util/openssl/openssl_h_Compatibility.java -@@ -33,16 +33,45 @@ public class openssl_h_Compatibility { - public static final boolean OPENSSL3; - public static final boolean BORINGSSL; - public static final boolean LIBRESSL; -+ -+ public static final int MAJOR; -+ public static final int MINOR; -+ - static { - String versionString = OpenSSL_version(0).getString(0); - OPENSSL = versionString.contains("OpenSSL"); - OPENSSL3 = OPENSSL && OpenSSL_version_num() >= 0x3000000fL; - BORINGSSL = versionString.contains("BoringSSL"); - LIBRESSL = versionString.contains("LibreSSL"); -+ int majorVersion = 0; -+ int minorVersion = 0; -+ try { -+ String[] blocks = versionString.split("\\s"); -+ if (blocks.length >= 2) { -+ versionString = blocks[1]; -+ } -+ String[] versionNumberStrings = versionString.split("\\."); -+ if (versionNumberStrings.length >= 2) { -+ majorVersion = Integer.parseInt(versionNumberStrings[0]); -+ minorVersion = Integer.parseInt(versionNumberStrings[1]); -+ } -+ } catch (Exception e) { -+ // Ignore, default to 0 -+ } finally { -+ MAJOR = majorVersion; -+ MINOR = minorVersion; -+ } -+ } -+ -+ public static boolean isLibreSSLPre35() { -+ return LIBRESSL && ((MAJOR == 3 && MINOR < 5) || MAJOR < 3); - } - - // OpenSSL 1.1 FIPS_mode - public static int FIPS_mode() { -+ if (isLibreSSLPre35()) { -+ return 0; -+ } - class Holder { - static final String NAME = "FIPS_mode"; - static final FunctionDescriptor DESC = FunctionDescriptor.of(JAVA_INT); -@@ -61,6 +90,9 @@ public class openssl_h_Compatibility { - - // OpenSSL 1.1 FIPS_mode_set - public static int FIPS_mode_set(int r) { -+ if (isLibreSSLPre35()) { -+ return 0; -+ } - class Holder { - static final String NAME = "FIPS_mode_set"; - static final FunctionDescriptor DESC = FunctionDescriptor.of(JAVA_INT, JAVA_INT); -diff --git a/res/openssl/openssl-tomcat.conf b/res/openssl/openssl-tomcat.conf -index 892f3b84af..337e7a831e 100644 ---- a/res/openssl/openssl-tomcat.conf -+++ b/res/openssl/openssl-tomcat.conf -@@ -16,7 +16,7 @@ - -t org.apache.tomcat.util.openssl - -lssl - # Configure include path ---I /usr/lib/gcc/x86_64-redhat-linux/14/include -+-I /usr/lib/gcc/x86_64-redhat-linux/15/include - --output ../../java - - #### Extracted from: /usr/include/openssl/asn1.h -@@ -108,12 +108,17 @@ - --include-function OCSP_REQUEST_free # header: /usr/include/openssl/ocsp.h - --include-function OCSP_REQUEST_new # header: /usr/include/openssl/ocsp.h - --include-function OCSP_RESPONSE_free # header: /usr/include/openssl/ocsp.h -+--include-function OCSP_basic_verify # header: /usr/include/openssl/ocsp.h - --include-function OCSP_cert_to_id # header: /usr/include/openssl/ocsp.h -+--include-function OCSP_check_validity # header: /usr/include/openssl/ocsp.h -+--include-function OCSP_check_nonce # header: /usr/include/openssl/ocsp.h - --include-function OCSP_request_add0_id # header: /usr/include/openssl/ocsp.h -+--include-function OCSP_request_add1_nonce # header: /usr/include/openssl/ocsp.h - --include-function OCSP_response_get1_basic # header: /usr/include/openssl/ocsp.h - --include-function OCSP_response_status # header: /usr/include/openssl/ocsp.h - --include-function OCSP_resp_find # header: /usr/include/openssl/ocsp.h - --include-function OCSP_resp_get0 # header: /usr/include/openssl/ocsp.h -+--include-function OCSP_resp_get0_certs # header: /usr/include/openssl/ocsp.h - --include-function OCSP_single_get0_status # header: /usr/include/openssl/ocsp.h - --include-function d2i_OCSP_RESPONSE # header: /usr/include/openssl/ocsp.h - --include-function i2d_OCSP_REQUEST # header: /usr/include/openssl/ocsp.h -@@ -342,20 +347,26 @@ - --include-function X509_STORE_CTX_get_error # header: /usr/include/openssl/x509_vfy.h - --include-function X509_STORE_CTX_get_error_depth # header: /usr/include/openssl/x509_vfy.h - --include-function X509_STORE_CTX_get_ex_data # header: /usr/include/openssl/x509_vfy.h ----include-function X509_STORE_CTX_get0_current_issuer # header: /usr/include/openssl/x509_vfy.h -+--include-function X509_STORE_CTX_get0_store # header: /usr/include/openssl/x509_vfy.h - --include-function X509_STORE_CTX_get0_untrusted # header: /usr/include/openssl/x509_vfy.h -+--include-function X509_STORE_CTX_get1_issuer # header: /usr/include/openssl/x509_vfy.h - --include-function X509_STORE_CTX_set_error # header: /usr/include/openssl/x509_vfy.h - --include-function X509_STORE_set_flags # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_L_ADD_DIR # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_L_FILE_LOAD # header: /usr/include/openssl/x509_vfy.h ----include-constant X509_V_ERR_APPLICATION_VERIFICATION # header: /usr/include/openssl/x509_vfy.h ----include-constant X509_V_ERR_CERT_UNTRUSTED # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_OK # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_ERR_UNABLE_TO_GET_CRL # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_V_ERR_CRL_HAS_EXPIRED # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_ERR_CERT_REVOKED # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_ERR_CERT_UNTRUSTED # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_ERR_APPLICATION_VERIFICATION # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_ERR_OCSP_RESP_INVALID # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_ERR_OCSP_SIGNATURE_FAILURE # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_ERR_OCSP_NOT_YET_VALID # header: /usr/include/openssl/x509_vfy.h -+--include-constant X509_V_ERR_OCSP_HAS_EXPIRED # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_V_FLAG_CRL_CHECK # header: /usr/include/openssl/x509_vfy.h - --include-constant X509_V_FLAG_CRL_CHECK_ALL # header: /usr/include/openssl/x509_vfy.h ----include-constant X509_V_OK # header: /usr/include/openssl/x509_vfy.h -- -diff --git a/test/org/apache/tomcat/security/TestSecurity2017Ocsp.java b/test/org/apache/tomcat/security/TestSecurity2017Ocsp.java -new file mode 100644 -index 0000000000..2187396985 ---- /dev/null -+++ b/test/org/apache/tomcat/security/TestSecurity2017Ocsp.java -@@ -0,0 +1,107 @@ -+/* -+ * 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.security; -+ -+import java.io.IOException; -+ -+import javax.net.ssl.SSLHandshakeException; -+import javax.servlet.http.HttpServletResponse; -+ -+import org.junit.AfterClass; -+import org.junit.Assert; -+import org.junit.Assume; -+import org.junit.BeforeClass; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+ -+import org.apache.catalina.Context; -+import org.apache.catalina.startup.Tomcat; -+import org.apache.tomcat.util.buf.ByteChunk; -+import org.apache.tomcat.util.net.SSLHostConfig; -+import org.apache.tomcat.util.net.TesterSupport; -+import org.apache.tomcat.util.net.TesterSupport.SimpleServlet; -+import org.apache.tomcat.util.net.ocsp.OcspBaseTest; -+import org.apache.tomcat.util.net.ocsp.TesterOcspResponder; -+import org.apache.tomcat.util.net.openssl.OpenSSLStatus; -+ -+@RunWith(Parameterized.class) -+public class TestSecurity2017Ocsp extends OcspBaseTest { -+ -+ private static TesterOcspResponder ocspResponder; -+ -+ @BeforeClass -+ public static void startOcspResponder() { -+ ocspResponder = new TesterOcspResponder(); -+ try { -+ ocspResponder.start(); -+ } catch (IOException ioe) { -+ ocspResponder = null; -+ } -+ } -+ -+ -+ @AfterClass -+ public static void stopOcspResponder() { -+ if (ocspResponder != null) { -+ ocspResponder.stop(); -+ ocspResponder = null; -+ } -+ } -+ -+ -+ /* -+ * In addition to testing Tomcat Native (where the CVE occurred), this also tests JSSE and OpenSSl via FFM. -+ */ -+ @Test(expected=SSLHandshakeException.class) -+ public void testCVE_2017_15698() throws Exception { -+ if ("OpenSSL-FFM".equals(connectorName)) { -+ Assume.assumeFalse(OpenSSLStatus.isBoringSSL() || OpenSSLStatus.isLibreSSLPre35()); -+ } -+ Assume.assumeNotNull(ocspResponder); -+ -+ Tomcat tomcat = getTomcatInstance(); -+ -+ // No file system docBase required -+ Context ctx = tomcat.addContext("", null); -+ -+ Tomcat.addServlet(ctx, "simple", new SimpleServlet()); -+ ctx.addServletMappingDecoded("/simple", "simple"); -+ -+ // User a valid (non-revoked) server certificate -+ TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_RSA_JKS, useOpenSSLTrust); -+ -+ // Require client certificates and enable verification -+ SSLHostConfig sslHostConfig = tomcat.getConnector().findSslHostConfigs()[0]; -+ sslHostConfig.setOcspEnabled(true); -+ sslHostConfig.setCertificateVerification("required"); -+ -+ // Configure a revoked client certificate with a long AIA -+ // Don't verify the server certificate -+ TesterSupport.configureClientSsl(false, TesterSupport.CLIENT_CRL_LONG_JKS); -+ -+ // Disable soft-fail -+ sslHostConfig.setOcspSoftFail(false); -+ -+ tomcat.start(); -+ -+ int rc = getUrl("https://localhost:" + getPort() + "/simple", new ByteChunk(), false); -+ -+ // If the TLS handshake fails, the test won't get this far. -+ Assert.assertEquals(HttpServletResponse.SC_OK, rc); -+ } -+} -diff --git a/test/org/apache/tomcat/util/net/TestSSLHostConfigCipher.java b/test/org/apache/tomcat/util/net/TestSSLHostConfigCipher.java -new file mode 100644 -index 0000000000..75c8e90d00 ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/TestSSLHostConfigCipher.java -@@ -0,0 +1,161 @@ -+/* -+ * 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.util.ArrayList; -+import java.util.Collection; -+import java.util.List; -+ -+import javax.net.ssl.SSLHandshakeException; -+ -+import org.junit.Assert; -+import org.junit.Assume; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+import org.junit.runners.Parameterized.Parameter; -+ -+import org.apache.catalina.Context; -+import org.apache.catalina.connector.Connector; -+import org.apache.catalina.startup.TesterServlet; -+import org.apache.catalina.startup.Tomcat; -+import org.apache.catalina.startup.TomcatBaseTest; -+import org.apache.tomcat.util.buf.ByteChunk; -+import org.apache.tomcat.util.net.openssl.OpenSSLStatus; -+ -+@RunWith(Parameterized.class) -+public class TestSSLHostConfigCipher extends TomcatBaseTest { -+ -+ private static final String CIPHER_12_AVAILABLE = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; -+ private static final String CIPHER_12_NOT_AVAILABLE = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; -+ private static final String CIPHER_13_AVAILABLE = "TLS_AES_128_GCM_SHA256"; -+ private static final String CIPHER_13_NOT_AVAILABLE = "TLS_AES_256_GCM_SHA384"; -+ -+ @Parameterized.Parameters(name = "{0}") -+ public static Collection parameters() { -+ List parameterSets = new ArrayList<>(); -+ parameterSets.add(new Object[] { -+ "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); -+ parameterSets.add(new Object[] { -+ "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); -+ parameterSets.add(new Object[] { -+ "OpenSSL-FFM", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation"}); -+ -+ return parameterSets; -+ } -+ -+ @Parameter(0) -+ public String connectorName; -+ -+ @Parameter(1) -+ public boolean useOpenSSL; -+ -+ @Parameter(2) -+ public String sslImplementationName; -+ -+ -+ @Override -+ public void setUp() throws Exception { -+ super.setUp(); -+ -+ Tomcat tomcat = getTomcatInstance(); -+ -+ // Server-side TLS configuration -+ TesterSupport.initSsl(tomcat); -+ TesterSupport.configureSSLImplementation(tomcat, sslImplementationName, useOpenSSL); -+ -+ // Test specific, server-side cipher & protocol configuration -+ SSLHostConfig sslHostConfig = getSSLHostConfig(); -+ sslHostConfig.setProtocols("+TLSv1.2+TLSv1.3"); -+ sslHostConfig.setCiphers(CIPHER_12_AVAILABLE); -+ sslHostConfig.setCipherSuites(CIPHER_13_AVAILABLE); -+ -+ // Simple webapp -+ Context ctxt = getProgrammaticRootContext(); -+ Tomcat.addServlet(ctxt, "TesterServlet", new TesterServlet()); -+ ctxt.addServletMappingDecoded("/*", "TesterServlet"); -+ } -+ -+ -+ @Test -+ public void testTls12CipherAvailable() throws Exception { -+ if ("OpenSSL-FFM".equals(connectorName)) { -+ // The functionality works, but the two ciphers used are not available -+ Assume.assumeFalse(OpenSSLStatus.isBoringSSL()); -+ } -+ // Client-side TLS configuration -+ TesterSupport.configureClientSsl(true, new String[] { CIPHER_12_AVAILABLE } ); -+ -+ doTest(); -+ } -+ -+ -+ @Test(expected=SSLHandshakeException.class) -+ public void testTls12CipherNotAvailable() throws Exception { -+ if ("OpenSSL-FFM".equals(connectorName)) { -+ Assume.assumeFalse(OpenSSLStatus.isBoringSSL()); -+ } -+ // Client-side TLS configuration -+ TesterSupport.configureClientSsl(true, new String[] { CIPHER_12_NOT_AVAILABLE } ); -+ -+ doTest(); -+ } -+ -+ -+ @Test -+ public void testTls13CipherAvailable() throws Exception { -+ if ("OpenSSL-FFM".equals(connectorName)) { -+ Assume.assumeFalse(OpenSSLStatus.isBoringSSL()); -+ } -+ // Client-side TLS configuration -+ TesterSupport.configureClientSsl(new String[] { CIPHER_13_AVAILABLE } ); -+ -+ doTest(); -+ } -+ -+ -+ @Test(expected=SSLHandshakeException.class) -+ public void testTls13CipherNotAvailable() throws Exception { -+ if ("OpenSSL-FFM".equals(connectorName)) { -+ // The TLS 1.3 call might not be present -+ Assume.assumeFalse(OpenSSLStatus.isLibreSSLPre35()); -+ Assume.assumeFalse(OpenSSLStatus.isBoringSSL()); -+ } -+ // Client-side TLS configuration -+ TesterSupport.configureClientSsl(new String[] { CIPHER_13_NOT_AVAILABLE } ); -+ -+ doTest(); -+ } -+ -+ -+ private void doTest() throws Exception { -+ Tomcat tomcat = getTomcatInstance(); -+ -+ tomcat.start(); -+ -+ // Check a request can be made -+ ByteChunk res = getUrl("https://localhost:" + getPort() + "/"); -+ Assert.assertEquals("OK", res.toString()); -+ } -+ -+ -+ private SSLHostConfig getSSLHostConfig() { -+ Tomcat tomcat = getTomcatInstance(); -+ Connector connector = tomcat.getConnector(); -+ return connector.findSslHostConfigs()[0]; -+ } -+} -diff --git a/test/org/apache/tomcat/util/net/TestSsl.java b/test/org/apache/tomcat/util/net/TestSsl.java -index 5aeada0951..e21b61da93 100644 ---- a/test/org/apache/tomcat/util/net/TestSsl.java -+++ b/test/org/apache/tomcat/util/net/TestSsl.java -@@ -251,7 +251,7 @@ public class TestSsl extends TomcatBaseTest { - Context ctxt = tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); - ctxt.addApplicationListener(WsContextListener.class.getName()); - -- TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_KEYPASS_JKS, -+ TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_KEYPASS_JKS, false, - TesterSupport.JKS_PASS, null, TesterSupport.JKS_KEY_PASS, null); - - TesterSupport.configureSSLImplementation(tomcat, sslImplementationName, useOpenSSL); -@@ -274,7 +274,7 @@ public class TestSsl extends TomcatBaseTest { - Context ctxt = tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); - ctxt.addApplicationListener(WsContextListener.class.getName()); - -- TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_KEYPASS_JKS, -+ TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_KEYPASS_JKS, false, - null, TesterSupport.JKS_PASS_FILE, null, TesterSupport.JKS_KEY_PASS_FILE); - - TesterSupport.configureSSLImplementation(tomcat, sslImplementationName, useOpenSSL); -diff --git a/test/org/apache/tomcat/util/net/TesterSupport.java b/test/org/apache/tomcat/util/net/TesterSupport.java -index 711cbadfc8..f9ff77499e 100644 ---- a/test/org/apache/tomcat/util/net/TesterSupport.java -+++ b/test/org/apache/tomcat/util/net/TesterSupport.java -@@ -55,11 +55,11 @@ import org.apache.catalina.LifecycleListener; - import org.apache.catalina.authenticator.SSLAuthenticator; - import org.apache.catalina.connector.Connector; - import org.apache.catalina.core.AprLifecycleListener; --import org.apache.catalina.core.AprStatus; - import org.apache.catalina.core.OpenSSLLifecycleListener; - import org.apache.catalina.core.StandardServer; - import org.apache.catalina.startup.TesterMapRealm; - import org.apache.catalina.startup.Tomcat; -+import org.apache.tomcat.jni.AprStatus; - import org.apache.tomcat.util.descriptor.web.LoginConfig; - import org.apache.tomcat.util.descriptor.web.SecurityCollection; - import org.apache.tomcat.util.descriptor.web.SecurityConstraint; -@@ -87,6 +87,9 @@ public final class TesterSupport { - public static final String LOCALHOST_EC_KEY_PEM = SSL_DIR + "localhost-ec-key.pem"; - public static final String LOCALHOST_RSA_CERT_PEM = SSL_DIR + "localhost-rsa-cert.pem"; - public static final String LOCALHOST_RSA_KEY_PEM = SSL_DIR + "localhost-rsa-key.pem"; -+ public static final String DB_INDEX = SSL_DIR + "index.db"; -+ public static final String OCSP_RESPONDER_RSA_CERT = SSL_DIR + "oscp-responder-rsa-cert.pem"; -+ public static final String OCSP_RESPONDER_RSA_KEY = SSL_DIR + "oscp-responder-rsa-key.pem"; - public static final boolean TLSV13_AVAILABLE; - - public static final String ROLE = "testrole"; -diff --git a/test/org/apache/tomcat/util/net/ca-cert.pem b/test/org/apache/tomcat/util/net/ca-cert.pem -index a5171578c1..e8e344f6b1 100644 ---- a/test/org/apache/tomcat/util/net/ca-cert.pem -+++ b/test/org/apache/tomcat/util/net/ca-cert.pem -@@ -1,39 +1,39 @@ - -----BEGIN CERTIFICATE----- --MIIGvzCCBKegAwIBAgIUd8TEpsZJz7k3Ddw/oRfCrdlmRlcwDQYJKoZIhvcNAQEL --BQAwgZMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJNQTESMBAGA1UEBxMJV2FrZWZp --ZWxkMScwJQYDVQQKEx5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xGjAY --BgNVBAsTEUFwYWNoZSBUb21jYXQgUE1DMR4wHAYDVQQDExVBcGFjaGUgVG9tY2F0 --IFRlc3QgQ0EwHhcNMjUwODE3MDczNDAwWhcNMzUwODE1MDczNDAwWjCBkzELMAkG --A1UEBhMCVVMxCzAJBgNVBAgTAk1BMRIwEAYDVQQHEwlXYWtlZmllbGQxJzAlBgNV --BAoTHlRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbjEaMBgGA1UECxMRQXBh --Y2hlIFRvbWNhdCBQTUMxHjAcBgNVBAMTFUFwYWNoZSBUb21jYXQgVGVzdCBDQTCC --AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK6iRe7N1DwdOhFVwvTsB3Ed --b1aZoylw9Zv+/JB1y6Fr4lcn1a753t+nGml67GeMOYMJk2jSSKYjudggQMx3dZV6 --fvlqgxmdDv6838ZlBfHNI/Pa/NNnIQRMCqzsOwbA7kIrbLmxYqXnv5ALP837EzsT --A7I2Sa37vEjV5D7PaxQ0tEwrtpuibyeb/BV+0YBciKuJuZOq6SjGOvx2kQODvtUL --L16p7qRyKXoW+euZismqavDMaV1SXDiOoeXUgmcnnPbzW/PNDRTlQt6K4GkMZdw4 --ehofzNjGKUFWk+5ENEE5xfXt7k2i5m0NMV6aQmrmezc8O35aMm+5g1IQssFuc/5L --VXqa34xT0+wXpN2VVlnHEUP2E9ioDPKbAkbNMpsTyO5mu5CzAviJ+3IQuYs+Mix6 --1W1eJ+xQ1rLoJ8Ovmw3qv4ouuElZSqGKLaYfWPHhwuaV/fTxM5zzROV2+8j1x+tv --n3r3nhwQT7t2VpS+dFsEB5U0c0eXl7rx+/CkqC29CG2DWtnbDV+hKQDLI1GRitRk --p7jO1TH0TbD2oibc6RnIxw9MpiQFVqFHorVsKjr25pSvFjg1piU98p0mYZ+Kj8nZ --YZ2our2driIdHJilvnMq9iYf1w2maflXjbKGZfu2MwnNTJbDwrFekT+oRUHbCXXX --A2C4QvwJpnL7e7SJoKptAgMBAAGjggEHMIIBAzAdBgNVHQ4EFgQUAPKYTSEsADxA --m4T03irwJu4yDp8wgdMGA1UdIwSByzCByIAUAPKYTSEsADxAm4T03irwJu4yDp+h --gZmkgZYwgZMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJNQTESMBAGA1UEBxMJV2Fr --ZWZpZWxkMScwJQYDVQQKEx5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24x --GjAYBgNVBAsTEUFwYWNoZSBUb21jYXQgUE1DMR4wHAYDVQQDExVBcGFjaGUgVG9t --Y2F0IFRlc3QgQ0GCFHfExKbGSc+5Nw3cP6EXwq3ZZkZXMAwGA1UdEwQFMAMBAf8w --DQYJKoZIhvcNAQELBQADggIBAD839dBKpesTMCsiSrx1GXP6hbjXfNtKcskzlce3 --zGYDdIUFYit1gnuftvcl4u2hDCqodCn30LUE6wRQd3E2hiItOzlWufp4Rb6KZNie --xp/A5ifu90qbJgEBlZScLDydcvkts1JTF4WuzQdKGY5MEh1OgNPj1M3cwg92UmGJ --fGU57jnvpaJxS9IoJXIeIpmCr5dM1nk5NMY3Vt2Fg+vssHLS9t7glKQBlSa4+Ts6 --26xWINXQvJOomWWEDrs96pzZ2AHAJ+L/eExofAa6FyCXB1Oxd5M+U8A9DgehHVqi --9r5/FMi3nS+v8UR0/4KpAUPjKAMCyZZbLFza0o0sHYWKehG/NdAUio4jKJKFCh/Z --bQxGtPNW92N0FOQaWv3TUCbfv5bDtX6RC8b9D8u/bvUlYDYnT+c/2Z1RQHwxuoyF --+/514VUZztpr/DBidlUlHBpqsAbRAHsoRVtn1xjTXraDRHewnvdA/AV1f+PuIKJf --4DAnUCn7OKExUAFe87EZizdoaKu5lr0kNUhXdKKVgqGrSolHD67etEviHjAqEJdn --mPO1aIeG3ukFGh3vp8/SFZk9J34qZ5jEl+QldIhAEFWHEX5wmZ74GatAUnOSmiHq --xSQMB2ULGTOC1HMBUQMgelY4Qiwsa92pO1qySsZIL5npmBM9ok+o/jshCpoTCCin --nzrk -+MIIGwjCCBKqgAwIBAgIUb23jgHGhJDQJaz0iHUfKwRV5z5kwDQYJKoZIhvcNAQEL -+BQAwgZQxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJERTETMBEGA1UEBxMKV2lsbWlu -+Z3RvbjEnMCUGA1UEChMeVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRow -+GAYDVQQLExFBcGFjaGUgVG9tY2F0IFBNQzEeMBwGA1UEAxMVQXBhY2hlIFRvbWNh -+dCBUZXN0IENBMB4XDTI1MTIwNTE5MTIzOFoXDTM1MTIwMzE5MTIzOFowgZQxCzAJ -+BgNVBAYTAlVTMQswCQYDVQQIEwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUG -+A1UEChMeVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFB -+cGFjaGUgVG9tY2F0IFBNQzEeMBwGA1UEAxMVQXBhY2hlIFRvbWNhdCBUZXN0IENB -+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqeIoIFXsR468dJCUYnNX -+E4DLI9J2jLIz/T1Jiq/tA9XCzA+XFqf3tlZdXLsfQhDLg0lf+wHqQfSvbQ0Gcatn -+Iw8BIvA7yq6PDKsO4cjQ2EdrkTn2JD7hJW5uUB9Je95TUUbKuNxOatihwS4DNU2J -+aoI2R2iUGasXsawVR+4qj1UJByawlsGHxFCqhVoaUKM/fKXK7LllbyHsRxuZTgab -+Spmvj2jcMxyeDN2ZjlBdsrSg+8FpYvnPKzHpdFiA6d4pxU6QJbeDeWPQ6B64yWi1 -+eImFvilqZQoQ3RR/1gDjoFuLCdWK7mAvfaSXFzax1YK3D/MiCowTZ8M0iWmGqMg1 -+QF6luhPL+5p8Q2/KooE3CZol0IpCUGr3cQs3FC1deL5ySNMYniXQMgxGqVE3x0i1 -+Wlf5bItGY0Ha9vc+s4vmnRZxW4O+fXiuG9OXS5XjfWGAjzkJ6wXgFRJKbWDsSPkR -+Sw9j9SAsLE6cycY66eMl94QdOl6KRXVyeaLHJbRMBux7WvDXYS/eWKFHjmPYNKq6 -+btIB7ELTqoMuwTAWj83bdkQgMac5fsTozKduM+C63sSg3mhmyy6yVgCX1eECqPNk -+N4K4oWdhQvKYvCp1n1EySAupZqrxudBLp/LDHRfGh7gfAZgP8hxRaoBqh2u0H8Fh -+RwSAML8zEeRH/si3G7LfXzECAwEAAaOCAQgwggEEMB0GA1UdDgQWBBSsh9yLPYrb -+iUh+bzscxnCSCRdv+TCB1AYDVR0jBIHMMIHJgBSsh9yLPYrbiUh+bzscxnCSCRdv -++aGBmqSBlzCBlDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkRFMRMwEQYDVQQHEwpX -+aWxtaW5ndG9uMScwJQYDVQQKEx5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRp -+b24xGjAYBgNVBAsTEUFwYWNoZSBUb21jYXQgUE1DMR4wHAYDVQQDExVBcGFjaGUg -+VG9tY2F0IFRlc3QgQ0GCFG9t44BxoSQ0CWs9Ih1HysEVec+ZMAwGA1UdEwQFMAMB -+Af8wDQYJKoZIhvcNAQELBQADggIBAA/DyqPhxRAluY1e1S9L2SkkrcYePjb033Wl -+ZmMVdXvf6LZtpjquNz81ThNoX5yfgV6CawDRw7COI4dAU3HOLVtOeKybm11Jq1BH -+AWmlZVQIOplgnitoEoZi8brxEpSgeyRGLKHYaW1YxshPRC5tVDKsbyYBtvmTaBtK -+dMirc36cEDkSfEe2dq+MkHgzHyyvySqTSlI/MH7CKQYBjGg2D+Gcle/BNrK02wef -+Rol9M3R3skDfV/P0NFmrfFi4B/cXt/EFxm1thMsQ6ofd0GUMGgv6fJKN1AVDihx6 -+sQvbn712+54ilkcWMa3gW5L/BIxcDS+ZZiO/7T2tZ2d3tcz86gYbFkiQbWelnTmn -+FBSHno9PDgxRWZzqauKqlsczAsz5qLf8zF+GDubEcxvOgEf0wQ/vPwtSb2R4egb+ -+3Vn+InqDy9/78ug497KV842jxQy2G6wZLND0q81H04t8NYQopbX4DI0hS5BJnKuV -+TM3rh4C/hNXs8kUpjusqnnV8nbBpab2R1YzEOefhgtTFdk/dHI7a5+6BKNSK55yn -+hDqgemD5p+5A6FLu3M0RDgbTZ1WdrtYDvQZrAMB10mrV0YDoDgnEzGYEc/PQwkYF -+gOeqb97mOdjf9YUJli4S4XLkZ5zn/IitEQRbnKen2VE60qIgW/UMYKTiwuSZtRaW -+gxBAeoi3 - -----END CERTIFICATE----- -diff --git a/test/org/apache/tomcat/util/net/ca.jks b/test/org/apache/tomcat/util/net/ca.jks -index 615060a41f..d740b45124 100644 -Binary files a/test/org/apache/tomcat/util/net/ca.jks and b/test/org/apache/tomcat/util/net/ca.jks differ -diff --git a/test/org/apache/tomcat/util/net/index.db b/test/org/apache/tomcat/util/net/index.db -new file mode 100644 -index 0000000000..eb521a4242 ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/index.db -@@ -0,0 +1,6 @@ -+V 271205191323Z 1000 unknown /C=US/ST=DE/L=Wilmington/O=The Apache Software Foundation/OU=Apache Tomcat PMC/CN=localhost -+R 271205191327Z 251205192921Z 1001 unknown /C=US/ST=DE/L=Wilmington/O=The Apache Software Foundation/OU=Apache Tomcat PMC/CN=localhost -+V 271205191331Z 1002 unknown /C=US/ST=DE/L=Wilmington/O=The Apache Software Foundation/OU=Apache Tomcat PMC/CN=user1 -+R 271205191335Z 251205192924Z 1003 unknown /C=US/ST=DE/L=Wilmington/O=The Apache Software Foundation/OU=Apache Tomcat PMC/CN=user2 -+V 271205191540Z 1004 unknown /C=US/ST=DE/L=Wilmington/O=The Apache Software Foundation/OU=Apache Tomcat PMC/CN=localhost -+V 271205193355Z 1005 unknown /C=US/ST=DE/L=Wilmington/O=The Apache Software Foundation/OU=Apache Tomcat PMC/CN=OCSP Responder -diff --git a/test/org/apache/tomcat/util/net/index.db.attr b/test/org/apache/tomcat/util/net/index.db.attr -new file mode 100644 -index 0000000000..3a7e39e6ee ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/index.db.attr -@@ -0,0 +1 @@ -+unique_subject = no -diff --git a/test/org/apache/tomcat/util/net/localhost-crl-rsa-cert.pem b/test/org/apache/tomcat/util/net/localhost-crl-rsa-cert.pem -new file mode 100644 -index 0000000000..7cfe515a25 ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/localhost-crl-rsa-cert.pem -@@ -0,0 +1,108 @@ -+Certificate: -+ Data: -+ Version: 3 (0x2) -+ Serial Number: 4097 (0x1001) -+ Signature Algorithm: sha256WithRSAEncryption -+ Issuer: C=US, ST=DE, L=Wilmington, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=Apache Tomcat Test CA -+ Validity -+ Not Before: Dec 5 19:13:27 2025 GMT -+ Not After : Dec 5 19:13:27 2027 GMT -+ Subject: C=US, ST=DE, L=Wilmington, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=localhost -+ Subject Public Key Info: -+ Public Key Algorithm: rsaEncryption -+ Public-Key: (2048 bit) -+ Modulus: -+ 00:aa:f2:ee:01:dd:21:fd:4b:f6:1e:9f:a1:a6:65: -+ 42:71:1c:db:cf:d7:47:6d:20:81:63:01:c7:6c:a2: -+ 5a:2e:17:0d:5d:d9:60:78:e5:d9:2a:9a:c0:2d:1c: -+ 2d:24:9d:b3:f6:26:a9:93:80:86:ad:0e:b0:06:4e: -+ 64:dc:11:da:70:a0:eb:47:aa:9d:39:3e:10:1c:b5: -+ fe:bc:ca:b2:5b:b8:3f:0c:a8:d4:b3:cb:9e:dd:f5: -+ 19:0e:dc:83:34:54:1d:17:b9:0d:2e:5d:4c:31:d7: -+ 9b:64:e9:40:89:de:77:75:ad:6e:86:3e:46:15:88: -+ ed:48:88:bb:a2:77:a5:05:4a:33:33:3e:bb:cb:7b: -+ f7:00:9b:eb:4e:2b:f5:4a:59:07:ff:18:5a:a1:49: -+ c2:25:48:21:03:55:64:da:d7:75:0f:e8:55:a8:61: -+ 39:ca:af:09:64:c2:c1:67:4b:ec:95:df:66:50:2d: -+ 39:45:d6:4c:8d:07:a8:3d:d1:fc:3c:46:76:92:2f: -+ 1a:b0:27:f0:0c:e8:19:2b:c6:b4:ad:62:c4:c6:21: -+ 7c:23:17:c4:13:a4:0e:7d:d3:05:3b:0b:43:ab:43: -+ 32:88:12:67:91:1b:01:e4:98:90:fc:67:88:d7:8b: -+ 8e:6b:f0:2a:59:62:d1:dc:24:38:28:8c:b7:e9:1b: -+ 7b:27 -+ Exponent: 65537 (0x10001) -+ X509v3 extensions: -+ X509v3 Basic Constraints: -+ CA:FALSE -+ Netscape Comment: -+ OpenSSL Generated Certificate -+ X509v3 Subject Key Identifier: -+ CB:A6:D2:18:07:CE:1A:E1:A7:F1:DC:FB:4C:A0:2C:85:AE:A5:40:A2 -+ X509v3 Authority Key Identifier: -+ AC:87:DC:8B:3D:8A:DB:89:48:7E:6F:3B:1C:C6:70:92:09:17:6F:F9 -+ Authority Information Access: -+ OCSP - URI:http://127.0.0.1:8888 -+ X509v3 Subject Alternative Name: -+ DNS:localhost, IP Address:127.0.0.1 -+ Signature Algorithm: sha256WithRSAEncryption -+ Signature Value: -+ 11:8b:03:aa:50:38:53:88:71:66:01:2f:d5:ab:82:49:ba:4d: -+ 45:5a:20:b6:f7:6e:1f:ca:77:ce:f7:93:85:ec:4d:da:ba:17: -+ 71:dc:30:7b:7f:55:35:07:88:a2:4a:47:06:9c:8c:1b:a0:33: -+ 5f:46:dd:c9:c6:f5:0e:27:48:6e:1f:0b:a0:e8:17:e4:16:3b: -+ d0:e3:0b:56:4f:5c:5f:b7:ae:fb:da:46:13:0b:fc:e8:3d:72: -+ 7e:ab:2d:19:4d:6c:09:8b:32:51:9a:7a:b8:49:70:7e:ce:ce: -+ 78:7f:95:9c:3a:8e:05:cc:29:af:0b:de:42:b8:cd:5e:56:a8: -+ 2f:78:ea:19:67:ed:a7:59:c0:ce:0a:4c:50:46:67:9a:6e:72: -+ 6b:fd:ae:00:a6:2f:9a:93:97:39:58:06:b4:05:a3:78:a9:b6: -+ df:66:22:0d:ae:5b:fd:e8:37:78:25:ac:2e:5a:a0:65:56:3e: -+ 83:04:bf:98:96:30:e1:11:f9:da:3b:6a:97:c4:77:28:d6:d7: -+ 46:27:a4:05:67:2e:f5:b8:d4:2e:c7:00:39:49:08:9b:a7:58: -+ 21:48:4c:fb:8f:dd:99:69:ea:59:bc:41:96:fd:1a:29:1a:fe: -+ 53:16:6a:2b:ac:92:51:18:ac:85:d9:7d:d5:77:ad:60:63:98: -+ 47:2c:52:ec:85:ef:ad:ff:b0:58:d7:12:7b:6f:70:2b:93:2a: -+ 92:f8:99:3c:15:7a:26:d4:79:16:05:93:9a:f4:01:bc:e6:9b: -+ a0:31:c3:d7:12:23:47:12:81:30:02:06:0c:13:ca:38:4c:63: -+ 96:2d:17:41:53:06:8b:c5:a3:8c:c3:96:b7:e2:b5:85:49:f7: -+ cd:46:01:21:ff:4f:d1:65:be:37:1b:84:7c:79:a6:e1:a8:a8: -+ d7:8c:63:34:35:45:d5:42:10:03:0f:60:fa:52:c5:39:03:26: -+ b1:41:6c:b9:53:3c:cf:8d:5d:fa:02:ac:0a:7a:04:27:28:df: -+ 33:b2:01:69:d8:3e:72:38:57:60:d3:a8:47:5f:98:55:8c:55: -+ 15:36:58:6e:c7:fc:65:a5:f8:c7:7f:1a:8c:de:b7:79:21:50: -+ 98:76:69:8a:b3:48:b0:1d:b2:91:fd:25:8f:bd:59:17:81:22: -+ bc:67:32:d5:fb:e6:c3:cd:3c:b3:79:6f:cd:1c:4a:b0:04:13: -+ 3c:af:80:53:7c:f0:c6:28:f3:37:3e:36:4d:65:ef:38:dc:00: -+ 5f:88:7e:04:34:75:66:fa:ba:6c:1f:76:b2:55:bb:21:60:fe: -+ b8:48:f8:ac:cb:6e:16:2f:75:87:44:d0:c3:6d:d5:6a:e1:e6: -+ b9:32:7e:39:a6:e6:d0:7f -+-----BEGIN CERTIFICATE----- -+MIIFZjCCA06gAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT -+MQswCQYDVQQIEwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUGA1UEChMeVGhl -+IEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFjaGUgVG9t -+Y2F0IFBNQzEeMBwGA1UEAxMVQXBhY2hlIFRvbWNhdCBUZXN0IENBMB4XDTI1MTIw -+NTE5MTMyN1oXDTI3MTIwNTE5MTMyN1owgYgxCzAJBgNVBAYTAlVTMQswCQYDVQQI -+EwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUGA1UEChMeVGhlIEFwYWNoZSBT -+b2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFjaGUgVG9tY2F0IFBNQzES -+MBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -+AQEAqvLuAd0h/Uv2Hp+hpmVCcRzbz9dHbSCBYwHHbKJaLhcNXdlgeOXZKprALRwt -+JJ2z9iapk4CGrQ6wBk5k3BHacKDrR6qdOT4QHLX+vMqyW7g/DKjUs8ue3fUZDtyD -+NFQdF7kNLl1MMdebZOlAid53da1uhj5GFYjtSIi7onelBUozMz67y3v3AJvrTiv1 -+SlkH/xhaoUnCJUghA1Vk2td1D+hVqGE5yq8JZMLBZ0vsld9mUC05RdZMjQeoPdH8 -+PEZ2ki8asCfwDOgZK8a0rWLExiF8IxfEE6QOfdMFOwtDq0MyiBJnkRsB5JiQ/GeI -+14uOa/AqWWLR3CQ4KIy36Rt7JwIDAQABo4HLMIHIMAkGA1UdEwQCMAAwLAYJYIZI -+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW -+BBTLptIYB84a4afx3PtMoCyFrqVAojAfBgNVHSMEGDAWgBSsh9yLPYrbiUh+bzsc -+xnCSCRdv+TAxBggrBgEFBQcBAQQlMCMwIQYIKwYBBQUHMAGGFWh0dHA6Ly8xMjcu -+MC4wLjE6ODg4ODAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcN -+AQELBQADggIBABGLA6pQOFOIcWYBL9Wrgkm6TUVaILb3bh/Kd873k4XsTdq6F3Hc -+MHt/VTUHiKJKRwacjBugM19G3cnG9Q4nSG4fC6DoF+QWO9DjC1ZPXF+3rvvaRhML -+/Og9cn6rLRlNbAmLMlGaerhJcH7Oznh/lZw6jgXMKa8L3kK4zV5WqC946hln7adZ -+wM4KTFBGZ5pucmv9rgCmL5qTlzlYBrQFo3iptt9mIg2uW/3oN3glrC5aoGVWPoME -+v5iWMOER+do7apfEdyjW10YnpAVnLvW41C7HADlJCJunWCFITPuP3Zlp6lm8QZb9 -+Gika/lMWaiusklEYrIXZfdV3rWBjmEcsUuyF763/sFjXEntvcCuTKpL4mTwVeibU -+eRYFk5r0Abzmm6Axw9cSI0cSgTACBgwTyjhMY5YtF0FTBovFo4zDlrfitYVJ981G -+ASH/T9FlvjcbhHx5puGoqNeMYzQ1RdVCEAMPYPpSxTkDJrFBbLlTPM+NXfoCrAp6 -+BCco3zOyAWnYPnI4V2DTqEdfmFWMVRU2WG7H/GWl+Md/Gozet3khUJh2aYqzSLAd -+spH9JY+9WReBIrxnMtX75sPNPLN5b80cSrAEEzyvgFN88MYo8zc+Nk1l7zjcAF+I -+fgQ0dWb6umwfdrJVuyFg/rhI+KzLbhYvdYdE0MNt1Wrh5rkyfjmm5tB/ -+-----END CERTIFICATE----- -diff --git a/test/org/apache/tomcat/util/net/localhost-crl-rsa-key.pem b/test/org/apache/tomcat/util/net/localhost-crl-rsa-key.pem -new file mode 100644 -index 0000000000..f8de8c251b ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/localhost-crl-rsa-key.pem -@@ -0,0 +1,28 @@ -+-----BEGIN PRIVATE KEY----- -+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCq8u4B3SH9S/Ye -+n6GmZUJxHNvP10dtIIFjAcdsolouFw1d2WB45dkqmsAtHC0knbP2JqmTgIatDrAG -+TmTcEdpwoOtHqp05PhActf68yrJbuD8MqNSzy57d9RkO3IM0VB0XuQ0uXUwx15tk -+6UCJ3nd1rW6GPkYViO1IiLuid6UFSjMzPrvLe/cAm+tOK/VKWQf/GFqhScIlSCED -+VWTa13UP6FWoYTnKrwlkwsFnS+yV32ZQLTlF1kyNB6g90fw8RnaSLxqwJ/AM6Bkr -+xrStYsTGIXwjF8QTpA590wU7C0OrQzKIEmeRGwHkmJD8Z4jXi45r8CpZYtHcJDgo -+jLfpG3snAgMBAAECggEAGwmoPlA454SjrU1HNneujhBn7dQZXne1LzEhVxvIkqCf -+wxe2C/kio3vtaFUcCL4OsCCGUqeR5X48tgqhJjOGrqis/d1M17hquPfKDhcrJZmb -+E0gCuFs8ydNRvsl+0QB6x31DyfEEs59r2waPaB7xGwIuyHnCAPbyvLWvo68zwQWs -+q3YF8Z03wPoSVxx9IrIsi01vaZGYREXmsNEX5krvd+Ku2JsQJ9NreduMg/gtegbB -+snN9MpjbydRWnwql4YzOCPaaGlQltrUFixKw6InZJRkKaSri49gEseaiSqwx31mY -+RvnWtyZfq1qRkcQm+NC9WO3cyCH38Um1egQmVpmguQKBgQDUlfAuAotMDN9aFnQ5 -+DUviMyVy+ea1SDvJ3TnoaplZ4vp9pmwX5B2RPz8MzHKVLhll9h6GjAIXZuLT2Fed -+OyGUhM0Cd//+5esp0dHMKQFdzVMrhn8eGPPPBReEZtILbi3ulRJI6nsagAmKnLLN -+bik5fbcsc1KhtIUzGFbrw9ThWQKBgQDN3DTFrxP50XLc1hfs3OjP3OqZ7mqMyVXq -+JFJ4JNiFCFk/Jhqz83IuxrzoWGVmtnDjj9sdN/TsClG337xD9L3OgpS1yjjbzhi5 -+wYG4cCjNxpqis097LFHqZDBBSZ9d3SWsdENqSWPbWOVLZQKrwR239m3mjCipSewI -+JRnX+1cwfwKBgQCrySoYFAg6gWBvrRtoCv2aIZiOi7DKJz/hRPsJfDLFtyySIszQ -+lY7rE3/AuOmS8XimszdBpJwACy0a4YUTUng1Swdbilr8wRDCb4Ioh65J/aTK1Fme -+ma1TShsR7ACqKfPGCwKGl6y44mRTdYLrjKyVf6horBxG/dhxTKbYyBwbqQKBgQDE -+vQPuPXFg2ivlI/L/muwg46eN704DONOUDpyGV+hZ022/rUHt4uaoD6UwhHJ8ZDWl -+NbGZzgWTpBUPHpMFexv/BcrrpdULNH9q36WCyCYm6vyUK7v1Ipky4gdADgVxpk0/ -+8GkRZgw58E5K7MFNtiUZ0DieEis2BwC9k/+L65gbLwKBgG87Ag/C0un6LYMHI8gT -+DyqrsjARdlwVeyL864p3GHQbfGeQ2VTxSriEPHwSc2H1FtRsFo06P98DBjVW1xDD -+MPY8PD9MZ347rnNi1lcG42moxY6ywYesRwKaDPC98PgvaXzmm81wSyjOerwDQubi -+UQ6bYhVLe3BdVfFI8N8kSRzu -+-----END PRIVATE KEY----- -diff --git a/test/org/apache/tomcat/util/net/localhost-crl-rsa.jks b/test/org/apache/tomcat/util/net/localhost-crl-rsa.jks -new file mode 100644 -index 0000000000..1519eab143 -Binary files /dev/null and b/test/org/apache/tomcat/util/net/localhost-crl-rsa.jks differ -diff --git a/test/org/apache/tomcat/util/net/localhost-ec-cert.pem b/test/org/apache/tomcat/util/net/localhost-ec-cert.pem -index 341e6f72da..520b300a8b 100644 ---- a/test/org/apache/tomcat/util/net/localhost-ec-cert.pem -+++ b/test/org/apache/tomcat/util/net/localhost-ec-cert.pem -@@ -1,22 +1,22 @@ - Certificate: - Data: - Version: 3 (0x2) -- Serial Number: 4113 (0x1011) -+ Serial Number: 4100 (0x1004) - Signature Algorithm: sha256WithRSAEncryption -- Issuer: C=US, ST=MA, L=Wakefield, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=Apache Tomcat Test CA -+ Issuer: C=US, ST=DE, L=Wilmington, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=Apache Tomcat Test CA - Validity -- Not Before: Feb 16 17:59:33 2025 GMT -- Not After : Feb 16 17:59:33 2027 GMT -+ Not Before: Dec 5 19:15:40 2025 GMT -+ Not After : Dec 5 19:15:40 2027 GMT - Subject: C=US, ST=DE, L=Wilmington, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=localhost - Subject Public Key Info: - Public Key Algorithm: id-ecPublicKey - Public-Key: (256 bit) - pub: -- 04:0a:0a:c9:36:e4:18:27:f0:ef:ac:f3:8a:8b:a8: -- 9c:15:f5:71:95:94:10:bc:74:4a:c5:1e:e7:c5:fd: -- b0:b3:35:c0:5e:fe:11:2b:ae:ba:a7:a4:27:09:bd: -- 37:c5:de:bc:e7:6d:f7:de:dd:ab:ed:9d:cf:02:59: -- 1e:ba:b2:6a:b0 -+ 04:4a:67:a8:52:9a:a4:a8:54:e0:0a:26:01:7b:c8: -+ 20:fc:99:99:09:b9:ce:a4:11:bd:99:0f:9d:73:b3: -+ 82:ef:9f:a9:73:31:bf:e5:f2:10:b2:b4:91:82:e1: -+ d5:9e:91:4b:e4:f2:ce:87:e1:a6:ee:6b:b5:68:39: -+ c0:c0:9a:e7:5d - ASN1 OID: prime256v1 - NIST CURVE: P-256 - X509v3 extensions: -@@ -25,62 +25,66 @@ Certificate: - Netscape Comment: - OpenSSL Generated Certificate - X509v3 Subject Key Identifier: -- B2:76:F0:C0:C9:97:89:B7:00:A2:9C:AA:5B:49:D8:62:C7:2B:81:AD -+ AD:35:5C:21:09:CA:97:51:8F:CC:F2:33:B0:86:80:DF:73:4F:FD:73 - X509v3 Authority Key Identifier: -- 00:F2:98:4D:21:2C:00:3C:40:9B:84:F4:DE:2A:F0:26:EE:32:0E:9F -+ AC:87:DC:8B:3D:8A:DB:89:48:7E:6F:3B:1C:C6:70:92:09:17:6F:F9 -+ Authority Information Access: -+ OCSP - URI:http://127.0.0.1:8888 - Signature Algorithm: sha256WithRSAEncryption - Signature Value: -- 55:68:78:de:91:87:35:36:63:ca:bf:b1:bb:17:89:ef:01:7d: -- be:40:d6:e3:cb:45:ae:3b:7f:97:0f:5f:f4:7c:eb:2b:5d:0f: -- 2f:23:17:2d:2d:25:76:b1:1b:b8:59:24:4c:8b:0a:c7:cc:07: -- 37:f5:55:b2:20:b4:51:c9:ee:3b:0b:2f:b0:b2:d0:7f:76:30: -- 0e:46:65:63:45:67:cd:bd:42:ba:55:72:16:cd:6d:37:07:9b: -- 9c:9b:ee:cc:63:e1:32:15:c2:3c:76:05:a6:25:51:c2:a7:99: -- dd:03:36:d4:d4:75:47:50:a9:bc:e6:d6:a7:95:49:6a:54:12: -- 26:27:94:a2:67:48:8a:42:38:fd:e4:58:8b:3c:c1:67:a2:dc: -- ba:4e:72:72:f7:60:d8:ce:18:c7:56:2d:61:bf:b5:5b:f7:d8: -- b9:d5:f0:3e:62:20:2f:f1:b2:6d:0e:b0:e2:9a:60:a0:3f:8c: -- 7c:4a:ec:4f:fa:90:29:e5:b5:01:6e:20:f5:e5:d8:cd:ed:29: -- 59:e3:93:29:08:a9:a3:6b:1f:9f:6b:91:48:78:ad:03:1f:64: -- 0d:36:c7:c4:d3:40:a0:fc:cf:72:09:f5:8e:71:7b:cb:6c:fd: -- 1a:d3:02:5e:37:96:d0:41:ef:b2:2b:a9:28:18:fc:de:68:7e: -- 53:80:c4:8c:2b:90:42:de:61:ff:56:88:ea:f7:80:42:3f:cd: -- 13:46:9d:6d:70:b3:83:b9:69:35:94:a0:56:d9:3e:39:fc:b1: -- bb:f5:6d:d4:3c:22:80:86:b3:32:2a:eb:2a:c9:5d:a8:4b:b9: -- 48:70:68:d1:2c:2b:b7:bd:9c:2c:79:70:b4:e7:69:ba:32:bc: -- 97:ff:07:2a:49:78:d7:a1:6f:d0:24:96:73:1e:8c:3f:20:a2: -- 3c:fb:8f:11:e0:88:d3:86:06:6c:02:b8:a5:25:f2:10:1a:b3: -- bf:9a:ec:57:81:d4:d4:91:e1:6d:70:21:0b:6f:c0:a2:5d:49: -- 29:9c:fa:bd:78:7f:a7:3b:45:65:96:79:68:33:71:f8:a9:ea: -- 5c:69:69:b4:bf:8a:45:66:49:0d:e1:13:65:8b:27:72:cc:e6: -- 99:42:80:6c:b8:cc:6b:d8:f0:d2:71:bb:a6:f1:fa:5a:70:8a: -- 7b:df:65:4c:2f:bf:18:2c:b9:de:db:7f:e1:73:96:66:5d:73: -- aa:ef:f3:87:9e:e6:79:14:50:99:ae:bd:38:04:f2:78:54:db: -- ef:03:8a:57:9c:99:a8:57:87:c7:e7:84:19:d1:d9:4d:cf:a2: -- 8d:66:29:1a:78:a8:28:85:3e:0b:44:9e:60:d6:f0:14:92:11: -- 80:48:b5:5c:1b:81:8f:ba -+ 9a:74:81:f5:9d:87:bc:47:ea:33:a9:ef:d4:6b:6a:de:77:4e: -+ fc:41:c4:44:e7:ca:02:63:8b:a6:4f:b3:ed:14:44:8d:3f:29: -+ 3b:ee:2f:30:2b:31:bc:2f:88:64:ce:e7:4e:77:d7:d2:94:c6: -+ 31:98:ea:b8:c3:0c:23:e9:cd:00:99:2f:bd:41:bb:49:5d:ae: -+ f0:65:c7:b8:1b:c3:07:58:ea:ed:0e:ff:22:be:7b:0a:77:15: -+ 62:49:e0:7c:39:6a:9d:02:7d:b3:6d:94:eb:14:e6:75:1f:8a: -+ 40:cd:88:13:bd:42:03:49:18:ae:11:43:d5:f1:98:c5:a0:87: -+ 18:33:ae:84:c6:65:8f:61:89:be:54:d9:52:02:80:59:30:42: -+ df:02:d0:e5:44:9c:f5:36:28:3b:26:5c:a3:28:89:d2:b9:a3: -+ c7:2a:99:d3:86:b5:fd:13:6d:d7:f9:5d:7e:88:35:af:19:9e: -+ 4e:9c:8b:48:92:15:62:47:c7:c4:1e:25:4e:d5:8b:96:1f:7e: -+ cc:55:10:5f:82:1e:3f:b7:c7:ba:00:38:59:55:53:59:3c:f9: -+ 0b:2a:ab:d4:bf:0e:84:2b:71:61:be:14:4d:12:c1:8d:ab:8b: -+ 14:d7:af:b2:b4:6a:7e:b6:23:64:a2:7b:11:6b:ec:6b:1a:64: -+ ea:49:f0:a7:9f:d0:c9:47:71:fa:01:8a:3b:be:b9:6d:4a:d9: -+ 58:25:1a:a8:f6:88:35:e5:d4:98:53:48:62:f9:24:db:87:21: -+ bb:67:5f:b7:d1:60:0f:34:f5:63:f9:52:fd:f1:33:cb:5f:79: -+ 16:c8:e5:e4:c1:79:0c:d9:76:b4:44:56:ff:e7:86:a5:9f:dd: -+ 72:c6:15:4f:ed:6e:2d:1a:54:61:b3:5c:c7:26:10:98:9f:7e: -+ 77:0b:80:4c:a9:d7:bd:28:4c:3c:3b:05:67:e1:af:6d:1b:26: -+ d5:24:96:5f:01:69:84:37:1e:f2:30:3e:9d:e9:8a:fd:0f:28: -+ 56:87:d1:28:8f:32:5d:c9:96:f0:ec:14:b1:34:b9:0d:63:16: -+ 1b:26:e5:76:33:12:fe:52:f5:49:17:2d:14:06:fc:3f:4e:81: -+ b2:02:7d:e7:16:ae:62:d2:0f:1c:df:a1:50:a3:ff:3e:69:d5: -+ 7f:e7:c4:e7:6a:b8:93:b2:d8:99:9b:72:30:e9:e0:62:d6:c3: -+ c1:39:a0:1b:30:37:63:6e:b0:0f:47:20:71:8a:20:56:2f:2d: -+ a6:54:35:ee:72:38:fc:e2:bb:67:60:4f:f7:b8:79:cb:57:6e: -+ f3:7c:b3:55:03:01:41:29:48:ca:f6:a9:3a:4a:6a:26:cb:f7: -+ 21:54:fa:70:31:3d:95:d0 - -----BEGIN CERTIFICATE----- --MIIESTCCAjGgAwIBAgICEBEwDQYJKoZIhvcNAQELBQAwgZMxCzAJBgNVBAYTAlVT --MQswCQYDVQQIEwJNQTESMBAGA1UEBxMJV2FrZWZpZWxkMScwJQYDVQQKEx5UaGUg --QXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xGjAYBgNVBAsTEUFwYWNoZSBUb21j --YXQgUE1DMR4wHAYDVQQDExVBcGFjaGUgVG9tY2F0IFRlc3QgQ0EwHhcNMjUwMjE2 --MTc1OTMzWhcNMjcwMjE2MTc1OTMzWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgM --AkRFMRMwEQYDVQQHDApXaWxtaW5ndG9uMScwJQYDVQQKDB5UaGUgQXBhY2hlIFNv --ZnR3YXJlIEZvdW5kYXRpb24xGjAYBgNVBAsMEUFwYWNoZSBUb21jYXQgUE1DMRIw --EAYDVQQDDAlsb2NhbGhvc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQKCsk2 --5Bgn8O+s84qLqJwV9XGVlBC8dErFHufF/bCzNcBe/hErrrqnpCcJvTfF3rznbffe --3avtnc8CWR66smqwo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVu --U1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUsnbwwMmXibcAopyq --W0nYYscrga0wHwYDVR0jBBgwFoAUAPKYTSEsADxAm4T03irwJu4yDp8wDQYJKoZI --hvcNAQELBQADggIBAFVoeN6RhzU2Y8q/sbsXie8Bfb5A1uPLRa47f5cPX/R86ytd --Dy8jFy0tJXaxG7hZJEyLCsfMBzf1VbIgtFHJ7jsLL7Cy0H92MA5GZWNFZ829QrpV --chbNbTcHm5yb7sxj4TIVwjx2BaYlUcKnmd0DNtTUdUdQqbzm1qeVSWpUEiYnlKJn --SIpCOP3kWIs8wWei3LpOcnL3YNjOGMdWLWG/tVv32LnV8D5iIC/xsm0OsOKaYKA/ --jHxK7E/6kCnltQFuIPXl2M3tKVnjkykIqaNrH59rkUh4rQMfZA02x8TTQKD8z3IJ --9Y5xe8ts/RrTAl43ltBB77IrqSgY/N5oflOAxIwrkELeYf9WiOr3gEI/zRNGnW1w --s4O5aTWUoFbZPjn8sbv1bdQ8IoCGszIq6yrJXahLuUhwaNEsK7e9nCx5cLTnaboy --vJf/BypJeNehb9AklnMejD8gojz7jxHgiNOGBmwCuKUl8hAas7+a7FeB1NSR4W1w --IQtvwKJdSSmc+r14f6c7RWWWeWgzcfip6lxpabS/ikVmSQ3hE2WLJ3LM5plCgGy4 --zGvY8NJxu6bx+lpwinvfZUwvvxgsud7bf+FzlmZdc6rv84ee5nkUUJmuvTgE8nhU --2+8DilecmahXh8fnhBnR2U3Poo1mKRp4qCiFPgtEnmDW8BSSEYBItVwbgY+6 -+MIIEfzCCAmegAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT -+MQswCQYDVQQIEwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUGA1UEChMeVGhl -+IEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFjaGUgVG9t -+Y2F0IFBNQzEeMBwGA1UEAxMVQXBhY2hlIFRvbWNhdCBUZXN0IENBMB4XDTI1MTIw -+NTE5MTU0MFoXDTI3MTIwNTE5MTU0MFowgYgxCzAJBgNVBAYTAlVTMQswCQYDVQQI -+DAJERTETMBEGA1UEBwwKV2lsbWluZ3RvbjEnMCUGA1UECgweVGhlIEFwYWNoZSBT -+b2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLDBFBcGFjaGUgVG9tY2F0IFBNQzES -+MBAGA1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESmeo -+UpqkqFTgCiYBe8gg/JmZCbnOpBG9mQ+dc7OC75+pczG/5fIQsrSRguHVnpFL5PLO -+h+Gm7mu1aDnAwJrnXaOBrzCBrDAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1P -+cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUrTVcIQnKl1GP -+zPIzsIaA33NP/XMwHwYDVR0jBBgwFoAUrIfciz2K24lIfm87HMZwkgkXb/kwMQYI -+KwYBBQUHAQEEJTAjMCEGCCsGAQUFBzABhhVodHRwOi8vMTI3LjAuMC4xOjg4ODgw -+DQYJKoZIhvcNAQELBQADggIBAJp0gfWdh7xH6jOp79Rrat53TvxBxETnygJji6ZP -+s+0URI0/KTvuLzArMbwviGTO505319KUxjGY6rjDDCPpzQCZL71Bu0ldrvBlx7gb -+wwdY6u0O/yK+ewp3FWJJ4Hw5ap0CfbNtlOsU5nUfikDNiBO9QgNJGK4RQ9XxmMWg -+hxgzroTGZY9hib5U2VICgFkwQt8C0OVEnPU2KDsmXKMoidK5o8cqmdOGtf0Tbdf5 -+XX6INa8Znk6ci0iSFWJHx8QeJU7Vi5YffsxVEF+CHj+3x7oAOFlVU1k8+Qsqq9S/ -+DoQrcWG+FE0SwY2rixTXr7K0an62I2SiexFr7GsaZOpJ8Kef0MlHcfoBiju+uW1K -+2VglGqj2iDXl1JhTSGL5JNuHIbtnX7fRYA809WP5Uv3xM8tfeRbI5eTBeQzZdrRE -+Vv/nhqWf3XLGFU/tbi0aVGGzXMcmEJiffncLgEyp170oTDw7BWfhr20bJtUkll8B -+aYQ3HvIwPp3piv0PKFaH0SiPMl3JlvDsFLE0uQ1jFhsm5XYzEv5S9UkXLRQG/D9O -+gbICfecWrmLSDxzfoVCj/z5p1X/nxOdquJOy2JmbcjDp4GLWw8E5oBswN2NusA9H -+IHGKIFYvLaZUNe5yOPziu2dgT/e4ectXbvN8s1UDAUEpSMr2qTpKaibL9yFU+nAx -+PZXQ - -----END CERTIFICATE----- -diff --git a/test/org/apache/tomcat/util/net/localhost-ec-key.pem b/test/org/apache/tomcat/util/net/localhost-ec-key.pem -index b652c24a6e..e6621274ca 100644 ---- a/test/org/apache/tomcat/util/net/localhost-ec-key.pem -+++ b/test/org/apache/tomcat/util/net/localhost-ec-key.pem -@@ -1,5 +1,8 @@ -------BEGIN PRIVATE KEY----- --MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIGiUWTenuT85M7WD --zpFQvWMq5xsQgZoNqmgg1BfGuyahRANCAAQKCsk25Bgn8O+s84qLqJwV9XGVlBC8 --dErFHufF/bCzNcBe/hErrrqnpCcJvTfF3rznbffe3avtnc8CWR66smqw -------END PRIVATE KEY----- -+-----BEGIN EC PARAMETERS----- -+BggqhkjOPQMBBw== -+-----END EC PARAMETERS----- -+-----BEGIN EC PRIVATE KEY----- -+MHcCAQEEIF9PqIbcIMlMOKkaAID2L1ULbJApzzOj3WlBYuyZQqaaoAoGCCqGSM49 -+AwEHoUQDQgAESmeoUpqkqFTgCiYBe8gg/JmZCbnOpBG9mQ+dc7OC75+pczG/5fIQ -+srSRguHVnpFL5PLOh+Gm7mu1aDnAwJrnXQ== -+-----END EC PRIVATE KEY----- -diff --git a/test/org/apache/tomcat/util/net/localhost-ec.jks b/test/org/apache/tomcat/util/net/localhost-ec.jks -index 0fc20baca4..e510be8894 100644 -Binary files a/test/org/apache/tomcat/util/net/localhost-ec.jks and b/test/org/apache/tomcat/util/net/localhost-ec.jks differ -diff --git a/test/org/apache/tomcat/util/net/localhost-rsa-cert.pem b/test/org/apache/tomcat/util/net/localhost-rsa-cert.pem -index 488f1fb3c6..9d016d3b17 100644 ---- a/test/org/apache/tomcat/util/net/localhost-rsa-cert.pem -+++ b/test/org/apache/tomcat/util/net/localhost-rsa-cert.pem -@@ -1,35 +1,35 @@ - Certificate: - Data: - Version: 3 (0x2) -- Serial Number: 4112 (0x1010) -+ Serial Number: 4096 (0x1000) - Signature Algorithm: sha256WithRSAEncryption -- Issuer: C=US, ST=MA, L=Wakefield, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=Apache Tomcat Test CA -+ Issuer: C=US, ST=DE, L=Wilmington, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=Apache Tomcat Test CA - Validity -- Not Before: Feb 16 17:53:36 2025 GMT -- Not After : Feb 16 17:53:36 2027 GMT -+ Not Before: Dec 5 19:13:23 2025 GMT -+ Not After : Dec 5 19:13:23 2027 GMT - Subject: C=US, ST=DE, L=Wilmington, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=localhost - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: -- 00:c0:40:4c:7d:58:4b:93:4a:0c:4d:ba:59:cc:50: -- a1:99:c1:ce:e3:3e:c8:a2:41:b0:e8:24:92:92:d4: -- f6:c1:31:d9:d6:41:c0:fa:de:d0:2e:59:09:75:a9: -- c3:3b:d4:56:d3:4f:79:a3:30:df:71:15:cd:d8:a7: -- 03:d6:be:fb:49:b0:cc:69:75:c4:b9:fb:a2:de:2e: -- da:30:db:72:27:1c:f9:96:e1:9f:bd:13:39:8f:da: -- a3:12:95:c7:a1:67:3e:4c:14:8c:98:03:6a:86:18: -- 8b:3a:d5:4e:09:77:7d:c1:be:6a:53:75:cc:c8:0f: -- 35:fc:4d:fd:40:63:a3:e4:10:0b:77:d9:b3:82:1b: -- 30:4c:35:02:9e:41:dc:8f:b5:70:a6:d7:be:75:1e: -- 57:a7:26:14:33:5a:e7:17:68:98:27:10:a6:9c:0c: -- 17:81:6b:d1:15:36:44:01:95:f8:91:38:9c:6d:d0: -- 97:45:0d:02:3c:c3:18:20:8d:a6:2a:e7:e0:df:8d: -- c1:81:81:71:bb:89:b2:b6:02:87:51:2c:7a:ca:9f: -- c9:ec:ab:e0:01:26:0c:dc:38:bd:17:be:2d:fe:48: -- 4c:7f:9c:42:1a:38:a0:39:60:5c:38:65:54:d4:71: -- ab:d3:a6:d0:c9:a2:a3:3c:0f:59:09:8d:8b:57:dc: -- 2b:05 -+ 00:b1:da:2e:50:5c:5b:22:db:84:61:5e:e4:9d:e1: -+ a4:24:6c:92:d3:96:5a:77:52:c8:f7:cf:16:b5:60: -+ 80:a7:15:0e:12:75:1a:bc:3f:0b:54:38:96:f6:2f: -+ 0a:38:6c:21:68:da:13:49:a2:7b:7c:80:c7:aa:69: -+ fe:e3:8c:b1:ce:73:e6:5b:80:e2:36:89:49:5b:03: -+ ce:76:47:bf:35:20:ee:c6:78:df:62:aa:d1:d7:bf: -+ 91:b0:fc:aa:fd:7f:59:3f:8a:51:9f:7d:59:0f:e1: -+ d6:dc:7b:16:80:62:3f:6c:c2:2c:1b:a5:05:1e:40: -+ 90:60:20:e1:c3:6d:3f:ff:1c:73:84:92:86:59:03: -+ e5:4a:f6:d6:dc:e6:6e:68:1f:05:5f:f7:21:a9:fc: -+ 5e:e6:fc:8b:c7:36:34:18:fc:d5:70:21:54:5a:f1: -+ 10:c9:24:c8:08:92:2c:91:13:54:b1:d9:59:70:80: -+ 39:9f:8c:90:ad:c9:d2:b8:bd:a3:28:20:3f:67:35: -+ a2:d9:20:e2:3f:2e:be:3d:88:d2:3b:7d:3b:47:44: -+ 79:53:e2:52:98:72:13:ae:a2:9d:fe:68:bd:36:8c: -+ 2e:43:b1:3b:cd:50:35:3d:b5:f7:2f:43:ea:1e:c9: -+ d1:10:ac:e8:24:c1:8c:ee:e6:d0:c2:06:de:14:2d: -+ 1a:89 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: -@@ -37,69 +37,72 @@ Certificate: - Netscape Comment: - OpenSSL Generated Certificate - X509v3 Subject Key Identifier: -- BE:46:EA:26:EA:2A:17:93:67:DD:17:0B:57:8D:ED:A0:30:14:00:B2 -+ 70:34:99:AD:29:E3:27:9D:BD:97:72:50:20:98:D2:97:B3:6C:AD:A1 - X509v3 Authority Key Identifier: -- 00:F2:98:4D:21:2C:00:3C:40:9B:84:F4:DE:2A:F0:26:EE:32:0E:9F -+ AC:87:DC:8B:3D:8A:DB:89:48:7E:6F:3B:1C:C6:70:92:09:17:6F:F9 -+ Authority Information Access: -+ OCSP - URI:http://127.0.0.1:8888 - X509v3 Subject Alternative Name: - DNS:localhost, IP Address:127.0.0.1 - Signature Algorithm: sha256WithRSAEncryption - Signature Value: -- 90:9b:b3:66:a4:42:07:c2:68:05:aa:f3:a2:c9:66:35:45:42: -- b4:be:40:c7:90:34:71:b4:cf:79:fd:74:f7:4b:46:3f:f3:da: -- 81:3b:55:c3:62:7f:79:12:12:7f:b2:8d:72:55:d8:85:97:cf: -- 54:44:0e:9f:22:02:57:98:e9:02:a8:c7:6d:45:3e:b7:f6:7c: -- 56:58:a1:1b:0b:fa:a7:4c:57:66:92:3a:92:bd:f4:27:c6:5c: -- af:06:3b:d8:be:e9:b7:9a:d3:85:ae:9f:da:5f:59:05:bf:12: -- c9:13:49:75:25:1e:76:2d:c9:b7:c1:55:76:25:30:db:48:f4: -- c9:c4:cb:a4:dc:b6:df:13:1c:c1:44:2b:67:14:15:da:53:56: -- 18:e8:86:5a:75:89:96:a5:88:72:47:36:b5:0b:9c:51:13:50: -- c4:93:1c:a1:2b:d0:d8:0c:c7:f6:c5:30:88:93:6c:02:ff:6e: -- fe:92:ce:60:4b:17:27:e7:67:9a:d0:27:ae:4e:94:86:2a:ad: -- 99:3b:2e:6f:99:a5:d0:a1:a8:e8:3f:d1:c2:b6:1c:1a:f8:dc: -- 96:49:3b:79:be:c0:f8:3b:6a:93:d9:08:1e:3a:a9:36:0b:a1: -- 64:df:eb:fa:14:34:9b:73:25:49:29:25:e0:39:aa:49:0f:2d: -- 4b:ec:40:19:f7:44:00:47:7b:41:72:e8:5f:06:31:31:74:ca: -- 7b:98:e7:63:f8:19:ac:7e:5d:1f:5a:b4:22:d8:73:88:27:70: -- f4:18:5d:10:a9:52:6c:e3:e1:35:b0:4e:e3:91:79:63:49:86: -- 86:19:98:c4:9a:46:a8:bd:dd:5f:6a:8e:14:75:9e:e1:35:6b: -- ad:ab:83:8c:31:b6:cb:c2:cc:a5:86:4f:d9:e7:9a:cb:d6:a6: -- f5:ee:a9:8e:85:a1:85:54:3a:f6:f3:0e:b9:9f:e2:bc:5d:e5: -- eb:42:75:f1:3f:e1:a6:50:09:cc:a6:d3:c5:34:40:55:84:66: -- 61:60:99:f0:ea:f7:56:0b:fe:c7:b2:d2:ed:68:dc:0b:35:2f: -- 79:bf:f6:0a:af:2f:eb:25:8a:f2:9a:c7:72:00:04:ad:99:21: -- 08:14:b6:e4:12:f8:d0:c4:a3:55:c8:c7:ec:4f:e4:fb:4a:3e: -- 14:e4:56:cf:f8:a5:e1:b2:b2:50:8b:83:ce:fc:13:68:45:55: -- f6:1c:bc:e5:fe:f2:f2:51:0d:b7:9e:49:f2:19:3e:10:59:a3: -- dd:e0:72:ab:75:25:a0:0e:3c:b1:b9:17:ad:7e:46:9c:37:f1: -- 2a:19:be:91:54:2d:ab:3e:13:54:4c:aa:d6:05:56:b9:f6:3e: -- 19:61:cb:b3:c8:95:25:ad -+ 77:af:4a:b3:09:d8:9b:43:5a:73:78:10:ba:31:ad:a5:06:50: -+ 49:5d:14:f7:7b:1c:38:f0:3a:9b:67:b3:cb:71:52:7a:df:67: -+ fa:e1:c1:8b:18:dc:4e:bf:21:6d:58:b1:5f:df:2d:f1:ee:62: -+ a1:b6:78:dd:e2:c5:f2:4f:0b:9d:3d:cc:88:c7:26:8d:f0:41: -+ 02:ad:bd:e0:29:21:f9:0c:0a:07:cf:38:a4:f1:db:87:f7:e5: -+ ed:55:59:b5:34:7d:b4:39:70:ca:81:7a:bb:20:fa:2e:85:47: -+ 72:9c:35:f8:f2:e1:57:f9:9e:5c:9c:76:92:50:6a:c9:52:e9: -+ a0:d3:4d:41:03:f7:4f:bb:fc:5c:b8:aa:2c:7d:10:ff:3f:6c: -+ 82:e0:60:b8:d5:58:66:de:e0:db:30:b7:bf:3c:09:b9:3c:5c: -+ 36:cc:c6:d3:aa:58:9f:90:fe:e7:eb:5b:62:e2:66:a5:88:ec: -+ dd:2b:64:d1:25:08:e6:0a:49:91:5f:ac:1f:35:8d:2c:a2:71: -+ de:01:18:b0:0e:13:3d:cd:83:92:67:62:63:8a:63:bb:eb:8d: -+ f9:b7:95:b0:b6:a8:9c:14:8c:0b:00:34:8b:65:af:b7:6c:b9: -+ 1b:94:e2:54:3f:ee:87:0f:81:a9:3f:61:10:5f:ee:4d:42:b5: -+ 67:77:30:2e:04:4f:ad:5d:4e:de:e3:20:b3:8f:ca:46:98:7d: -+ 97:91:1d:4c:04:d9:bb:ae:02:3d:6f:55:dd:39:64:f3:53:86: -+ b6:4a:6a:eb:4a:7a:46:4e:0f:3b:44:8e:c2:46:c6:4b:07:1e: -+ b1:4e:8a:1c:fd:6a:06:55:2e:88:c6:85:8c:9b:c2:ea:90:e1: -+ 0b:d9:b1:af:2d:80:7f:b6:a2:c7:7a:63:7d:0a:cd:60:f6:46: -+ ea:40:3d:7d:4e:89:3e:0b:5d:22:8f:b7:3a:3a:38:18:26:a3: -+ 76:e9:cf:18:bc:c1:3c:8b:06:74:b6:f2:a8:a9:b4:cf:e1:96: -+ 54:bd:87:21:1d:20:b6:25:d1:d9:c6:fa:94:25:c6:6e:2b:1e: -+ a1:51:e3:31:ff:43:77:bd:e0:4c:6a:c2:24:97:43:99:f6:cb: -+ dd:3f:63:31:88:af:07:ef:e0:2b:3b:8e:3b:80:26:27:a6:c3: -+ 58:95:53:fa:39:14:59:42:3d:3a:e5:02:ff:0d:5b:e0:63:ad: -+ 93:72:8e:1d:55:c2:f9:49:7d:5c:cb:35:d2:11:b4:86:2d:26: -+ 61:74:1e:4d:e6:c7:97:e7:99:8b:fc:91:41:c8:9f:b8:ec:3e: -+ a3:f9:18:b5:2a:2e:1d:ee:2d:b6:cd:8f:14:be:b8:1c:6d:fd: -+ c3:59:61:66:87:e8:31:82 - -----BEGIN CERTIFICATE----- --MIIFMjCCAxqgAwIBAgICEBAwDQYJKoZIhvcNAQELBQAwgZMxCzAJBgNVBAYTAlVT --MQswCQYDVQQIEwJNQTESMBAGA1UEBxMJV2FrZWZpZWxkMScwJQYDVQQKEx5UaGUg --QXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xGjAYBgNVBAsTEUFwYWNoZSBUb21j --YXQgUE1DMR4wHAYDVQQDExVBcGFjaGUgVG9tY2F0IFRlc3QgQ0EwHhcNMjUwMjE2 --MTc1MzM2WhcNMjcwMjE2MTc1MzM2WjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgT --AkRFMRMwEQYDVQQHEwpXaWxtaW5ndG9uMScwJQYDVQQKEx5UaGUgQXBhY2hlIFNv --ZnR3YXJlIEZvdW5kYXRpb24xGjAYBgNVBAsTEUFwYWNoZSBUb21jYXQgUE1DMRIw --EAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB --AQDAQEx9WEuTSgxNulnMUKGZwc7jPsiiQbDoJJKS1PbBMdnWQcD63tAuWQl1qcM7 --1FbTT3mjMN9xFc3YpwPWvvtJsMxpdcS5+6LeLtow23InHPmW4Z+9EzmP2qMSlceh --Zz5MFIyYA2qGGIs61U4Jd33BvmpTdczIDzX8Tf1AY6PkEAt32bOCGzBMNQKeQdyP --tXCm1751HlenJhQzWucXaJgnEKacDBeBa9EVNkQBlfiROJxt0JdFDQI8wxggjaYq --5+DfjcGBgXG7ibK2AodRLHrKn8nsq+ABJgzcOL0Xvi3+SEx/nEIaOKA5YFw4ZVTU --cavTptDJoqM8D1kJjYtX3CsFAgMBAAGjgZgwgZUwCQYDVR0TBAIwADAsBglghkgB --hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE --FL5G6ibqKheTZ90XC1eN7aAwFACyMB8GA1UdIwQYMBaAFADymE0hLAA8QJuE9N4q --8CbuMg6fMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsF --AAOCAgEAkJuzZqRCB8JoBarzoslmNUVCtL5Ax5A0cbTPef1090tGP/PagTtVw2J/ --eRISf7KNclXYhZfPVEQOnyICV5jpAqjHbUU+t/Z8VlihGwv6p0xXZpI6kr30J8Zc --rwY72L7pt5rTha6f2l9ZBb8SyRNJdSUedi3Jt8FVdiUw20j0ycTLpNy23xMcwUQr --ZxQV2lNWGOiGWnWJlqWIckc2tQucURNQxJMcoSvQ2AzH9sUwiJNsAv9u/pLOYEsX --J+dnmtAnrk6UhiqtmTsub5ml0KGo6D/RwrYcGvjclkk7eb7A+Dtqk9kIHjqpNguh --ZN/r+hQ0m3MlSSkl4DmqSQ8tS+xAGfdEAEd7QXLoXwYxMXTKe5jnY/gZrH5dH1q0 --IthziCdw9BhdEKlSbOPhNbBO45F5Y0mGhhmYxJpGqL3dX2qOFHWe4TVrrauDjDG2 --y8LMpYZP2eeay9am9e6pjoWhhVQ69vMOuZ/ivF3l60J18T/hplAJzKbTxTRAVYRm --YWCZ8Or3Vgv+x7LS7WjcCzUveb/2Cq8v6yWK8prHcgAErZkhCBS25BL40MSjVcjH --7E/k+0o+FORWz/il4bKyUIuDzvwTaEVV9hy85f7y8lENt55J8hk+EFmj3eByq3Ul --oA48sbkXrX5GnDfxKhm+kVQtqz4TVEyq1gVWufY+GWHLs8iVJa0= -+MIIFZjCCA06gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT -+MQswCQYDVQQIEwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUGA1UEChMeVGhl -+IEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFjaGUgVG9t -+Y2F0IFBNQzEeMBwGA1UEAxMVQXBhY2hlIFRvbWNhdCBUZXN0IENBMB4XDTI1MTIw -+NTE5MTMyM1oXDTI3MTIwNTE5MTMyM1owgYgxCzAJBgNVBAYTAlVTMQswCQYDVQQI -+EwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUGA1UEChMeVGhlIEFwYWNoZSBT -+b2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFjaGUgVG9tY2F0IFBNQzES -+MBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -+AQEAsdouUFxbItuEYV7kneGkJGyS05Zad1LI988WtWCApxUOEnUavD8LVDiW9i8K -+OGwhaNoTSaJ7fIDHqmn+44yxznPmW4DiNolJWwPOdke/NSDuxnjfYqrR17+RsPyq -+/X9ZP4pRn31ZD+HW3HsWgGI/bMIsG6UFHkCQYCDhw20//xxzhJKGWQPlSvbW3OZu -+aB8FX/chqfxe5vyLxzY0GPzVcCFUWvEQySTICJIskRNUsdlZcIA5n4yQrcnSuL2j -+KCA/ZzWi2SDiPy6+PYjSO307R0R5U+JSmHITrqKd/mi9NowuQ7E7zVA1PbX3L0Pq -+HsnREKzoJMGM7ubQwgbeFC0aiQIDAQABo4HLMIHIMAkGA1UdEwQCMAAwLAYJYIZI -+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW -+BBRwNJmtKeMnnb2XclAgmNKXs2ytoTAfBgNVHSMEGDAWgBSsh9yLPYrbiUh+bzsc -+xnCSCRdv+TAxBggrBgEFBQcBAQQlMCMwIQYIKwYBBQUHMAGGFWh0dHA6Ly8xMjcu -+MC4wLjE6ODg4ODAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcN -+AQELBQADggIBAHevSrMJ2JtDWnN4ELoxraUGUEldFPd7HDjwOptns8txUnrfZ/rh -+wYsY3E6/IW1YsV/fLfHuYqG2eN3ixfJPC509zIjHJo3wQQKtveApIfkMCgfPOKTx -+24f35e1VWbU0fbQ5cMqBersg+i6FR3KcNfjy4Vf5nlycdpJQaslS6aDTTUED90+7 -+/Fy4qix9EP8/bILgYLjVWGbe4Nswt788Cbk8XDbMxtOqWJ+Q/ufrW2LiZqWI7N0r -+ZNElCOYKSZFfrB81jSyicd4BGLAOEz3Ng5JnYmOKY7vrjfm3lbC2qJwUjAsANItl -+r7dsuRuU4lQ/7ocPgak/YRBf7k1CtWd3MC4ET61dTt7jILOPykaYfZeRHUwE2buu -+Aj1vVd05ZPNThrZKautKekZODztEjsJGxksHHrFOihz9agZVLojGhYybwuqQ4QvZ -+sa8tgH+2osd6Y30KzWD2RupAPX1OiT4LXSKPtzo6OBgmo3bpzxi8wTyLBnS28qip -+tM/hllS9hyEdILYl0dnG+pQlxm4rHqFR4zH/Q3e94ExqwiSXQ5n2y90/YzGIrwfv -+4Cs7jjuAJiemw1iVU/o5FFlCPTrlAv8NW+BjrZNyjh1VwvlJfVzLNdIRtIYtJmF0 -+Hk3mx5fnmYv8kUHIn7jsPqP5GLUqLh3uLbbNjxS+uBxt/cNZYWaH6DGC - -----END CERTIFICATE----- -diff --git a/test/org/apache/tomcat/util/net/localhost-rsa-copy1.jks b/test/org/apache/tomcat/util/net/localhost-rsa-copy1.jks -index e14fa0f161..7422fd6f20 100644 -Binary files a/test/org/apache/tomcat/util/net/localhost-rsa-copy1.jks and b/test/org/apache/tomcat/util/net/localhost-rsa-copy1.jks differ -diff --git a/test/org/apache/tomcat/util/net/localhost-rsa-key.pem b/test/org/apache/tomcat/util/net/localhost-rsa-key.pem -index 495d6ae75c..752f23619e 100644 ---- a/test/org/apache/tomcat/util/net/localhost-rsa-key.pem -+++ b/test/org/apache/tomcat/util/net/localhost-rsa-key.pem -@@ -1,28 +1,28 @@ - -----BEGIN PRIVATE KEY----- --MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAQEx9WEuTSgxN --ulnMUKGZwc7jPsiiQbDoJJKS1PbBMdnWQcD63tAuWQl1qcM71FbTT3mjMN9xFc3Y --pwPWvvtJsMxpdcS5+6LeLtow23InHPmW4Z+9EzmP2qMSlcehZz5MFIyYA2qGGIs6 --1U4Jd33BvmpTdczIDzX8Tf1AY6PkEAt32bOCGzBMNQKeQdyPtXCm1751HlenJhQz --WucXaJgnEKacDBeBa9EVNkQBlfiROJxt0JdFDQI8wxggjaYq5+DfjcGBgXG7ibK2 --AodRLHrKn8nsq+ABJgzcOL0Xvi3+SEx/nEIaOKA5YFw4ZVTUcavTptDJoqM8D1kJ --jYtX3CsFAgMBAAECggEAR6xxF9YALwRPO/c6nTp+VOV1bTEt+ZgGDTX9UzKEYBhm --v0M6YA0Ljgvxw+UrfTW3vQYHMjj5RJ69ZIU3oCsJYjrAqpyWYEQZPz42aDqX/08F --GiQ5unLdZe08GKSwjVMBXbnXhKDZaO7jkWaOtmbPApkr6LulQfyxwsOMpCHBqzdN --peFcartqRkqhSYyXsMNekp9kZfZqzOkLkpFH0Qo0Y0BkK/1Bo+96iiD72FT3Cmgm --X5JQhjap6H6v2iy0A2ERAsYwNItnauMDGQbZoYk8pyKNfQBYpHKziA/AomEDXHLE --N42hjqTjlWfVvJ70TcQ06OcBPnpxdNrFrhYq2LSbbQKBgQD4YQE9/+hh7JrHElBq --bmF5sR2PyYp6+G1C74b8fSXS69Aijtbtvm2KNII2lCalP0iK1UPBlBAyhrqZs+Pw --B0fc/FGgZq1O/aM9JYUxGn+LpRfD1a73UrmKakgQj5Ph+6R2VrWSNlDYe/2hhUAB --WUnyFrPY56bQuhy+uu1K7amatwKBgQDGJmpLSGJ4BRZS2Nb6EDJJOva+KF49cKTC --GO8UtXXllOP2Y9e86wQ+f+/ZPC53C36hNItd6n9PG2CIpEBeDYbiv6E6a+tNWe27 --GqNCR/Rbs5MPiOm3tgbrK+eX0PT/+tKElopozp7ijIjYbjd5YbBuPDC7fr4pgBHc --x1nSWUAcIwKBgEYsggFWT/16r7AWyImJbhjHpaZ+NpXPom8K5YRoh0s0PLXGzYqW --BrTJaRCqgtClNIWlA2OpxXnA/u92F6w1ImSZFSbQW565omkgNKVO60I0/qXhtXFC --+hDVPk8PgaSTSD/29427stO3FE2SLCc1ZuLy7xUVPdgy/PQWM/y7cPO5AoGBALR6 --UN5485c1qvuSnVvuXJ7uocbZpdx4ONjBNSG7lcKiNnA4yEs+FAOJK8DFW9z6D0Bt --R3MnHwXCfc53LFl+IJluyT8ZBJzTiACfZov8VckgapX/skCt/uc8ehiBLmXo4s34 --/+AuMfFO52WaHdTk8Xm2QPzFmBbcm2hn+pvoxsfZAoGBAOxLL1iMDwMSAsECzy3s --B337lOWxb5pE1vIDxuUHScy1GMNpQ9YFyXAwDb0RkVfbQAutu4Uj0Eto58YjtpIP --y7Qw2vm19vVvyAjtdSTGHOhUB9v77MO8abrVBzlAgOVCGnvk3mUaCwL4uHKDMFLJ --WePSjVhSZRNhjwootd8hbPtr -+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCx2i5QXFsi24Rh -+XuSd4aQkbJLTllp3Usj3zxa1YICnFQ4SdRq8PwtUOJb2Lwo4bCFo2hNJont8gMeq -+af7jjLHOc+ZbgOI2iUlbA852R781IO7GeN9iqtHXv5Gw/Kr9f1k/ilGffVkP4dbc -+exaAYj9swiwbpQUeQJBgIOHDbT//HHOEkoZZA+VK9tbc5m5oHwVf9yGp/F7m/IvH -+NjQY/NVwIVRa8RDJJMgIkiyRE1Sx2VlwgDmfjJCtydK4vaMoID9nNaLZIOI/Lr49 -+iNI7fTtHRHlT4lKYchOuop3+aL02jC5DsTvNUDU9tfcvQ+oeydEQrOgkwYzu5tDC -+Bt4ULRqJAgMBAAECggEAAqX0dvsIodFhzimzbSpMuCdZnObktgPd60UpnYpJLz5k -+fTjQc/X3lVt9zffN2KC7yILhOiTTiZ7eSHiT+AUNN/YTdIJL7cuu7Hj+SZ1QYbMr -+lpYlV2PNRH+vAShpjp4KzWsMpyZJehMmEKStHjzGgEZxWIdBqOSFgA3Tgzf5Q/NS -+OiWNgarUkwVGLDRFH99WWbVmAJEnJeB9pxEQllqb/5AkgeiDD3Mx+BwNgO5GRu4u -+z4BwB6InA4e6T+vBhnPra3qxaS3bPfna1P2Gz7jsH8xOHFt51hIVMCzeVj0/wOWL -+Ie7YinLbCAhIa5YD8F1LTvrzCGuJn+a8Rlt6AXPYDQKBgQD1O0plltNO/3y8WN1i -+c3Ox7sQfTsTj5ZFoW4U6kbAIPF5ByKTBAXdWHWxUwBxoZA+4lgYPEvdwXWPG+VXy -+JXAFbR2/JQO/yROKnodB4O73WZitt81PIHdFP7myEeN5QSjnYSvd6lIiaxe178BM -+qyO/85GgcBf/o3MAQib0UCwXHQKBgQC5qXZjspZd8nC33NP6A6HYawjkrZeVYG8S -+qPgT0ctmsb1EpihK+wU1iAJzECZuTSgoZtcRPL/N17/xgSuwk6nTUJyOdQwnmVP+ -++Cfz7lcvx8Dg9FdrmjiEjFHnAYzaZ4bJP5Tub0tsUJRE/7YbhPlvlzaD95USLMKB -+IHzAQWx5XQKBgHgsmgS2qM6pvQK/uZ2pXiTwEQQWob3cnik50EwnYNBoZPhvzu0W -+Ptjgilnt2v39KwcV3do9PSy/V0oGneuQFRlTo6QsC25Mp1ri3P2XsQNd0Mgwrlf8 -+XPZ+iA2PXp3pJJZetBSH48AiIvhxiRcJNve18MNiqyAHhS+3O0e2kiSxAoGAL3uY -+rKzK6iIME+nlSMbPCKNvNdTztJ9iKNqP/7mjFJOWfU0ldu+2CFfNkJHr0j/nalXK -+4TyxLTrleyV3AATz5Phz4bcrsaD0K3xZ83fcUnr66E11Yi6iD7w3YiYyWNUrUqLx -+Ov25w2zkTrU7ZNRgWtrIdX3HYUuTPyUI4r6YuH0CgYA+Qs6ZexX1Xys6qBbO2OiR -+6+eRItL12doGDDCO7tqtscf8S3VGSLk29lfwipyz6YhO46yRP2FypqVHYYhwvYuW -+ubXGUUZhzI3JBvqI0Lrtwt0KJ2QUXzfqZqO1cvKe3+gooywmemvzg5s1jZ+/Ys3b -+rQR0KWEn04xhcDMyTr/A9Q== - -----END PRIVATE KEY----- -diff --git a/test/org/apache/tomcat/util/net/localhost-rsa.jks b/test/org/apache/tomcat/util/net/localhost-rsa.jks -index 5a18bd30ad..fcb9b0c066 100644 -Binary files a/test/org/apache/tomcat/util/net/localhost-rsa.jks and b/test/org/apache/tomcat/util/net/localhost-rsa.jks differ -diff --git a/test/org/apache/tomcat/util/net/ocsp-responder-rsa-cert.pem b/test/org/apache/tomcat/util/net/ocsp-responder-rsa-cert.pem -new file mode 100644 -index 0000000000..02d8d5656b ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/ocsp-responder-rsa-cert.pem -@@ -0,0 +1,105 @@ -+Certificate: -+ Data: -+ Version: 3 (0x2) -+ Serial Number: 4101 (0x1005) -+ Signature Algorithm: sha256WithRSAEncryption -+ Issuer: C=US, ST=DE, L=Wilmington, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=Apache Tomcat Test CA -+ Validity -+ Not Before: Dec 5 19:33:55 2025 GMT -+ Not After : Dec 5 19:33:55 2027 GMT -+ Subject: C=US, ST=DE, L=Wilmington, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=OCSP Responder -+ Subject Public Key Info: -+ Public Key Algorithm: rsaEncryption -+ Public-Key: (2048 bit) -+ Modulus: -+ 00:9b:ae:b1:40:e5:e4:84:b6:c3:ec:93:cf:23:63: -+ 51:51:7f:bd:d3:64:1d:e0:23:bb:33:44:f1:47:c6: -+ f5:d2:4d:2a:13:2a:f4:4c:d2:44:13:56:03:73:16: -+ 30:98:be:66:b1:fb:3c:e9:9c:5a:61:25:b8:47:ef: -+ 72:04:ad:ab:6a:f8:83:fe:00:a6:c0:8b:a3:ef:34: -+ 09:4f:13:e6:fa:96:d3:2b:24:db:e3:d1:4a:40:50: -+ 5f:9f:8f:31:fa:de:42:0d:e6:a2:4a:7a:e6:a6:48: -+ 5a:97:04:b3:b9:bd:52:2e:2f:e9:02:27:1b:8f:bf: -+ 2b:19:28:e8:96:eb:29:d0:6e:39:0b:d9:bf:2a:d2: -+ 3e:65:a4:e0:87:30:ab:26:09:01:ea:4a:a7:a2:38: -+ 09:0e:f5:d3:b8:66:0a:cc:17:61:72:fb:a9:5e:e4: -+ 98:ff:30:e4:93:11:f7:6e:13:f3:76:f6:f4:44:b7: -+ a8:2a:79:b3:4f:59:d8:67:b7:c0:4c:cd:50:57:d2: -+ 09:65:f5:5e:2d:3b:e7:29:bf:e3:11:ff:37:1d:ad: -+ f2:cf:3b:ff:f7:49:d1:1a:05:1d:2b:0e:59:fe:fe: -+ e6:6a:5d:73:7f:0b:8c:b3:6d:c3:65:2a:93:f8:87: -+ b7:fd:c2:4a:e3:b8:d5:e6:55:8b:b3:e5:0e:4f:f4: -+ fa:a7 -+ Exponent: 65537 (0x10001) -+ X509v3 extensions: -+ X509v3 Basic Constraints: critical -+ CA:FALSE -+ X509v3 Key Usage: critical -+ Digital Signature -+ X509v3 Extended Key Usage: -+ OCSP Signing -+ X509v3 Subject Key Identifier: -+ FA:23:45:E2:94:8E:6A:88:B8:72:B1:53:EA:2A:AE:B9:39:F8:6A:C8 -+ X509v3 Authority Key Identifier: -+ AC:87:DC:8B:3D:8A:DB:89:48:7E:6F:3B:1C:C6:70:92:09:17:6F:F9 -+ Signature Algorithm: sha256WithRSAEncryption -+ Signature Value: -+ 3b:39:47:9e:28:f1:c0:46:eb:a8:de:0e:44:63:4d:3c:f4:59: -+ c1:a4:2a:eb:6a:e5:50:76:ea:76:f7:a9:ca:a2:cb:70:91:c9: -+ d3:c5:fd:d6:c9:86:3d:ad:f2:b8:a7:e4:b1:93:09:44:eb:27: -+ 30:01:85:13:db:0a:62:f0:0f:fa:59:de:af:93:1a:9e:df:07: -+ da:b8:ec:19:c1:c9:56:f9:a6:8e:4e:03:ae:e0:f9:d8:d2:b7: -+ d2:94:4a:70:95:b7:a8:7f:42:b2:1d:43:77:3a:9e:f8:76:93: -+ 4b:3a:48:09:5a:8b:3b:2c:38:97:ed:27:6b:d5:31:0b:f0:3d: -+ a9:dc:d4:0b:96:55:07:41:59:e1:1f:68:70:47:04:6a:11:a4: -+ 81:e7:7d:75:08:15:9f:ca:20:20:69:fe:ef:50:3f:cf:02:0b: -+ 96:4a:9e:e7:ce:08:07:8a:c0:93:a6:aa:a9:91:53:ac:5e:80: -+ 3b:bd:6f:cb:d2:7c:e3:9b:cd:ff:b0:12:ec:9a:71:48:e1:01: -+ 96:21:f4:ee:bb:f8:1d:99:77:00:68:ef:e3:bc:5d:1d:58:bc: -+ 91:88:51:39:93:b1:91:88:5c:d0:9d:0f:87:0b:0d:04:ca:be: -+ 79:05:b9:42:ae:b3:62:df:7a:02:d7:d5:4e:a8:27:8f:0b:b8: -+ 4c:aa:d5:07:a6:e4:65:b0:13:78:cd:3a:3b:10:58:49:13:d7: -+ 74:88:76:8a:77:a4:d4:24:01:61:fe:0b:46:fb:4e:15:3a:fa: -+ 2b:c3:ca:10:9c:5f:2b:f5:33:21:93:16:be:a4:c5:bd:a4:80: -+ 88:74:2a:1e:09:d4:2a:c6:af:ed:be:46:7f:b8:d7:ad:a6:e0: -+ 8f:92:ae:2b:8a:97:ca:9c:fb:21:29:48:f1:38:98:09:f9:2b: -+ 55:53:7c:99:a5:23:21:58:35:1a:36:15:67:79:80:3f:fc:94: -+ 60:94:2b:78:a5:f1:81:b4:51:5c:08:1a:50:24:21:da:0b:cc: -+ db:d7:3c:7d:d8:2c:b1:93:9d:f4:94:bb:fe:37:ad:8d:3f:06: -+ 9d:83:b0:e5:f2:ef:e4:88:75:e9:50:3a:f3:ef:aa:e4:00:54: -+ ad:1d:cd:a7:6b:ec:0e:b7:31:92:82:da:0d:4b:c3:27:ee:7a: -+ a8:f4:e0:a9:0a:f1:40:61:a0:09:a5:fb:24:f9:68:34:28:a9: -+ 1b:b6:5a:bd:aa:3a:c4:b8:89:92:ba:92:9c:81:f8:a8:ff:5a: -+ 0c:ef:af:97:b4:86:09:71:e8:13:28:1c:89:16:6f:43:de:1b: -+ 2f:1d:16:9f:37:7f:9c:5f:4e:4a:a8:22:4b:77:9e:f6:94:f8: -+ d9:05:4b:bc:a6:aa:f7:6e -+-----BEGIN CERTIFICATE----- -+MIIFFDCCAvygAwIBAgICEAUwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT -+MQswCQYDVQQIEwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUGA1UEChMeVGhl -+IEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFjaGUgVG9t -+Y2F0IFBNQzEeMBwGA1UEAxMVQXBhY2hlIFRvbWNhdCBUZXN0IENBMB4XDTI1MTIw -+NTE5MzM1NVoXDTI3MTIwNTE5MzM1NVowgY0xCzAJBgNVBAYTAlVTMQswCQYDVQQI -+EwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUGA1UEChMeVGhlIEFwYWNoZSBT -+b2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFjaGUgVG9tY2F0IFBNQzEX -+MBUGA1UEAxMOT0NTUCBSZXNwb25kZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -+ggEKAoIBAQCbrrFA5eSEtsPsk88jY1FRf73TZB3gI7szRPFHxvXSTSoTKvRM0kQT -+VgNzFjCYvmax+zzpnFphJbhH73IEratq+IP+AKbAi6PvNAlPE+b6ltMrJNvj0UpA -+UF+fjzH63kIN5qJKeuamSFqXBLO5vVIuL+kCJxuPvysZKOiW6ynQbjkL2b8q0j5l -+pOCHMKsmCQHqSqeiOAkO9dO4ZgrMF2Fy+6le5Jj/MOSTEfduE/N29vREt6gqebNP -+Wdhnt8BMzVBX0gll9V4tO+cpv+MR/zcdrfLPO//3SdEaBR0rDln+/uZqXXN/C4yz -+bcNlKpP4h7f9wkrjuNXmVYuz5Q5P9PqnAgMBAAGjdTBzMAwGA1UdEwEB/wQCMAAw -+DgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMJMB0GA1UdDgQWBBT6 -+I0XilI5qiLhysVPqKq65OfhqyDAfBgNVHSMEGDAWgBSsh9yLPYrbiUh+bzscxnCS -+CRdv+TANBgkqhkiG9w0BAQsFAAOCAgEAOzlHnijxwEbrqN4ORGNNPPRZwaQq62rl -+UHbqdvepyqLLcJHJ08X91smGPa3yuKfksZMJROsnMAGFE9sKYvAP+lner5Mant8H -+2rjsGcHJVvmmjk4DruD52NK30pRKcJW3qH9Csh1Ddzqe+HaTSzpICVqLOyw4l+0n -+a9UxC/A9qdzUC5ZVB0FZ4R9ocEcEahGkged9dQgVn8ogIGn+71A/zwILlkqe584I -+B4rAk6aqqZFTrF6AO71vy9J845vN/7AS7JpxSOEBliH07rv4HZl3AGjv47xdHVi8 -+kYhROZOxkYhc0J0PhwsNBMq+eQW5Qq6zYt96AtfVTqgnjwu4TKrVB6bkZbATeM06 -+OxBYSRPXdIh2inek1CQBYf4LRvtOFTr6K8PKEJxfK/UzIZMWvqTFvaSAiHQqHgnU -+Ksav7b5Gf7jXrabgj5KuK4qXypz7ISlI8TiYCfkrVVN8maUjIVg1GjYVZ3mAP/yU -+YJQreKXxgbRRXAgaUCQh2gvM29c8fdgssZOd9JS7/jetjT8GnYOw5fLv5Ih16VA6 -+8++q5ABUrR3Np2vsDrcxkoLaDUvDJ+56qPTgqQrxQGGgCaX7JPloNCipG7Zavao6 -+xLiJkrqSnIH4qP9aDO+vl7SGCXHoEygciRZvQ94bLx0Wnzd/nF9OSqgiS3ee9pT4 -+2QVLvKaq924= -+-----END CERTIFICATE----- -diff --git a/test/org/apache/tomcat/util/net/ocsp-responder-rsa-key.pem b/test/org/apache/tomcat/util/net/ocsp-responder-rsa-key.pem -new file mode 100644 -index 0000000000..1b5c681c93 ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/ocsp-responder-rsa-key.pem -@@ -0,0 +1,28 @@ -+-----BEGIN PRIVATE KEY----- -+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCbrrFA5eSEtsPs -+k88jY1FRf73TZB3gI7szRPFHxvXSTSoTKvRM0kQTVgNzFjCYvmax+zzpnFphJbhH -+73IEratq+IP+AKbAi6PvNAlPE+b6ltMrJNvj0UpAUF+fjzH63kIN5qJKeuamSFqX -+BLO5vVIuL+kCJxuPvysZKOiW6ynQbjkL2b8q0j5lpOCHMKsmCQHqSqeiOAkO9dO4 -+ZgrMF2Fy+6le5Jj/MOSTEfduE/N29vREt6gqebNPWdhnt8BMzVBX0gll9V4tO+cp -+v+MR/zcdrfLPO//3SdEaBR0rDln+/uZqXXN/C4yzbcNlKpP4h7f9wkrjuNXmVYuz -+5Q5P9PqnAgMBAAECggEAALCpC3sZZLc0rh9Hm0YM7boNutqmQUCXS1ZiZWmN3GVI -+KvaVR6Pk9lr6v+9YvsyVQvO0pOpzAhw7MWJv1HJ6oIpCd4VEN/VGgEBwTB/v9atm -+ezn6GYvrctaIXfoyBAUpMMuVa5QY4qLOd/3m2AttSlQfCcnnlt8Hj2B9i3G2aTya -+EgwH9GKBoQ0FIMP3Znytx2YEj2dMk2wxApafNhxpZ302JZgvQG163UovQeGfJXvN -+d0xwtA8Xyzuv+/l1Bx8KyD0dYjeA6++khJ/oDNkM1+JKfN6qRzIhcNYWZAx6Au78 -+tJwhBuUVqpbZnPkMXwyFjnAMvzSRcJrGIHdrIyPsWQKBgQDIgbcgiECHldkdrIUF -+3qKluX8g8mLTGts/wXG20iY730KThAnbxJ0ORPD5S3HZDSKZkG31ohoZHH7YT9iC -+0+pnu4bEhqtfPttXIK9q3PQh6i5jhiENc2x0NvJ0nUg8DkVqVmnmC3eIVIHfnnUU -+PDhe0GjHC02TegBFXfOFz3LDSQKBgQDGxRa4tKtB/0BeJCu4RD7pHuikt+NUKS7n -+4F3QBpyIzchjImIlHbutFwIbmUQ6C5TzEcgnTDAlJadBmljZYemaX5RN1UEPulPT -+NvSOdGdxyhJmKpFX+umUbypAcpKC6+EElaOuCUphMDOISIyooKUtJqWUXTVgO60x -+2vh94BHebwKBgGpIL/0DnEkCikLrdtukpsx35kZdlTrXio5iCNfizzd/Ybf2Do+6 -+yZGNw7oxXpiyGLwTzeWdVn4nF6mrsVWv5Rm1UnuL8v0awYOOpM1db98mVg6VQ6Hw -+o/V6Rsy/rlF/MxZp1dqGC4dtXCZfxSnDvhGsIU4Y1LcuvUQHyBUO4INZAoGAPATV -+GI7NS49Uk1iervREfsXrf5lbFlWdKT0RdrgYWiKxCGYgdo6k1d4lr8m21UQcBM1w -+v5T80Kqu91swyusKy6dis6HaFHKxzwxACifR+IUIyzq9SnCkSULL4kv2O3wYJPc+ -+RlXd1LzmQpeNiXmAhsKtqr/+VwGOCYjSEcgv/RcCgYBfUrsTG3dgWUVKviFzS63R -+nb0T9yKZij79HkIM0bROpaU5atTgQa/iwvSktw8mHGuJkjQZ6BqVpKHbDOq/Y/zB -+NihYIlf4WUPlQVr/sBLzfTtaxBKcnuVm1d8igKK3qQ0XuH5jk0gD6tzaU4ySTJ+P -+ldxvbWraHRcPzn08xJ6+UA== -+-----END PRIVATE KEY----- -diff --git a/test/org/apache/tomcat/util/net/ocsp/OcspBaseTest.java b/test/org/apache/tomcat/util/net/ocsp/OcspBaseTest.java -new file mode 100644 -index 0000000000..a4c5617309 ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/ocsp/OcspBaseTest.java -@@ -0,0 +1,166 @@ -+/* -+ * 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.ocsp; -+ -+import java.io.File; -+import java.io.FileOutputStream; -+import java.io.IOException; -+import java.nio.channels.FileLock; -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.List; -+ -+import javax.servlet.http.HttpServletResponse; -+ -+import org.junit.AfterClass; -+import org.junit.Assert; -+import org.junit.Assume; -+import org.junit.BeforeClass; -+import org.junit.runners.Parameterized.Parameter; -+import org.junit.runners.Parameterized.Parameters; -+ -+import org.apache.catalina.Context; -+import org.apache.catalina.startup.Tomcat; -+import org.apache.catalina.startup.TomcatBaseTest; -+import org.apache.tomcat.util.buf.ByteChunk; -+import org.apache.tomcat.util.net.SSLHostConfig; -+import org.apache.tomcat.util.net.TesterSupport; -+import org.apache.tomcat.util.net.TesterSupport.SimpleServlet; -+import org.apache.tomcat.util.net.openssl.OpenSSLStatus; -+ -+public class OcspBaseTest extends TomcatBaseTest { -+ -+ private static final File lockFile = new File("test/org/apache/tomcat/util/net/ocsp/ocsp-responder.lock"); -+ private static FileLock lock = null; -+ -+ @BeforeClass -+ public static void obtainOcspResponderLock() throws IOException { -+ @SuppressWarnings("resource") -+ FileOutputStream fos = new FileOutputStream(lockFile); -+ lock = fos.getChannel().lock(); -+ } -+ -+ @AfterClass -+ public static void releaseOcspResponderLock() throws IOException { -+ // Should not be null be in case obtaining the lock fails, avoid a second error. -+ if (lock != null) { -+ lock.release(); -+ } -+ } -+ -+ -+ @Parameters(name = "{0} with OpenSSL trust {2}") -+ public static Collection parameters() { -+ List parameterSets = new ArrayList<>(); -+ parameterSets.add(new Object[] { "JSSE", Boolean.FALSE, Boolean.FALSE, -+ "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); -+ parameterSets.add(new Object[] { "OpenSSL", Boolean.TRUE, Boolean.TRUE, -+ "org.apache.tomcat.util.net.openssl.OpenSSLImplementation" }); -+ parameterSets.add(new Object[] { "OpenSSL", Boolean.TRUE, Boolean.FALSE, -+ "org.apache.tomcat.util.net.openssl.OpenSSLImplementation" }); -+ parameterSets.add(new Object[] { "OpenSSL-FFM", Boolean.TRUE, Boolean.TRUE, -+ "org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation" }); -+ parameterSets.add(new Object[] { "OpenSSL-FFM", Boolean.TRUE, Boolean.FALSE, -+ "org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation" }); -+ -+ return parameterSets; -+ } -+ -+ @Parameter(0) -+ public String connectorName; -+ -+ @Parameter(1) -+ public boolean useOpenSSL; -+ -+ @Parameter(2) -+ public boolean useOpenSSLTrust; -+ -+ @Parameter(3) -+ public String sslImplementationName; -+ -+ @Override -+ public void setUp() throws Exception { -+ super.setUp(); -+ Tomcat tomcat = getTomcatInstance(); -+ TesterSupport.configureSSLImplementation(tomcat, sslImplementationName, useOpenSSL); -+ } -+ -+ -+ protected void doTest(boolean clientCertValid, boolean serverCertValid, ClientCertificateVerification verifyClientCert, -+ boolean verifyServerCert) throws Exception { -+ -+ if ("OpenSSL-FFM".equals(connectorName)) { -+ Assume.assumeFalse(OpenSSLStatus.isBoringSSL() || OpenSSLStatus.isLibreSSLPre35()); -+ } -+ Assume.assumeFalse(!useOpenSSLTrust && verifyClientCert == ClientCertificateVerification.OPTIONAL_NO_CA); -+ -+ Tomcat tomcat = getTomcatInstance(); -+ -+ // No file system docBase required -+ Context ctx = tomcat.addContext("", null); -+ -+ Tomcat.addServlet(ctx, "simple", new SimpleServlet()); -+ ctx.addServletMappingDecoded("/simple", "simple"); -+ -+ if (serverCertValid) { -+ TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_RSA_JKS, useOpenSSLTrust); -+ } else { -+ TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_CRL_RSA_JKS, useOpenSSLTrust); -+ } -+ SSLHostConfig sslHostConfig = tomcat.getConnector().findSslHostConfigs()[0]; -+ switch (verifyClientCert) { -+ case DEFAULT: -+ sslHostConfig.setCertificateVerification("required"); -+ break; -+ case DISABLED: -+ sslHostConfig.setOcspEnabled(false); -+ sslHostConfig.setCertificateVerification("required"); -+ break; -+ case ENABLED: -+ sslHostConfig.setOcspEnabled(true); -+ sslHostConfig.setCertificateVerification("required"); -+ break; -+ case OPTIONAL_NO_CA: -+ sslHostConfig.setOcspEnabled(true); -+ sslHostConfig.setCertificateVerification("optionalNoCA"); -+ break; -+ -+ } -+ -+ if (clientCertValid) { -+ TesterSupport.configureClientSsl(verifyServerCert, TesterSupport.CLIENT_JKS); -+ } else { -+ TesterSupport.configureClientSsl(verifyServerCert, TesterSupport.CLIENT_CRL_JKS); -+ } -+ -+ tomcat.start(); -+ -+ int rc = getUrl("https://localhost:" + getPort() + "/simple", new ByteChunk(), false); -+ -+ // If the TLS handshake fails, the test won't get this far. -+ Assert.assertEquals(HttpServletResponse.SC_OK, rc); -+ } -+ -+ -+ protected enum ClientCertificateVerification { -+ DEFAULT, -+ ENABLED, -+ OPTIONAL_NO_CA, -+ DISABLED -+ } -+ -+} -diff --git a/test/org/apache/tomcat/util/net/ocsp/TestOcspEnabled.java b/test/org/apache/tomcat/util/net/ocsp/TestOcspEnabled.java -new file mode 100644 -index 0000000000..e67d934b2c ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/ocsp/TestOcspEnabled.java -@@ -0,0 +1,186 @@ -+/* -+ * 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.ocsp; -+ -+import java.io.File; -+import java.io.FileOutputStream; -+import java.io.IOException; -+import java.nio.channels.FileLock; -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.List; -+ -+import javax.net.ssl.SSLHandshakeException; -+import javax.servlet.http.HttpServletResponse; -+ -+import org.junit.AfterClass; -+import org.junit.Assert; -+import org.junit.BeforeClass; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+import org.junit.runners.Parameterized.Parameter; -+ -+import org.apache.catalina.Context; -+import org.apache.catalina.startup.Tomcat; -+import org.apache.catalina.startup.TomcatBaseTest; -+import org.apache.tomcat.util.buf.ByteChunk; -+import org.apache.tomcat.util.net.SSLHostConfig; -+import org.apache.tomcat.util.net.TesterSupport; -+import org.apache.tomcat.util.net.TesterSupport.SimpleServlet; -+ -+ -+@RunWith(Parameterized.class) -+public class TestOcspEnabled extends TomcatBaseTest { -+ -+ private static TesterOcspResponder ocspResponder; -+ private static final File lockFile = new File("test/org/apache/tomcat/util/net/ocsp/ocsp-responder.lock"); -+ private static FileLock lock = null; -+ -+ @BeforeClass -+ public static void obtainOcspResponderLock() throws IOException { -+ @SuppressWarnings("resource") -+ FileOutputStream fos = new FileOutputStream(lockFile); -+ lock = fos.getChannel().lock(); -+ } -+ -+ @AfterClass -+ public static void releaseOcspResponderLock() throws IOException { -+ // Should not be null be in case obtaining the lock fails, avoid a second error. -+ if (lock != null) { -+ lock.release(); -+ } -+ } -+ -+ -+ @Parameterized.Parameters(name = "{0} with OpenSSL trust {2}") -+ public static Collection parameters() { -+ List parameterSets = new ArrayList<>(); -+ parameterSets.add(new Object[] { "JSSE", Boolean.FALSE, Boolean.FALSE, -+ "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); -+ parameterSets.add(new Object[] { "OpenSSL", Boolean.TRUE, Boolean.TRUE, -+ "org.apache.tomcat.util.net.openssl.OpenSSLImplementation" }); -+ parameterSets.add(new Object[] { "OpenSSL", Boolean.TRUE, Boolean.FALSE, -+ "org.apache.tomcat.util.net.openssl.OpenSSLImplementation" }); -+ parameterSets.add(new Object[] { "OpenSSL-FFM", Boolean.TRUE, Boolean.TRUE, -+ "org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation" }); -+ parameterSets.add(new Object[] { "OpenSSL-FFM", Boolean.TRUE, Boolean.FALSE, -+ "org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation" }); -+ -+ return parameterSets; -+ } -+ -+ @Parameter(0) -+ public String connectorName; -+ -+ @Parameter(1) -+ public boolean useOpenSSL; -+ -+ @Parameter(2) -+ public boolean useOpenSSLTrust; -+ -+ @Parameter(3) -+ public String sslImplementationName; -+ -+ -+ @BeforeClass -+ public static void startOcspResponder() throws IOException { -+ ocspResponder = new TesterOcspResponder(); -+ ocspResponder.start(); -+ } -+ -+ -+ @Override -+ public void setUp() throws Exception { -+ super.setUp(); -+ Tomcat tomcat = getTomcatInstance(); -+ TesterSupport.configureSSLImplementation(tomcat, sslImplementationName, useOpenSSL); -+ } -+ -+ -+ @AfterClass -+ public static void stopOcspResponder() { -+ ocspResponder.stop(); -+ ocspResponder = null; -+ } -+ -+ -+ @Test -+ public void testValidClientValidServerVerifyNone() throws Exception { -+ doTest(true, true, false, false, HttpServletResponse.SC_OK); -+ } -+ -+ @Test -+ public void testValidClientRevokedServerVerifyNone() throws Exception { -+ doTest(true, false, false, false, HttpServletResponse.SC_OK); -+ } -+ -+ @Test -+ public void testRevokedClientValidServerVerifyNone() throws Exception { -+ doTest(false, true, false, false, HttpServletResponse.SC_OK); -+ } -+ -+ @Test -+ public void testRevokedClientRevokedServerVerifyNone() throws Exception { -+ doTest(false, false, false, false, HttpServletResponse.SC_OK); -+ } -+ -+ -+ @Test -+ public void testValidClientValidServerVerifyClient() throws Exception { -+ doTest(true, true, true, false, HttpServletResponse.SC_OK); -+ } -+ -+ @Test(expected = SSLHandshakeException.class) -+ public void testRevokedClientValidServerVerifyClient() throws Exception { -+ doTest(false, true, true, false, HttpServletResponse.SC_OK); -+ } -+ -+ -+ private void doTest(boolean clientCertValid, boolean serverCertValid, boolean verifyClientCert, -+ boolean verifyServerCert, int expectedStatusCode) throws Exception { -+ Tomcat tomcat = getTomcatInstance(); -+ -+ // No file system docBase required -+ Context ctx = tomcat.addContext("", null); -+ -+ Tomcat.addServlet(ctx, "simple", new SimpleServlet()); -+ ctx.addServletMappingDecoded("/simple", "simple"); -+ -+ if (serverCertValid) { -+ TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_RSA_JKS, useOpenSSLTrust); -+ } else { -+ TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_CRL_RSA_JKS, useOpenSSLTrust); -+ } -+ SSLHostConfig sslHostConfig = tomcat.getConnector().findSslHostConfigs()[0]; -+ sslHostConfig.setCertificateVerification("required"); -+ sslHostConfig.setOcspEnabled(verifyClientCert); -+ -+ if (clientCertValid) { -+ TesterSupport.configureClientSsl(TesterSupport.CLIENT_JKS); -+ } else { -+ TesterSupport.configureClientSsl(TesterSupport.CLIENT_CRL_JKS); -+ } -+ // TODO enable client-side OCSP checks -+ -+ tomcat.start(); -+ -+ int rc = getUrl("https://localhost:" + getPort() + "/simple", new ByteChunk(), false); -+ -+ Assert.assertEquals(expectedStatusCode, rc); -+ } -+} -diff --git a/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java b/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java -new file mode 100644 -index 0000000000..9012d7196a ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/ocsp/TestOcspIntegration.java -@@ -0,0 +1,432 @@ -+/* -+ * 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.ocsp; -+ -+import java.io.Closeable; -+import java.io.File; -+import java.io.FileInputStream; -+import java.io.IOException; -+import java.io.OutputStream; -+import java.net.InetSocketAddress; -+import java.net.ServerSocket; -+import java.net.URI; -+import java.net.URL; -+import java.nio.file.Files; -+import java.security.KeyStore; -+import java.security.KeyStoreException; -+import java.security.cert.CRLReason; -+import java.security.cert.CertPathValidator; -+import java.security.cert.CertPathValidatorException; -+import java.security.cert.Certificate; -+import java.security.cert.CertificateRevokedException; -+import java.security.cert.PKIXBuilderParameters; -+import java.security.cert.PKIXRevocationChecker; -+import java.security.cert.TrustAnchor; -+import java.security.cert.X509CertSelector; -+import java.security.cert.X509Certificate; -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.Date; -+import java.util.EnumSet; -+import java.util.Enumeration; -+import java.util.HashMap; -+import java.util.HashSet; -+import java.util.List; -+import java.util.Set; -+ -+import javax.net.ssl.CertPathTrustManagerParameters; -+import javax.net.ssl.HttpsURLConnection; -+import javax.net.ssl.KeyManagerFactory; -+import javax.net.ssl.SSLContext; -+import javax.net.ssl.SSLHandshakeException; -+import javax.net.ssl.SSLSocketFactory; -+import javax.net.ssl.TrustManagerFactory; -+import javax.security.auth.x500.X500Principal; -+ -+import jakarta.servlet.http.HttpServletResponse; -+ -+import org.junit.Assert; -+import org.junit.Assume; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+import org.junit.runners.Parameterized.Parameter; -+ -+import org.apache.catalina.Context; -+import org.apache.catalina.connector.Connector; -+import org.apache.catalina.startup.Tomcat; -+import org.apache.catalina.startup.TomcatBaseTest; -+import org.apache.tomcat.util.net.Constants; -+import org.apache.tomcat.util.net.SSLHostConfig; -+import org.apache.tomcat.util.net.SSLHostConfigCertificate; -+import org.apache.tomcat.util.net.TesterSupport; -+import org.apache.tomcat.util.net.openssl.OpenSSLStatus; -+ -+import com.sun.net.httpserver.Headers; -+import com.sun.net.httpserver.HttpServer; -+ -+ -+@RunWith(Parameterized.class) -+public class TestOcspIntegration extends TomcatBaseTest { -+ -+ private static final String CA_CERTIFICATE_PATH = "ca-cert.pem"; -+ private static final String SERVER_CERTIFICATE_PATH = "server-cert.pem"; -+ private static final String SERVER_CERTIFICATE_KEY_PATH = "server-key.pem"; -+ private static final String TRUSTSTORE_PATH = "trustStore.p12"; -+ private static final String TRUSTSTORE_PASS = "trust-password"; -+ private static final String KEYSTORE_TYPE = "PKCS12"; -+ private static final String OCSP_SERVER_CERT_GOOD_RESPONSE = "ocsp-good.der"; -+ private static final String OCSP_SERVER_CERT_REVOKED_RESPONSE = "ocsp-revoked.der"; -+ private static final String CLIENT_KEYSTORE_PATH = "client-keystore.p12"; -+ private static final String CLIENT_KEYSTORE_PASS = "client-password"; -+ private static final String OCSP_CLIENT_CERT_GOOD_RESPONSE = "ocsp-client-good.der"; -+ private static final String OCSP_CLIENT_CERT_REVOKED_RESPONSE = "ocsp-client-revoked.der"; -+ -+ @Parameterized.Parameters(name = "{0}") -+ public static Collection parameters() { -+ List parameterSets = new ArrayList<>(); -+ /* -+ * Future JSSE testing -+ parameterSets.add(new Object[] { -+ "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); -+ */ -+ /* -+ * Disabled until a Tomcat Native release (2.0.10 onwards) is available with the OCSP fix -+ parameterSets.add(new Object[] { -+ "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); -+ */ -+ parameterSets.add(new Object[] { -+ "OpenSSL-FFM", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation"}); -+ -+ return parameterSets; -+ } -+ -+ @Parameter(0) -+ public String connectorName; -+ -+ @Parameter(1) -+ public boolean useOpenSSL; -+ -+ @Parameter(2) -+ public String sslImplementationName; -+ -+ -+ @Test -+ public void testOcspGood_ClientVerifiesServerCertificateOnly() throws Exception { -+ Assert.assertEquals(HttpServletResponse.SC_OK, testOCSP(OCSP_SERVER_CERT_GOOD_RESPONSE, false, true)); -+ } -+ -+ @Test -+ public void testOcspGood_Mutual() throws Exception { -+ testOCSPWithClientResponder(OCSP_CLIENT_CERT_GOOD_RESPONSE, () -> Assert.assertEquals(HttpServletResponse.SC_OK, -+ testOCSP(OCSP_SERVER_CERT_GOOD_RESPONSE, true, true))); -+ } -+ -+ @Test -+ public void testOcspGood_ServerVerifiesClientCertificateOnly() throws Exception { -+ testOCSPWithClientResponder(OCSP_CLIENT_CERT_GOOD_RESPONSE, () -> Assert.assertEquals(HttpServletResponse.SC_OK, -+ testOCSP(OCSP_SERVER_CERT_REVOKED_RESPONSE, true, false))); -+ } -+ -+ @Test(expected = CertificateRevokedException.class) -+ public void testOcspRevoked_ClientVerifiesServerCertificateOnly() throws Exception { -+ try { -+ testOCSP(OCSP_SERVER_CERT_REVOKED_RESPONSE, false, true); -+ } catch (SSLHandshakeException sslHandshakeException) { -+ handleExceptionWhenRevoked(sslHandshakeException); -+ } -+ } -+ -+ @Test(expected = CertificateRevokedException.class) -+ public void testOcspRevoked_Mutual() throws Exception { -+ try { -+ // The exception is thrown before server side verification, while client does OCSP verification. -+ testOCSP(OCSP_SERVER_CERT_REVOKED_RESPONSE, true, true); -+ } catch (SSLHandshakeException sslHandshakeException) { -+ handleExceptionWhenRevoked(sslHandshakeException); -+ } -+ } -+ -+ @Test(expected = SSLHandshakeException.class) -+ public void testOcspRevoked_ServerVerifiesClientCertificateOnly() throws Exception { -+ Assume.assumeFalse("BoringSSL does not support OCSP in a compatible way", -+ TesterSupport.isOpenSSLVariant(sslImplementationName, OpenSSLStatus.Name.BORINGSSL)); -+ testOCSPWithClientResponder(OCSP_CLIENT_CERT_REVOKED_RESPONSE, -+ () -> testOCSP(OCSP_SERVER_CERT_GOOD_RESPONSE, true, false)); -+ } -+ -+ @Test -+ public void testOcsp_NoVerification() throws Exception { -+ testOCSPWithClientResponder(OCSP_CLIENT_CERT_REVOKED_RESPONSE, () -> Assert -+ .assertEquals(HttpServletResponse.SC_OK, testOCSP(OCSP_SERVER_CERT_REVOKED_RESPONSE, false, false))); -+ } -+ -+ @Test -+ public void testOcspResponderUrlDiscoveryViaCertificateAIA() throws Exception { -+ final int ocspPort = 8888; -+ Assume.assumeTrue("Port " + ocspPort + " is not available.", isPortAvailable(ocspPort)); -+ Assert.assertEquals(HttpServletResponse.SC_OK, -+ testOCSP(OCSP_SERVER_CERT_GOOD_RESPONSE, false, true, true, ocspPort)); -+ } -+ -+ public static void testLongUrlForOcspViaAIAWithTomcatNative(Tomcat tomcat) throws Exception { -+ final int ocspResponderPortForClient = 8889; -+ Assume.assumeTrue("Port " + ocspResponderPortForClient + " is not available.", isPortAvailable(ocspResponderPortForClient)); -+ try (FakeOcspResponder fakeOcspResponder = new FakeOcspResponder(true, "/ocsp/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", -+ Files.readAllBytes(new File(getPath(OCSP_CLIENT_CERT_REVOKED_RESPONSE)).toPath()), ocspResponderPortForClient)) { -+ fakeOcspResponder.start(); -+ testOCSP(tomcat, OCSP_SERVER_CERT_GOOD_RESPONSE, true, false, false, 0, -+ "org.apache.tomcat.util.net.openssl.OpenSSLImplementation", true); -+ } -+ } -+ -+ @FunctionalInterface -+ private interface TestOCSPAction { -+ void execute() throws Exception; -+ } -+ -+ private void testOCSPWithClientResponder(String clientResponsePath, TestOCSPAction testOCSPAction) -+ throws Exception { -+ final int ocspResponderPortForClient = 8889; -+ Assume.assumeTrue("Port " + ocspResponderPortForClient + " is not available.", -+ isPortAvailable(ocspResponderPortForClient)); -+ try (FakeOcspResponder fakeOcspResponder = new FakeOcspResponder( -+ Files.readAllBytes(new File(getPath(clientResponsePath)).toPath()), ocspResponderPortForClient)) { -+ fakeOcspResponder.start(); -+ testOCSPAction.execute(); -+ } -+ } -+ -+ private int testOCSP(String pathToOcspResponse, boolean serverSideVerificationEnabled, -+ boolean clientSideOcspVerificationEnabled) throws Exception { -+ return testOCSP(pathToOcspResponse, serverSideVerificationEnabled, clientSideOcspVerificationEnabled, false, 0); -+ } -+ -+ private int testOCSP(String pathToOcspResponse, boolean serverSideVerificationEnabled, -+ boolean clientSideOcspVerificationEnabled, boolean clientDiscoversResponderFromAIA, int ocspResponderPort) -+ throws Exception { -+ return testOCSP(getTomcatInstance(), pathToOcspResponse, serverSideVerificationEnabled, -+ clientSideOcspVerificationEnabled, clientDiscoversResponderFromAIA, ocspResponderPort, -+ sslImplementationName, useOpenSSL); -+ } -+ -+ private static int testOCSP(Tomcat tomcat, String pathToOcspResponse, boolean serverSideVerificationEnabled, -+ boolean clientSideOcspVerificationEnabled, boolean clientDiscoversResponderFromAIA, int ocspResponderPort, -+ String sslImplementationName, boolean useOpenSSL) -+ throws Exception { -+ -+ File certificateFile = new File(getPath(SERVER_CERTIFICATE_PATH)); -+ File certificateKeyFile = new File(getPath(SERVER_CERTIFICATE_KEY_PATH)); -+ File certificateChainFile = new File(getPath(CA_CERTIFICATE_PATH)); -+ initSsl(tomcat, serverSideVerificationEnabled, certificateFile, certificateKeyFile, certificateChainFile); -+ -+ TesterSupport.configureSSLImplementation(tomcat, sslImplementationName, useOpenSSL); -+ -+ Context context = tomcat.addContext("", null); -+ Tomcat.addServlet(context, "simple", new TesterSupport.SimpleServlet()); -+ context.addServletMappingDecoded("/", "simple"); -+ -+ KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE); -+ String trustStorePass = Files.readString(new File(getPath(TRUSTSTORE_PASS)).toPath()).trim(); -+ trustStore.load(new FileInputStream(new File(getPath(TRUSTSTORE_PATH)).getAbsolutePath()), -+ trustStorePass.toCharArray()); -+ KeyStore clientKeystore = KeyStore.getInstance(KEYSTORE_TYPE); -+ String clientKeystorePass = Files.readString(new File(getPath(CLIENT_KEYSTORE_PASS)).toPath()).trim(); -+ clientKeystore.load(new FileInputStream(new File(getPath(CLIENT_KEYSTORE_PATH)).getAbsolutePath()), -+ clientKeystorePass.toCharArray()); -+ byte[] ocspResponse = Files.readAllBytes(new File(getPath(pathToOcspResponse)).toPath()); -+ try (FakeOcspResponder fakeOcspResponder = new FakeOcspResponder(ocspResponse, ocspResponderPort)) { -+ fakeOcspResponder.start(); -+ tomcat.start(); -+ -+ URL url = new URI("https://127.0.0.1:" + tomcat.getConnector().getLocalPort() + "/").toURL(); -+ HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); -+ SSLSocketFactory sslSocketFactory; -+ if (clientSideOcspVerificationEnabled) { -+ sslSocketFactory = buildClientSslSocketFactoryWithOcsp( -+ clientDiscoversResponderFromAIA ? null : fakeOcspResponder.url(), trustStore, clientKeystore, -+ clientKeystorePass); -+ } else { -+ sslSocketFactory = buildClientSslSocketFactoryNoOcsp(trustStore, clientKeystore, clientKeystorePass); -+ } -+ connection.setSSLSocketFactory(sslSocketFactory); -+ connection.connect(); -+ return connection.getResponseCode(); -+ } finally { -+ tomcat.stop(); -+ } -+ } -+ -+ private static void initSsl(Tomcat tomcat, boolean serverSideVerificationEnabled, File certificateFile, -+ File certificateKeyFile, File certificateChainFile) { -+ Connector connector = tomcat.getConnector(); -+ connector.setSecure(true); -+ connector.setProperty("SSLEnabled", "true"); -+ -+ SSLHostConfig sslHostConfig = new SSLHostConfig(); -+ SSLHostConfigCertificate certificate = new SSLHostConfigCertificate(sslHostConfig, SSLHostConfigCertificate.Type.UNDEFINED); -+ sslHostConfig.addCertificate(certificate); -+ certificate.setCertificateFile(certificateFile.getAbsolutePath()); -+ certificate.setCertificateKeyFile(certificateKeyFile.getAbsolutePath()); -+ certificate.setCertificateChainFile(certificateChainFile.getAbsolutePath()); -+ if (serverSideVerificationEnabled) { -+ sslHostConfig.setCertificateVerification("required"); -+ } else { -+ sslHostConfig.setCertificateVerification("optionalNoCA"); -+ } -+ sslHostConfig.setCaCertificateFile(certificateChainFile.getAbsolutePath()); -+ connector.addSslHostConfig(sslHostConfig); -+ } -+ -+ private static SSLSocketFactory buildClientSslSocketFactoryWithOcsp(String ocspUrl, KeyStore trustStore, -+ KeyStore clientKeystore, String clientKeystorePass) throws Exception { -+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); -+ kmf.init(clientKeystore, clientKeystorePass.toCharArray()); -+ Set trustAnchors = getTrustAnchorsFromKeystore(trustStore); -+ PKIXRevocationChecker revocationChecker =(PKIXRevocationChecker) CertPathValidator.getInstance("PKIX").getRevocationChecker(); -+ if (ocspUrl != null) { -+ revocationChecker.setOcspResponder(new URI(ocspUrl)); -+ } -+ revocationChecker.setOptions(EnumSet.of(PKIXRevocationChecker.Option.NO_FALLBACK)); -+ -+ PKIXBuilderParameters pkix = new PKIXBuilderParameters(trustAnchors, new X509CertSelector()); -+ pkix.addCertPathChecker(revocationChecker); -+ -+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX"); -+ trustManagerFactory.init(new CertPathTrustManagerParameters(pkix)); -+ return initSSLContext(kmf, trustManagerFactory).getSocketFactory(); -+ } -+ -+ private static SSLSocketFactory buildClientSslSocketFactoryNoOcsp(KeyStore trustStore, KeyStore clientKeystore, -+ String clientKeystorePass) throws Exception { -+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); -+ kmf.init(clientKeystore, clientKeystorePass.toCharArray()); -+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); -+ trustManagerFactory.init(trustStore); -+ return initSSLContext(kmf, trustManagerFactory).getSocketFactory(); -+ } -+ -+ private static SSLContext initSSLContext(KeyManagerFactory keyManagerFactory, -+ TrustManagerFactory trustManagerFactory) throws Exception { -+ SSLContext sslContext; -+ if (TesterSupport.isTlsv13Available()) { -+ sslContext = SSLContext.getInstance(Constants.SSL_PROTO_TLSv1_3); -+ } else { -+ sslContext = SSLContext.getInstance(Constants.SSL_PROTO_TLSv1_2); -+ } -+ sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); -+ return sslContext; -+ } -+ -+ private static Set getTrustAnchorsFromKeystore(KeyStore keyStore) throws KeyStoreException { -+ Set trustAnchors = new HashSet<>(); -+ Enumeration aliases = keyStore.aliases(); -+ while (aliases.hasMoreElements()) { -+ String alias = aliases.nextElement(); -+ Certificate certificate = keyStore.getCertificate(alias); -+ if (certificate instanceof X509Certificate) { -+ trustAnchors.add(new TrustAnchor((X509Certificate)certificate, null)); -+ } -+ } -+ return trustAnchors; -+ } -+ -+ private static void handleExceptionWhenRevoked(Exception exception) throws Exception { -+ if (exception.getCause().getCause() instanceof CertPathValidatorException cpe) { -+ Assert.assertEquals("REVOKED", cpe.getReason().toString()); -+ Assert.assertTrue(cpe.toString().contains("reason: KEY_COMPROMISE")); -+ // Some JDKs only expose CertPathValidatorException -+ if (cpe.getCause() instanceof CertificateRevokedException) { -+ throw (CertificateRevokedException) cpe.getCause(); -+ } else { -+ throw new CertificateRevokedException(new Date(), CRLReason.KEY_COMPROMISE, new X500Principal(""), new HashMap<>()); -+ } -+ } -+ } -+ -+ private static class FakeOcspResponder implements Closeable { -+ private final byte[] ocspResponse; -+ private HttpServer server; -+ private int port; -+ private boolean strictPath = false; -+ private String path = "/ocsp"; -+ -+ FakeOcspResponder(boolean strictPath, String path, byte[] ocspResponse, int port) { -+ this(ocspResponse, port); -+ this.strictPath = strictPath; -+ this.path = path; -+ } -+ -+ FakeOcspResponder(byte[] ocspResponse, int port) { -+ this.ocspResponse = ocspResponse; -+ this.port = port; -+ } -+ -+ void start() throws IOException { -+ server = HttpServer.create(new InetSocketAddress("127.0.0.1", port), 0); -+ server.createContext(this.path, httpExchange -> { -+ if (strictPath) { -+ String path = httpExchange.getRequestURI().getPath(); -+ if (!this.path.equals(path)) { -+ httpExchange.sendResponseHeaders(404, -1); -+ httpExchange.close(); -+ return; -+ } -+ } -+ byte[] body = ocspResponse; -+ Headers headers = httpExchange.getResponseHeaders(); -+ headers.add("Content-Type", "application/ocsp-response"); -+ httpExchange.sendResponseHeaders(HttpServletResponse.SC_OK, body.length); -+ try (OutputStream os = httpExchange.getResponseBody()) { -+ os.write(body); -+ } -+ }); -+ server.start(); -+ port = server.getAddress().getPort(); -+ } -+ -+ String url() { -+ return "http://127.0.0.1:" + port + path; -+ } -+ @Override public void close() { -+ if (server != null) { -+ server.stop(0); -+ } -+ } -+ } -+ -+ private static String getPath(String file) throws IOException { -+ if (file == null) { -+ return null; -+ } -+ String packageName = TestOcspIntegration.class.getPackageName(); -+ String path = packageName.replace(".", File.separator); -+ File f = new File("test" + File.separator + path + File.separator + file); -+ -+ return f.getCanonicalPath(); -+ } -+ -+ @SuppressWarnings("unused") -+ private static boolean isPortAvailable(int port) { -+ try (ServerSocket serverSocket = new ServerSocket(port)) { -+ return true; -+ } catch (IOException e) { -+ return false; -+ } -+ } -+} -diff --git a/test/org/apache/tomcat/util/net/ocsp/TestOcspSoftFail.java b/test/org/apache/tomcat/util/net/ocsp/TestOcspSoftFail.java -new file mode 100644 -index 0000000000..382db3838b ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/ocsp/TestOcspSoftFail.java -@@ -0,0 +1,59 @@ -+/* -+ * 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.ocsp; -+ -+import java.net.SocketException; -+ -+import javax.net.ssl.SSLHandshakeException; -+ -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+ -+/* -+ * Only looking to test the Tomcat (server) side configuration of soft fail. -+ */ -+@RunWith(Parameterized.class) -+public class TestOcspSoftFail extends OcspBaseTest { -+ -+ @Test -+ public void testNoResponderDefaultSoftFail() throws Exception { -+ // Default behaviour should be the same for all configurations and equivalent to enabled. -+ doTest(false, false, ClientCertificateVerification.ENABLED, false, null); -+ } -+ -+ -+ @Test -+ public void testNoResponderWithSoftFail() throws Exception { -+ doTest(false, false, ClientCertificateVerification.ENABLED, false, Boolean.TRUE); -+ } -+ -+ -+ @Test(expected = SSLHandshakeException.class) -+ public void testNoResponderWithoutSoftFail() throws Exception { -+ try { -+ doTest(false, false, ClientCertificateVerification.ENABLED, false, Boolean.FALSE); -+ } catch (SocketException se) { -+ // NIO2 may throw a SocketException rather than a SSLHandshakeException -+ if (getTomcatInstance().getConnector().getProtocolHandlerClassName().contains("Nio2")) { -+ throw new SSLHandshakeException(se.getMessage()); -+ } else { -+ throw se; -+ } -+ } -+ } -+} -diff --git a/test/org/apache/tomcat/util/net/ocsp/TestOcspTimeout.java b/test/org/apache/tomcat/util/net/ocsp/TestOcspTimeout.java -new file mode 100644 -index 0000000000..290b08822a ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/ocsp/TestOcspTimeout.java -@@ -0,0 +1,73 @@ -+/* -+ * 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.ocsp; -+ -+import java.net.SocketException; -+import java.net.SocketTimeoutException; -+ -+import javax.net.ssl.SSLHandshakeException; -+ -+import org.junit.AfterClass; -+import org.junit.BeforeClass; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+ -+/* -+ * The timeout for reading an OCSP response is 15s by default for both JSSE and OpenSSL. -+ */ -+@RunWith(Parameterized.class) -+public class TestOcspTimeout extends OcspBaseTest { -+ -+ private static TesterOcspResponderNoResponse ocspResponder; -+ -+ @BeforeClass -+ public static void startOcspResponder() { -+ /* -+ * Use shorter timeout to speed up test. -+ * -+ * Note: OpenSSL timeout set later as it requires access to SSLHostConfig. -+ */ -+ System.setProperty("com.sun.security.ocsp.readtimeout", "1000ms"); -+ ocspResponder = new TesterOcspResponderNoResponse(); -+ ocspResponder.start(); -+ } -+ -+ -+ @AfterClass -+ public static void stopOcspResponder() { -+ ocspResponder.stop(); -+ ocspResponder = null; -+ } -+ -+ -+ @Test -+ public void testTimeoutWithSoftFail() throws Exception { -+ doTest(false, false, ClientCertificateVerification.ENABLED, false, Boolean.TRUE); -+ } -+ -+ -+ @Test(expected = SSLHandshakeException.class) -+ public void testTimeoutWithoutSoftFail() throws Exception { -+ try { -+ doTest(false, false, ClientCertificateVerification.ENABLED, false, Boolean.FALSE); -+ } catch (SocketTimeoutException | SocketException e) { -+ // May throw a SocketTimeoutException or SocketException rather than a SSLHandshakeException -+ throw new SSLHandshakeException(e.getMessage()); -+ } -+ } -+} -diff --git a/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponder.java b/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponder.java -new file mode 100644 -index 0000000000..27def84db8 ---- /dev/null -+++ b/test/org/apache/tomcat/util/net/ocsp/TesterOcspResponder.java -@@ -0,0 +1,125 @@ -+/* -+ * 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.ocsp; -+ -+import java.io.BufferedReader; -+import java.io.IOException; -+import java.io.InputStreamReader; -+import java.io.PrintStream; -+import java.io.Reader; -+import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.List; -+import java.util.Map; -+import java.util.concurrent.TimeUnit; -+ -+import org.junit.Assert; -+ -+import org.apache.tomcat.util.net.TesterSupport; -+ -+/* -+ * The OpenSSL ocsp tool is great, but it does generate a lot of output. That output needs to be swallowed, else the -+ * process will freeze when the output buffers (stdout and stderr) are full. -+ * -+ * There is a command line option to redirect stdout (which could be redirected to /dev/null), but there is no option to -+ * redirect stderr. Therefore, this class uses a couple of dedicated threads to read stdout and stderr. By default, the -+ * output is ignored, but it can be dumped to Java's stdout/stderr if required for debugging purposes. -+ */ -+public class TesterOcspResponder { -+ -+ private static List ocspArgs = Arrays.asList("ocsp", "-port", "8888", "-text", "-index", -+ TesterSupport.DB_INDEX, "-CA", TesterSupport.CA_CERT_PEM, "-rkey", TesterSupport.OCSP_RESPONDER_RSA_KEY, -+ "-rsigner", TesterSupport.OCSP_RESPONDER_RSA_CERT, "-nmin", "60"); -+ -+ private Process p; -+ -+ public void start() throws IOException { -+ if (p != null) { -+ throw new IllegalStateException("Already started"); -+ } -+ -+ String openSSLPath = System.getProperty("tomcat.test.openssl.path"); -+ String openSSLLibPath = null; -+ if (openSSLPath == null || openSSLPath.length() == 0) { -+ openSSLPath = "openssl"; -+ } else { -+ // Explicit OpenSSL path may also need explicit lib path -+ // (e.g. Gump needs this) -+ openSSLLibPath = openSSLPath.substring(0, openSSLPath.lastIndexOf('/')); -+ openSSLLibPath = openSSLLibPath + "/../:" + openSSLLibPath + "/../lib:" + openSSLLibPath + "/../lib64"; -+ } -+ List cmd = new ArrayList<>(); -+ cmd.add(openSSLPath); -+ cmd.addAll(ocspArgs); -+ -+ ProcessBuilder pb = new ProcessBuilder(cmd.toArray(new String[0])); -+ -+ if (openSSLLibPath != null) { -+ Map env = pb.environment(); -+ String libraryPath = env.get("LD_LIBRARY_PATH"); -+ if (libraryPath == null) { -+ libraryPath = openSSLLibPath; -+ } else { -+ libraryPath = libraryPath + ":" + openSSLLibPath; -+ } -+ env.put("LD_LIBRARY_PATH", libraryPath); -+ } -+ -+ p = pb.start(); -+ -+ redirect(new BufferedReader(new InputStreamReader(p.getInputStream())) , System.out, true); -+ redirect(new BufferedReader(new InputStreamReader(p.getErrorStream())), System.err, true); -+ -+ Assert.assertTrue(p.isAlive()); -+ } -+ -+ public void stop() { -+ if (p == null) { -+ throw new IllegalStateException("Not started"); -+ } -+ p.destroy(); -+ -+ try { -+ if (!p.waitFor(30, TimeUnit.SECONDS)) { -+ throw new IllegalStateException("Failed to stop"); -+ } -+ } catch (InterruptedException e) { -+ throw new IllegalStateException("Interrupted while waiting to stop", e); -+ } -+ } -+ -+ -+ private void redirect(final Reader r, final PrintStream os, final boolean swallow) { -+ /* -+ * InputStream will close when process ends. Thread will exit once stream closes. -+ */ -+ new Thread( () -> { -+ char[] cbuf = new char[1024]; -+ try { -+ int read; -+ while ((read = r.read(cbuf)) > 0) { -+ if (!swallow) { -+ os.print(new String(cbuf, 0, read)); -+ } -+ } -+ } catch (IOException ignore) { -+ // Ignore -+ } -+ -+ }).start(); -+ } -+} -diff --git a/test/org/apache/tomcat/util/net/ocsp/ocsp-responder.lock b/test/org/apache/tomcat/util/net/ocsp/ocsp-responder.lock -new file mode 100644 -index 0000000000..e69de29bb2 -diff --git a/test/org/apache/tomcat/util/net/user1.jks b/test/org/apache/tomcat/util/net/user1.jks -index 76625a9eab..727de3cccc 100644 -Binary files a/test/org/apache/tomcat/util/net/user1.jks and b/test/org/apache/tomcat/util/net/user1.jks differ -diff --git a/test/org/apache/tomcat/util/net/user2-crl.jks b/test/org/apache/tomcat/util/net/user2-crl.jks -new file mode 100644 -index 0000000000..068517b598 -Binary files /dev/null and b/test/org/apache/tomcat/util/net/user2-crl.jks differ -diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml ---- a/webapps/docs/changelog.xml 2026-04-21 15:48:53.192243701 -0400 -+++ b/webapps/docs/changelog.xml 2026-04-21 15:49:48.893470762 -0400 -@@ -104,6 +104,782 @@ - They eventually become mixed with the numbered issues (i.e., numbered - issues do not "pop up" wrt. others). - --> -+
-+ -+ -+ -+ Refactor generation of the remote user element in the access log to -+ remove unnecessary code. (markt) -+ -+ -+ Fix a regression in the previous release that meant ?- -+ could appear in the access log rather than ? when the query -+ string was present but empty. (markt) -+ -+ -+ Failed precondition should make WebDAV DELETE fail. 982 -+ submitted by Mahmoud Alarby. (remm) -+ -+ -+ Align the escaping in ExtendedAccessLogValve with the other -+ AccessLogValve implementations. (markt) -+ -+ -+ -+ -+ -+ -+ Avoid various edge cases if Content-Length is set via -+ setHeader(String,String) or -+ addHeader(String,String) with an invalid value by always -+ clearing the previous value whether the new value is valid or not and -+ ignoring any invalid new value. (markt) -+ -+ -+ Refactor the calculation of the real index in the HPACK dynamic header -+ table implementation to reduce code duplication. (markt) -+ -+ -+ Fix various minor issues with some HTTP/2 stream error messages for -+ HTTP/2. (markt) -+ -+ -+ Consistently reject URIs containing NULL bytes when -+ normalizing. (markt) -+ -+ -+ Fix a few minor memory leaks on error paths reading TLS keys and -+ certificates when using FFM. (markt) -+ -+ -+ Avoid possible NPEs when using a TLS enabled custom connector. (remm) -+ -+ -+ Refactor clean-up after HTTP/2 headers have been processed to aid GC -+ after a stream reset. (markt) -+ -+ -+ Align HTTP/2 trailer fields with HTTP/1.1 and filter out any fields -+ not permitted in trailers. (markt) -+ -+ -+ -+ -+ -+ -+ 69993: Update the URL to the CDDL 1.0 license. (markt) -+ -+ -+ -+ -+ -+ -+ Add escaping for URI and query string in the access log. (markt) -+ -+ -+ -+ -+ -+ -+ Align buffer reuse of the OpenSSLEngine for tomcat-native with the FFM -+ code. (remm) -+ -+ -+ Fix an HTTP/2 header frame parsing bug that could result in a connection -+ being closed without a GOAWAY frame if an invalid -+ HEADERS frame was received. (markt) -+ -+ -+ 69982: Fix a bug in the non-blocking flushing code for -+ NIO+TLS that meant that a response may not be fully written until the -+ connection is closed. Pull request 966 provided by Phil Clay. -+ (markt) -+ -+ -+ Ensure the HTTP/2 request header read buffer is reset (including -+ restoration to default size) after a stream reset. (markt) -+ -+ -+ Provide trailer field filtering equivalent to that provided for -+ non-trailer fields. Control characters (excluding TAB), and characters -+ with code points above 255 will be replaced with a space. (markt) -+ -+ -+ Align OpenSSl FFM behaviour with Tomcat Native for various OCSP edge -+ cases. (markt) -+ -+ -+ -+ -+ -+ -+ 69995: Make dependent ordering predictable. Patch submitted -+ by Jan Luehe. (remm) -+ -+ -+ -+ -+ -+ -+ Reduce log verbosity of the Kubernetes connection attempts and failure. -+ (remm) -+ -+ -+ Better error handling for the EncryptInterceptor. (markt) -+ -+ -+ -+ -+ -+ -+ Update bnd to 7.2.3. (markt) -+ -+ -+ Improvements to French translations. (remm) -+ -+ -+ Improvements to Japanese translations provided by tak7iji. (markt) -+ -+ -+ -+ -+ -+ -+ 69967: Fix inconsistencies related to -+ Content-Length and Content-Type headers when -+ accessed using the getHeader method and similar. (remm) -+ -+ -+ 69940: Improve redirect handling in the -+ LoadBalancerDrainingValve. (schultz) -+ -+ -+ -+ -+ -+ -+ 69938: Avoid changing the closed state of TLS channel when -+ resetting it after close. (remm) -+ -+ -+ Add an HTTP configuration setting, noCompressionEncodings, -+ that can be used to control which content encodings will not be -+ compressed when compression is enabled. Based on pull request -+ 914 by Long9725. (markt) -+ -+ -+ Add size limit for OCSP responses. Based on code submitted by Chenjp. -+ (remm) -+ -+ -+ To maintain the documented alignment with the OpenSSL development -+ branch, the use of the aliases SSLv3, EXPORT, -+ EXPORT40, EXPORT56, KRB5, -+ kFZA, aFZA, eFZA and -+ FZA are no longer supported when setting the -+ ciphers attribute of an SSLHostConfig element. -+ (markt) -+ -+ -+ To maintain the documented alignment with the OpenSSL development -+ branch, add support for the aliases ARIAGCM and -+ CBCwhen setting the ciphers attribute of -+ an SSLHostConfig element. (markt) -+ -+ -+ 69870: Add a drainTimeout to the HTTP/2 -+ UpgradeProtocol element to allow configuration of an -+ time between the two final GOAWAY frames sent by Tomcat -+ when closing am HTTP/2 connection. Pull request 917 provided by -+ Kai Burjack. (markt) -+ -+ -+ Log an information message if an APR Connector is used, recommending -+ that the appropriate NIO Connector is used instead. (markt) -+ -+ -+ Respect the value for the jdk.tls.namedGroups system -+ property as the default value for the configured group list on the -+ Connector. (remm) -+ -+ -+ 69964: Respect the configured cipher order, which was no -+ longer respected following the addition of TLS 1.3 specific cipher -+ configuration. TLS 1.3 ciphers will always be first in the list. (remm) -+ -+ -+ Free the x509 object in the FFM code when getting the peer certificate -+ if getting the bytes from the certificate somehow fails. -+ Pull request 951 provided by Chenjp. (remm) -+ -+ -+ Improve HPACK exception use, making sure HpackException -+ is thrown instead of unexpected types. (remm) -+ -+ -+ Update the parser for the HTTP Host header and -+ :authority pseudo header to convert the port, if any, to an -+ Integer rather than a Long to be consistent -+ with how port is exposed in the Servlet API. (markt) -+ -+ -+ To aid the migration from the single ciphers configuration -+ attribute to the use of ciphers and -+ cipherSuites, TLS 1.3 cipher suites listed in the -+ ciphers attribute will be removed from the -+ ciphers attribute and added to the end of the -+ cipherSuites attribute. This behaviour will be removed in -+ Tomcat 12.0.x onwards. (markt) -+ -+ -+ Replace the external OpenSSL based OCSP responder used during unit tests -+ with a Bouncy Castle based, in-process Java OCSP responder. (markt) -+ -+ -+ Relax HTTP/2 header validation and respond to invalid requests with a -+ stream reset or a 400 response as appropriate rather then with a -+ connection reset. (markt) -+ -+ -+ Add validation of chunk extensions for chunked transfer encoding. -+ (markt) -+ -+ -+ Update the recommended version for Tomcat Native to 1.3.7. (markt) -+ -+ -+ Align the FFM handling of OCSP TRY_LATER responses with -+ Tomcat Native. (remm) -+ -+ -+ Free CA certificate after calling SSL_CTX_add_client_CA -+ in the FFM code. Based on code from PR 44 from tomcat-native. (remm) -+ -+ -+ Free certificate chain if an error occurs, in the FFM code. (remm) -+ -+ -+ Report handshake issues as SSLException in the FFM -+ code, rather than IllegalStateException. (remm) -+ -+ -+ Fix case sensitive handling of the protocol host name. (remm) -+ -+ -+ -+ -+ -+ -+ 69948: Avoid ArrayOutOfBoundsException instead of -+ PropertyNotFoundException when generating a properties not found -+ exception in AstValue. Based on 950 submitted by Jérôme -+ Besnard. (remm) -+ -+ -+ Add support for specifying Java 27 (with the value 27) as -+ the compiler source and/or compiler target for JSP compilation. If used -+ with an Eclipse JDT compiler version that does not support these values, -+ a warning will be logged and the default will be used. -+ (markt) -+ -+ -+ -+ -+ -+ -+ 69970: Support raw IPv6 in Kubernetes membership provider -+ for the service host. (remm) -+ -+ -+ Add support for new algorithms provided by JPA providers to the -+ EncryptInterceptor. (markt) -+ -+ -+ -+ -+ -+ -+ 69972: Remove unwanted space in DIGEST authorization header. -+ Patch submitted by Stefan Kalscheuer in 957. (remm) -+ -+ -+ 69844: Close the connection with a protocol error if the -+ server sends masked frames. (markt) -+ -+ -+ -+ -+ -+ -+ 69931: Add <label> for fields in the HTML manager -+ application. Patch provided by yukitidev. (schultz) -+ -+ -+ -+ -+ -+ -+ Update the internal fork of Apache Commons BCEL to 6.12.0. (markt) -+ -+ -+ Update Tomcat Native to 1.3.7. (markt) -+ -+ -+ Update Objenesis to 3.5. (markt) -+ -+ -+ Update Byte Buddy to 1.18.7. (markt) -+ -+ -+ Update BND to 7.2.1. (markt) -+ -+ -+ Improvements to French translations. (remm) -+ -+ -+ Improvements to Chinese translations provided by eaststrongox. (markt) -+ -+ -+ Improvements to Japanese translations provided by tak7iji. (markt) -+ -+ -+ -+ -+ -+ -+ Prevent concurrent release of OpenSSLEngine resources and -+ the termination of the Tomcat Native library as it can cause crashes -+ during Tomcat shutdown. (markt) -+ -+ -+ -+ -+ -+ -+ Add property "gpg.sign.files" to optionally disable release artefact -+ signing with GPG. (rjung) -+ -+ -+ -+ -+ -+ -+ 69623: Additional fix for the long standing regression that -+ meant that calls to ClassLoader.getResource().getContent() -+ failed when made from within a web application with resource caching -+ enabled if the target resource was packaged in a JAR file. (markt) -+ -+ -+ Pull request 923: Avoid adding multiple CSRF tokens to a URL in -+ the CsrfPreventionFilter. (schultz) -+ -+ -+ 69918: Ensure request parameters are correctly parsed for -+ HTTP/2 requests when the content-length header is not set. (dsoumis) -+ -+ -+ Update the minimum and recommended versions for Tomcat Native to 1.3.4. -+ (markt) -+ -+ -+ Add a new ssoReauthenticationMode to the Tomcat provided -+ Authenticators that provides a per Authenticator override of the SSO -+ Valve requireReauthentication attribute. (markt) -+ -+ -+ Ensure URL encoding errors in the Rewrite Valve trigger an exception -+ rather than silently using a replacement character. (markt) -+ -+ -+ -+ -+ -+ -+ Improve warnings when setting ciphers lists in the FFM code, mirroring -+ the tomcat-native changes. (remm) -+ -+ -+ 69910: Dereference TLS objects right after closing a socket -+ to improve memory efficiency. (remm) -+ -+ -+ Relax the JSSE vs OpenSSL configuration style checks on -+ SSLHostConfig to reflect the existing implementation that -+ allows one configuration style to be used for the trust attributes and a -+ different style for all the other attributes. (markt) -+ -+ -+ Better warning message when OpenSSLConf configuration -+ elements are used with a JSSE TLS implementation. (markt) -+ -+ -+ When using OpenSSL via FFM, don't log a warning about missing CA -+ certificates unless CA certificates were configured and the -+ configuration failed. (markt) -+ -+ -+ For configuration consistency between OpenSSL and JSSE TLS -+ implementations, TLSv1.3 cipher suites included in the -+ ciphers attribute of an SSLHostConfig are now -+ always ignored (previously they would be ignored with OpenSSL -+ implementations and used with JSSE implementations) and a warning is -+ logged that the cipher suite has been ignored. (markt) -+ -+ -+ Add the ciphersuite attribute to -+ SSLHostConfig to configure the TLSv1.3 cipher suites. -+ (markt) -+ -+ -+ Add OCSP support to JSSE based TLS connectors and make the use of OCSP -+ configurable per connector for both JSSE and OpenSSL based TLS -+ implementations. Align the checks performed by OpenSSL with those -+ performed by JSSE. (markt) -+ -+ -+ Add support for soft failure of OCSP checks with soft failure support -+ disabled by default. (markt) -+ -+ -+ Add support for configuring the verification flags passed to -+ OCSP_basic_verify when using an OpenSSL based TLS -+ implementation. (markt) -+ -+ -+ Fix OpenSSL FFM code compatibility with LibreSSL versions below 3.5. -+ (remm) -+ -+ -+ -+ -+ -+ -+ 69333: Correct a regression in the previous fix for -+ 69333 and ensure that reuse() or -+ release() is always called for a tag. (markt) -+ -+ -+ -+ -+ -+ -+ 62814: Document that human-readable names may be used for -+ mapSendOptions and align documentation with -+ channelSendOptions. Based on pull request 929 by -+ archan0621. (markt) -+ -+ -+ -+ -+ -+ -+ 69920: When attempting to write to a closed -+ Writer or OutputStream obtained from a -+ WebSocket session, throw an IOException rather than an -+ IllegalStateExcpetion as required by Writer -+ and strongly suggested by OutputStream. (markt) -+ -+ -+ -+ -+ -+ -+ Add test.silent property to suppress JUnit console output -+ during test execution. Useful for cleaner console output when running -+ tests with multiple threads. (csutherl) -+ -+ -+ Update the internal fork of Commons Pool to 2.13.1. (markt) -+ -+ -+ Update the internal fork of Commons DBCP to 2.14.0. (markt) -+ -+ -+ Update Commons Daemon to 1.5.1. (markt) -+ -+ -+ Update ByteBuddy to 1.18.3. (markt) -+ -+ -+ Update UnboundID to 7.0.4. (markt) -+ -+ -+ Update Checkstyle to 12.3.1. (markt) -+ -+ -+ Improvements to French translations. (markt) -+ -+ -+ Improvements to Japanese translations provided by tak7iji. (markt) -+ -+ -+ Improvements to Chinese translations provided by Yang. vincent.h and -+ yong hu. (markt) -+ -+ -+ Update Tomcat Native to 1.3.5. (markt) -+ -+ -+ Update bnd to 7.2.0. (markt) -+ -+ -+ -+ -+ -+ -+ 69871: Increase log level to INFO for missing configuration -+ for the rewrite valve. (remm) -+ -+ -+ Add log warnings for additional Host appBase suspicious -+ values. (remm) -+ -+ -+ Remove hard dependency on tomcat-jni.jar for catalina.jar. -+ org.apache.catalina.Connector no longer requires -+ org.apache.tomcat.jni.AprStatus to be present. (markt) -+ -+ -+ Add the ability to use a custom function to generate the client -+ identifier in the CrawlerSessionManagerValve. This is only -+ available programmatically. Pull request 902 by Brian Matzon. -+ (markt) -+ -+ -+ Change the SSO reauthentication behaviour for SPNEGO authentication so -+ that a normal SPNEGO authentication is performed if the SSL Valve is -+ configured with reauthentication enabled. This is so that the delegated -+ credentials will be available to the web application. (markt) -+ -+ -+ -+ -+ -+ -+ Don't log an incorrect certificate KeyStore location when -+ creating a TLS connector if the KeyStore instance has been -+ set directly on the connector. (markt) -+ -+ -+ HTTP/0.9 only allows GET as the HTTP method. (remm) -+ -+ -+ Add strictSni attribute on the Connector to -+ allow matching the SSLHostConfig configuration associated -+ with the SNI host name to the SSLHostConfig configuration -+ matched from the HTTP protocol host name. Non matching configurations -+ will cause the request to be rejected. The attribute default value is -+ true, enabling the matching. (remm) -+ -+ -+ -+ -+ -+ -+ 69877: Catch IllegalArgumentException when processing URIs -+ when creating the classpath to handle invalid URIs. (remm) -+ -+ -+ Fix populating the classpath with the webapp classloader repositories. -+ (remm) -+ -+ -+ -+ -+ -+ -+ Correct a regression introduced in 9.0.109 that broke some clustering -+ configurations. (markt) -+ -+ -+ -+ -+ -+ -+ Manager: Fix abrupt truncation of the HTML and JSON complete server -+ status output if one or more of the web applications failed to start. -+ (schultz) -+ -+ -+ Manager: Include web application state in the HTML and JSON complete -+ server status output. (markt) -+ -+ -+ Documentation: Expand the documentation to better explain when OCSP is -+ supported and when it is not. (markt) -+ -+ -+ -+ -+ -+ -+ 64083: If the underlying connection has been closed, don't -+ add it to the pool when it is returned. Pull request 235 by -+ Alex Panchenko. (markt) -+ -+ -+ -+ -+ -+ -+ Add test profile system for selective test execution. Profiles can be -+ specified via -Dtest.profile=<name> to run specific -+ test subsets without using patterns directly. Profile patterns are -+ defined in test-profiles.properties. (csutherl) -+ -+ -+ Update file extension to media type mappings to align with the current -+ list used by the Apache Web Server (httpd). (markt) -+ -+ -+ Update Commons Daemon to 1.5.0. (markt) -+ -+ -+ Update Byte Buddy to 1.18.2. (markt) -+ -+ -+ Update Checkstyle to 12.2.0. (markt) -+ -+ -+ Improvements to Spanish translations provided by White Vogel. (markt) -+ -+ -+ Improvements to French translations. (remm) -+ -+ -+ Improvements to Japanese translations provided by tak7iji. (markt) -+ -+ -+ -+ -+ -+ -+ When generating the class path in the Loader, re-order the check on -+ individual class path components to avoid a potential -+ NullPointerException. Identified by Coverity Scan. (markt) -+ -+ -+ Fix SSL socket factory configuration in the JNDI realm. Based on pull -+ request 915 by Joshua Rogers. (remm) -+ -+ -+ Add an attribute, digestInRfc3112Order, to -+ MessageDigestCredentialHandler to control the order in -+ which the credential and salt are digested. By default, the current, -+ non-RFC 3112 compliant, order of salt then credential will be used. This -+ default will change in Tomcat 12 to the RFC 3112 compliant order of -+ credential then salt. (markt) -+ -+ -+ -+ -+ -+ -+ Graceful failure for OCSP on BoringSSL in the FFM code. (remm) -+ -+ -+ 69866: Fix a memory leak when using a trust store with the -+ OpenSSL provider. Pull request 912 by aogburn. (markt) -+ -+ -+ Fix AJP message length check. Pull request 916 by Joshua -+ Rogers. (remm) -+ -+ -+ -+ -+ -+ -+ 69862: Avoid NPE unwrapping Servlet exception which would -+ hide some exception details. Patch submitted by Eric Blanquer. (remm) -+ -+ -+ -+ -+ -+ -+ Update the internal fork of Apache Commons BCEL to 6.11.0. (markt) -+ -+ -+ Update to Byte Buddy 1.17.8. (markt) -+ -+ -+ Update to Checkstyle 12.1.1. (markt) -+ -+ -+ Update to Jacoco 0.8.14. (markt) -+ -+ -+ Update to SpotBugs 4.9.8. (markt) -+ -+ -+ Update to JSign 7.4. (markt) -+ -+ -+ Update Maven Resolver Ant Tasks to 1.6.0. (rjung) -+ -+ -+ Improvements to French translations. (remm) -+ -+ -+ Improvements to Japanese translations provided by tak7iji. (markt) -+ -+ -+ -+ -+ -+ -+ Log warnings when the SSO configuration does not comply with the -+ documentation. (remm) -+ -+ -+ Deprecate the RemoteAddrFilter and -+ RemoteAddrValve in favour of the -+ RemoteCIDRFilter and RemoteCIDRValve. (markt) -+ -+ -+ 69837: Fix corruption of the class path generated by the -+ Loader when running on Windows. (markt) -+ -+ -+ Reject requests that map to invalid Windows file names earlier. (markt) -+ -+ -+ 69839: Ensure that changes to session IDs (typically after -+ authentication) are promulgated to the SSO Valve to ensure that SSO -+ entries are fully clean-up on session expiration. Patch provided by Kim -+ Johan Andersson. (markt) -+ -+ -+ Fix a race condition in the creation of the storage location for the -+ FileStore. (markt) -+ -+ -+ -+ -+ -+ -+ 69848: Fix copy/paste errors in 9.0.110 that meant DELETE -+ requests received via the AJP connector were processed as OPTIONS -+ requests and PROPFIND requests were processed as TRACE. (markt) -+ -+ -+ Various OCSP processing issues in the OpenSSL FFM code. (dsoumis) -+ -+ -+ -+ -+ -+ -+ 69845: When using permessage-deflate with Java -+ 25 onwards, handle the underlying Inflater and/or -+ Deflater throwing IllegalStateException -+ when closed rather than NullPointerException as they do in -+ Java 24 and earlier. (markt) -+ -+ -+ -+
-
- - - diff --git a/rhel-168081.patch b/rhel-168081.patch deleted file mode 100644 index 3781b0b..0000000 --- a/rhel-168081.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff -up ./java/org/apache/coyote/ajp/Constants.java ./java/org/apache/coyote/ajp/Constants.java ---- ./java/org/apache/coyote/ajp/Constants.java 2025-10-01 04:36:05.000000000 -0400 -+++ ./java/org/apache/coyote/ajp/Constants.java 2026-04-14 15:27:50.820988961 -0400 -@@ -105,7 +105,7 @@ - - // Translates integer codes to names of HTTP methods - private static final String[] methodTransArray = -- { Method.OPTIONS, Method.GET, Method.HEAD, Method.POST, Method.PUT, Method.OPTIONS, Method.TRACE, Method.TRACE, Method.PROPPATCH, Method.MKCOL, Method.COPY, -+ { Method.OPTIONS, Method.GET, Method.HEAD, Method.POST, Method.PUT, Method.DELETE, Method.TRACE, Method.TRACE, Method.PROPPATCH, Method.MKCOL, Method.COPY, - Method.MOVE, Method.LOCK, Method.UNLOCK, "ACL", "REPORT", "VERSION-CONTROL", "CHECKIN", "CHECKOUT", "UNCHECKOUT", - "SEARCH", "MKWORKSPACE", "UPDATE", "LABEL", "MERGE", "BASELINE-CONTROL", "MKACTIVITY" }; - -diff -up ./test/org/apache/catalina/realm/TestRealmBase.java ./test/org/apache/catalina/realm/TestRealmBase.java ---- ./test/org/apache/catalina/realm/TestRealmBase.java 2025-10-01 04:36:05.000000000 -0400 -+++ ./test/org/apache/catalina/realm/TestRealmBase.java 2026-04-14 15:27:50.821211035 -0400 -@@ -660,7 +660,7 @@ - SecurityConstraint deleteConstraint = new SecurityConstraint(); - deleteConstraint.addAuthRole(ROLE1); - SecurityCollection deleteCollection = new SecurityCollection(); -- deleteCollection.addMethod(Method.OPTIONS); -+ deleteCollection.addMethod(Method.DELETE); - deleteCollection.addPatternDecoded("/*"); - deleteConstraint.addCollection(deleteCollection); - -@@ -772,7 +772,7 @@ - - // Only user1 should be able to perform a DELETE as only that user has - // role1. -- request.setMethod(Method.OPTIONS); -+ request.setMethod(Method.DELETE); - - SecurityConstraint[] constraintsDelete = - mapRealm.findSecurityConstraints(request, context); - diff --git a/sources b/sources index 38dc472..111567c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (apache-tomcat-9.0.110-src.tar.gz) = a8fe2c59a801d6fb16ea74019c6fc58c34543d4d25a16d64e929e67c7736f6e16d08ec2061b37f1783ebfa0b1dacfff991e46ed5d24d89300a140cb94449f570 +SHA512 (apache-tomcat-9.0.117-src.tar.gz) = f40854a6ed1f208ccdd3da82527fc806eb9231aebaee86d6987e9699d1d31bb548765241424368708b89bdce01d4558a638532a35932f686d3edabd26951041d diff --git a/tomcat.spec b/tomcat.spec index 935ebe7..0252713 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -31,7 +31,7 @@ %global jspspec 2.3 %global major_version 9 %global minor_version 0 -%global micro_version 110 +%global micro_version 117 %global packdname apache-%{name}-%{major_version}.%{minor_version}.%{micro_version}-src %global servletspec 4.0 %global elspec 3.0 @@ -56,7 +56,7 @@ Name: tomcat Epoch: 1 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 4%{?dist} +Release: 1%{?dist} Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API License: ASL 2.0 @@ -81,8 +81,6 @@ Patch2: %{name}-build.patch Patch3: %{name}-%{major_version}.%{minor_version}-catalina-policy.patch Patch4: rhbz-1857043.patch Patch6: %{name}-%{major_version}.%{minor_version}-bnd-annotation.patch -Patch7: rhel-168081.patch -Patch8: rhel-150714.patch BuildArch: noarch @@ -199,8 +197,6 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch -P3 -p0 %patch -P4 -p0 %patch -P6 -p0 -%patch -P7 -p1 -%patch -P8 -p1 # Remove webservices naming resources as it's generally unused %{__rm} -rf java/org/apache/naming/factory/webservices @@ -566,8 +562,34 @@ fi %{appdir}/ROOT %changelog -* Tue Apr 20 2026 Pietro Meloni - 1:9.0.110-4 +* Wed May 26 2026 Pietro Meloni - 1:9.0.117-1 - Resolves: RHEL-150714 Certificate revocation bypass due to improper OCSP response validation +- Resolves: + Tomcat: OCSP checks sometimes soft-fail with FFM even when soft-fail is disabled (CVE-2026-34500) +- Resolves: + Tomcat: Cloud membership for clustering component exposed the Kubernetes bearer token (CVE-2026-34487) +- Resolves: + Tomcat: The fix for CVE-2026-29146 allowed the bypass of the EncryptInterceptor (CVE-2026-34486) +- Resolves: + Tomcat: Incomplete escaping of JSON access logs (CVE-2026-34483) +- Resolves: + Tomcat: The fix for CVE-2025-66614 was incomplete (CVE-2026-32990) +- Resolves: + Tomcat: EncryptInterceptor vulnerable to padding oracle attack by default (CVE-2026-29146) +- Resolves: + Tomcat: OCSP checks sometimes soft-fail even when soft-fail is disabled (CVE-2026-29145) +- Resolves: + Tomcat: Configured TLS cipher preference order not preserved (CVE-2026-29129) +- Resolves: + Tomcat: Occasionally open redirect (CVE-2026-25854) +- Resolves: + Tomcat: Request smuggling via invalid chunk extension (CVE-2026-24880) +- Resolves: + Tomcat: Incomplete OCSP verification checks (CVE-2026-24734) +- Resolves: + Tomcat: Security constraint bypass (CVE-2026-24733) +- Resolves: + Tomcat: Client certificate verification bypass due to virtual host mapping (CVE-2025-66614) * Tue Apr 14 2026 Coty Sutherland - 1:9.0.110-3 - Resolves: RHEL-168081 Fix copy/paste error in AJP connector that caused DELETE requests to be processed as OPTIONS requests (BZ#69848)