You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2026/09/08 11:09:55 UTC
(cxf) branch main updated: Fix STS secret-key sizing (#3453)
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new d34ae62a4dc Fix STS secret-key sizing (#3453)
d34ae62a4dc is described below
commit d34ae62a4dcfd04b046828ced88cdb76d80b90a2
Author: Colm O hEigeartaigh <co...@users.noreply.github.com>
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.
*/