Author: coheigea
Date: Tue Dec 21 12:55:25 2010
New Revision: 1051481
URL: http://svn.apache.org/viewvc?rev=1051481&view=rev
Log:
[WSS-232] - Some cleanup of the STRParser implementations
Modified:
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/SignatureProcessor.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/X509Util.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
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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -57,7 +57,7 @@ public class DerivedKeyTokenProcessor im
if (secRefElement != null) {
STRParser strParser = new DerivedKeyTokenSTRParser();
strParser.parseSecurityTokenReference(
- secRefElement, null, crypto, cb, wsDocInfo, null
+ secRefElement, crypto, cb, wsDocInfo, 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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -184,7 +184,7 @@ public class EncryptedKeyProcessor imple
);
}
STRParser strParser = new EncryptedKeySTRParser();
- strParser.parseSecurityTokenReference(strElement, null, crypto,
cb, wsDocInfo, null);
+ strParser.parseSecurityTokenReference(strElement, crypto, cb,
wsDocInfo, null);
X509Certificate[] certs = strParser.getCertificates();
if (certs == null || certs.length < 1 || certs[0] == null) {
throw new WSSecurityException(
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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -20,7 +20,9 @@
package org.apache.ws.security.processor;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.crypto.SecretKey;
import javax.security.auth.callback.CallbackHandler;
@@ -147,8 +149,10 @@ public class ReferenceListProcessor impl
symmetricKey = X509Util.getSharedKey(keyInfoElement, symEncAlgo,
cb);
} else {
STRParser strParser = new SecurityTokenRefSTRParser();
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ parameters.put(SecurityTokenRefSTRParser.SIGNATURE_METHOD,
symEncAlgo);
strParser.parseSecurityTokenReference(
- secRefToken, symEncAlgo, crypto, cb, wsDocInfo, null
+ secRefToken, crypto, cb, wsDocInfo, parameters
);
byte[] secretKey = strParser.getSecretKey();
symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo,
secretKey);
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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -62,14 +62,19 @@ import javax.xml.crypto.dsig.keyinfo.Key
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
+import java.math.BigInteger;
import java.security.Key;
import java.security.PublicKey;
import java.security.Principal;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class SignatureProcessor implements Processor {
- private static Log log =
LogFactory.getLog(SignatureProcessor.class.getName());
+ private static Log LOG =
LogFactory.getLog(SignatureProcessor.class.getName());
private XMLSignatureFactory signatureFactory =
XMLSignatureFactory.getInstance("DOM");
@@ -83,8 +88,8 @@ public class SignatureProcessor implemen
WSDocInfo wsDocInfo,
WSSConfig wsc
) throws WSSecurityException {
- if (log.isDebugEnabled()) {
- log.debug("Found signature element");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found signature element");
}
Element keyInfoElement =
WSSecurityUtil.getDirectChildElement(
@@ -112,14 +117,19 @@ public class SignatureProcessor implemen
principal = validatePublicKey(cb, publicKey);
} else {
STRParser strParser = new SignatureSTRParser();
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ parameters.put(SignatureSTRParser.SIGNATURE_METHOD,
signatureMethod);
+ parameters.put(
+ SignatureSTRParser.SECRET_KEY_LENGTH, new
Integer(wsc.getSecretKeyLength())
+ );
strParser.parseSecurityTokenReference(
- strElement, signatureMethod, crypto, cb, wsDocInfo, wsc
+ strElement, crypto, cb, wsDocInfo, parameters
);
- strParser.validateCredentials();
principal = strParser.getPrincipal();
certs = strParser.getCertificates();
publicKey = strParser.getPublicKey();
secretKey = strParser.getSecretKey();
+ validateCredentials(certs, crypto);
}
}
@@ -178,6 +188,214 @@ public class SignatureProcessor implemen
}
}
+ /**
+ * Validate the credentials that were extracted from the
SecurityTokenReference
+ * TODO move into Validator
+ * @throws WSSecurityException if the credentials are invalid
+ */
+ private void validateCredentials(
+ X509Certificate[] certs,
+ Crypto crypto
+ ) throws WSSecurityException {
+ //
+ // Validate certificates and verify trust
+ //
+ validateCertificates(certs);
+ if (certs != null) {
+ boolean trust = false;
+ if (certs.length == 1) {
+ trust = verifyTrust(certs[0], crypto);
+ } else if (certs.length > 1) {
+ trust = verifyTrust(certs, crypto);
+ }
+ if (!trust) {
+ throw new
WSSecurityException(WSSecurityException.FAILED_CHECK);
+ }
+ }
+ }
+
+ /**
+ * Validate an array of certificates by checking the validity of each cert
+ * @param certsToValidate The array of certificates to validate
+ * @throws WSSecurityException
+ */
+ private static void validateCertificates(
+ X509Certificate[] certsToValidate
+ ) throws WSSecurityException {
+ if (certsToValidate != null && certsToValidate.length > 0) {
+ try {
+ for (int i = 0; i < certsToValidate.length; i++) {
+ certsToValidate[i].checkValidity();
+ }
+ } catch (CertificateExpiredException e) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_CHECK, "invalidCert", null, e
+ );
+ } catch (CertificateNotYetValidException e) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_CHECK, "invalidCert", null, e
+ );
+ }
+ }
+ }
+
+
+ /**
+ * Evaluate whether a given certificate should be trusted.
+ *
+ * Policy used in this implementation:
+ * 1. Search the keystore for the transmitted certificate
+ * 2. Search the keystore for a connection to the transmitted certificate
+ * (that is, search for certificate(s) of the issuer of the transmitted
certificate
+ * 3. Verify the trust path for those certificates found because the
search for the issuer
+ * might be fooled by a phony DN (String!)
+ *
+ * @param cert the certificate that should be validated against the
keystore
+ * @return true if the certificate is trusted, false if not
+ * @throws WSSecurityException
+ */
+ private static boolean verifyTrust(X509Certificate cert, Crypto crypto)
+ throws WSSecurityException {
+
+ // If no certificate was transmitted, do not trust the signature
+ if (cert == null) {
+ return false;
+ }
+
+ String subjectString = cert.getSubjectX500Principal().getName();
+ String issuerString = cert.getIssuerX500Principal().getName();
+ BigInteger issuerSerial = cert.getSerialNumber();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Transmitted certificate has subject " + subjectString);
+ LOG.debug(
+ "Transmitted certificate has issuer " + issuerString + "
(serial "
+ + issuerSerial + ")"
+ );
+ }
+
+ //
+ // FIRST step - Search the keystore for the transmitted certificate
+ //
+ if (crypto.isCertificateInKeyStore(cert)) {
+ return true;
+ }
+
+ //
+ // SECOND step - Search for the issuer of the transmitted certificate
in the
+ // keystore or the truststore
+ //
+ String[] aliases = crypto.getAliasesForDN(issuerString);
+
+ // If the alias has not been found, the issuer is not in the
keystore/truststore
+ // As a direct result, do not trust the transmitted certificate
+ if (aliases == null || aliases.length < 1) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ "No aliases found in keystore for issuer " + issuerString
+ + " of certificate for " + subjectString
+ );
+ }
+ return false;
+ }
+
+ //
+ // THIRD step
+ // Check the certificate trust path for every alias of the issuer
found in the
+ // keystore/truststore
+ //
+ for (int i = 0; i < aliases.length; i++) {
+ String alias = aliases[i];
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ "Preparing to validate certificate path with alias " +
alias
+ + " for issuer " + issuerString
+ );
+ }
+
+ // Retrieve the certificate(s) for the alias from the
keystore/truststore
+ X509Certificate[] certs = crypto.getCertificates(alias);
+
+ // If no certificates have been found, there has to be an error:
+ // The keystore/truststore can find an alias but no certificate(s)
+ if (certs == null || certs.length < 1) {
+ throw new WSSecurityException(
+ "Could not get certificates for alias " + alias
+ );
+ }
+
+ //
+ // Form a certificate chain from the transmitted certificate
+ // and the certificate(s) of the issuer from the
keystore/truststore
+ //
+ X509Certificate[] x509certs = new X509Certificate[certs.length +
1];
+ x509certs[0] = cert;
+ for (int j = 0; j < certs.length; j++) {
+ x509certs[j + 1] = certs[j];
+ }
+
+ //
+ // Use the validation method from the crypto to check whether the
subjects'
+ // certificate was really signed by the issuer stated in the
certificate
+ //
+ if (crypto.validateCertPath(x509certs)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ "Certificate path has been verified for certificate
with subject "
+ + subjectString
+ );
+ }
+ return true;
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ "Certificate path could not be verified for certificate with
subject "
+ + subjectString
+ );
+ }
+ return false;
+ }
+
+
+ /**
+ * Evaluate whether the given certificate chain should be trusted.
+ *
+ * @param certificates the certificate chain that should be validated
against the keystore
+ * @return true if the certificate chain is trusted, false if not
+ * @throws WSSecurityException
+ */
+ private static boolean verifyTrust(X509Certificate[] certificates, Crypto
crypto)
+ throws WSSecurityException {
+ String subjectString =
certificates[0].getSubjectX500Principal().getName();
+ //
+ // Use the validation method from the crypto to check whether the
subjects'
+ // certificate was really signed by the issuer stated in the
certificate
+ //
+ if (certificates != null && certificates.length > 1
+ && crypto.validateCertPath(certificates)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ "Certificate path has been verified for certificate with
subject "
+ + subjectString
+ );
+ }
+ return true;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ "Certificate path could not be verified for certificate with
subject "
+ + subjectString
+ );
+ }
+
+ return false;
+ }
+
+
private PublicKey parseKeyValue(
Element keyInfoElement
) throws WSSecurityException {
@@ -198,7 +416,7 @@ public class SignatureProcessor implemen
//
return keyValue.getPublicKey();
} catch (java.security.KeyException ex) {
- log.error(ex.getMessage(), ex);
+ LOG.error(ex.getMessage(), ex);
throw new
WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, ex);
}
} else {
@@ -297,8 +515,8 @@ public class SignatureProcessor implemen
String signatureMethod,
WSDocInfo wsDocInfo
) throws WSSecurityException {
- if (log.isDebugEnabled()) {
- log.debug("Verify XML Signature");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Verify XML Signature");
}
//
@@ -329,11 +547,11 @@ public class SignatureProcessor implemen
//
// Log the exact signature error
//
- if (log.isDebugEnabled()) {
- log.debug("XML Signature verification has failed");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("XML Signature verification has failed");
boolean signatureValidationCheck =
xmlSignature.getSignatureValue().validate(context);
- log.debug("Signature Validation check: " +
signatureValidationCheck);
+ LOG.debug("Signature Validation check: " +
signatureValidationCheck);
java.util.Iterator<?> referenceIterator =
xmlSignature.getSignedInfo().getReferences().iterator();
while (referenceIterator.hasNext()) {
@@ -343,7 +561,7 @@ public class SignatureProcessor implemen
if (id == null) {
id = reference.getURI();
}
- log.debug("Reference " + id + " check: " +
referenceValidationCheck);
+ LOG.debug("Reference " + id + " check: " +
referenceValidationCheck);
}
}
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/X509Util.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/X509Util.java?rev=1051481&r1=1051480&r2=1051481&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/X509Util.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/X509Util.java
Tue Dec 21 12:55:25 2010
@@ -27,6 +27,7 @@ import org.apache.ws.security.WSSecurity
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import org.w3c.dom.Text;
import javax.crypto.SecretKey;
import javax.security.auth.callback.Callback;
@@ -78,13 +79,18 @@ public class X509Util {
keyInfoElem, "KeyName", WSConstants.SIG_NS
);
if (keyNmElem != null) {
- keyNmElem.normalize();
- Node tmpN = keyNmElem.getFirstChild();
- if (tmpN != null && tmpN.getNodeType() == Node.TEXT_NODE) {
- keyName = tmpN.getNodeValue();
+
+ Node node = keyNmElem.getFirstChild();
+ StringBuilder builder = new StringBuilder();
+ while (node != null) {
+ if (Node.TEXT_NODE == node.getNodeType()) {
+ builder.append(((Text)node).getData());
+ }
+ node = node.getNextSibling();
}
+ keyName = builder.toString();
}
- if (keyName == null) {
+ if (keyName == null || keyName.length() <= 0) {
throw new
WSSecurityException(WSSecurityException.INVALID_SECURITY, "noKeyname");
}
WSPasswordCallback pwCb = new WSPasswordCallback(keyName,
WSPasswordCallback.KEY_NAME);
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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -22,7 +22,6 @@ 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;
@@ -37,22 +36,36 @@ import java.io.IOException;
import java.security.Principal;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
+import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
+/**
+ * This implementation of STRParser is for parsing a SecurityTokenReference
element associated
+ * with a DerivedKeyToken element.
+ */
public class DerivedKeyTokenSTRParser implements STRParser {
private byte[] secretKey;
+ /**
+ * 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 parameters A set of implementation-specific parameters
+ * @throws WSSecurityException
+ */
public void parseSecurityTokenReference(
Element strElement,
- String algorithm,
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
- WSSConfig wssConfig
+ Map<String, Object> parameters
) throws WSSecurityException {
SecurityTokenReference secRef = new SecurityTokenReference(strElement);
@@ -114,23 +127,34 @@ public class DerivedKeyTokenSTRParser im
}
}
-
- public void validateCredentials() throws WSSecurityException {
- //
- }
-
+ /**
+ * Get the X509Certificates associated with this SecurityTokenReference
+ * @return the X509Certificates associated with this SecurityTokenReference
+ */
public X509Certificate[] getCertificates() {
return null;
}
+ /**
+ * Get the Principal associated with this SecurityTokenReference
+ * @return the Principal associated with this SecurityTokenReference
+ */
public Principal getPrincipal() {
return null;
}
+ /**
+ * Get the PublicKey associated with this SecurityTokenReference
+ * @return the PublicKey associated with this SecurityTokenReference
+ */
public PublicKey getPublicKey() {
return null;
}
+ /**
+ * Get the Secret Key associated with this SecurityTokenReference
+ * @return the Secret Key associated with this SecurityTokenReference
+ */
public byte[] getSecretKey() {
return secretKey;
}
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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -23,7 +23,6 @@ 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;
@@ -37,31 +36,43 @@ import org.w3c.dom.Element;
import java.security.Principal;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
+import java.util.Map;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
+/**
+ * This implementation of STRParser is for parsing a SecurityTokenReference
element, found in the
+ * KeyInfo element associated with an EncryptedKey element
+ */
public class EncryptedKeySTRParser implements STRParser {
private static final Log LOG =
LogFactory.getLog(EncryptedKeySTRParser.class.getName());
private X509Certificate[] certs;
+ /**
+ * 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 parameters A set of implementation-specific parameters
+ * @throws WSSecurityException
+ */
public void parseSecurityTokenReference(
Element strElement,
- String algorithm,
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
- WSSConfig wssConfig
+ Map<String, Object> parameters
) throws WSSecurityException {
SecurityTokenReference secRef = new SecurityTokenReference(strElement);
//
- // handle X509IssuerSerial here. First check if all elements are
available,
+ // Handle X509IssuerSerial here. First check if all elements are
available,
// get the appropriate data, check if all data is available.
- // If all is ok up to that point, look up the certificate alias
according
- // to issuer name and serial number.
- // This method is recommended by OASIS WS-S specification, X509 profile
+ // Then look up the certificate alias according to issuer name and
serial number.
//
if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
String alias = secRef.getX509IssuerSerialAlias(crypto);
@@ -149,23 +160,34 @@ public class EncryptedKeySTRParser imple
}
}
-
- public void validateCredentials() throws WSSecurityException {
- //
- }
-
+ /**
+ * Get the X509Certificates associated with this SecurityTokenReference
+ * @return the X509Certificates associated with this SecurityTokenReference
+ */
public X509Certificate[] getCertificates() {
return certs;
}
+ /**
+ * Get the Principal associated with this SecurityTokenReference
+ * @return the Principal associated with this SecurityTokenReference
+ */
public Principal getPrincipal() {
return null;
}
+ /**
+ * Get the PublicKey associated with this SecurityTokenReference
+ * @return the PublicKey associated with this SecurityTokenReference
+ */
public PublicKey getPublicKey() {
return null;
}
+ /**
+ * Get the Secret Key associated with this SecurityTokenReference
+ * @return the Secret Key associated with this SecurityTokenReference
+ */
public byte[] getSecretKey() {
return null;
}
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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -20,7 +20,6 @@
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;
@@ -28,27 +27,55 @@ import org.w3c.dom.Element;
import java.security.Principal;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
+import java.util.Map;
import javax.security.auth.callback.CallbackHandler;
+/**
+ * This interface describes a pluggable way of extracting credentials from
SecurityTokenReference
+ * elements. The implementations are used by various processors.
+ */
public interface STRParser {
+ /**
+ * 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 parameters A set of implementation-specific parameters
+ * @throws WSSecurityException
+ */
public void parseSecurityTokenReference(
Element strElement,
- String algorithm,
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
- WSSConfig wssConfig
+ Map<String, Object> parameters
) throws WSSecurityException;
- public void validateCredentials() throws WSSecurityException;
-
+ /**
+ * Get the X509Certificates associated with this SecurityTokenReference
+ * @return the X509Certificates associated with this SecurityTokenReference
+ */
public X509Certificate[] getCertificates();
+ /**
+ * Get the Principal associated with this SecurityTokenReference
+ * @return the Principal associated with this SecurityTokenReference
+ */
public Principal getPrincipal();
+ /**
+ * Get the PublicKey associated with this SecurityTokenReference
+ * @return the PublicKey associated with this SecurityTokenReference
+ */
public PublicKey getPublicKey();
+ /**
+ * Get the Secret Key associated with this SecurityTokenReference
+ * @return the Secret Key associated with this SecurityTokenReference
+ */
public byte[] getSecretKey();
}
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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -22,7 +22,6 @@ 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;
@@ -37,21 +36,40 @@ import org.w3c.dom.Element;
import java.security.Principal;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
+import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
+/**
+ * This implementation of STRParser is for parsing a SecurityTokenReference
element, found in the
+ * KeyInfo element associated with an EncryptedData element.
+ */
public class SecurityTokenRefSTRParser implements STRParser {
+ /**
+ * The Signature method. This is used when deriving a key.
+ */
+ public static final String SIGNATURE_METHOD = "signature_method";
+
private byte[] secretKey;
+ /**
+ * 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 parameters A set of implementation-specific parameters
+ * @throws WSSecurityException
+ */
public void parseSecurityTokenReference(
Element strElement,
- String algorithm,
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
- WSSConfig wssConfig
+ Map<String, Object> parameters
) throws WSSecurityException {
SecurityTokenReference secRef = new SecurityTokenReference(strElement);
@@ -73,6 +91,7 @@ public class SecurityTokenRefSTRParser i
(DerivedKeyToken)result.get(WSSecurityEngineResult.TAG_DERIVED_KEY_TOKEN);
byte[] secret =
(byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
+ String algorithm =
(String)parameters.get(SIGNATURE_METHOD);
secretKey =
dkt.deriveKey(WSSecurityUtil.getKeyLength(algorithm), secret);
} else if (WSConstants.ST_UNSIGNED == action) {
Element samlElement = wsDocInfo.getTokenElement(id);
@@ -149,23 +168,34 @@ public class SecurityTokenRefSTRParser i
}
}
-
- public void validateCredentials() throws WSSecurityException {
- //
- }
-
+ /**
+ * Get the X509Certificates associated with this SecurityTokenReference
+ * @return the X509Certificates associated with this SecurityTokenReference
+ */
public X509Certificate[] getCertificates() {
return null;
}
+ /**
+ * Get the Principal associated with this SecurityTokenReference
+ * @return the Principal associated with this SecurityTokenReference
+ */
public Principal getPrincipal() {
return null;
}
+ /**
+ * Get the PublicKey associated with this SecurityTokenReference
+ * @return the PublicKey associated with this SecurityTokenReference
+ */
public PublicKey getPublicKey() {
return null;
}
+ /**
+ * Get the Secret Key associated with this SecurityTokenReference
+ * @return the Secret Key associated with this SecurityTokenReference
+ */
public byte[] getSecretKey() {
return secretKey;
}
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=1051481&r1=1051480&r2=1051481&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
Tue Dec 21 12:55:25 2010
@@ -19,13 +19,10 @@
package org.apache.ws.security.str;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.CustomTokenPrincipal;
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;
@@ -44,21 +41,32 @@ import org.apache.ws.security.util.WSSec
import org.opensaml.SAMLAssertion;
import org.w3c.dom.Element;
-import java.math.BigInteger;
import java.security.Principal;
import java.security.PublicKey;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.List;
+import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
+/**
+ * This implementation of STRParser is for parsing a SecurityTokenReference
element, found in the
+ * KeyInfo element associated with a Signature element.
+ */
public class SignatureSTRParser implements STRParser {
- private static final Log LOG =
LogFactory.getLog(SignatureSTRParser.class.getName());
+ /**
+ * The Signature method. This is used when deriving a key to use for
verifying the signature.
+ */
+ public static final String SIGNATURE_METHOD = "signature_method";
+
+ /**
+ * The secret key length. This is used when deriving a key from a Username
token for the
+ * non-standard WSE implementation.
+ */
+ public static final String SECRET_KEY_LENGTH = "secret_key_length";
private X509Certificate[] certs;
@@ -68,19 +76,23 @@ public class SignatureSTRParser implemen
private Principal principal;
- private boolean validateCertChain;
-
- private Crypto crypto;
-
+ /**
+ * 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 parameters A set of implementation-specific parameters
+ * @throws WSSecurityException
+ */
public void parseSecurityTokenReference(
Element strElement,
- String algorithm,
Crypto crypto,
CallbackHandler cb,
WSDocInfo wsDocInfo,
- WSSConfig wssConfig
+ Map<String, Object> parameters
) throws WSSecurityException {
- this.crypto = crypto;
SecurityTokenReference secRef = new SecurityTokenReference(strElement);
//
// Here we get some information about the document that is being
@@ -101,9 +113,6 @@ public class SignatureSTRParser implemen
QName el = new QName(token.getNamespaceURI(),
token.getLocalName());
if (el.equals(WSSecurityEngine.BINARY_TOKEN)) {
certs = getCertificatesTokenReference(token, crypto);
- if (certs != null && certs.length > 1) {
- validateCertChain = true;
- }
} else if (el.equals(WSSecurityEngine.SAML_TOKEN)) {
if (crypto == null) {
throw new WSSecurityException(
@@ -111,7 +120,10 @@ public class SignatureSTRParser implemen
);
}
SAMLKeyInfo samlKi = SAMLUtil.getSAMLKeyInfo(token,
crypto, cb);
- certs = samlKi.getCerts();
+ X509Certificate[] foundCerts = samlKi.getCerts();
+ if (foundCerts != null) {
+ certs = new X509Certificate[]{foundCerts[0]};
+ }
secretKey = samlKi.getSecret();
principal = createPrincipalFromSAMLKeyInfo(samlKi);
} else if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)){
@@ -139,15 +151,13 @@ public class SignatureSTRParser implemen
if (usernameToken.isDerivedKey()) {
secretKey = usernameToken.getDerivedKey();
} else {
- secretKey =
usernameToken.getSecretKey(wssConfig.getSecretKeyLength());
+ int keyLength =
((Integer)parameters.get(SECRET_KEY_LENGTH)).intValue();
+ secretKey = usernameToken.getSecretKey(keyLength);
}
principal = usernameToken.createPrincipal();
} else if (WSConstants.BST == action) {
certs =
(X509Certificate[])result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATES);
- if (certs != null && certs.length > 1) {
- validateCertChain = true;
- }
} else if (WSConstants.ENCR == action) {
secretKey =
(byte[])result.get(WSSecurityEngineResult.TAG_DECRYPTED_KEY);
String id =
(String)result.get(WSSecurityEngineResult.TAG_ID);
@@ -164,6 +174,7 @@ public class SignatureSTRParser implemen
(DerivedKeyToken)result.get(WSSecurityEngineResult.TAG_DERIVED_KEY_TOKEN);
int keyLength = dkt.getLength();
if (keyLength <= 0) {
+ String algorithm =
(String)parameters.get(SIGNATURE_METHOD);
keyLength = WSSecurityUtil.getKeyLength(algorithm);
}
byte[] secret =
(byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
@@ -178,14 +189,20 @@ public class SignatureSTRParser implemen
Element samlElement = wsDocInfo.getTokenElement(uri);
SAMLKeyInfo keyInfo =
SAMLUtil.getSAMLKeyInfo(samlElement, crypto, cb);
- certs = keyInfo.getCerts();
+ X509Certificate[] foundCerts = keyInfo.getCerts();
+ if (foundCerts != null) {
+ certs = new X509Certificate[]{foundCerts[0]};
+ }
secretKey = keyInfo.getSecret();
publicKey = keyInfo.getPublicKey();
principal = createPrincipalFromSAMLKeyInfo(keyInfo);
}
}
} else if (secRef.containsX509Data() ||
secRef.containsX509IssuerSerial()) {
- certs = secRef.getX509IssuerSerial(crypto);
+ X509Certificate[] foundCerts = secRef.getX509IssuerSerial(crypto);
+ if (foundCerts != null) {
+ certs = new X509Certificate[]{foundCerts[0]};
+ }
} else if (secRef.containsKeyIdentifier()) {
if
(secRef.getKeyIdentifierValueType().equals(SecurityTokenReference.ENC_KEY_SHA1_URI))
{
String id = secRef.getKeyIdentifierValue();
@@ -201,12 +218,18 @@ public class SignatureSTRParser implemen
);
}
SAMLKeyInfo samlKi = SAMLUtil.getSAMLKeyInfo(token, crypto,
cb);
- certs = samlKi.getCerts();
+ X509Certificate[] foundCerts = samlKi.getCerts();
+ if (foundCerts != null) {
+ certs = new X509Certificate[]{foundCerts[0]};
+ }
secretKey = samlKi.getSecret();
publicKey = samlKi.getPublicKey();
principal = createPrincipalFromSAMLKeyInfo(samlKi);
} else {
- certs = secRef.getKeyIdentifier(crypto);
+ X509Certificate[] foundCerts = secRef.getKeyIdentifier(crypto);
+ if (foundCerts != null) {
+ certs = new X509Certificate[]{foundCerts[0]};
+ }
}
} else {
throw new WSSecurityException(
@@ -215,224 +238,42 @@ public class SignatureSTRParser implemen
new Object[]{strElement.toString()}
);
}
- }
-
- public void validateCredentials() throws WSSecurityException {
- //
- // Validate certificates and verify trust
- //
- validateCertificates(certs);
- if (certs != null) {
- if (principal == null) {
- principal = certs[0].getSubjectX500Principal();
- }
- boolean trust = false;
- if (!validateCertChain || certs.length == 1) {
- trust = verifyTrust(certs[0], crypto);
- } else if (validateCertChain && certs.length > 1) {
- trust = verifyTrust(certs, crypto);
- }
- if (!trust) {
- throw new
WSSecurityException(WSSecurityException.FAILED_CHECK);
- }
+
+ if (certs != null && principal == null) {
+ principal = certs[0].getSubjectX500Principal();
}
}
+ /**
+ * Get the X509Certificates associated with this SecurityTokenReference
+ * @return the X509Certificates associated with this SecurityTokenReference
+ */
public X509Certificate[] getCertificates() {
return certs;
}
- public Principal getPrincipal() {
- return principal;
- }
-
- public PublicKey getPublicKey() {
- return publicKey;
- }
-
- public byte[] getSecretKey() {
- return secretKey;
- }
-
/**
- * Validate an array of certificates by checking the validity of each cert
- * @param certsToValidate The array of certificates to validate
- * @throws WSSecurityException
+ * Get the Principal associated with this SecurityTokenReference
+ * @return the Principal associated with this SecurityTokenReference
*/
- private static void validateCertificates(
- X509Certificate[] certsToValidate
- ) throws WSSecurityException {
- if (certsToValidate != null && certsToValidate.length > 0) {
- try {
- for (int i = 0; i < certsToValidate.length; i++) {
- certsToValidate[i].checkValidity();
- }
- } catch (CertificateExpiredException e) {
- throw new WSSecurityException(
- WSSecurityException.FAILED_CHECK, "invalidCert", null, e
- );
- } catch (CertificateNotYetValidException e) {
- throw new WSSecurityException(
- WSSecurityException.FAILED_CHECK, "invalidCert", null, e
- );
- }
- }
+ public Principal getPrincipal() {
+ return principal;
}
-
/**
- * Evaluate whether a given certificate should be trusted.
- *
- * Policy used in this implementation:
- * 1. Search the keystore for the transmitted certificate
- * 2. Search the keystore for a connection to the transmitted certificate
- * (that is, search for certificate(s) of the issuer of the transmitted
certificate
- * 3. Verify the trust path for those certificates found because the
search for the issuer
- * might be fooled by a phony DN (String!)
- *
- * @param cert the certificate that should be validated against the
keystore
- * @return true if the certificate is trusted, false if not
- * @throws WSSecurityException
+ * Get the PublicKey associated with this SecurityTokenReference
+ * @return the PublicKey associated with this SecurityTokenReference
*/
- private static boolean verifyTrust(X509Certificate cert, Crypto crypto)
- throws WSSecurityException {
-
- // If no certificate was transmitted, do not trust the signature
- if (cert == null) {
- return false;
- }
-
- String subjectString = cert.getSubjectX500Principal().getName();
- String issuerString = cert.getIssuerX500Principal().getName();
- BigInteger issuerSerial = cert.getSerialNumber();
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Transmitted certificate has subject " + subjectString);
- LOG.debug(
- "Transmitted certificate has issuer " + issuerString + "
(serial "
- + issuerSerial + ")"
- );
- }
-
- //
- // FIRST step - Search the keystore for the transmitted certificate
- //
- if (crypto.isCertificateInKeyStore(cert)) {
- return true;
- }
-
- //
- // SECOND step - Search for the issuer of the transmitted certificate
in the
- // keystore or the truststore
- //
- String[] aliases = crypto.getAliasesForDN(issuerString);
-
- // If the alias has not been found, the issuer is not in the
keystore/truststore
- // As a direct result, do not trust the transmitted certificate
- if (aliases == null || aliases.length < 1) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "No aliases found in keystore for issuer " + issuerString
- + " of certificate for " + subjectString
- );
- }
- return false;
- }
-
- //
- // THIRD step
- // Check the certificate trust path for every alias of the issuer
found in the
- // keystore/truststore
- //
- for (int i = 0; i < aliases.length; i++) {
- String alias = aliases[i];
-
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "Preparing to validate certificate path with alias " +
alias
- + " for issuer " + issuerString
- );
- }
-
- // Retrieve the certificate(s) for the alias from the
keystore/truststore
- X509Certificate[] certs = crypto.getCertificates(alias);
-
- // If no certificates have been found, there has to be an error:
- // The keystore/truststore can find an alias but no certificate(s)
- if (certs == null || certs.length < 1) {
- throw new WSSecurityException(
- "Could not get certificates for alias " + alias
- );
- }
-
- //
- // Form a certificate chain from the transmitted certificate
- // and the certificate(s) of the issuer from the
keystore/truststore
- //
- X509Certificate[] x509certs = new X509Certificate[certs.length +
1];
- x509certs[0] = cert;
- for (int j = 0; j < certs.length; j++) {
- x509certs[j + 1] = certs[j];
- }
-
- //
- // Use the validation method from the crypto to check whether the
subjects'
- // certificate was really signed by the issuer stated in the
certificate
- //
- if (crypto.validateCertPath(x509certs)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "Certificate path has been verified for certificate
with subject "
- + subjectString
- );
- }
- return true;
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "Certificate path could not be verified for certificate with
subject "
- + subjectString
- );
- }
- return false;
+ public PublicKey getPublicKey() {
+ return publicKey;
}
-
/**
- * Evaluate whether the given certificate chain should be trusted.
- *
- * @param certificates the certificate chain that should be validated
against the keystore
- * @return true if the certificate chain is trusted, false if not
- * @throws WSSecurityException
+ * Get the Secret Key associated with this SecurityTokenReference
+ * @return the Secret Key associated with this SecurityTokenReference
*/
- private static boolean verifyTrust(X509Certificate[] certificates, Crypto
crypto)
- throws WSSecurityException {
- String subjectString =
certificates[0].getSubjectX500Principal().getName();
- //
- // Use the validation method from the crypto to check whether the
subjects'
- // certificate was really signed by the issuer stated in the
certificate
- //
- if (certificates != null && certificates.length > 1
- && crypto.validateCertPath(certificates)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "Certificate path has been verified for certificate with
subject "
- + subjectString
- );
- }
- return true;
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug(
- "Certificate path could not be verified for certificate with
subject "
- + subjectString
- );
- }
-
- return false;
+ public byte[] getSecretKey() {
+ return secretKey;
}
@@ -537,7 +378,6 @@ public class SignatureSTRParser implemen
return pwcb.getKey();
}
-
/**
* Get the Secret Key from a CallbackHandler for the Encrypted Key SHA1
case.
* @param id The id of the element