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

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

commit f1a29de7da3dd0d9053038e97cb151b000ac1887
Author: remm <[email protected]>
AuthorDate: Thu Sep 11 11:58:00 2025 +0200

    Rename SignatureAlgorithm enum to SignatureScheme
    
    From https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
    Although many use SignatureAlgorithm for this, this one is supposed to
    be quite like our Authentication enum (which I am not renaming).
    Allow specifying a certificate for ED(25519 and 448) since apparently it
    is different from ECDSA, it replaces DSA.
    Make MLKEM groups uppercase.
---
 .../tomcat/util/net/AbstractJsseEndpoint.java      | 15 +++---
 .../tomcat/util/net/SSLHostConfigCertificate.java  |  8 +--
 .../apache/tomcat/util/net/SecureNioChannel.java   | 10 ++--
 .../tomcat/util/net/TLSClientHelloExtractor.java   | 20 ++++----
 .../util/net/openssl/ciphers/Authentication.java   |  1 +
 .../tomcat/util/net/openssl/ciphers/Group.java     |  6 +--
 ...ignatureAlgorithm.java => SignatureScheme.java} | 57 +++++++++++++---------
 7 files changed, 64 insertions(+), 53 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java 
b/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
index 9b1690edc8..874da515fb 100644
--- a/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
@@ -32,13 +32,14 @@ import org.apache.tomcat.util.compat.JreCompat;
 import org.apache.tomcat.util.net.openssl.OpenSSLStatus;
 import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
 import org.apache.tomcat.util.net.openssl.ciphers.Group;
-import org.apache.tomcat.util.net.openssl.ciphers.SignatureAlgorithm;
+import org.apache.tomcat.util.net.openssl.ciphers.SignatureScheme;
 
 public abstract class AbstractJsseEndpoint<S, U> extends AbstractEndpoint<S,U> 
{
 
+    // Thread local use to pass additional arguments to createSSLEngine 
without changing the protected method signature
     static final ThreadLocal<List<String>> clientRequestedProtocolsThreadLocal 
= new ThreadLocal<>();
     static final ThreadLocal<List<Group>> clientSupportedGroupsThreadLocal = 
new ThreadLocal<>();
-    static final ThreadLocal<List<SignatureAlgorithm>> 
clientSignatureAlgorithmsThreadLocal = new ThreadLocal<>();
+    static final ThreadLocal<List<SignatureScheme>> 
clientSignatureSchemesThreadLocal = new ThreadLocal<>();
 
     private String sslImplementationName = null;
     private int sniParseLimit = 64 * 1024;
@@ -128,12 +129,12 @@ public abstract class AbstractJsseEndpoint<S, U> extends 
AbstractEndpoint<S,U> {
             List<String> clientRequestedApplicationProtocols) {
         List<String> clientRequestedProtocols = 
clientRequestedProtocolsThreadLocal.get();
         List<Group> clientSupportedGroups = 
clientSupportedGroupsThreadLocal.get();
-        List<SignatureAlgorithm> clientSignatureAlgorithms = 
clientSignatureAlgorithmsThreadLocal.get();
+        List<SignatureScheme> clientSignatureSchemes = 
clientSignatureSchemesThreadLocal.get();
 
         SSLHostConfig sslHostConfig = getSSLHostConfig(sniHostName);
 
         SSLHostConfigCertificate certificate = 
selectCertificate(sslHostConfig, clientRequestedCiphers,
-                clientRequestedProtocols, clientSignatureAlgorithms);
+                clientRequestedProtocols, clientSignatureSchemes);
 
         SSLContext sslContext = certificate.getSslContext();
         if (sslContext == null) {
@@ -197,7 +198,7 @@ public abstract class AbstractJsseEndpoint<S, U> extends 
AbstractEndpoint<S,U> {
 
 
     private SSLHostConfigCertificate selectCertificate(SSLHostConfig 
sslHostConfig, List<Cipher> clientCiphers,
-            List<String> clientRequestedProtocols, List<SignatureAlgorithm> 
clientSignatureAlgorithms) {
+            List<String> clientRequestedProtocols, List<SignatureScheme> 
clientSignatureSchemes) {
 
         Set<SSLHostConfigCertificate> certificates = 
sslHostConfig.getCertificates(true);
         if (certificates.size() == 1) {
@@ -207,9 +208,9 @@ public abstract class AbstractJsseEndpoint<S, U> extends 
AbstractEndpoint<S,U> {
         // Use signature algorithm for cipher matching with TLS 1.3
         if ((clientRequestedProtocols.contains(Constants.SSL_PROTO_TLSv1_3)) &&
                 
sslHostConfig.getProtocols().contains(Constants.SSL_PROTO_TLSv1_3)) {
-            for (SignatureAlgorithm signatureAlgorithm : 
clientSignatureAlgorithms) {
+            for (SignatureScheme signatureScheme : clientSignatureSchemes) {
                 for (SSLHostConfigCertificate certificate : certificates) {
-                    if 
(certificate.getType().isCompatibleWith(signatureAlgorithm)) {
+                    if 
(certificate.getType().isCompatibleWith(signatureScheme)) {
                         return certificate;
                     }
                 }
diff --git a/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java 
b/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
index b7606dd89b..f41fa2d017 100644
--- a/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
+++ b/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
@@ -30,7 +30,7 @@ import javax.net.ssl.X509KeyManager;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.net.openssl.ciphers.Authentication;
-import org.apache.tomcat.util.net.openssl.ciphers.SignatureAlgorithm;
+import org.apache.tomcat.util.net.openssl.ciphers.SignatureScheme;
 import org.apache.tomcat.util.res.StringManager;
 
 public class SSLHostConfigCertificate implements Serializable {
@@ -317,7 +317,7 @@ public class SSLHostConfigCertificate implements 
Serializable {
 
         UNDEFINED,
         RSA(Authentication.RSA),
-        DSA(Authentication.DSS),
+        DSA(Authentication.DSS, Authentication.EdDSA),
         EC(Authentication.ECDH, Authentication.ECDSA),
         MLDSA(Authentication.MLDSA);
 
@@ -334,8 +334,8 @@ public class SSLHostConfigCertificate implements 
Serializable {
             return compatibleAuthentications.contains(au);
         }
 
-        public boolean isCompatibleWith(SignatureAlgorithm al) {
-            return al.toString().toUpperCase().startsWith(toString());
+        public boolean isCompatibleWith(SignatureScheme scheme) {
+            return compatibleAuthentications.contains(scheme.getAuth());
         }
 
     }
diff --git a/java/org/apache/tomcat/util/net/SecureNioChannel.java 
b/java/org/apache/tomcat/util/net/SecureNioChannel.java
index 184216e2aa..92c4da0907 100644
--- a/java/org/apache/tomcat/util/net/SecureNioChannel.java
+++ b/java/org/apache/tomcat/util/net/SecureNioChannel.java
@@ -43,7 +43,7 @@ import 
org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper;
 import org.apache.tomcat.util.net.TLSClientHelloExtractor.ExtractorResult;
 import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
 import org.apache.tomcat.util.net.openssl.ciphers.Group;
-import org.apache.tomcat.util.net.openssl.ciphers.SignatureAlgorithm;
+import org.apache.tomcat.util.net.openssl.ciphers.SignatureScheme;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -277,7 +277,7 @@ public class SecureNioChannel extends NioChannel {
         List<Cipher> clientRequestedCiphers = null;
         List<String> clientRequestedApplicationProtocols = null;
         List<Group> clientSupportedGroups = null;
-        List<SignatureAlgorithm> clientSignatureAlgorithms = null;
+        List<SignatureScheme> clientSignatureSchemes = null;
         switch (extractor.getResult()) {
             case COMPLETE:
                 hostName = extractor.getSNIValue();
@@ -286,7 +286,7 @@ public class SecureNioChannel extends NioChannel {
             case NOT_PRESENT:
                 clientRequestedCiphers = extractor.getClientRequestedCiphers();
                 clientSupportedGroups = extractor.getClientSupportedGroups();
-                clientSignatureAlgorithms = 
extractor.getClientSignatureAlgorithms();
+                clientSignatureSchemes = extractor.getClientSignatureSchemes();
                 break;
             case NEED_READ:
                 return SelectionKey.OP_READ;
@@ -313,12 +313,12 @@ public class SecureNioChannel extends NioChannel {
         try {
             
AbstractJsseEndpoint.clientRequestedProtocolsThreadLocal.set(extractor.getClientRequestedProtocols());
             
AbstractJsseEndpoint.clientSupportedGroupsThreadLocal.set(clientSupportedGroups);
-            
AbstractJsseEndpoint.clientSignatureAlgorithmsThreadLocal.set(clientSignatureAlgorithms);
+            
AbstractJsseEndpoint.clientSignatureSchemesThreadLocal.set(clientSignatureSchemes);
             sslEngine = endpoint.createSSLEngine(hostName, 
clientRequestedCiphers, clientRequestedApplicationProtocols);
         } finally {
             AbstractJsseEndpoint.clientRequestedProtocolsThreadLocal.set(null);
             AbstractJsseEndpoint.clientSupportedGroupsThreadLocal.set(null);
-            
AbstractJsseEndpoint.clientSignatureAlgorithmsThreadLocal.set(null);
+            AbstractJsseEndpoint.clientSignatureSchemesThreadLocal.set(null);
         }
 
         // Populate additional TLS attributes obtained from the handshake that
diff --git a/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java 
b/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java
index ed153c87da..0f26b2799d 100644
--- a/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java
+++ b/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java
@@ -30,7 +30,7 @@ import org.apache.tomcat.util.buf.HexUtils;
 import org.apache.tomcat.util.http.parser.HttpParser;
 import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
 import org.apache.tomcat.util.net.openssl.ciphers.Group;
-import org.apache.tomcat.util.net.openssl.ciphers.SignatureAlgorithm;
+import org.apache.tomcat.util.net.openssl.ciphers.SignatureScheme;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -48,7 +48,7 @@ public class TLSClientHelloExtractor {
     private final List<String> clientRequestedApplicationProtocols;
     private final List<String> clientRequestedProtocols;
     private final List<Group> clientSupportedGroups;
-    private final List<SignatureAlgorithm> clientSignatureAlgorithms;
+    private final List<SignatureScheme> clientSignatureSchemes;
 
     private static final int TLS_RECORD_HEADER_LEN = 5;
 
@@ -84,7 +84,7 @@ public class TLSClientHelloExtractor {
         List<String> clientRequestedApplicationProtocols = new ArrayList<>();
         List<String> clientRequestedProtocols = new ArrayList<>();
         List<Group> clientSupportedGroups = new ArrayList<>();
-        List<SignatureAlgorithm> clientSignatureAlgorithms = new ArrayList<>();
+        List<SignatureScheme> clientSignatureSchemes = new ArrayList<>();
         String sniValue = null;
         try {
             // Switch to read mode.
@@ -170,7 +170,7 @@ public class TLSClientHelloExtractor {
                         readSupportedGroups(netInBuffer, 
clientSupportedGroups);
                         break;
                     case TLS_EXTENSION_SIGNATURE_ALGORITHMS:
-                        readSignatureAlgorithms(netInBuffer, 
clientSignatureAlgorithms);
+                        readSignatureAlgorithms(netInBuffer, 
clientSignatureSchemes);
                         break;
                     case TLS_EXTENSION_ALPN:
                         readAlpnExtension(netInBuffer, 
clientRequestedApplicationProtocols);
@@ -197,12 +197,12 @@ public class TLSClientHelloExtractor {
             this.sniValue = sniValue;
             this.clientRequestedProtocols = clientRequestedProtocols;
             this.clientSupportedGroups = clientSupportedGroups;
-            this.clientSignatureAlgorithms = clientSignatureAlgorithms;
+            this.clientSignatureSchemes = clientSignatureSchemes;
             if (log.isTraceEnabled()) {
                 log.trace("TLS Client Hello: " + clientRequestedCiphers + " 
Names " + clientRequestedCipherNames +
                         " Protocols " + clientRequestedApplicationProtocols + 
" sniValue " + sniValue +
                         " clientRequestedProtocols " + 
clientRequestedProtocols + " clientSupportedGroups " + clientSupportedGroups +
-                        " clientSignatureAlgorithms " + 
clientSignatureAlgorithms);
+                        " clientSignatureSchemes " + clientSignatureSchemes);
             }
             // Whatever happens, return the buffer to its original state
             netInBuffer.limit(limit);
@@ -273,9 +273,9 @@ public class TLSClientHelloExtractor {
     }
 
 
-    public List<SignatureAlgorithm> getClientSignatureAlgorithms() {
+    public List<SignatureScheme> getClientSignatureSchemes() {
         if (result == ExtractorResult.COMPLETE || result == 
ExtractorResult.NOT_PRESENT) {
-            return clientSignatureAlgorithms;
+            return clientSignatureSchemes;
         } else {
             throw new 
IllegalStateException(sm.getString("sniExtractor.tooEarly"));
         }
@@ -478,13 +478,13 @@ public class TLSClientHelloExtractor {
     }
 
 
-    private static void readSignatureAlgorithms(ByteBuffer bb, 
List<SignatureAlgorithm> signatureAlgorithms) {
+    private static void readSignatureAlgorithms(ByteBuffer bb, 
List<SignatureScheme> signatureAlgorithms) {
         // First 2 bytes are size of the signature algorithm list
         int toRead = bb.getChar() / 2;
         // Then the list of protocols
         for (int i = 0; i < toRead; i++) {
             char id = bb.getChar();
-            SignatureAlgorithm signatureAlgorithm = 
SignatureAlgorithm.valueOf(id);
+            SignatureScheme signatureAlgorithm = SignatureScheme.valueOf(id);
             if (signatureAlgorithm != null) {
                 signatureAlgorithms.add(signatureAlgorithm);
             }
diff --git 
a/java/org/apache/tomcat/util/net/openssl/ciphers/Authentication.java 
b/java/org/apache/tomcat/util/net/openssl/ciphers/Authentication.java
index 052808a36b..91a859000d 100644
--- a/java/org/apache/tomcat/util/net/openssl/ciphers/Authentication.java
+++ b/java/org/apache/tomcat/util/net/openssl/ciphers/Authentication.java
@@ -29,6 +29,7 @@ public enum Authentication {
     GOST01 /* GOST R 34.10-2001 */,
     FZA /* Fortezza */,
     SRP /* Secure Remote Password */,
+    EdDSA /* EdDSA */,
     MLDSA /* ML-DSA */,
     ANY /* TLS 1.3 */
 }
diff --git a/java/org/apache/tomcat/util/net/openssl/ciphers/Group.java 
b/java/org/apache/tomcat/util/net/openssl/ciphers/Group.java
index 801fe80095..a85f757be7 100644
--- a/java/org/apache/tomcat/util/net/openssl/ciphers/Group.java
+++ b/java/org/apache/tomcat/util/net/openssl/ciphers/Group.java
@@ -36,9 +36,9 @@ public enum Group {
     ffdhe8192(0x0104),
 
     // Post-Quantum Key Exchange
-    mlkem512(0x0200),
-    mlkem768(0x0201),
-    mlkem1024(0x0202),
+    MLKEM512(0x0200),
+    MLKEM768(0x0201),
+    MLKEM1024(0x0202),
 
     // Hybrid Key Exchange
     SecP256r1MLKEM768(0x11EB),
diff --git 
a/java/org/apache/tomcat/util/net/openssl/ciphers/SignatureAlgorithm.java 
b/java/org/apache/tomcat/util/net/openssl/ciphers/SignatureScheme.java
similarity index 53%
rename from 
java/org/apache/tomcat/util/net/openssl/ciphers/SignatureAlgorithm.java
rename to java/org/apache/tomcat/util/net/openssl/ciphers/SignatureScheme.java
index 7b2f94f3f6..d5df3f72fa 100644
--- a/java/org/apache/tomcat/util/net/openssl/ciphers/SignatureAlgorithm.java
+++ b/java/org/apache/tomcat/util/net/openssl/ciphers/SignatureScheme.java
@@ -19,45 +19,47 @@ package org.apache.tomcat.util.net.openssl.ciphers;
 import java.util.HashMap;
 import java.util.Map;
 
-public enum SignatureAlgorithm {
+public enum SignatureScheme {
 
     // RSASSA-PKCS1-v1_5 algorithms
-    rsa_pkcs1_sha256(0x0401),
-    rsa_pkcs1_sha384(0x0501),
-    rsa_pkcs1_sha512(0x0601),
+    rsa_pkcs1_sha256(0x0401, Authentication.RSA),
+    rsa_pkcs1_sha384(0x0501, Authentication.RSA),
+    rsa_pkcs1_sha512(0x0601, Authentication.RSA),
 
     // ECDSA algorithms
-    ecdsa_secp256r1_sha256(0x0403),
-    ecdsa_secp384r1_sha384(0x0503),
-    ecdsa_secp521r1_sha512(0x0603),
+    ecdsa_secp256r1_sha256(0x0403, Authentication.ECDSA),
+    ecdsa_secp384r1_sha384(0x0503, Authentication.ECDSA),
+    ecdsa_secp521r1_sha512(0x0603, Authentication.ECDSA),
 
     // RSASSA-PSS algorithms with public key OID rsaEncryption
-    rsa_pss_rsae_sha256(0x0804),
-    rsa_pss_rsae_sha384(0x0805),
-    rsa_pss_rsae_sha512(0x0806),
+    rsa_pss_rsae_sha256(0x0804, Authentication.RSA),
+    rsa_pss_rsae_sha384(0x0805, Authentication.RSA),
+    rsa_pss_rsae_sha512(0x0806, Authentication.RSA),
 
     // EdDSA algorithms
-    ed25519(0x0807),
-    ed448(0x0808),
+    ed25519(0x0807, Authentication.EdDSA),
+    ed448(0x0808, Authentication.EdDSA),
 
     // RSASSA-PSS algorithms with public key OID RSASSA-PSS
-    rsa_pss_pss_sha256(0x0809),
-    rsa_pss_pss_sha384(0x080a),
-    rsa_pss_pss_sha512(0x080b),
+    rsa_pss_pss_sha256(0x0809, Authentication.RSA),
+    rsa_pss_pss_sha384(0x080a, Authentication.RSA),
+    rsa_pss_pss_sha512(0x080b, Authentication.RSA),
 
     // Legacy algorithms
-    rsa_pkcs1_sha1(0x0201),
-    ecdsa_sha1(0x0203),
+    rsa_pkcs1_sha1(0x0201, Authentication.RSA),
+    ecdsa_sha1(0x0203, Authentication.ECDSA),
 
     // ML-DSA algorithms
-    mldsa44(0x0904),
-    mldsa65(0x0905),
-    mldsa87(0x0906);
+    mldsa44(0x0904, Authentication.MLDSA),
+    mldsa65(0x0905, Authentication.MLDSA),
+    mldsa87(0x0906, Authentication.MLDSA);
 
     private final int id;
+    private final Authentication auth;
 
-    SignatureAlgorithm(int id) {
+    SignatureScheme(int id, Authentication auth) {
         this.id = id;
+        this.auth = auth;
     }
 
     /**
@@ -67,10 +69,17 @@ public enum SignatureAlgorithm {
         return this.id;
     }
 
-    private static final Map<Integer,SignatureAlgorithm> idMap = new 
HashMap<>();
+    /**
+     * @return the auth
+     */
+    public Authentication getAuth() {
+        return this.auth;
+    }
+
+    private static final Map<Integer,SignatureScheme> idMap = new HashMap<>();
 
     static {
-        for (SignatureAlgorithm group : values()) {
+        for (SignatureScheme group : values()) {
             int id = group.getId();
 
             if (id > 0 && id < 0xFFFF) {
@@ -80,7 +89,7 @@ public enum SignatureAlgorithm {
     }
 
 
-    public static SignatureAlgorithm valueOf(int groupId) {
+    public static SignatureScheme valueOf(int groupId) {
         return idMap.get(Integer.valueOf(groupId));
     }
 }


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

Reply via email to