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

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


The following commit(s) were added to refs/heads/10.1.x by this push:
     new e4c1afe550 Review "Do not store the runtime-derived OpenSSLConfCmd 
groups..."
e4c1afe550 is described below

commit e4c1afe550cadbe7540f1427ea47de24128a3446
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Oct 21 08:22:53 2026 +0100

    Review "Do not store the runtime-derived OpenSSLConfCmd groups..."
    
    More than one groups command means they must all be user specified
    
    Co-authored by: CoPilot / GPT-5.6 Sol
---
 .../catalina/storeconfig/SSLHostConfigSF.java      | 25 +++++++++++++---------
 .../catalina/storeconfig/TestStoreConfig.java      | 14 ++++++++++++
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/java/org/apache/catalina/storeconfig/SSLHostConfigSF.java 
b/java/org/apache/catalina/storeconfig/SSLHostConfigSF.java
index f672ccb70a..c5bf93a444 100644
--- a/java/org/apache/catalina/storeconfig/SSLHostConfigSF.java
+++ b/java/org/apache/catalina/storeconfig/SSLHostConfigSF.java
@@ -109,28 +109,33 @@ public class SSLHostConfigSF extends StoreFactoryBase {
 
     /*
      * When the SSL context is created, the OpenSSL implementation adds a 
runtime "groups" command derived from the
-     * SSLHostConfig "groups" attribute. Store a copy of the configuration 
without such a command, since it duplicates
-     * the attribute and a stored command would shadow later changes of the 
attribute. A command whose value differs
-     * from the derived one was written by the user and is kept.
+     * SSLHostConfig "groups" attribute if no other groups command has been 
specified. Store a copy of the configuration
+     * without such a command, since it duplicates the attribute and a stored 
command would shadow later changes of the
+     * attribute. A command whose value differs from the derived one was 
written by the user and is kept.
      */
     private OpenSSLConf removeRuntimeCommands(OpenSSLConf openSslConf, 
SSLHostConfig sslHostConfig) {
         if (openSslConf == null || sslHostConfig.getGroups() == null) {
             return openSslConf;
         }
         String derivedValue = sslHostConfig.getGroups().replace(',', ':');
-        ArrayList<OpenSSLConfCmd> retainedCommands = new ArrayList<>();
+        OpenSSLConfCmd runtimeCommand = null;
+        int groupCommandCount = 0;
         for (OpenSSLConfCmd command : openSslConf.getCommands()) {
-            if (OpenSSLConfCmd.GROUPS.equals(command.getName()) && 
derivedValue.equals(command.getValue())) {
-                continue;
+            if (OpenSSLConfCmd.GROUPS.equals(command.getName())) {
+                groupCommandCount++;
+                if (derivedValue.equals(command.getValue())) {
+                    runtimeCommand = command;
+                }
             }
-            retainedCommands.add(command);
         }
-        if (retainedCommands.size() == openSslConf.getCommands().size()) {
+        if (groupCommandCount != 1 || runtimeCommand == null) {
             return openSslConf;
         }
         OpenSSLConf filteredCommands = new OpenSSLConf();
-        for (OpenSSLConfCmd command : retainedCommands) {
-            filteredCommands.addCmd(command);
+        for (OpenSSLConfCmd command : openSslConf.getCommands()) {
+            if (command != runtimeCommand) {
+                filteredCommands.addCmd(command);
+            }
         }
         return filteredCommands;
     }
diff --git a/test/org/apache/catalina/storeconfig/TestStoreConfig.java 
b/test/org/apache/catalina/storeconfig/TestStoreConfig.java
index 0420d4e0e9..d48b4a79b2 100644
--- a/test/org/apache/catalina/storeconfig/TestStoreConfig.java
+++ b/test/org/apache/catalina/storeconfig/TestStoreConfig.java
@@ -605,6 +605,20 @@ public class TestStoreConfig extends TomcatBaseTest {
         Assert.assertTrue(dump, dump.contains("name=\"groups\""));
         Assert.assertTrue(dump, dump.contains("value=\"X25519\""));
 
+        // When multiple groups commands are present, all are user-written 
because the runtime only adds its derived
+        // command when no groups command is configured. Keep every command, 
including one that matches the attribute.
+        SSLHostConfig multipleCommands = new SSLHostConfig();
+        multipleCommands.setGroups("secp256r1,secp384r1");
+        multipleCommands.setOpenSslConf(new OpenSSLConf());
+        multipleCommands.getOpenSslConf().addCmd(new 
OpenSSLConfCmd(OpenSSLConfCmd.GROUPS, "X25519"));
+        multipleCommands.getOpenSslConf()
+                .addCmd(new OpenSSLConfCmd(OpenSSLConfCmd.GROUPS, 
"secp256r1:secp384r1"));
+        dump = storeToString(desc, multipleCommands);
+        int firstCommand = dump.indexOf("value=\"X25519\"");
+        int secondCommand = dump.indexOf("value=\"secp256r1:secp384r1\"");
+        Assert.assertTrue(dump, firstCommand != -1);
+        Assert.assertTrue(dump, secondCommand > firstCommand);
+
         // Without the attribute, a groups command can only be user-written 
and must be kept
         SSLHostConfig noAttribute = new SSLHostConfig();
         noAttribute.setGroups(null);


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

Reply via email to