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 2011/11/08 15:04:56 UTC
svn commit: r1199249 - in
/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j:
PolicyBasedWSS4JInInterceptor.java
policyvalidators/AsymmetricBindingPolicyValidator.java
policyvalidators/EndorsingTokenPolicyValidator.java
Author: coheigea
Date: Tue Nov 8 14:04:55 2011
New Revision: 1199249
URL: http://svn.apache.org/viewvc?rev=1199249&view=rev
Log:
Improved EndorsingSupportingToken policy validation for X.509 tokens and KerberosTokens.
Modified:
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AsymmetricBindingPolicyValidator.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java?rev=1199249&r1=1199248&r2=1199249&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java Tue Nov 8 14:04:55 2011
@@ -574,6 +574,10 @@ public class PolicyBasedWSS4JInIntercept
suppValidator.setValidateUsernameToken(utWithCallbacks);
suppValidator.validatePolicy(aim);
+ EndorsingTokenPolicyValidator endorsingValidator =
+ new EndorsingTokenPolicyValidator(results, signedResults, msg);
+ endorsingValidator.validatePolicy(aim);
+
//REVISIT - probably can verify some of these like if UT is encrypted and/or signed, etc...
assertPolicy(aim, SP12Constants.SIGNED_ENCRYPTED_SUPPORTING_TOKENS);
assertPolicy(aim, SP12Constants.SUPPORTING_TOKENS);
@@ -583,14 +587,6 @@ public class PolicyBasedWSS4JInIntercept
assertPolicy(aim, SP12Constants.ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
assertPolicy(aim, SP12Constants.SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
}
- if (isRequestor(msg)) {
- assertPolicy(aim, SP12Constants.ENDORSING_SUPPORTING_TOKENS);
- } else {
- // TODO need to revisit all of the other endorsed policies
- EndorsingTokenPolicyValidator endorsingValidator =
- new EndorsingTokenPolicyValidator(signedResults, msg);
- endorsingValidator.validatePolicy(aim);
- }
super.doResults(msg, actor, soapHeader, soapBody, results, utWithCallbacks);
}
private void assertHeadersExists(AssertionInfoMap aim, SoapMessage msg, Node header)
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AsymmetricBindingPolicyValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AsymmetricBindingPolicyValidator.java?rev=1199249&r1=1199248&r2=1199249&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AsymmetricBindingPolicyValidator.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AsymmetricBindingPolicyValidator.java Tue Nov 8 14:04:55 2011
@@ -108,16 +108,21 @@ public class AsymmetricBindingPolicyVali
if (binding.getInitiatorToken() != null) {
Token token = binding.getInitiatorToken().getToken();
if (token instanceof X509Token) {
+ boolean foundCert = false;
for (WSSecurityEngineResult result : signedResults) {
X509Certificate cert =
(X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
- if (cert == null) {
- String error = "An X.509 certificate was not used for the initiator token";
- notAssertPolicy(aim, binding.getInitiatorToken().getName(), error);
- ai.setNotAsserted(error);
- return false;
+ if (cert != null) {
+ foundCert = true;
+ break;
}
}
+ if (!foundCert && !signedResults.isEmpty()) {
+ String error = "An X.509 certificate was not used for the initiator token";
+ notAssertPolicy(aim, binding.getInitiatorToken().getName(), error);
+ ai.setNotAsserted(error);
+ return false;
+ }
}
assertPolicy(aim, binding.getInitiatorToken());
if (!checkDerivedKeys(
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java?rev=1199249&r1=1199248&r2=1199249&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java Tue Nov 8 14:04:55 2011
@@ -19,35 +19,68 @@
package org.apache.cxf.ws.security.wss4j.policyvalidators;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.xml.namespace.QName;
+import org.w3c.dom.Element;
+
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.security.transport.TLSSessionInfo;
import org.apache.cxf.ws.policy.AssertionInfo;
import org.apache.cxf.ws.policy.AssertionInfoMap;
import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.policy.SPConstants;
+import org.apache.cxf.ws.security.policy.model.KerberosToken;
+import org.apache.cxf.ws.security.policy.model.SupportingToken;
+import org.apache.cxf.ws.security.policy.model.Token;
+import org.apache.cxf.ws.security.policy.model.X509Token;
+import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDataRef;
import org.apache.ws.security.WSSecurityEngine;
import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.message.token.BinarySecurity;
+import org.apache.ws.security.message.token.KerberosSecurity;
+import org.apache.ws.security.message.token.PKIPathSecurity;
+import org.apache.ws.security.message.token.Timestamp;
+import org.apache.ws.security.message.token.X509Security;
+import org.apache.ws.security.util.WSSecurityUtil;
/**
* Validate an EndorsingSupportingToken policy.
*/
-public class EndorsingTokenPolicyValidator {
+public class EndorsingTokenPolicyValidator extends AbstractTokenPolicyValidator {
+ private List<WSSecurityEngineResult> results;
private List<WSSecurityEngineResult> signedResults;
private Message message;
-
+ private Element timestamp;
+ private boolean tls;
+
public EndorsingTokenPolicyValidator(
+ List<WSSecurityEngineResult> results,
List<WSSecurityEngineResult> signedResults,
Message message
) {
+ this.results = results;
this.signedResults = signedResults;
this.message = message;
+ WSSecurityEngineResult result = WSSecurityUtil.fetchActionResult(results, WSConstants.TS);
+ if (result != null) {
+ Timestamp ts = (Timestamp)result.get(WSSecurityEngineResult.TAG_TIMESTAMP);
+ timestamp = ts.getElement();
+ }
+
+ // See whether TLS is in use or not
+ TLSSessionInfo tlsInfo = message.get(TLSSessionInfo.class);
+ if (tlsInfo != null) {
+ tls = true;
+ }
}
public boolean validatePolicy(
@@ -56,16 +89,28 @@ public class EndorsingTokenPolicyValidat
Collection<AssertionInfo> endorsingAis = aim.get(SP12Constants.ENDORSING_SUPPORTING_TOKENS);
if (endorsingAis != null && !endorsingAis.isEmpty()) {
for (AssertionInfo ai : endorsingAis) {
+ SupportingToken binding = (SupportingToken)ai.getAssertion();
+ if (SPConstants.SupportTokenType.SUPPORTING_TOKEN_ENDORSING != binding.getTokenType()) {
+ continue;
+ }
ai.setAsserted(true);
- TLSSessionInfo tlsInfo = message.get(TLSSessionInfo.class);
- boolean transport = false;
- if (tlsInfo != null) {
- transport = true;
- }
- if (!checkEndorsed(transport)) {
- ai.setNotAsserted("Message fails endorsing supporting tokens requirements");
- return false;
+ List<Token> tokens = binding.getTokens();
+ for (Token token : tokens) {
+ if (!isTokenRequired(token, message)) {
+ continue;
+ }
+ if (token instanceof KerberosToken && !processKerberosTokens()) {
+ ai.setNotAsserted(
+ "The received token does not match the supporting token requirement"
+ );
+ return false;
+ } else if (token instanceof X509Token && !processX509Tokens()) {
+ ai.setNotAsserted(
+ "The received token does not match the supporting token requirement"
+ );
+ return false;
+ }
}
}
}
@@ -73,24 +118,66 @@ public class EndorsingTokenPolicyValidat
return true;
}
+ private boolean processKerberosTokens() {
+ List<WSSecurityEngineResult> tokenResults = new ArrayList<WSSecurityEngineResult>();
+ for (WSSecurityEngineResult wser : results) {
+ Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+ if (actInt.intValue() == WSConstants.BST) {
+ BinarySecurity binarySecurity =
+ (BinarySecurity)wser.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
+ if (binarySecurity instanceof KerberosSecurity) {
+ tokenResults.add(wser);
+ }
+ }
+ }
+
+ if (tokenResults.isEmpty()) {
+ return false;
+ }
+
+ return checkEndorsed(tokenResults, tls);
+ }
+
+ private boolean processX509Tokens() {
+ List<WSSecurityEngineResult> tokenResults = new ArrayList<WSSecurityEngineResult>();
+ for (WSSecurityEngineResult wser : results) {
+ Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+ if (actInt.intValue() == WSConstants.BST) {
+ BinarySecurity binarySecurity =
+ (BinarySecurity)wser.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
+ if (binarySecurity instanceof X509Security
+ || binarySecurity instanceof PKIPathSecurity) {
+ tokenResults.add(wser);
+ }
+ }
+ }
+
+ if (tokenResults.isEmpty()) {
+ return false;
+ }
+
+ return checkEndorsed(tokenResults, tls);
+ }
+
/**
* Check the endorsing supporting token policy. If we're using the Transport Binding then
* check that the Timestamp is signed. Otherwise, check that the signature is signed.
* @param transport
* @return true if the endorsed supporting token policy is correct
*/
- private boolean checkEndorsed(boolean transport) {
+ private boolean checkEndorsed(List<WSSecurityEngineResult> tokenResults, boolean transport) {
if (transport) {
- return checkTimestampIsSigned();
+ return checkTimestampIsSigned(tokenResults);
}
- return checkSignatureIsSigned();
+ return checkSignatureIsSigned(tokenResults);
}
/**
- * Return true if the Timestamp is signed
+ * Return true if the Timestamp is signed by one of the token results
+ * @param tokenResults A list of WSSecurityEngineResults corresponding to tokens
* @return true if the Timestamp is signed
*/
- private boolean checkTimestampIsSigned() {
+ private boolean checkTimestampIsSigned(List<WSSecurityEngineResult> tokenResults) {
for (WSSecurityEngineResult signedResult : signedResults) {
List<WSDataRef> sl =
CastUtils.cast((List<?>)signedResult.get(
@@ -98,8 +185,8 @@ public class EndorsingTokenPolicyValidat
));
if (sl != null) {
for (WSDataRef dataRef : sl) {
- QName signedQName = dataRef.getName();
- if (WSSecurityEngine.TIMESTAMP.equals(signedQName)) {
+ if (timestamp == dataRef.getProtectedElement()
+ && checkSignature(signedResult, tokenResults)) {
return true;
}
}
@@ -109,19 +196,21 @@ public class EndorsingTokenPolicyValidat
}
/**
- * Return true if the Signature is itself signed
+ * Return true if the Signature is itself signed by one of the token results
+ * @param tokenResults A list of WSSecurityEngineResults corresponding to tokens
* @return true if the Signature is itself signed
*/
- private boolean checkSignatureIsSigned() {
+ private boolean checkSignatureIsSigned(List<WSSecurityEngineResult> tokenResults) {
for (WSSecurityEngineResult signedResult : signedResults) {
List<WSDataRef> sl =
CastUtils.cast((List<?>)signedResult.get(
WSSecurityEngineResult.TAG_DATA_REF_URIS
));
- if (sl != null) {
+ if (sl != null && sl.size() == 1) {
for (WSDataRef dataRef : sl) {
QName signedQName = dataRef.getName();
- if (WSSecurityEngine.SIGNATURE.equals(signedQName)) {
+ if (WSSecurityEngine.SIGNATURE.equals(signedQName)
+ && checkSignature(signedResult, tokenResults)) {
return true;
}
}
@@ -129,4 +218,45 @@ public class EndorsingTokenPolicyValidat
}
return false;
}
+
+ /**
+ * Check that a WSSecurityEngineResult corresponding to a signature uses the same
+ * signing credential as one of the tokens.
+ * @param signatureResult a WSSecurityEngineResult corresponding to a signature
+ * @param tokenResult A list of WSSecurityEngineResults corresponding to tokens
+ * @return
+ */
+ private boolean checkSignature(
+ WSSecurityEngineResult signatureResult,
+ List<WSSecurityEngineResult> tokenResult
+ ) {
+ // See what was used to sign this result
+ X509Certificate cert =
+ (X509Certificate)signatureResult.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+ byte[] secret = (byte[])signatureResult.get(WSSecurityEngineResult.TAG_SECRET);
+
+ // Now see if the same credential exists in the tokenResult list
+ for (WSSecurityEngineResult token : tokenResult) {
+ Integer actInt = (Integer)token.get(WSSecurityEngineResult.TAG_ACTION);
+ if (actInt.intValue() == WSConstants.BST) {
+ BinarySecurity binarySecurity =
+ (BinarySecurity)token.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
+ if (binarySecurity instanceof X509Security
+ || binarySecurity instanceof PKIPathSecurity) {
+ X509Certificate foundCert =
+ (X509Certificate)token.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+ if (foundCert.equals(cert)) {
+ return true;
+ }
+ } else if (binarySecurity instanceof KerberosSecurity) {
+ byte[] foundSecret = (byte[])token.get(WSSecurityEngineResult.TAG_SECRET);
+ if (foundSecret != null && Arrays.equals(foundSecret, secret)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
}