You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by gi...@apache.org on 2013/07/10 11:32:38 UTC
svn commit: r1501691 - in /webservices/wss4j/trunk:
ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/
ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/
ws-security-stax/src/main/java/org/apache/w...
Author: giger
Date: Wed Jul 10 09:32:37 2013
New Revision: 1501691
URL: http://svn.apache.org/r1501691
Log:
WSS-457 - Incorrect validation of ProtectTokens assertion
Modified:
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/TokenProtectionAssertionState.java
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/TokenProtectionTest.java
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSUtils.java
Modified: webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/TokenProtectionAssertionState.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/TokenProtectionAssertionState.java?rev=1501691&r1=1501690&r2=1501691&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/TokenProtectionAssertionState.java (original)
+++ webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/TokenProtectionAssertionState.java Wed Jul 10 09:32:37 2013
@@ -91,10 +91,7 @@ public class TokenProtectionAssertionSta
for (int i = 0; i < tokenSecurityEvents.size(); i++) {
TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent = tokenSecurityEvents.get(i);
- SecurityToken securityToken = tokenSecurityEvent.getSecurityToken();
- while (securityToken.getKeyWrappingToken() != null) {
- securityToken = securityToken.getKeyWrappingToken();
- }
+ SecurityToken securityToken = getEffectiveSignatureToken(tokenSecurityEvent.getSecurityToken());
//a token can only be signed if it is included in the message:
if (securityToken.isIncludedInMessage() && isSignatureToken(securityToken)) {
@@ -142,8 +139,9 @@ public class TokenProtectionAssertionSta
return false;
}
- private boolean isEndorsingToken(SecurityToken securityToken) {
- List<WSSecurityTokenConstants.TokenUsage> tokenUsages = securityToken.getTokenUsages();
+ private boolean isEndorsingToken(SecurityToken securityToken) throws XMLSecurityException {
+ SecurityToken rootToken = WSSUtils.getRootToken(securityToken);
+ List<WSSecurityTokenConstants.TokenUsage> tokenUsages = rootToken.getTokenUsages();
for (int i = 0; i < tokenUsages.size(); i++) {
WSSecurityTokenConstants.TokenUsage tokenUsage = tokenUsages.get(i);
if (tokenUsage.getName().contains("Endorsing")) {
@@ -153,8 +151,9 @@ public class TokenProtectionAssertionSta
return false;
}
- private boolean isSignedSupportingToken(SecurityToken securityToken) {
- List<WSSecurityTokenConstants.TokenUsage> tokenUsages = securityToken.getTokenUsages();
+ private boolean isSignedSupportingToken(SecurityToken securityToken) throws XMLSecurityException {
+ SecurityToken rootToken = WSSUtils.getRootToken(securityToken);
+ List<WSSecurityTokenConstants.TokenUsage> tokenUsages = rootToken.getTokenUsages();
for (int i = 0; i < tokenUsages.size(); i++) {
WSSecurityTokenConstants.TokenUsage tokenUsage = tokenUsages.get(i);
if (tokenUsage.getName().contains("Signed")) {
@@ -164,8 +163,9 @@ public class TokenProtectionAssertionSta
return false;
}
- private boolean isMainSignatureToken(SecurityToken securityToken) {
- List<WSSecurityTokenConstants.TokenUsage> tokenUsages = securityToken.getTokenUsages();
+ private boolean isMainSignatureToken(SecurityToken securityToken) throws XMLSecurityException {
+ SecurityToken rootToken = WSSUtils.getRootToken(securityToken);
+ List<WSSecurityTokenConstants.TokenUsage> tokenUsages = rootToken.getTokenUsages();
return tokenUsages.contains(WSSecurityTokenConstants.TokenUsage_MainSignature);
}
@@ -178,10 +178,7 @@ public class TokenProtectionAssertionSta
for (int i = 0; i < signedElementEvents.size(); i++) {
SignedElementSecurityEvent signedElementSecurityEvent = signedElementEvents.get(i);
if (WSSUtils.pathMatches(signedElementSecurityEvent.getElementPath(), signaturePath, true, false)) {
- SecurityToken signingSecurityToken = signedElementSecurityEvent.getSecurityToken();
- while (signingSecurityToken != null && signingSecurityToken.getKeyWrappingToken() != null) {
- signingSecurityToken = signingSecurityToken.getKeyWrappingToken();
- }
+ SecurityToken signingSecurityToken = getEffectiveSignatureToken(signedElementSecurityEvent.getSecurityToken());
//todo ATM me just check if the token signs a signature but we don't know if it's the main signature
if (signingSecurityToken != null && signingSecurityToken.getId().equals(securityToken.getId())) {
return true;
@@ -197,19 +194,15 @@ public class TokenProtectionAssertionSta
if (WSSUtils.pathMatches(signedElementSecurityEvent.getElementPath(), securityToken.getElementPath(), false, false)) {
SecurityToken signingSecurityToken = signedElementSecurityEvent.getSecurityToken();
- while (signingSecurityToken != null && signingSecurityToken.getKeyWrappingToken() != null) {
- signingSecurityToken = signingSecurityToken.getKeyWrappingToken();
- }
+ signingSecurityToken = getEffectiveSignatureToken(signingSecurityToken);
- if (signingSecurityToken != null && signingSecurityToken.getId().equals(securityToken.getId())) {
+ if (signingSecurityToken.getId().equals(securityToken.getId())) {
//ok we've found the correlating signedElementSecurityEvent. Now we have to find the Token that
//is covered by this signedElementSecurityEvent:
for (int j = 0; j < tokenSecurityEvents.size(); j++) {
TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent = tokenSecurityEvents.get(j);
- SecurityToken st = tokenSecurityEvent.getSecurityToken();
- while (st.getKeyWrappingToken() != null) {
- st = st.getKeyWrappingToken();
- }
+ SecurityToken st = getEffectiveSignatureToken(tokenSecurityEvent.getSecurityToken());
+
if (signedElementSecurityEvent.getXmlSecEvent() == st.getXMLSecEvent()) {
//...and we got the covered token
//next we have to see if the token is the same:
@@ -243,10 +236,8 @@ public class TokenProtectionAssertionSta
for (int j = 0; j < signedElementEvents.size(); j++) {
SignedElementSecurityEvent signedElementSecurityEvent = signedElementEvents.get(j);
if (WSSUtils.pathMatches(signedElementSecurityEvent.getElementPath(), elementPath, false, false)) {
- SecurityToken elementSignatureToken = signedElementSecurityEvent.getSecurityToken();
- while (elementSignatureToken != null && elementSignatureToken.getKeyWrappingToken() != null) {
- elementSignatureToken = elementSignatureToken.getKeyWrappingToken();
- }
+ SecurityToken elementSignatureToken = getEffectiveSignatureToken(signedElementSecurityEvent.getSecurityToken());
+
if (elementSignatureToken != null && elementSignatureToken.getId().equals(securityToken.getId())) {
if (!signedElements.contains(signedElementSecurityEvent)) {
signedElements.add(signedElementSecurityEvent);
@@ -266,4 +257,21 @@ public class TokenProtectionAssertionSta
return true;
}
+
+ private SecurityToken getEffectiveSignatureToken(SecurityToken securityToken) throws XMLSecurityException {
+ SecurityToken tmp = WSSUtils.getRootToken(securityToken);
+ List<? extends SecurityToken> wrappedTokens = tmp.getWrappedTokens();
+ for (int i = 0; i < wrappedTokens.size(); i++) {
+ SecurityToken token = wrappedTokens.get(i);
+ if (isSignatureToken(token)) {
+ //WSP 1.3, 6.5 [Token Protection] Property: Note that in cases where derived keys are used
+ //the 'main' token, and NOT the derived key token, is covered by the signature.
+ if (WSSecurityTokenConstants.DerivedKeyToken.equals(token.getTokenType())) {
+ return tmp;
+ }
+ tmp = token;
+ }
+ }
+ return tmp;
+ }
}
Modified: webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/TokenProtectionTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/TokenProtectionTest.java?rev=1501691&r1=1501690&r2=1501691&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/TokenProtectionTest.java (original)
+++ webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/TokenProtectionTest.java Wed Jul 10 09:32:37 2013
@@ -26,10 +26,14 @@ import org.apache.wss4j.stax.securityTok
import org.apache.wss4j.stax.impl.securityToken.X509SecurityTokenImpl;
import org.apache.wss4j.stax.securityEvent.OperationSecurityEvent;
import org.apache.xml.security.stax.ext.XMLSecurityConstants;
+import org.apache.xml.security.stax.impl.securityToken.AbstractInboundSecurityToken;
+import org.apache.xml.security.stax.impl.util.IDGenerator;
+import org.apache.xml.security.stax.securityEvent.EncryptedKeyTokenSecurityEvent;
import org.apache.xml.security.stax.securityEvent.SignedElementSecurityEvent;
import org.apache.xml.security.stax.securityEvent.X509TokenSecurityEvent;
import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
import org.apache.xml.security.stax.securityToken.SecurityToken;
+import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -489,4 +493,215 @@ public class TokenProtectionTest extends
Assert.assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
}
}
+
+ @Test
+ public void testPolicySymmetricBindingProtectSignatureToken() throws Exception {
+ String policyString =
+ "<sp:SymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
+ "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
+ " <sp:AlgorithmSuite>\n" +
+ " <wsp:Policy>\n" +
+ " <sp:Basic256/>\n" +
+ " </wsp:Policy>\n" +
+ " </sp:AlgorithmSuite>\n" +
+ "<sp:ProtectTokens/>\n" +
+ "</wsp:Policy>\n" +
+ "</sp:SymmetricBinding>";
+ PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
+
+ List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<XMLSecurityConstants.ContentType>();
+ protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
+
+ List<QName> bstPath = new ArrayList<QName>();
+ bstPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ bstPath.add(WSSConstants.TAG_wsse_BinarySecurityToken);
+
+ List<QName> ekPath = new ArrayList<QName>();
+ ekPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ ekPath.add(WSSConstants.TAG_xenc_EncryptedKey);
+
+ List<QName> sigPath = new ArrayList<QName>();
+ sigPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ sigPath.add(WSSConstants.TAG_dsig_Signature);
+
+ X509SecurityTokenImpl x509SecurityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
+ x509SecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_MainSignature);
+ x509SecurityToken.setElementPath(bstPath);
+
+ AbstractInboundSecurityToken ekSecurityToken = new AbstractInboundSecurityToken(
+ null, IDGenerator.generateID(null),
+ SecurityTokenConstants.KeyIdentifier_EncryptedKey, true) {
+ @Override
+ public SecurityTokenConstants.TokenType getTokenType() {
+ return SecurityTokenConstants.EncryptedKeyToken;
+ }
+ };
+ ekSecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_Signature);
+ ekSecurityToken.setKeyWrappingToken(x509SecurityToken);
+ ekSecurityToken.setElementPath(ekPath);
+
+ x509SecurityToken.addWrappedToken(ekSecurityToken);
+
+ X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
+ x509TokenSecurityEvent.setSecurityToken(x509SecurityToken);
+ policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
+
+ EncryptedKeyTokenSecurityEvent encryptedKeyTokenSecurityEvent = new EncryptedKeyTokenSecurityEvent();
+ encryptedKeyTokenSecurityEvent.setSecurityToken(ekSecurityToken);
+ policyEnforcer.registerSecurityEvent(encryptedKeyTokenSecurityEvent);
+
+ SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(ekSecurityToken, true, protectionOrder);
+ signedElementSecurityEvent.setElementPath(ekPath);
+ policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
+
+ OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
+ operationSecurityEvent.setOperation(new QName("definitions"));
+
+ policyEnforcer.registerSecurityEvent(operationSecurityEvent);
+ policyEnforcer.doFinal();
+ }
+
+ @Test
+ public void testPolicySymmetricBindingProtectRootToken() throws Exception {
+ String policyString =
+ "<sp:SymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
+ "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
+ " <sp:AlgorithmSuite>\n" +
+ " <wsp:Policy>\n" +
+ " <sp:Basic256/>\n" +
+ " </wsp:Policy>\n" +
+ " </sp:AlgorithmSuite>\n" +
+ "<sp:ProtectTokens/>\n" +
+ "</wsp:Policy>\n" +
+ "</sp:SymmetricBinding>";
+ PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
+
+ List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<XMLSecurityConstants.ContentType>();
+ protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
+
+ List<QName> bstPath = new ArrayList<QName>();
+ bstPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ bstPath.add(WSSConstants.TAG_wsse_BinarySecurityToken);
+
+ List<QName> ekPath = new ArrayList<QName>();
+ ekPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ ekPath.add(WSSConstants.TAG_xenc_EncryptedKey);
+
+ List<QName> sigPath = new ArrayList<QName>();
+ sigPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ sigPath.add(WSSConstants.TAG_dsig_Signature);
+
+ X509SecurityTokenImpl x509SecurityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
+ x509SecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_MainSignature);
+ x509SecurityToken.setElementPath(bstPath);
+
+ AbstractInboundSecurityToken ekSecurityToken = new AbstractInboundSecurityToken(
+ null, IDGenerator.generateID(null),
+ SecurityTokenConstants.KeyIdentifier_EncryptedKey, true) {
+ @Override
+ public SecurityTokenConstants.TokenType getTokenType() {
+ return SecurityTokenConstants.EncryptedKeyToken;
+ }
+ };
+ ekSecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_Signature);
+ ekSecurityToken.setKeyWrappingToken(x509SecurityToken);
+ ekSecurityToken.setElementPath(ekPath);
+
+ x509SecurityToken.addWrappedToken(ekSecurityToken);
+
+ X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
+ x509TokenSecurityEvent.setSecurityToken(x509SecurityToken);
+ policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
+
+ EncryptedKeyTokenSecurityEvent encryptedKeyTokenSecurityEvent = new EncryptedKeyTokenSecurityEvent();
+ encryptedKeyTokenSecurityEvent.setSecurityToken(ekSecurityToken);
+ policyEnforcer.registerSecurityEvent(encryptedKeyTokenSecurityEvent);
+
+ SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(x509SecurityToken, true, protectionOrder);
+ signedElementSecurityEvent.setElementPath(bstPath);
+ policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
+
+ OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
+ operationSecurityEvent.setOperation(new QName("definitions"));
+
+ try {
+ policyEnforcer.registerSecurityEvent(operationSecurityEvent);
+ } catch (WSSecurityException e) {
+ Assert.assertTrue(e.getCause() instanceof PolicyViolationException);
+ Assert.assertEquals(e.getCause().getMessage(),
+ "Token /{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://www.w3.org/2001/04/xmlenc#}EncryptedKey must be signed by its signature.");
+ Assert.assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
+ }
+ }
+
+ @Test
+ public void testPolicySymmetricBindingProtectAllToken() throws Exception {
+ String policyString =
+ "<sp:SymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
+ "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
+ " <sp:AlgorithmSuite>\n" +
+ " <wsp:Policy>\n" +
+ " <sp:Basic256/>\n" +
+ " </wsp:Policy>\n" +
+ " </sp:AlgorithmSuite>\n" +
+ "<sp:ProtectTokens/>\n" +
+ "</wsp:Policy>\n" +
+ "</sp:SymmetricBinding>";
+ PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
+
+ List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<XMLSecurityConstants.ContentType>();
+ protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
+
+ List<QName> bstPath = new ArrayList<QName>();
+ bstPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ bstPath.add(WSSConstants.TAG_wsse_BinarySecurityToken);
+
+ List<QName> ekPath = new ArrayList<QName>();
+ ekPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ ekPath.add(WSSConstants.TAG_xenc_EncryptedKey);
+
+ List<QName> sigPath = new ArrayList<QName>();
+ sigPath.addAll(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ sigPath.add(WSSConstants.TAG_dsig_Signature);
+
+ X509SecurityTokenImpl x509SecurityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
+ x509SecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_MainSignature);
+ x509SecurityToken.setElementPath(bstPath);
+
+ AbstractInboundSecurityToken ekSecurityToken = new AbstractInboundSecurityToken(
+ null, IDGenerator.generateID(null),
+ SecurityTokenConstants.KeyIdentifier_EncryptedKey, true) {
+ @Override
+ public SecurityTokenConstants.TokenType getTokenType() {
+ return SecurityTokenConstants.EncryptedKeyToken;
+ }
+ };
+ ekSecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_Signature);
+ ekSecurityToken.setKeyWrappingToken(x509SecurityToken);
+ ekSecurityToken.setElementPath(ekPath);
+
+ x509SecurityToken.addWrappedToken(ekSecurityToken);
+
+ X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
+ x509TokenSecurityEvent.setSecurityToken(x509SecurityToken);
+ policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
+
+ EncryptedKeyTokenSecurityEvent encryptedKeyTokenSecurityEvent = new EncryptedKeyTokenSecurityEvent();
+ encryptedKeyTokenSecurityEvent.setSecurityToken(ekSecurityToken);
+ policyEnforcer.registerSecurityEvent(encryptedKeyTokenSecurityEvent);
+
+ SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(x509SecurityToken, true, protectionOrder);
+ signedElementSecurityEvent.setElementPath(bstPath);
+ policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
+
+ signedElementSecurityEvent = new SignedElementSecurityEvent(ekSecurityToken, true, protectionOrder);
+ signedElementSecurityEvent.setElementPath(ekPath);
+ policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
+
+ OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
+ operationSecurityEvent.setOperation(new QName("definitions"));
+
+ policyEnforcer.registerSecurityEvent(operationSecurityEvent);
+ policyEnforcer.doFinal();
+ }
}
Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSUtils.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSUtils.java?rev=1501691&r1=1501690&r2=1501691&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSUtils.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSUtils.java Wed Jul 10 09:32:37 2013
@@ -532,5 +532,13 @@ public class WSSUtils extends XMLSecurit
stringBuilder.append(qName.toString());
}
return stringBuilder.toString();
- }
+ }
+
+ public static SecurityToken getRootToken(SecurityToken securityToken) throws XMLSecurityException {
+ SecurityToken tmp = securityToken;
+ while (tmp.getKeyWrappingToken() != null) {
+ tmp = tmp.getKeyWrappingToken();
+ }
+ return tmp;
+ }
}