This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch 2_4_x-fixes in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git
commit 1b642a7359bf4d6ffc2680b6d7a7511d00040db1 Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Mon Sep 21 12:23:23 2026 +0100 Revert "Align StaX sender vouches with DOM layer (#720)" This reverts commit 00472e244b6bb75d7747fdf6d66523b03985763c. --- .../processor/input/SAMLTokenInputHandler.java | 46 +------ .../processor/input/SenderVouchesIdentityTest.java | 137 --------------------- 2 files changed, 1 insertion(+), 182 deletions(-) diff --git a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/SAMLTokenInputHandler.java b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/SAMLTokenInputHandler.java index 3e87ee675..e70918816 100644 --- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/SAMLTokenInputHandler.java +++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/SAMLTokenInputHandler.java @@ -527,40 +527,6 @@ public class SAMLTokenInputHandler extends AbstractInputSecurityHeaderHandler { * which can not be done until the whole soap-header is processed and we know that the whole soap-body * is signed. */ - /** - * Whether a security token identifies the sender that signed with it, as opposed to merely - * proving possession of a key. - * - * A certificate or a public key was checked against the receiver's own truststore when the - * token was verified - see X509SecurityTokenImpl#verify and - * RsaKeyValueSecurityTokenImpl#verify, both of which call Crypto#verifyTrust. A bare symmetric - * key was not, and could not be: an EncryptedKey that the sender minted for itself under the - * receiver's public certificate proves possession of a key the sender chose, and nothing - * whatsoever about who sent it. - * - * Two symmetric cases do carry an identity. A key derived from a UsernameToken required the - * password to derive, and a Kerberos session key came out of a ticket the KDC issued to a - * named client. These are the streaming counterparts of the results the DOM engine stamps - * with TAG_VALIDATED_TOKEN, plus its UT_SIGN case - see DOMSAMLUtil#establishesSenderIdentity. - * - * The token is resolved to the root of its key wrapping chain first, so that a - * DerivedKeyToken is judged on whatever it was derived from. - */ - static boolean establishesSenderIdentity(SecurityToken securityToken) throws XMLSecurityException { - SecurityToken rootToken = WSSUtils.getRootToken(securityToken); - - X509Certificate[] x509Certificates = rootToken.getX509Certificates(); - if (x509Certificates != null && x509Certificates.length > 0) { - return true; - } - if (rootToken.getPublicKey() != null) { - return true; - } - - return WSSecurityTokenConstants.USERNAME_TOKEN.equals(rootToken.getTokenType()) - || WSSecurityTokenConstants.KERBEROS_TOKEN.equals(rootToken.getTokenType()); - } - static class SAMLTokenVerifierInputProcessor extends AbstractInputProcessor implements SecurityEventListener { private SamlAssertionWrapper samlAssertionWrapper; @@ -744,20 +710,10 @@ public class SAMLTokenInputHandler extends AbstractInputSecurityHeaderHandler { samlTokenSignedElementSecurityEvent = signedElementSecurityEvent; } } - // A sender-vouches assertion is only worth as much as the identity of - // whoever vouched for it. An assertion that is itself signed carries that - // backing already, and the message signature merely binds it to this - // message, so any signature will do. An unsigned assertion has no such - // backing: the only party asserting it is whoever signed the message, so - // that signature has to have been made with a credential whose identity - // was actually established. if (bodySignedPartSecurityEvent != null && samlTokenSignedElementSecurityEvent != null && bodySignedPartSecurityEvent.getSecurityToken() - == samlTokenSignedElementSecurityEvent.getSecurityToken() - && (samlAssertionWrapper.isSigned() - || establishesSenderIdentity( - bodySignedPartSecurityEvent.getSecurityToken()))) { + == samlTokenSignedElementSecurityEvent.getSecurityToken()) { return; } methodNotSatisfied = true; diff --git a/ws-security-stax/src/test/java/org/apache/wss4j/stax/impl/processor/input/SenderVouchesIdentityTest.java b/ws-security-stax/src/test/java/org/apache/wss4j/stax/impl/processor/input/SenderVouchesIdentityTest.java deleted file mode 100644 index 30b4d7b97..000000000 --- a/ws-security-stax/src/test/java/org/apache/wss4j/stax/impl/processor/input/SenderVouchesIdentityTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.wss4j.stax.impl.processor.input; - -import java.security.KeyStore; -import java.security.cert.X509Certificate; - -import org.apache.wss4j.stax.impl.securityToken.EncryptedKeySha1SecurityTokenImpl; -import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants; -import org.apache.xml.security.stax.securityToken.SecurityTokenConstants; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * An unsigned sender-vouches assertion is only as good as the identity of whoever signed the - * message that carries it. These are the cases SAMLTokenInputHandler#establishesSenderIdentity - * has to separate: a credential the receiver made a trust decision about, against a bare - * symmetric key that says nothing about who sent the message. - */ -public class SenderVouchesIdentityTest { - - /** - * The bypass: an EncryptedKey the sender minted for itself under the receiver's public - * certificate. The HMAC signature it keys verifies perfectly and identifies nobody. - */ - @Test - public void testEncryptedKeyDoesNotVouch() throws Exception { - assertFalse(SAMLTokenInputHandler.establishesSenderIdentity( - token(WSSecurityTokenConstants.EncryptedKeyToken))); - } - - /** - * The same key reached through a DerivedKeyToken. The derived token is judged on what it was - * derived from, so this must not become a way round the previous case. - */ - @Test - public void testKeyDerivedFromAnEncryptedKeyDoesNotVouch() throws Exception { - EncryptedKeySha1SecurityTokenImpl derivedKey = token(WSSecurityTokenConstants.DerivedKeyToken); - derivedKey.setKeyWrappingToken(token(WSSecurityTokenConstants.EncryptedKeyToken)); - - assertFalse(SAMLTokenInputHandler.establishesSenderIdentity(derivedKey)); - } - - /** - * A certificate was checked against the receiver's truststore when the token was verified. - */ - @Test - public void testCertificateVouches() throws Exception { - EncryptedKeySha1SecurityTokenImpl securityToken = token(WSSecurityTokenConstants.X509V3Token); - securityToken.setX509Certificates(new X509Certificate[] {transmitterCertificate()}); - - assertTrue(SAMLTokenInputHandler.establishesSenderIdentity(securityToken)); - } - - /** - * So was a bare public key - see RsaKeyValueSecurityTokenImpl#verify. - */ - @Test - public void testPublicKeyVouches() throws Exception { - EncryptedKeySha1SecurityTokenImpl securityToken = token(WSSecurityTokenConstants.KeyValueToken); - securityToken.setPublicKey(transmitterCertificate().getPublicKey()); - - assertTrue(SAMLTokenInputHandler.establishesSenderIdentity(securityToken)); - } - - /** - * A UsernameToken derived key carries no credential for a trust decision, but deriving it - * required the password, so the sender is authenticated all the same. This is the streaming - * counterpart of the DOM engine's UT_SIGN case. - */ - @Test - public void testUsernameTokenVouches() throws Exception { - assertTrue(SAMLTokenInputHandler.establishesSenderIdentity( - token(WSSecurityTokenConstants.USERNAME_TOKEN))); - } - - /** - * A Kerberos session key came out of a ticket the KDC issued to a named client. - */ - @Test - public void testKerberosTokenVouches() throws Exception { - assertTrue(SAMLTokenInputHandler.establishesSenderIdentity( - token(WSSecurityTokenConstants.KERBEROS_TOKEN))); - } - - /** - * A token carrying only a symmetric key of some other provenance - a SecurityContextToken, - * say - is no better placed to vouch than an EncryptedKey is. - */ - @Test - public void testOtherSymmetricTokenDoesNotVouch() throws Exception { - assertFalse(SAMLTokenInputHandler.establishesSenderIdentity( - token(WSSecurityTokenConstants.SECURITY_CONTEXT_TOKEN))); - } - - /** - * A token of the given type carrying nothing else. EncryptedKeySha1SecurityTokenImpl is used - * only because it is a concrete inbound token whose credentials can be set from a test; what - * is under test is the rule, not the class. - */ - private EncryptedKeySha1SecurityTokenImpl token(SecurityTokenConstants.TokenType tokenType) { - return new EncryptedKeySha1SecurityTokenImpl(null, null, "sha1-identifier", "token-id") { - @Override - public SecurityTokenConstants.TokenType getTokenType() { - return tokenType; - } - }; - } - - private X509Certificate transmitterCertificate() throws Exception { - KeyStore keyStore = KeyStore.getInstance("jks"); - keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), - "default".toCharArray()); - X509Certificate certificate = (X509Certificate)keyStore.getCertificate("transmitter"); - assertNotNull(certificate, "precondition: the test keystore holds the transmitter certificate"); - return certificate; - } -}
