This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new cd9ec89d5c Review "Fix TLS 1.3 cipher suite configuration"
cd9ec89d5c is described below
commit cd9ec89d5c3c211c1f453cbf5fa28dda0ed36297
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Nov 3 21:11:46 2026 +0000
Review "Fix TLS 1.3 cipher suite configuration"
Make null reset the ciphers to the defaults.
---
java/org/apache/tomcat/util/net/SSLHostConfig.java | 43 +++++++++---------
.../apache/tomcat/util/net/TestSSLHostConfig.java | 51 +++++++++++++++++++++-
2 files changed, 70 insertions(+), 24 deletions(-)
diff --git a/java/org/apache/tomcat/util/net/SSLHostConfig.java
b/java/org/apache/tomcat/util/net/SSLHostConfig.java
index a8c1371258..2b16861c07 100644
--- a/java/org/apache/tomcat/util/net/SSLHostConfig.java
+++ b/java/org/apache/tomcat/util/net/SSLHostConfig.java
@@ -177,11 +177,11 @@ public class SSLHostConfig implements Serializable {
/**
* The cipher configuration for TLS 1.2 and below (OpenSSL format).
*/
- private String ciphers = DEFAULT_TLS_CIPHERS_12;
+ private String ciphers = null;
/**
* The cipher suite configuration for TLS 1.3.
*/
- private String cipherSuites = DEFAULT_TLS_CIPHERS_13;
+ private String cipherSuites = null;
private String cipherSuitesFromCiphers = null;
/**
* The parsed cipher list for TLS 1.2 and below.
@@ -785,16 +785,17 @@ public class SSLHostConfig implements Serializable {
* Set the new cipher (TLSv1.2 and below) configuration. Note: Regardless
of the format used to set the
* configuration, it is always stored in OpenSSL format.
*
- * @param ciphersList The new cipher configuration in OpenSSL or JSSE
format
+ * @param ciphersList The new cipher configuration in OpenSSL or JSSE
format. A value of {@code null} restores the
+ * default, {@link #DEFAULT_TLS_CIPHERS_12}.
*/
public void setCiphers(String ciphersList) {
// Ciphers is stored in OpenSSL format. Convert the provided value if
// necessary.
if (ciphersList != null) {
+ StringBuilder sbCiphers = new StringBuilder();
+ StringBuilder sbCipherSuitesFromCiphers = new StringBuilder();
if (ciphersList.contains(":")) {
// OpenSSL format
- StringBuilder sbCiphers = new StringBuilder();
- StringBuilder sbCipherSuitesFromCiphers = new StringBuilder();
String[] components = ciphersList.split(":");
// Remove any TLS 1.3 cipher suites
for (String component : components) {
@@ -812,13 +813,9 @@ public class SSLHostConfig implements Serializable {
sbCiphers.append(trimmed);
}
}
- this.ciphers = sbCiphers.toString();
- this.cipherSuitesFromCiphers =
sbCipherSuitesFromCiphers.toString();
} else {
// Not obviously in OpenSSL format. Might be a single OpenSSL
or JSSE
// cipher name. Might be a comma separated list of cipher names
- StringBuilder sbCiphers = new StringBuilder();
- StringBuilder sbCipherSuitesFromCiphers = new StringBuilder();
String[] ciphers = ciphersList.split(",");
for (String cipher : ciphers) {
String trimmed = JreCompat.getInstance().strip(cipher);
@@ -842,9 +839,9 @@ public class SSLHostConfig implements Serializable {
}
}
}
- this.ciphers = sbCiphers.toString();
- this.cipherSuitesFromCiphers =
sbCipherSuitesFromCiphers.toString();
}
+ this.ciphers = sbCiphers.toString();
+ this.cipherSuitesFromCiphers =
sbCipherSuitesFromCiphers.toString();
} else {
this.ciphers = null;
this.cipherSuitesFromCiphers = null;
@@ -858,9 +855,13 @@ public class SSLHostConfig implements Serializable {
/**
* Returns the cipher (TLSv1.2 and below) configuration.
*
- * @return An OpenSSL cipher string for the current configuration.
+ * @return An OpenSSL cipher string for the current configuration. If no
configuration has been set, or it was set
+ * to {@code null}, this is {@link #DEFAULT_TLS_CIPHERS_12}.
*/
public String getCiphers() {
+ if (ciphers == null) {
+ return DEFAULT_TLS_CIPHERS_12;
+ }
return ciphers;
}
@@ -899,11 +900,13 @@ public class SSLHostConfig implements Serializable {
* Set the cipher suite (TLSv1.3) configuration. Note: Regardless of the
format used to set the configuration, it is
* always stored in OpenSSL format.
*
- * @param cipherSuites The cipher suites to use in a colon-separated,
preference order list
+ * @param cipherSuites The cipher suites to use in a preference order
list. The list may be colon-separated
+ * (OpenSSL format) or comma-separated (JSSE
format). A value of {@code null} restores the
+ * default, {@link #DEFAULT_TLS_CIPHERS_13}.
*/
public void setCipherSuites(String cipherSuites) {
if (cipherSuites == null) {
- // As for setCiphers(), a null value is stored as provided.
+ // As for setCiphers(), a null value restores the default.
this.cipherSuites = null;
this.cipherSuiteList = null;
this.jsseCipherNames = null;
@@ -952,17 +955,13 @@ public class SSLHostConfig implements Serializable {
/**
* Obtain the current cipher suite (TLSv1.3) configuration.
*
- * @return An OpenSSL cipher suite string for the current configuration
- * or {@code null} if no cipher suites have been configured.
+ * @return An OpenSSL cipher suite string for the current configuration.
If no configuration has been set, or it
+ * was set to {@code null}, this is {@link
#DEFAULT_TLS_CIPHERS_13}.
*/
public String getCipherSuites() {
- if (cipherSuites == null && cipherSuitesFromCiphers == null) {
- return null;
- }
StringBuilder sb = new StringBuilder();
- if (cipherSuites != null) {
- sb.append(cipherSuites);
- }
+ // The default applies unless cipher suites have been configured
explicitly
+ sb.append(cipherSuites != null ? cipherSuites :
DEFAULT_TLS_CIPHERS_13);
if (cipherSuitesFromCiphers != null &&
!cipherSuitesFromCiphers.isEmpty()) {
if (sb.length() > 0) {
sb.append(':');
diff --git a/test/org/apache/tomcat/util/net/TestSSLHostConfig.java
b/test/org/apache/tomcat/util/net/TestSSLHostConfig.java
index 9a9941d9b7..f492a42e28 100644
--- a/test/org/apache/tomcat/util/net/TestSSLHostConfig.java
+++ b/test/org/apache/tomcat/util/net/TestSSLHostConfig.java
@@ -186,9 +186,56 @@ public class TestSSLHostConfig {
public void testCiphersuite05() {
SSLHostConfig hc = new SSLHostConfig();
- // Null should be handled without an error, as it is for setCiphers()
+ // Null restores the default, as it does for setCiphers()
+ hc.setCipherSuites(Cipher.TLS_AES_128_CCM_SHA256.getOpenSSLAlias());
hc.setCipherSuites(null);
- Assert.assertNull(hc.getCipherSuites());
+ Assert.assertEquals(SSLHostConfig.DEFAULT_TLS_CIPHERS_13,
hc.getCipherSuites());
+ // and the derived values must be usable
+ Assert.assertFalse(hc.getJsseCipherNames().isEmpty());
+ }
+
+
+ @Test
+ public void testCiphersWithoutTls13KeepDefaultCipherSuites() {
+ // Setting ciphers that do not include any TLS 1.3 cipher suites must
not remove the default TLS 1.3 cipher
+ // suites, whatever the format of the ciphers list
+ String[] ciphersLists = {
Cipher.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.getOpenSSLAlias(),
+ Cipher.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.getOpenSSLAlias()
+ ":" +
+
Cipher.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384.getOpenSSLAlias(),
+ Cipher.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.getOpenSSLAlias()
+ "," +
+
Cipher.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384.getOpenSSLAlias(),
+ "" };
+
+ for (String ciphersList : ciphersLists) {
+ SSLHostConfig hc = new SSLHostConfig();
+ hc.setCiphers(ciphersList);
+ Assert.assertEquals(ciphersList,
SSLHostConfig.DEFAULT_TLS_CIPHERS_13, hc.getCipherSuites());
+ }
+ }
+
+
+ @Test
+ public void testCiphersWithoutTls13KeepJsseCipherSuites() {
+ SSLHostConfig hc = new SSLHostConfig();
+
+ // A single TLS 1.2 cipher, which is not in OpenSSL (colon separated)
format
+
hc.setCiphers(Cipher.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.getOpenSSLAlias());
+ String tls13Name =
Cipher.TLS_AES_256_GCM_SHA384.getJsseNames().iterator().next();
+ Assert.assertTrue(hc.getJsseCipherNames().contains(tls13Name));
+ }
+
+
+ @Test
+ public void testCiphersNull() {
+ SSLHostConfig hc = new SSLHostConfig();
+
+ // Null restores the default
+
hc.setCiphers(Cipher.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.getOpenSSLAlias());
+ hc.setCiphers(null);
+ Assert.assertEquals(SSLHostConfig.DEFAULT_TLS_CIPHERS_12,
hc.getCiphers());
+ // and the derived values must be usable
+ Assert.assertFalse(hc.getCipherList().isEmpty());
+ Assert.assertFalse(hc.getJsseCipherNames().isEmpty());
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]