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

coheigea pushed a commit to branch 4.0.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 7b86cb77e17c91fd3f5996a16561e2f6e0b60f6b
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Tue Sep 8 12:09:49 2026 +0100

    Fix STS secret-key sizing (#3453)
---
 ...SecureConversationTokenInterceptorProvider.java |  7 +++--
 .../cxf/sts/operation/AbstractOperation.java       |  3 +-
 .../sts/token/provider/DefaultSubjectProvider.java |  8 +++--
 .../cxf/sts/token/provider/TokenProviderUtils.java | 36 ++++++++++++++++++++++
 4 files changed, 48 insertions(+), 6 deletions(-)

diff --git 
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
 
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
index fa354d35f58..0615b530841 100755
--- 
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
+++ 
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/policy/interceptors/SecureConversationTokenInterceptorProvider.java
@@ -41,6 +41,7 @@ import org.apache.wss4j.policy.SPConstants;
 import org.apache.wss4j.policy.model.AlgorithmSuite;
 import org.apache.wss4j.policy.model.SecureConversationToken;
 import org.apache.wss4j.policy.model.SupportingTokens;
+import org.apache.xml.security.algorithms.JCEMapper;
 
 /**
  *
@@ -104,8 +105,10 @@ public class SecureConversationTokenInterceptorProvider 
extends AbstractPolicyIn
         AlgorithmSuite suite = NegotiationUtils.getAlgorithmSuite(aim);
         if (suite != null) {
             client.setAlgorithmSuite(suite);
-            int x = 
suite.getAlgorithmSuiteType().getMaximumSymmetricKeyLength();
-            if (x < 256) {
+            // The secret must have exactly the length required by the 
encryption algorithm of the suite
+            int x = 
JCEMapper.getKeyLengthFromURI(suite.getAlgorithmSuiteType().getEncryption());
+            if (x >= 
suite.getAlgorithmSuiteType().getMinimumSymmetricKeyLength()
+                && x <= 
suite.getAlgorithmSuiteType().getMaximumSymmetricKeyLength()) {
                 client.setKeySize(x);
             }
         }
diff --git 
a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
 
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
index ef05d5fd67a..ac8c2db75bf 100644
--- 
a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
+++ 
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java
@@ -61,6 +61,7 @@ import 
org.apache.cxf.sts.token.delegation.TokenDelegationParameters;
 import org.apache.cxf.sts.token.delegation.TokenDelegationResponse;
 import org.apache.cxf.sts.token.provider.TokenProvider;
 import org.apache.cxf.sts.token.provider.TokenProviderParameters;
+import org.apache.cxf.sts.token.provider.TokenProviderUtils;
 import org.apache.cxf.sts.token.provider.TokenReference;
 import org.apache.cxf.sts.token.realm.Relationship;
 import org.apache.cxf.sts.token.realm.RelationshipResolver;
@@ -382,7 +383,7 @@ public abstract class AbstractOperation {
 
         final SecretKey symmetricKey;
         if (secret != null) {
-            symmetricKey = 
KeyUtils.prepareSecretKey(encryptionProperties.getEncryptionAlgorithm(), 
secret);
+            symmetricKey = TokenProviderUtils.createSecretKey(secret, 
keyRequirements, encryptionProperties);
         } else {
             KeyGenerator keyGen = 
KeyUtils.getKeyGenerator(encryptionProperties.getEncryptionAlgorithm());
             symmetricKey = keyGen.generateKey();
diff --git 
a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
 
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
index de7ae784e31..19339ed139e 100644
--- 
a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
+++ 
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultSubjectProvider.java
@@ -266,7 +266,8 @@ public class DefaultSubjectProvider implements 
SubjectProvider {
                 }
                 Document doc = subjectProviderParameters.getDoc();
                 byte[] secret = subjectProviderParameters.getSecret();
-                return createEncryptedKeyKeyInfo(certs[0], secret, doc, 
encryptionProperties, crypto);
+                return createEncryptedKeyKeyInfo(certs[0], secret, doc, 
encryptionProperties, crypto,
+                                                 keyRequirements);
             } catch (WSSecurityException ex) {
                 LOG.log(Level.WARNING, "", ex);
                 throw new STSException(ex.getMessage(), ex);
@@ -327,7 +328,8 @@ public class DefaultSubjectProvider implements 
SubjectProvider {
         byte[] secret,
         Document doc,
         EncryptionProperties encryptionProperties,
-        Crypto encryptionCrypto
+        Crypto encryptionCrypto,
+        KeyRequirements keyRequirements
     ) throws WSSecurityException {
         KeyInfoBean keyInfo = new KeyInfoBean();
 
@@ -339,7 +341,7 @@ public class DefaultSubjectProvider implements 
SubjectProvider {
 
         final SecretKey symmetricKey;
         if (secret != null) {
-            symmetricKey = 
KeyUtils.prepareSecretKey(encryptionProperties.getEncryptionAlgorithm(), 
secret);
+            symmetricKey = TokenProviderUtils.createSecretKey(secret, 
keyRequirements, encryptionProperties);
         } else {
             KeyGenerator keyGen = 
KeyUtils.getKeyGenerator(encryptionProperties.getEncryptionAlgorithm());
             symmetricKey = keyGen.generateKey();
diff --git 
a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderUtils.java
 
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderUtils.java
index 91b4f6a3162..2b8907b4ea8 100644
--- 
a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderUtils.java
+++ 
b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/TokenProviderUtils.java
@@ -44,6 +44,7 @@ import org.apache.cxf.ws.addressing.EndpointReferenceType;
 import org.apache.cxf.ws.security.wss4j.WSS4JUtils;
 import org.apache.wss4j.common.ConfigurationConstants;
 import org.apache.wss4j.common.WSEncryptionPart;
+import org.apache.wss4j.common.WSS4JConstants;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.util.KeyUtils;
 import org.apache.wss4j.dom.handler.WSHandlerConstants;
@@ -58,6 +59,11 @@ public final class TokenProviderUtils {
 
     private static final Logger LOG = 
LogUtils.getL7dLogger(TokenProviderUtils.class);
 
+    private static final Map<Integer, String> AES_ALGORITHMS = Map.of(
+        16, WSS4JConstants.AES_128,
+        24, WSS4JConstants.AES_192,
+        32, WSS4JConstants.AES_256);
+
     private TokenProviderUtils() {
         // complete
     }
@@ -104,6 +110,36 @@ public final class TokenProviderUtils {
         return null;
     }
 
+    /**
+     * Create a SecretKey for the given issued secret. The secret was sized 
according to the KeySize and
+     * EncryptWith values of the request, so the algorithm associated with it 
must match that length
+     * rather than simply being the algorithm that the STS is configured with.
+     */
+    public static SecretKey createSecretKey(
+        byte[] secret,
+        KeyRequirements keyRequirements,
+        EncryptionProperties encryptionProperties
+    ) throws WSSecurityException {
+        String encryptWith = keyRequirements.getEncryptWith();
+        if (encryptWith == null
+            || 
!encryptionProperties.getAcceptedEncryptionAlgorithms().contains(encryptWith)
+            || KeyUtils.getKeyLength(encryptWith) != secret.length) {
+            encryptWith = encryptionProperties.getEncryptionAlgorithm();
+        }
+        if (KeyUtils.getKeyLength(encryptWith) != secret.length) {
+            // Fall back on an algorithm that matches the length of the issued 
secret
+            encryptWith = AES_ALGORITHMS.get(secret.length);
+            if (encryptWith == null) {
+                throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
+            }
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Issued secret does not match the configured 
encryption algorithm, using: "
+                    + encryptWith);
+            }
+        }
+        return KeyUtils.prepareSecretKey(encryptWith, secret);
+    }
+
     /**
      * Encrypt a Token element using the given arguments.
      */

Reply via email to