Author: coheigea
Date: Fri Mar 4 17:25:32 2011
New Revision: 1078063
URL: http://svn.apache.org/viewvc?rev=1078063&view=rev
Log:
Added the ability to automatically trust a certificate used to verify a
signature, if the certificate is in the Subject of a trusted SAML Assertion
- Added test as well
- Changed the STR interface a bit, so that we can load processors from a
WSSConfig instance.
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/CustomTokenPrincipal.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/SAMLUtil.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/STRParser.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SecurityTokenRefSTRParser.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/transform/STRTransformUtil.java
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/AbstractSAMLCallbackHandler.java
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML1CallbackHandler.java
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML2CallbackHandler.java
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/CustomTokenPrincipal.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/CustomTokenPrincipal.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/CustomTokenPrincipal.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/CustomTokenPrincipal.java
Fri Mar 4 17:25:32 2011
@@ -29,6 +29,7 @@ public class CustomTokenPrincipal implem
private Element tokenElement;
private String name;
private Object tokenObject;
+ private boolean trusted = false;
public Object getTokenObject() {
return tokenObject;
@@ -54,4 +55,12 @@ public class CustomTokenPrincipal implem
this.tokenElement = tokenElement;
}
+ public boolean isTrusted() {
+ return trusted;
+ }
+
+ public void setIsTrusted(boolean trust) {
+ trusted = trust;
+ }
+
}
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
Fri Mar 4 17:25:32 2011
@@ -182,6 +182,8 @@ public class SecurityTokenReference {
*
* The method gets the URI attribute of the {@link Reference} contained in
* the {@link SecurityTokenReference} and tries to find the referenced
+ * Element in the document. Alternatively, it gets the value of the
KeyIdentifier
+ * contained in the {@link SecurityTokenReference} and tries to find the
referenced
* Element in the document.
*
* @param doc the document that contains the binary security token
@@ -191,76 +193,59 @@ public class SecurityTokenReference {
* @param docInfo A WSDocInfo object containing previous results
* @param cb A CallbackHandler object to obtain tokens that are not in the
message
* @return Element containing the signing token, must be a
BinarySecurityToken
- * @throws WSSecurityException When either no <code>Reference</code>
element, or the found
- * reference contains no URI, or the referenced signing
not found.
+ * @throws WSSecurityException if the referenced element is not found.
*/
public Element getTokenElement(
Document doc, WSDocInfo docInfo, CallbackHandler cb
) throws WSSecurityException {
Reference ref = getReference();
- String uri = ref.getURI();
+ String uri = null;
+ String valueType = null;
+ if (ref != null) {
+ uri = ref.getURI();
+ valueType = ref.getValueType();
+ } else {
+ uri = getKeyIdentifierValue();
+ valueType = getKeyIdentifierValueType();
+ }
if (doDebug) {
log.debug("Token reference uri: " + uri);
}
- Element tokElement =
- findTokenElement(doc, docInfo, cb, uri, ref.getValueType());
-
- if (tokElement == null) {
- throw new WSSecurityException(
- WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
- "noToken",
- new Object[]{uri}
- );
- }
- return tokElement;
- }
-
-
- /**
- * Gets the signing token element, which may be a <code>BinarySecurityToken
- * </code> or a SAML token.
- *
- * The method gets the value of the KeyIdentifier contained in
- * the {@link SecurityTokenReference} and tries to find the referenced
- * Element in the document.
- *
- * @param doc the document that contains the binary security token
- * element. This could be different from the document
- * that contains the SecurityTokenReference (STR). See
- * STRTransform.derefenceBST() method
- * @param docInfo A WSDocInfo object containing previous results
- * @param cb A CallbackHandler object to obtain tokens that are not in the
message
- * @return Element containing the signing token
- */
- public Element getKeyIdentifierTokenElement(
- Document doc, WSDocInfo docInfo, CallbackHandler cb
- ) throws WSSecurityException {
- String value = getKeyIdentifierValue();
- String type = getKeyIdentifierValueType();
- if (doDebug) {
- log.debug("Token reference uri: " + value);
- }
- if (value == null) {
+ if (uri == null) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "badReferenceURI"
);
}
- Element tokElement = findTokenElement(doc, docInfo, cb, value, type);
+ Element tokElement =
+ findProcessedTokenElement(doc, docInfo, cb, uri, valueType);
+ if (tokElement == null) {
+ tokElement = findUnprocessedTokenElement(doc, docInfo, cb, uri,
valueType);
+ }
if (tokElement == null) {
throw new WSSecurityException(
WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"noToken",
- new Object[]{value}
+ new Object[]{uri}
);
}
return tokElement;
}
-
- private Element findTokenElement(
+ /**
+ * Find a token that has not been processed already - in other words, it
searches for
+ * the element, rather than trying to access previous results to find the
element
+ * @param doc Parent Document
+ * @param docInfo WSDocInfo instance
+ * @param cb CallbackHandler instance
+ * @param uri URI of the element
+ * @param type Type of the element
+ * @return A DOM element
+ * @throws WSSecurityException
+ */
+ public Element findUnprocessedTokenElement(
Document doc,
WSDocInfo docInfo,
CallbackHandler cb,
@@ -272,17 +257,6 @@ public class SecurityTokenReference {
id = id.substring(1);
}
//
- // If the token type is a SAML Token or BinarySecurityToken, try to
find it from the
- // WSDocInfo instance first, to avoid searching the DOM element for it
- //
- if (docInfo != null) {
- Element token = docInfo.getTokenElement(id);
- if (token != null) {
- return token;
- }
- }
-
- //
// Try to find a SAML Assertion by searching the DOM tree
//
if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(type)
@@ -301,6 +275,48 @@ public class SecurityTokenReference {
}
}
+ //
+ // Try to find the element by its (wsu) Id
+ //
+ CallbackLookup callbackLookup = docInfo.getCallbackLookup();
+ if (callbackLookup == null) {
+ callbackLookup = new DOMCallbackLookup(doc);
+ }
+ return callbackLookup.getElement(uri, true);
+ }
+
+ /**
+ * Find a token that has been processed already - in other words, it
access previous
+ * results to find the element, rather than conducting a general search
+ * @param doc Parent Document
+ * @param docInfo WSDocInfo instance
+ * @param cb CallbackHandler instance
+ * @param uri URI of the element
+ * @param type Type of the element
+ * @return A DOM element
+ * @throws WSSecurityException
+ */
+ public Element findProcessedTokenElement(
+ Document doc,
+ WSDocInfo docInfo,
+ CallbackHandler cb,
+ String uri,
+ String type
+ ) throws WSSecurityException {
+ String id = uri;
+ if (id.charAt(0) == '#') {
+ id = id.substring(1);
+ }
+ //
+ // Try to find it from the WSDocInfo instance first
+ //
+ if (docInfo != null) {
+ Element token = docInfo.getTokenElement(id);
+ if (token != null) {
+ return token;
+ }
+ }
+
//
// Try to find a custom token
//
@@ -321,15 +337,7 @@ public class SecurityTokenReference {
// Consume this failure
}
}
-
- //
- // Finally try to find the element by its (wsu) Id
- //
- CallbackLookup callbackLookup = docInfo.getCallbackLookup();
- if (callbackLookup == null) {
- callbackLookup = new DOMCallbackLookup(doc);
- }
- return callbackLookup.getElement(uri, true);
+ return null;
}
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/DerivedKeyTokenProcessor.java
Fri Mar 4 17:25:32 2011
@@ -65,8 +65,7 @@ public class DerivedKeyTokenProcessor im
Element secRefElement = dkt.getSecurityTokenReferenceElement();
if (secRefElement != null) {
STRParser strParser = new DerivedKeyTokenSTRParser();
- strParser.setBspCompliant(config.isWsiBSPCompliant());
- strParser.parseSecurityTokenReference(secRefElement, crypto, cb,
wsDocInfo, null);
+ strParser.parseSecurityTokenReference(secRefElement, crypto, cb,
wsDocInfo, config, null);
secret = strParser.getSecretKey();
} else {
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/EncryptedKeyProcessor.java
Fri Mar 4 17:25:32 2011
@@ -217,10 +217,7 @@ public class EncryptedKeyProcessor imple
);
}
STRParser strParser = new EncryptedKeySTRParser();
- if (config != null) {
- strParser.setBspCompliant(config.isWsiBSPCompliant());
- }
- strParser.parseSecurityTokenReference(strElement, crypto, cb,
wsDocInfo, null);
+ strParser.parseSecurityTokenReference(strElement, crypto, cb,
wsDocInfo, config, null);
X509Certificate[] certs = strParser.getCertificates();
if (certs == null || certs.length < 1 || certs[0] == null) {
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/ReferenceListProcessor.java
Fri Mar 4 17:25:32 2011
@@ -169,11 +169,10 @@ public class ReferenceListProcessor impl
symmetricKey = X509Util.getSharedKey(keyInfoElement, symEncAlgo,
cb);
} else {
STRParser strParser = new SecurityTokenRefSTRParser();
- strParser.setBspCompliant(config.isWsiBSPCompliant());
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put(SecurityTokenRefSTRParser.SIGNATURE_METHOD,
symEncAlgo);
strParser.parseSecurityTokenReference(
- secRefToken, crypto, cb, wsDocInfo, parameters
+ secRefToken, crypto, cb, wsDocInfo, config, parameters
);
byte[] secretKey = strParser.getSecretKey();
symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo,
secretKey);
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
Fri Mar 4 17:25:32 2011
@@ -28,7 +28,6 @@ import org.apache.ws.security.WSSecurity
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.saml.ext.AssertionWrapper;
-import org.apache.ws.security.saml.ext.OpenSAMLUtil;
import org.apache.ws.security.util.DOM2Writer;
import org.apache.ws.security.validate.Credential;
import org.apache.ws.security.validate.SamlAssertionValidator;
@@ -88,16 +87,8 @@ public class SAMLTokenProcessor implemen
if (assertion.isSigned()) {
assertion.verifySignature(crypto, docInfo, config);
}
-
- // Check HOK requirements
- String confirmMethod = null;
- List<String> methods = assertion.getConfirmationMethods();
- if (methods != null && methods.size() > 0) {
- confirmMethod = methods.get(0);
- }
- if (OpenSAMLUtil.isMethodHolderOfKey(confirmMethod)) {
- assertion.parseHOKSubject(crypto, cb, docInfo, config);
- }
+ // Parse the HOK subject if it exists
+ assertion.parseHOKSubject(crypto, cb, docInfo, config);
// Now delegate the rest of the verification to the Validator
validator.setCrypto(crypto);
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/SignatureProcessor.java
Fri Mar 4 17:25:32 2011
@@ -21,6 +21,7 @@ package org.apache.ws.security.processor
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.CustomTokenPrincipal;
import org.apache.ws.security.PublicKeyPrincipal;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDataRef;
@@ -145,21 +146,28 @@ public class SignatureProcessor implemen
validator.validate(credential);
} else {
STRParser strParser = new SignatureSTRParser();
- strParser.setBspCompliant(config.isWsiBSPCompliant());
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put(SignatureSTRParser.SIGNATURE_METHOD,
signatureMethod);
parameters.put(
SignatureSTRParser.SECRET_KEY_LENGTH, new
Integer(config.getSecretKeyLength())
);
strParser.parseSecurityTokenReference(
- strElements.get(0), crypto, cb, wsDocInfo, parameters
+ strElements.get(0), crypto, cb, wsDocInfo, config,
parameters
);
principal = strParser.getPrincipal();
certs = strParser.getCertificates();
publicKey = strParser.getPublicKey();
secretKey = strParser.getSecretKey();
- if (publicKey != null || certs != null) {
+ boolean trusted = false;
+ // See if the certs come from a trusted SAML Assertion
+ if (principal instanceof CustomTokenPrincipal) {
+ trusted = ((CustomTokenPrincipal)principal).isTrusted();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Direct Trust for subject credential of a
trusted SAML Assertion");
+ }
+ }
+ if (!trusted && (publicKey != null || certs != null)) {
Credential credential = new Credential();
credential.setPublicKey(publicKey);
credential.setCertificates(certs);
@@ -193,6 +201,9 @@ public class SignatureProcessor implemen
buildProtectedRefs(
elem.getOwnerDocument(), xmlSignature.getSignedInfo(), config,
wsDocInfo
);
+ if (dataRefs.size() == 0) {
+ throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
+ }
int actionPerformed = WSConstants.SIGN;
if (principal instanceof WSUsernameTokenPrincipal) {
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/SAMLUtil.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/SAMLUtil.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/SAMLUtil.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/SAMLUtil.java
Fri Mar 4 17:25:32 2011
@@ -30,6 +30,7 @@ import org.apache.ws.security.components
import org.apache.ws.security.components.crypto.CryptoType;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.processor.EncryptedKeyProcessor;
+import org.apache.ws.security.processor.Processor;
import org.apache.ws.security.saml.ext.AssertionWrapper;
import org.apache.ws.security.util.Base64;
import org.apache.ws.security.util.WSSecurityUtil;
@@ -67,6 +68,7 @@ public class SAMLUtil {
* @param crypto The Crypto instance to use to obtain certificates
* @param cb The CallbackHandler instance used for secret keys
* @param wsDocInfo The WSDocInfo object that holds previous results
+ * @param config The WSSConfig object used to access configuration
* @return an AssertionWrapper object
* @throws WSSecurityException
*/
@@ -75,9 +77,11 @@ public class SAMLUtil {
Element strElement,
Crypto crypto,
CallbackHandler cb,
- WSDocInfo wsDocInfo
+ WSDocInfo wsDocInfo,
+ WSSConfig config
) throws WSSecurityException {
String keyIdentifierValue = secRef.getKeyIdentifierValue();
+ String type = secRef.getKeyIdentifierValueType();
WSSecurityEngineResult result =
wsDocInfo.getResult(keyIdentifierValue);
AssertionWrapper assertion = null;
@@ -88,10 +92,23 @@ public class SAMLUtil {
return assertion;
} else {
token =
- secRef.getKeyIdentifierTokenElement(
- strElement.getOwnerDocument(), wsDocInfo, cb
+ secRef.findProcessedTokenElement(
+ strElement.getOwnerDocument(), wsDocInfo, cb,
keyIdentifierValue, type
+ );
+ if (token != null) {
+ return new AssertionWrapper(token);
+ }
+ token =
+ secRef.findUnprocessedTokenElement(
+ strElement.getOwnerDocument(), wsDocInfo, cb,
keyIdentifierValue, type
+ );
+ Processor proc = config.getProcessor(WSSecurityEngine.SAML_TOKEN);
+ List<WSSecurityEngineResult> samlResult =
+ proc.handleToken(token, null, crypto, cb, wsDocInfo, config);
+ return
+ (AssertionWrapper)samlResult.get(0).get(
+ WSSecurityEngineResult.TAG_SAML_ASSERTION
);
- return new AssertionWrapper(token);
}
}
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
Fri Mar 4 17:25:32 2011
@@ -22,6 +22,7 @@ package org.apache.ws.security.str;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
@@ -49,16 +50,6 @@ public class DerivedKeyTokenSTRParser im
private byte[] secretKey;
- private boolean bspCompliant = true;
-
- /**
- * Set whether we should process tokens according to the BSP spec
- * @param bspCompliant whether we should process tokens according to the
BSP spec
- */
- public void setBspCompliant(boolean bspCompliant) {
- this.bspCompliant = bspCompliant;
- }
-
/**
* Parse a SecurityTokenReference element and extract credentials.
*
@@ -66,6 +57,7 @@ public class DerivedKeyTokenSTRParser im
* @param crypto The crypto instance used to extract credentials
* @param cb The CallbackHandler instance to supply passwords
* @param wsDocInfo The WSDocInfo object to access previous processing
results
+ * @param config The WSSConfig object used to access configuration
* @param parameters A set of implementation-specific parameters
* @throws WSSecurityException
*/
@@ -74,8 +66,14 @@ public class DerivedKeyTokenSTRParser im
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
+ WSSConfig config,
Map<String, Object> parameters
) throws WSSecurityException {
+ boolean bspCompliant = true;
+ if (config != null) {
+ bspCompliant = config.isWsiBSPCompliant();
+ }
+
SecurityTokenReference secRef = new SecurityTokenReference(strElement,
bspCompliant);
String uri = null;
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java
Fri Mar 4 17:25:32 2011
@@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityEngine;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
@@ -52,16 +53,6 @@ public class EncryptedKeySTRParser imple
private X509Certificate[] certs;
- private boolean bspCompliant = true;
-
- /**
- * Set whether we should process tokens according to the BSP spec
- * @param bspCompliant whether we should process tokens according to the
BSP spec
- */
- public void setBspCompliant(boolean bspCompliant) {
- this.bspCompliant = bspCompliant;
- }
-
/**
* Parse a SecurityTokenReference element and extract credentials.
*
@@ -69,6 +60,7 @@ public class EncryptedKeySTRParser imple
* @param crypto The crypto instance used to extract credentials
* @param cb The CallbackHandler instance to supply passwords
* @param wsDocInfo The WSDocInfo object to access previous processing
results
+ * @param config The WSSConfig object used to access configuration
* @param parameters A set of implementation-specific parameters
* @throws WSSecurityException
*/
@@ -77,8 +69,14 @@ public class EncryptedKeySTRParser imple
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
+ WSSConfig config,
Map<String, Object> parameters
) throws WSSecurityException {
+ boolean bspCompliant = true;
+ if (config != null) {
+ bspCompliant = config.isWsiBSPCompliant();
+ }
+
SecurityTokenReference secRef = new SecurityTokenReference(strElement,
bspCompliant);
//
// Handle X509IssuerSerial here. First check if all elements are
available,
@@ -99,7 +97,7 @@ public class EncryptedKeySTRParser imple
||
WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType()))
{
AssertionWrapper assertion =
SAMLUtil.getAssertionFromKeyIdentifier(
- secRef, strElement, crypto, cb, wsDocInfo
+ secRef, strElement, crypto, cb, wsDocInfo, config
);
SAMLKeyInfo samlKi =
SAMLUtil.getCredentialFromSubject(assertion, crypto, cb,
wsDocInfo, bspCompliant);
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/STRParser.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/STRParser.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/STRParser.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/STRParser.java
Fri Mar 4 17:25:32 2011
@@ -20,6 +20,7 @@
package org.apache.ws.security.str;
import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.w3c.dom.Element;
@@ -37,18 +38,13 @@ import javax.security.auth.callback.Call
public interface STRParser {
/**
- * Set whether we should process tokens according to the BSP spec
- * @param bspCompliant whether we should process tokens according to the
BSP spec
- */
- public void setBspCompliant(boolean bspCompliant);
-
- /**
* Parse a SecurityTokenReference element and extract credentials.
*
* @param strElement The SecurityTokenReference element
* @param crypto The crypto instance used to extract credentials
* @param cb The CallbackHandler instance to supply passwords
* @param wsDocInfo The WSDocInfo object to access previous processing
results
+ * @param config The WSSConfig object used to access configuration
* @param parameters A set of implementation-specific parameters
* @throws WSSecurityException
*/
@@ -57,6 +53,7 @@ public interface STRParser {
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
+ WSSConfig config,
Map<String, Object> parameters
) throws WSSecurityException;
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SecurityTokenRefSTRParser.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SecurityTokenRefSTRParser.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SecurityTokenRefSTRParser.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SecurityTokenRefSTRParser.java
Fri Mar 4 17:25:32 2011
@@ -22,6 +22,7 @@ package org.apache.ws.security.str;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
@@ -55,16 +56,6 @@ public class SecurityTokenRefSTRParser i
private byte[] secretKey;
- private boolean bspCompliant = true;
-
- /**
- * Set whether we should process tokens according to the BSP spec
- * @param bspCompliant whether we should process tokens according to the
BSP spec
- */
- public void setBspCompliant(boolean bspCompliant) {
- this.bspCompliant = bspCompliant;
- }
-
/**
* Parse a SecurityTokenReference element and extract credentials.
*
@@ -72,6 +63,7 @@ public class SecurityTokenRefSTRParser i
* @param crypto The crypto instance used to extract credentials
* @param cb The CallbackHandler instance to supply passwords
* @param wsDocInfo The WSDocInfo object to access previous processing
results
+ * @param config The WSSConfig object used to access configuration
* @param parameters A set of implementation-specific parameters
* @throws WSSecurityException
*/
@@ -80,9 +72,14 @@ public class SecurityTokenRefSTRParser i
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
+ WSSConfig config,
Map<String, Object> parameters
) throws WSSecurityException {
-
+ boolean bspCompliant = true;
+ if (config != null) {
+ bspCompliant = config.isWsiBSPCompliant();
+ }
+
SecurityTokenReference secRef = new SecurityTokenReference(strElement,
bspCompliant);
if (secRef.containsReference()) {
@@ -129,7 +126,7 @@ public class SecurityTokenRefSTRParser i
||
WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType()))
{
AssertionWrapper assertion =
SAMLUtil.getAssertionFromKeyIdentifier(
- secRef, strElement, crypto, cb, wsDocInfo
+ secRef, strElement, crypto, cb, wsDocInfo, config
);
SAMLKeyInfo samlKi =
SAMLUtil.getCredentialFromSubject(assertion, crypto, cb,
wsDocInfo, bspCompliant);
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
Fri Mar 4 17:25:32 2011
@@ -23,6 +23,7 @@ import org.apache.ws.security.CustomToke
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityEngine;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
@@ -34,10 +35,11 @@ import org.apache.ws.security.message.to
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.message.token.UsernameToken;
import org.apache.ws.security.message.token.X509Security;
-import org.apache.ws.security.processor.EncryptedKeyProcessor;
+import org.apache.ws.security.processor.Processor;
import org.apache.ws.security.saml.SAMLKeyInfo;
import org.apache.ws.security.saml.SAMLUtil;
import org.apache.ws.security.saml.ext.AssertionWrapper;
+import org.apache.ws.security.saml.ext.OpenSAMLUtil;
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Element;
@@ -76,16 +78,6 @@ public class SignatureSTRParser implemen
private Principal principal;
- private boolean bspCompliant = true;
-
- /**
- * Set whether we should process tokens according to the BSP spec
- * @param bspCompliant whether we should process tokens according to the
BSP spec
- */
- public void setBspCompliant(boolean bspCompliant) {
- this.bspCompliant = bspCompliant;
- }
-
/**
* Parse a SecurityTokenReference element and extract credentials.
*
@@ -93,6 +85,7 @@ public class SignatureSTRParser implemen
* @param crypto The crypto instance used to extract credentials
* @param cb The CallbackHandler instance to supply passwords
* @param wsDocInfo The WSDocInfo object to access previous processing
results
+ * @param config The WSSConfig object used to access configuration
* @param parameters A set of implementation-specific parameters
* @throws WSSecurityException
*/
@@ -101,8 +94,13 @@ public class SignatureSTRParser implemen
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
+ WSSConfig config,
Map<String, Object> parameters
) throws WSSecurityException {
+ boolean bspCompliant = true;
+ if (config != null) {
+ bspCompliant = config.isWsiBSPCompliant();
+ }
SecurityTokenReference secRef = new SecurityTokenReference(strElement,
bspCompliant);
//
// Here we get some information about the document that is being
@@ -125,22 +123,37 @@ public class SignatureSTRParser implemen
certs = getCertificatesTokenReference(token, crypto);
} else if (el.equals(WSSecurityEngine.SAML_TOKEN)
|| el.equals(WSSecurityEngine.SAML2_TOKEN)) {
-
- AssertionWrapper assertion = new AssertionWrapper(token);
- SAMLKeyInfo samlKi =
- SAMLUtil.getCredentialFromSubject(assertion, crypto,
cb, wsDocInfo, bspCompliant);
- X509Certificate[] foundCerts = samlKi.getCerts();
+ Processor proc =
config.getProcessor(WSSecurityEngine.SAML_TOKEN);
+ //
+ // Just check to see whether the token was processed or not
+ //
+ Element processedToken =
+ secRef.findProcessedTokenElement(
+ strElement.getOwnerDocument(), wsDocInfo, cb, uri,
ref.getValueType()
+ );
+ AssertionWrapper assertion = null;
+ if (processedToken == null) {
+ List<WSSecurityEngineResult> samlResult =
+ proc.handleToken(token, null, crypto, cb,
wsDocInfo, config);
+ assertion =
+ (AssertionWrapper)samlResult.get(0).get(
+ WSSecurityEngineResult.TAG_SAML_ASSERTION
+ );
+ } else {
+ assertion = new AssertionWrapper(processedToken);
+ assertion.parseHOKSubject(crypto, cb, wsDocInfo,
config);
+ }
+ SAMLKeyInfo keyInfo = assertion.getSubjectKeyInfo();
+ X509Certificate[] foundCerts = keyInfo.getCerts();
if (foundCerts != null) {
certs = new X509Certificate[]{foundCerts[0]};
}
- secretKey = samlKi.getSecret();
+ secretKey = keyInfo.getSecret();
principal = createPrincipalFromSAML(assertion);
- } else if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)){
- EncryptedKeyProcessor proc =
- new EncryptedKeyProcessor();
- WSDocInfo docInfo = new
WSDocInfo(token.getOwnerDocument());
+ } else if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)) {
+ Processor proc =
config.getProcessor(WSSecurityEngine.ENCRYPTED_KEY);
List<WSSecurityEngineResult> encrResult =
- proc.handleToken(token, null, crypto, cb, docInfo,
null);
+ proc.handleToken(token, null, crypto, cb, wsDocInfo,
config);
secretKey =
(byte[])encrResult.get(0).get(
WSSecurityEngineResult.TAG_SECRET
@@ -228,7 +241,7 @@ public class SignatureSTRParser implemen
||
WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType()))
{
AssertionWrapper assertion =
SAMLUtil.getAssertionFromKeyIdentifier(
- secRef, strElement, crypto, cb, wsDocInfo
+ secRef, strElement, crypto, cb, wsDocInfo, config
);
SAMLKeyInfo samlKi =
SAMLUtil.getCredentialFromSubject(assertion, crypto, cb,
wsDocInfo, bspCompliant);
@@ -351,6 +364,14 @@ public class SignatureSTRParser implemen
) {
Principal principal = new CustomTokenPrincipal(assertion.getId());
((CustomTokenPrincipal)principal).setTokenObject(assertion);
+ String confirmMethod = null;
+ List<String> methods = assertion.getConfirmationMethods();
+ if (methods != null && methods.size() > 0) {
+ confirmMethod = methods.get(0);
+ }
+ if (OpenSAMLUtil.isMethodHolderOfKey(confirmMethod) &&
assertion.isSigned()) {
+ ((CustomTokenPrincipal)principal).setIsTrusted(true);
+ }
return principal;
}
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/transform/STRTransformUtil.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/transform/STRTransformUtil.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/transform/STRTransformUtil.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/transform/STRTransformUtil.java
Fri Mar 4 17:25:32 2011
@@ -95,7 +95,7 @@ public class STRTransformUtil {
}
if
(WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())
||
WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType()))
{
- return secRef.getKeyIdentifierTokenElement(doc, wsDocInfo,
null);
+ return secRef.getTokenElement(doc, wsDocInfo, null);
} else {
X509Certificate[] certs =
secRef.getKeyIdentifier(wsDocInfo.getCrypto());
if (certs == null || certs.length == 0 || certs[0] == null) {
Modified:
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/AbstractSAMLCallbackHandler.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/AbstractSAMLCallbackHandler.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/AbstractSAMLCallbackHandler.java
(original)
+++
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/AbstractSAMLCallbackHandler.java
Fri Mar 4 17:25:32 2011
@@ -70,6 +70,10 @@ public abstract class AbstractSAMLCallba
this.certIdentifier = certIdentifier;
}
+ public void setCerts(X509Certificate[] certs) {
+ this.certs = certs;
+ }
+
public byte[] getEphemeralKey() {
return ephemeralKey;
}
Modified:
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML1CallbackHandler.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML1CallbackHandler.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML1CallbackHandler.java
(original)
+++
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML1CallbackHandler.java
Fri Mar 4 17:25:32 2011
@@ -39,10 +39,12 @@ import java.io.IOException;
public class SAML1CallbackHandler extends AbstractSAMLCallbackHandler {
public SAML1CallbackHandler() throws Exception {
- Crypto crypto = CryptoFactory.getInstance("wss40.properties");
- CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
- cryptoType.setAlias("wss40");
- certs = crypto.getX509Certificates(cryptoType);
+ if (certs == null) {
+ Crypto crypto = CryptoFactory.getInstance("wss40.properties");
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("wss40");
+ certs = crypto.getX509Certificates(cryptoType);
+ }
subjectName = "uid=joe,ou=people,ou=saml-demo,o=example.com";
subjectQualifier = "www.example.com";
Modified:
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML2CallbackHandler.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML2CallbackHandler.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML2CallbackHandler.java
(original)
+++
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/common/SAML2CallbackHandler.java
Fri Mar 4 17:25:32 2011
@@ -38,10 +38,12 @@ import java.io.IOException;
public class SAML2CallbackHandler extends AbstractSAMLCallbackHandler {
public SAML2CallbackHandler() throws Exception {
- Crypto crypto = CryptoFactory.getInstance("wss40.properties");
- CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
- cryptoType.setAlias("wss40");
- certs = crypto.getX509Certificates(cryptoType);
+ if (certs == null) {
+ Crypto crypto = CryptoFactory.getInstance("wss40.properties");
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("wss40");
+ certs = crypto.getX509Certificates(cryptoType);
+ }
subjectName = "uid=joe,ou=people,ou=saml-demo,o=example.com";
subjectQualifier = "www.example.com";
Modified:
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java?rev=1078063&r1=1078062&r2=1078063&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
(original)
+++
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
Fri Mar 4 17:25:32 2011
@@ -33,6 +33,7 @@ import org.apache.ws.security.common.SAM
import org.apache.ws.security.common.SOAPUtil;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.components.crypto.CryptoType;
import org.apache.ws.security.components.crypto.Merlin;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.saml.ext.AssertionWrapper;
@@ -47,6 +48,7 @@ import javax.security.auth.callback.Call
import java.io.InputStream;
import java.security.KeyStore;
+import java.security.cert.X509Certificate;
import java.util.List;
/**
@@ -525,6 +527,75 @@ public class SignedSamlTokenHOKTest exte
}
/**
+ * Test that creates, sends and processes a signed SAML 1.1 authentication
assertion.
+ * The difference is that we don't trust the user signature, but as we
trust the
+ * signature of the issuer, we have (indirect) trust.
+ */
+ @org.junit.Test
+ @SuppressWarnings("unchecked")
+ public void testSAML1AuthnAssertionTrust() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+ callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
+ Crypto crypto = CryptoFactory.getInstance("crypto.properties");
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("16c73ab6-b892-458f-abf5-2f875f74882e");
+ X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+ callbackHandler.setCerts(certs);
+
+ SAMLIssuer saml = new SAMLIssuerImpl();
+ saml.setIssuerName("www.example.com");
+ saml.setIssuerCrypto(issuerCrypto);
+ saml.setIssuerKeyName("wss40_server");
+ saml.setIssuerKeyPassword("security");
+ saml.setSignAssertion(true);
+ saml.setCallbackHandler(callbackHandler);
+ AssertionWrapper assertion = saml.newAssertion();
+
+ WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
+ wsSign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+ wsSign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256");
+
wsSign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
+ wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document signedDoc =
+ wsSign.build(doc, crypto, assertion, null, null, null, secHeader);
+
+ String outputString =
+
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Signed SAML 1.1 Authn Assertion (key holder):");
+ LOG.debug(outputString);
+ }
+
+ List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto);
+
+ // Test we processed a SAML assertion
+ WSSecurityEngineResult actionResult =
+ WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
+ AssertionWrapper receivedAssertion =
+ (AssertionWrapper)
actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+ assertTrue(receivedAssertion != null);
+ assert receivedAssertion.isSigned();
+
+ // Test we processed a signature (SOAP body)
+ actionResult = WSSecurityUtil.fetchActionResult(results,
WSConstants.SIGN);
+ assertTrue(actionResult != null);
+ assertFalse(actionResult.isEmpty());
+ final List<WSDataRef> refs =
+ (List<WSDataRef>)
actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+ assertTrue(refs.size() == 1);
+
+ WSDataRef wsDataRef = (WSDataRef)refs.get(0);
+ String xpath = wsDataRef.getXpath();
+ assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
+ }
+
+ /**
* Verifies the soap envelope
*
* @param doc