You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2012/11/21 18:18:51 UTC
svn commit: r1412201 [1/2] - in /webservices/wss4j/trunk:
ws-security-common/src/main/java/org/apache/ws/security/common/crypto/
ws-security-common/src/main/java/org/apache/ws/security/common/saml/
ws-security-dom/src/main/java/org/apache/ws/security/d...
Author: coheigea
Date: Wed Nov 21 17:18:49 2012
New Revision: 1412201
URL: http://svn.apache.org/viewvc?rev=1412201&view=rev
Log:
[WSS-406] - Add the ability to define which algorithms are acceptable when processing a security header
Conflicts:
ws-security-common/src/main/java/org/apache/ws/security/common/saml/SAMLUtil.java
ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java
ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java
ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java
ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java
ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java
ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java
ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java
ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java
Added:
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java
webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java
webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java
webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/saml/SamlAlgorithmSuiteTest.java
Modified:
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java
Added: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java?rev=1412201&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java (added)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java Wed Nov 21 17:18:49 2012
@@ -0,0 +1,176 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.security.common.crypto;
+
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * This class holds the permitted values for encryption/signature/etc. algorithms on the
+ * inbound side. If the corresponding value is not null then the received algorithm must
+ * match the appropriate algorithm stored in this class.
+ */
+public class AlgorithmSuite {
+
+ private Set<String> signatureMethods = Collections.emptySet();
+ private Set<String> c14nAlgorithms = Collections.emptySet();
+ private Set<String> digestAlgorithms = Collections.emptySet();
+ private Set<String> transformAlgorithms = Collections.emptySet();
+
+ private Set<String> encryptionMethods = Collections.emptySet();
+ private Set<String> keyWrapAlgorithms = Collections.emptySet();
+
+ private Set<String> derivedKeyAlgorithms = Collections.emptySet();
+
+ private int maximumSymmetricKeyLength = 256;
+ private int minimumSymmetricKeyLength = 128;
+ private int maximumAsymmetricKeyLength = 4096;
+ private int minimumAsymmetricKeyLength = 1024;
+
+ private int signatureDerivedKeyLength;
+ private int encryptionDerivedKeyLength;
+
+ public void addSignatureMethod(String signatureMethod) {
+ if (signatureMethods.isEmpty()) {
+ signatureMethods = new HashSet<String>();
+ }
+ signatureMethods.add(signatureMethod);
+ }
+
+ public Set<String> getSignatureMethods() {
+ return signatureMethods;
+ }
+
+ public void addC14nAlgorithm(String c14nAlgorithm) {
+ if (c14nAlgorithms.isEmpty()) {
+ c14nAlgorithms = new HashSet<String>();
+ }
+ c14nAlgorithms.add(c14nAlgorithm);
+ }
+
+ public Set<String> getC14nAlgorithms() {
+ return c14nAlgorithms;
+ }
+
+ public void addDigestAlgorithm(String digestAlgorithm) {
+ if (digestAlgorithms.isEmpty()) {
+ digestAlgorithms = new HashSet<String>();
+ }
+ digestAlgorithms.add(digestAlgorithm);
+ }
+
+ public Set<String> getDigestAlgorithms() {
+ return digestAlgorithms;
+ }
+
+ public void addTransformAlgorithm(String transformAlgorithm) {
+ if (transformAlgorithms.isEmpty()) {
+ transformAlgorithms = new HashSet<String>();
+ }
+ transformAlgorithms.add(transformAlgorithm);
+ }
+
+ public Set<String> getTransformAlgorithms() {
+ return transformAlgorithms;
+ }
+
+ public void addEncryptionMethod(String encryptionMethod) {
+ if (encryptionMethods.isEmpty()) {
+ encryptionMethods = new HashSet<String>();
+ }
+ encryptionMethods.add(encryptionMethod);
+ }
+
+ public Set<String> getEncryptionMethods() {
+ return encryptionMethods;
+ }
+
+ public void addKeyWrapAlgorithm(String keyWrapAlgorithm) {
+ if (keyWrapAlgorithms.isEmpty()) {
+ keyWrapAlgorithms = new HashSet<String>();
+ }
+ keyWrapAlgorithms.add(keyWrapAlgorithm);
+ }
+
+ public Set<String> getKeyWrapAlgorithms() {
+ return keyWrapAlgorithms;
+ }
+
+ public void addDerivedKeyAlgorithm(String derivedKeyAlgorithm) {
+ if (derivedKeyAlgorithms.isEmpty()) {
+ derivedKeyAlgorithms = new HashSet<String>();
+ }
+ derivedKeyAlgorithms.add(derivedKeyAlgorithm);
+ }
+
+ public Set<String> getDerivedKeyAlgorithms() {
+ return derivedKeyAlgorithms;
+ }
+
+ public int getMaximumSymmetricKeyLength() {
+ return maximumSymmetricKeyLength;
+ }
+
+ public void setMaximumSymmetricKeyLength(int maximumSymmetricKeyLength) {
+ this.maximumSymmetricKeyLength = maximumSymmetricKeyLength;
+ }
+
+ public int getMinimumAsymmetricKeyLength() {
+ return minimumAsymmetricKeyLength;
+ }
+
+ public void setMinimumAsymmetricKeyLength(int minimumAsymmetricKeyLength) {
+ this.minimumAsymmetricKeyLength = minimumAsymmetricKeyLength;
+ }
+
+ public int getMaximumAsymmetricKeyLength() {
+ return maximumAsymmetricKeyLength;
+ }
+
+ public void setMaximumAsymmetricKeyLength(int maximumAsymmetricKeyLength) {
+ this.maximumAsymmetricKeyLength = maximumAsymmetricKeyLength;
+ }
+
+ public int getEncryptionDerivedKeyLength() {
+ return encryptionDerivedKeyLength;
+ }
+
+ public void setEncryptionDerivedKeyLength(int encryptionDerivedKeyLength) {
+ this.encryptionDerivedKeyLength = encryptionDerivedKeyLength;
+ }
+
+ public int getSignatureDerivedKeyLength() {
+ return signatureDerivedKeyLength;
+ }
+
+ public void setSignatureDerivedKeyLength(int signatureDerivedKeyLength) {
+ this.signatureDerivedKeyLength = signatureDerivedKeyLength;
+ }
+
+ public int getMinimumSymmetricKeyLength() {
+ return minimumSymmetricKeyLength;
+ }
+
+ public void setMinimumSymmetricKeyLength(int minimumSymmetricKeyLength) {
+ this.minimumSymmetricKeyLength = minimumSymmetricKeyLength;
+ }
+
+}
\ No newline at end of file
Added: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java?rev=1412201&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java (added)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java Wed Nov 21 17:18:49 2012
@@ -0,0 +1,262 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.security.common.crypto;
+
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Set;
+
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLSignature;
+
+import org.apache.ws.security.common.ext.WSSecurityException;
+
+/**
+ * Validate signature/encryption/etc. algorithms against an AlgorithmSuite policy.
+ */
+public class AlgorithmSuiteValidator {
+
+ private static final org.apache.commons.logging.Log LOG =
+ org.apache.commons.logging.LogFactory.getLog(AlgorithmSuiteValidator.class);
+
+ private final AlgorithmSuite algorithmSuite;
+
+ public AlgorithmSuiteValidator(
+ AlgorithmSuite algorithmSuite
+ ) {
+ this.algorithmSuite = algorithmSuite;
+ }
+
+ /**
+ * Check the Signature Method
+ */
+ public void checkSignatureMethod(
+ String signatureMethod
+ ) throws WSSecurityException {
+ Set<String> allowedSignatureMethods = algorithmSuite.getSignatureMethods();
+ if (!allowedSignatureMethods.isEmpty()
+ && !allowedSignatureMethods.contains(signatureMethod)) {
+ LOG.debug(
+ "SignatureMethod " + signatureMethod + " does not match required values"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ }
+
+ /**
+ * Check the C14n Algorithm
+ */
+ public void checkC14nAlgorithm(
+ String c14nAlgorithm
+ ) throws WSSecurityException {
+ Set<String> allowedC14nAlgorithms = algorithmSuite.getC14nAlgorithms();
+ if (!allowedC14nAlgorithms.isEmpty() && !allowedC14nAlgorithms.contains(c14nAlgorithm)) {
+ LOG.debug(
+ "C14nMethod " + c14nAlgorithm + " does not match required value"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ }
+
+ /**
+ * Check the Signature Algorithms
+ */
+ public void checkSignatureAlgorithms(
+ XMLSignature xmlSignature
+ ) throws WSSecurityException {
+ // Signature Algorithm
+ String signatureMethod =
+ xmlSignature.getSignedInfo().getSignatureMethod().getAlgorithm();
+ checkSignatureMethod(signatureMethod);
+
+ // C14n Algorithm
+ String c14nMethod =
+ xmlSignature.getSignedInfo().getCanonicalizationMethod().getAlgorithm();
+ checkC14nAlgorithm(c14nMethod);
+
+ for (Object refObject : xmlSignature.getSignedInfo().getReferences()) {
+ Reference reference = (Reference)refObject;
+ // Digest Algorithm
+ String digestMethod = reference.getDigestMethod().getAlgorithm();
+ Set<String> allowedDigestAlgorithms = algorithmSuite.getDigestAlgorithms();
+ if (!allowedDigestAlgorithms.isEmpty()
+ && !allowedDigestAlgorithms.contains(digestMethod)) {
+ LOG.debug(
+ "DigestMethod " + digestMethod + " does not match required value"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+
+ // Transform Algorithms
+ for (int i = 0; i < reference.getTransforms().size(); i++) {
+ Transform transform = (Transform)reference.getTransforms().get(i);
+ String algorithm = transform.getAlgorithm();
+ Set<String> allowedTransformAlgorithms =
+ algorithmSuite.getTransformAlgorithms();
+ if (!allowedTransformAlgorithms.isEmpty()
+ && !allowedTransformAlgorithms.contains(algorithm)) {
+ LOG.debug(
+ "Transform method " + algorithm + " does not match required value"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ }
+ }
+ }
+
+ public void checkEncryptionKeyWrapAlgorithm(
+ String keyWrapAlgorithm
+ ) throws WSSecurityException {
+ Set<String> keyWrapAlgorithms = algorithmSuite.getKeyWrapAlgorithms();
+ if (!keyWrapAlgorithms.isEmpty()
+ && !keyWrapAlgorithms.contains(keyWrapAlgorithm)) {
+ LOG.debug(
+ "The Key transport method does not match the requirement"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ }
+
+ public void checkSymmetricEncryptionAlgorithm(
+ String symmetricAlgorithm
+ ) throws WSSecurityException {
+ Set<String> encryptionMethods = algorithmSuite.getEncryptionMethods();
+ if (!encryptionMethods.isEmpty()
+ && !encryptionMethods.contains(symmetricAlgorithm)) {
+ LOG.debug(
+ "The encryption algorithm does not match the requirement"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ }
+
+ /**
+ * Check the asymmetric key length
+ */
+ public void checkAsymmetricKeyLength(
+ X509Certificate x509Certificate
+ ) throws WSSecurityException {
+ if (x509Certificate == null) {
+ return;
+ }
+
+ checkAsymmetricKeyLength(x509Certificate.getPublicKey());
+ }
+
+ /**
+ * Check the asymmetric key length
+ */
+ public void checkAsymmetricKeyLength(
+ PublicKey publicKey
+ ) throws WSSecurityException {
+ if (publicKey == null) {
+ return;
+ }
+ if (publicKey instanceof RSAPublicKey) {
+ int modulus = ((RSAPublicKey)publicKey).getModulus().bitLength();
+ if (modulus < algorithmSuite.getMinimumAsymmetricKeyLength()
+ || modulus > algorithmSuite.getMaximumAsymmetricKeyLength()) {
+ LOG.debug(
+ "The asymmetric key length does not match the requirement"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ } else if (publicKey instanceof DSAPublicKey) {
+ int length = ((DSAPublicKey)publicKey).getParams().getP().bitLength();
+ if (length < algorithmSuite.getMinimumAsymmetricKeyLength()
+ || length > algorithmSuite.getMaximumAsymmetricKeyLength()) {
+ LOG.debug(
+ "The asymmetric key length does not match the requirement"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ } else {
+ LOG.debug(
+ "An unknown public key was provided"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ }
+
+ /**
+ * Check the symmetric key length
+ */
+ public void checkSymmetricKeyLength(
+ int secretKeyLength
+ ) throws WSSecurityException {
+ if (secretKeyLength < (algorithmSuite.getMinimumSymmetricKeyLength() / 8)
+ || secretKeyLength > (algorithmSuite.getMaximumSymmetricKeyLength() / 8)) {
+ LOG.debug(
+ "The symmetric key length does not match the requirement"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ }
+
+ /**
+ * Check Signature Derived Key length (in bytes)
+ */
+ public void checkSignatureDerivedKeyLength(
+ int derivedKeyLength
+ ) throws WSSecurityException {
+ int requiredKeyLength = algorithmSuite.getSignatureDerivedKeyLength();
+ if (requiredKeyLength > 0 && (derivedKeyLength / 8) != requiredKeyLength) {
+ LOG.debug(
+ "The signature derived key length of " + derivedKeyLength + " does not match"
+ + "the requirement of " + requiredKeyLength
+ );
+ }
+ }
+
+ /**
+ * Check Encryption Derived Key length (in bytes)
+ */
+ public void checkEncryptionDerivedKeyLength(
+ int derivedKeyLength
+ ) throws WSSecurityException {
+ int requiredKeyLength = algorithmSuite.getEncryptionDerivedKeyLength();
+ if (requiredKeyLength > 0 && (derivedKeyLength / 8) != requiredKeyLength) {
+ LOG.debug(
+ "The encryption derived key length of " + derivedKeyLength + " does not match"
+ + "the requirement of " + requiredKeyLength
+ );
+ }
+ }
+
+ /**
+ * Check Derived Key algorithm
+ */
+ public void checkDerivedKeyAlgorithm(
+ String algorithm
+ ) throws WSSecurityException {
+ Set<String> derivedKeyAlgorithms = algorithmSuite.getDerivedKeyAlgorithms();
+ if (!derivedKeyAlgorithms.isEmpty()
+ && !derivedKeyAlgorithms.contains(algorithm)) {
+ LOG.debug(
+ "The Derived Key Algorithm does not match the requirement"
+ );
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+ }
+
+}
Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java Wed Nov 21 17:18:49 2012
@@ -511,6 +511,21 @@ public class AssertionWrapper {
SAMLUtil.getCredentialFromKeyInfo(
keyInfo.getDOM(), keyInfoProcessor, sigCrypto
);
+ verifySignature(samlKeyInfo);
+ } else {
+ LOG.debug("AssertionWrapper: no signature to validate");
+ }
+
+ }
+
+ /**
+ * Verify the signature of this assertion
+ *
+ * @throws ValidationException
+ */
+ public void verifySignature(SAMLKeyInfo samlKeyInfo) throws WSSecurityException {
+ Signature sig = getSignature();
+ if (sig != null) {
if (samlKeyInfo == null) {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity",
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java Wed Nov 21 17:18:49 2012
@@ -31,6 +31,7 @@ import java.security.Principal;
*/
public class WSDerivedKeyTokenPrincipal implements Principal {
+ private String algorithm;
private String id;
private String nonce;
private String label;
@@ -94,5 +95,14 @@ public class WSDerivedKeyTokenPrincipal
public void setBasetokenId(String basetokenId) {
this.basetokenId = basetokenId;
}
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java Wed Nov 21 17:18:49 2012
@@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.regex.Pattern;
import javax.security.auth.callback.CallbackHandler;
@@ -37,6 +38,7 @@ import org.apache.ws.security.dom.WSSCon
import org.apache.ws.security.dom.bsp.BSPEnforcer;
import org.apache.ws.security.dom.cache.ReplayCache;
import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
import org.apache.ws.security.common.crypto.Crypto;
import org.apache.ws.security.common.ext.WSSecurityException;
import org.apache.ws.security.dom.message.WSSecHeader;
@@ -92,6 +94,8 @@ public class RequestData {
private Collection<Pattern> subjectDNPatterns = new ArrayList<Pattern>();
private final List<BSPRule> ignoredBSPRules = new LinkedList<BSPRule>();
private boolean appendSignatureAfterTimestamp;
+ private AlgorithmSuite algorithmSuite;
+ private Map<QName, AlgorithmSuite> algorithmSuiteMap = Collections.emptyMap();
public void clear() {
soapConstants = null;
@@ -119,6 +123,8 @@ public class RequestData {
subjectDNPatterns.clear();
ignoredBSPRules.clear();
appendSignatureAfterTimestamp = false;
+ algorithmSuite = null;
+ algorithmSuiteMap.clear();
}
public Object getMsgContext() {
@@ -559,4 +565,20 @@ public class RequestData {
this.appendSignatureAfterTimestamp = appendSignatureAfterTimestamp;
}
+ public Map<QName, AlgorithmSuite> getAlgorithmSuiteMap() {
+ return algorithmSuiteMap;
+ }
+
+ public void setAlgorithmSuiteMap(Map<QName, AlgorithmSuite> algorithmSuiteMap) {
+ this.algorithmSuiteMap = algorithmSuiteMap;
+ }
+
+ public AlgorithmSuite getAlgorithmSuite() {
+ return algorithmSuite;
+ }
+
+ public void setAlgorithmSuite(AlgorithmSuite algorithmSuite) {
+ this.algorithmSuite = algorithmSuite;
+ }
+
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java Wed Nov 21 17:18:49 2012
@@ -19,12 +19,28 @@
package org.apache.ws.security.dom.handler;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+
import org.apache.ws.security.dom.WSConstants;
import org.apache.ws.security.dom.WSEncryptionPart;
import org.apache.ws.security.dom.WSSConfig;
import org.apache.ws.security.dom.WSSecurityEngine;
import org.apache.ws.security.dom.WSSecurityEngineResult;
import org.apache.ws.security.dom.action.Action;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
import org.apache.ws.security.common.crypto.Crypto;
import org.apache.ws.security.common.crypto.CryptoFactory;
import org.apache.ws.security.common.ext.WSPasswordCallback;
@@ -36,22 +52,6 @@ import org.apache.ws.security.dom.util.S
import org.apache.ws.security.dom.util.WSSecurityUtil;
import org.w3c.dom.Document;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-
/**
* Extracted from WSDoAllReceiver and WSDoAllSender
* Extended to all passwordless UsernameTokens and configurable identities.
@@ -539,6 +539,35 @@ public abstract class WSHandler {
reqData.setUseSingleCert(useSingleCert);
}
+ protected void decodeAlgorithmSuite(RequestData reqData) throws WSSecurityException {
+ AlgorithmSuite algorithmSuite = new AlgorithmSuite();
+
+ Object mc = reqData.getMsgContext();
+ if (mc == null) {
+ return;
+ }
+
+ String signatureAlgorithm = getString(WSHandlerConstants.SIG_ALGO, mc);
+ if (signatureAlgorithm != null && !"".equals(signatureAlgorithm)) {
+ algorithmSuite.addSignatureMethod(signatureAlgorithm);
+ }
+ String signatureDigestAlgorithm = getString(WSHandlerConstants.SIG_DIGEST_ALGO, mc);
+ if (signatureDigestAlgorithm != null && !"".equals(signatureDigestAlgorithm)) {
+ algorithmSuite.addDigestAlgorithm(signatureDigestAlgorithm);
+ }
+
+ String encrAlgorithm = getString(WSHandlerConstants.ENC_SYM_ALGO, mc);
+ if (encrAlgorithm != null && !"".equals(encrAlgorithm)) {
+ algorithmSuite.addEncryptionMethod(encrAlgorithm);
+ }
+ String transportAlgorithm = getString(WSHandlerConstants.ENC_KEY_TRANSPORT, mc);
+ if (transportAlgorithm != null && !"".equals(transportAlgorithm)) {
+ algorithmSuite.addKeyWrapAlgorithm(transportAlgorithm);
+ }
+
+ reqData.setAlgorithmSuite(algorithmSuite);
+ }
+
protected void decodeEncryptionParameter(RequestData reqData)
throws WSSecurityException {
Object mc = reqData.getMsgContext();
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java Wed Nov 21 17:18:49 2012
@@ -598,7 +598,7 @@ public final class WSHandlerConstants {
/**
* Defines which symmetric encryption algorithm to use. WSS4J supports the
- * following alorithms: {@link WSConstants#TRIPLE_DES},
+ * following algorithms: {@link WSConstants#TRIPLE_DES},
* {@link WSConstants#AES_128}, {@link WSConstants#AES_256},
* and {@link WSConstants#AES_192}. Except for AES 192 all of these
* algorithms are required by the XML Encryption specification.
@@ -612,7 +612,6 @@ public final class WSHandlerConstants {
/**
* Defines which algorithm to use to encrypt the generated symmetric key.
- * Currently WSS4J supports {@link WSConstants#KEYTRANSPORT_RSA15} only.
* <p/>
* The application may set this parameter using the following method:
* <pre>
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java Wed Nov 21 17:18:49 2012
@@ -489,6 +489,7 @@ public class DerivedKeyToken {
principal.setLabel(getLabel());
principal.setLength(getLength());
principal.setOffset(getOffset());
+ principal.setAlgorithm(getAlgorithm());
String basetokenId = null;
SecurityTokenReference securityTokenReference = getSecurityTokenReference();
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java Wed Nov 21 17:18:49 2012
@@ -19,18 +19,20 @@
package org.apache.ws.security.dom.processor;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
import org.apache.ws.security.dom.WSConstants;
import org.apache.ws.security.dom.WSDocInfo;
import org.apache.ws.security.dom.WSSecurityEngineResult;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
import org.apache.ws.security.common.ext.WSSecurityException;
import org.apache.ws.security.dom.handler.RequestData;
import org.apache.ws.security.dom.message.token.DerivedKeyToken;
import org.apache.ws.security.dom.str.DerivedKeyTokenSTRParser;
import org.apache.ws.security.dom.str.STRParser;
-import org.w3c.dom.Element;
-
-
-import java.util.List;
/**
* The processor to process <code>wsc:DerivedKeyToken</code>.
@@ -46,6 +48,17 @@ public class DerivedKeyTokenProcessor im
) throws WSSecurityException {
// Deserialize the DKT
DerivedKeyToken dkt = new DerivedKeyToken(elem, data.getBSPEnforcer());
+
+ // Check for compliance against the defined AlgorithmSuite
+ AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+ if (algorithmSuite != null) {
+ AlgorithmSuiteValidator algorithmSuiteValidator = new
+ AlgorithmSuiteValidator(algorithmSuite);
+ algorithmSuiteValidator.checkDerivedKeyAlgorithm(
+ dkt.getAlgorithm()
+ );
+ }
+
byte[] secret = null;
Element secRefElement = dkt.getSecurityTokenReferenceElement();
if (secRefElement != null) {
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java Wed Nov 21 17:18:49 2012
@@ -19,12 +19,28 @@
package org.apache.ws.security.dom.processor;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.crypto.SecretKey;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
import org.apache.ws.security.dom.WSConstants;
import org.apache.ws.security.dom.WSDataRef;
+import org.apache.ws.security.dom.WSDerivedKeyTokenPrincipal;
import org.apache.ws.security.dom.WSDocInfo;
import org.apache.ws.security.dom.WSSConfig;
import org.apache.ws.security.dom.WSSecurityEngineResult;
import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
import org.apache.ws.security.common.ext.WSSecurityException;
import org.apache.ws.security.dom.bsp.BSPEnforcer;
import org.apache.ws.security.dom.handler.RequestData;
@@ -33,17 +49,6 @@ import org.apache.ws.security.dom.str.Se
import org.apache.ws.security.dom.util.WSSecurityUtil;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.encryption.XMLEncryptionException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import javax.crypto.SecretKey;
-import javax.xml.namespace.QName;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
/**
* This will process incoming <code>xenc:EncryptedData</code> elements.
@@ -91,6 +96,7 @@ public class EncryptedDataProcessor impl
SecretKey key = null;
List<WSSecurityEngineResult> encrKeyResults = null;
+ Principal principal = null;
if (secRefToken != null) {
STRParser strParser = new SecurityTokenRefSTRParser();
Map<String, Object> parameters = new HashMap<String, Object>();
@@ -100,6 +106,7 @@ public class EncryptedDataProcessor impl
wsDocInfo, parameters
);
byte[] secretKey = strParser.getSecretKey();
+ principal = strParser.getPrincipal();
key = WSSecurityUtil.prepareSecretKey(symEncAlgo, secretKey);
} else if (encryptedKeyElement != null) {
EncryptedKeyProcessor encrKeyProc = new EncryptedKeyProcessor();
@@ -113,6 +120,24 @@ public class EncryptedDataProcessor impl
);
}
+ // Check for compliance against the defined AlgorithmSuite
+ AlgorithmSuite algorithmSuite = request.getAlgorithmSuite();
+ if (algorithmSuite != null) {
+ AlgorithmSuiteValidator algorithmSuiteValidator = new
+ AlgorithmSuiteValidator(algorithmSuite);
+
+ if (principal instanceof WSDerivedKeyTokenPrincipal) {
+ algorithmSuiteValidator.checkDerivedKeyAlgorithm(
+ ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
+ );
+ algorithmSuiteValidator.checkEncryptionDerivedKeyLength(
+ ((WSDerivedKeyTokenPrincipal)principal).getLength()
+ );
+ }
+ algorithmSuiteValidator.checkSymmetricKeyLength(key.getEncoded().length);
+ algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
+ }
+
// initialize Cipher ....
XMLCipher xmlCipher = null;
try {
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java Wed Nov 21 17:18:49 2012
@@ -32,7 +32,14 @@ import javax.crypto.SecretKey;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
import org.apache.ws.security.common.ext.WSSecurityException;
import org.apache.ws.security.dom.WSConstants;
import org.apache.ws.security.dom.WSDataRef;
@@ -46,10 +53,6 @@ import org.apache.ws.security.dom.util.W
import org.apache.xml.security.algorithms.JCEMapper;
import org.apache.xml.security.exceptions.Base64DecodingException;
import org.apache.xml.security.utils.Base64;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
public class EncryptedKeyProcessor implements Processor {
private static org.apache.commons.logging.Log log =
@@ -60,6 +63,15 @@ public class EncryptedKeyProcessor imple
RequestData data,
WSDocInfo wsDocInfo
) throws WSSecurityException {
+ return handleToken(elem, data, wsDocInfo, data.getAlgorithmSuite());
+ }
+
+ public List<WSSecurityEngineResult> handleToken(
+ Element elem,
+ RequestData data,
+ WSDocInfo wsDocInfo,
+ AlgorithmSuite algorithmSuite
+ ) throws WSSecurityException {
if (log.isDebugEnabled()) {
log.debug("Found encrypted key element");
}
@@ -104,6 +116,17 @@ public class EncryptedKeyProcessor imple
X509Certificate[] certs =
getCertificatesFromEncryptedKey(elem, data, wsDocInfo, strParser);
+ // Check for compliance against the defined AlgorithmSuite
+ if (algorithmSuite != null) {
+ AlgorithmSuiteValidator algorithmSuiteValidator = new
+ AlgorithmSuiteValidator(algorithmSuite);
+
+ algorithmSuiteValidator.checkAsymmetricKeyLength(certs[0]);
+ algorithmSuiteValidator.checkEncryptionKeyWrapAlgorithm(
+ encryptedKeyTransportMethod
+ );
+ }
+
try {
PrivateKey privateKey = data.getDecCrypto().getPrivateKey(certs[0], data.getCallbackHandler());
OAEPParameterSpec oaepParameterSpec = null;
@@ -377,7 +400,8 @@ public class EncryptedKeyProcessor imple
}
List<WSDataRef> dataRefs = new ArrayList<WSDataRef>();
for (String dataRefURI : dataRefURIs) {
- WSDataRef dataRef = decryptDataRef(doc, dataRefURI, docInfo, decryptedBytes, data);
+ WSDataRef dataRef =
+ decryptDataRef(doc, dataRefURI, docInfo, decryptedBytes, data);
dataRefs.add(dataRef);
}
return dataRefs;
@@ -417,6 +441,16 @@ public class EncryptedKeyProcessor imple
ex, new Object[]{symEncAlgo}
);
}
+
+ // Check for compliance against the defined AlgorithmSuite
+ AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+ if (algorithmSuite != null) {
+ AlgorithmSuiteValidator algorithmSuiteValidator = new
+ AlgorithmSuiteValidator(algorithmSuite);
+
+ algorithmSuiteValidator.checkSymmetricKeyLength(symmetricKey.getEncoded().length);
+ algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
+ }
return ReferenceListProcessor.decryptEncryptedData(
doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java Wed Nov 21 17:18:49 2012
@@ -19,6 +19,7 @@
package org.apache.ws.security.dom.processor;
+import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -26,11 +27,19 @@ import java.util.Map;
import javax.crypto.SecretKey;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
import org.apache.ws.security.dom.WSConstants;
import org.apache.ws.security.dom.WSDataRef;
+import org.apache.ws.security.dom.WSDerivedKeyTokenPrincipal;
import org.apache.ws.security.dom.WSDocInfo;
import org.apache.ws.security.dom.WSSecurityEngineResult;
import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
import org.apache.ws.security.common.ext.WSSecurityException;
import org.apache.ws.security.dom.bsp.BSPEnforcer;
import org.apache.ws.security.dom.handler.RequestData;
@@ -40,12 +49,9 @@ import org.apache.ws.security.dom.messag
import org.apache.ws.security.dom.str.STRParser;
import org.apache.ws.security.dom.str.SecurityTokenRefSTRParser;
import org.apache.ws.security.dom.util.WSSecurityUtil;
+
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.encryption.XMLEncryptionException;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
public class ReferenceListProcessor implements Processor {
private static org.apache.commons.logging.Log log =
@@ -156,6 +162,7 @@ public class ReferenceListProcessor impl
keyInfoElement, "SecurityTokenReference", WSConstants.WSSE_NS
);
SecretKey symmetricKey = null;
+ Principal principal = null;
if (secRefToken == null) {
symmetricKey = X509Util.getSharedKey(keyInfoElement, symEncAlgo, data.getCallbackHandler());
} else {
@@ -167,9 +174,29 @@ public class ReferenceListProcessor impl
wsDocInfo, parameters
);
byte[] secretKey = strParser.getSecretKey();
+ principal = strParser.getPrincipal();
symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo, secretKey);
}
+ // Check for compliance against the defined AlgorithmSuite
+ AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+ if (algorithmSuite != null) {
+ AlgorithmSuiteValidator algorithmSuiteValidator = new
+ AlgorithmSuiteValidator(algorithmSuite);
+
+ if (principal instanceof WSDerivedKeyTokenPrincipal) {
+ algorithmSuiteValidator.checkDerivedKeyAlgorithm(
+ ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
+ );
+ algorithmSuiteValidator.checkEncryptionDerivedKeyLength(
+ ((WSDerivedKeyTokenPrincipal)principal).getLength()
+ );
+ }
+
+ algorithmSuiteValidator.checkSymmetricKeyLength(symmetricKey.getEncoded().length);
+ algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
+ }
+
return
decryptEncryptedData(
doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java Wed Nov 21 17:18:49 2012
@@ -19,27 +19,56 @@
package org.apache.ws.security.dom.processor;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.util.List;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.XMLValidateContext;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
import org.apache.ws.security.dom.SAMLTokenPrincipal;
import org.apache.ws.security.dom.WSConstants;
import org.apache.ws.security.dom.WSDocInfo;
+import org.apache.ws.security.dom.WSSecurityEngine;
import org.apache.ws.security.dom.WSSecurityEngineResult;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
import org.apache.ws.security.common.ext.WSSecurityException;
import org.apache.ws.security.common.saml.AssertionWrapper;
+import org.apache.ws.security.common.saml.SAMLKeyInfo;
+import org.apache.ws.security.common.saml.SAMLUtil;
import org.apache.ws.security.common.util.DOM2Writer;
import org.apache.ws.security.dom.handler.RequestData;
import org.apache.ws.security.dom.saml.WSSSAMLKeyInfoProcessor;
import org.apache.ws.security.dom.validate.Credential;
import org.apache.ws.security.dom.validate.Validator;
-import org.w3c.dom.Element;
-
-import java.util.List;
-import javax.xml.namespace.QName;
+import org.opensaml.security.SAMLSignatureProfileValidator;
+import org.opensaml.xml.signature.KeyInfo;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.validation.ValidationException;
public class SAMLTokenProcessor implements Processor {
private static org.apache.commons.logging.Log log =
org.apache.commons.logging.LogFactory.getLog(SAMLTokenProcessor.class);
-
+ private XMLSignatureFactory signatureFactory;
+
+ public SAMLTokenProcessor() {
+ // Try to install the Santuario Provider - fall back to the JDK provider if this does
+ // not work
+ try {
+ signatureFactory = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
+ } catch (NoSuchProviderException ex) {
+ signatureFactory = XMLSignatureFactory.getInstance("DOM");
+ }
+ }
+
public List<WSSecurityEngineResult> handleToken(
Element elem,
RequestData data,
@@ -107,9 +136,68 @@ public class SAMLTokenProcessor implemen
) throws WSSecurityException {
AssertionWrapper assertion = new AssertionWrapper(token);
if (assertion.isSigned()) {
- assertion.verifySignature(
- new WSSSAMLKeyInfoProcessor(data, docInfo), data.getSigVerCrypto()
- );
+ Signature sig = assertion.getSignature();
+
+ SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
+ try {
+ profileValidator.validate(sig);
+ } catch (ValidationException ex) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+ "empty", ex, "SAML signature validation failed");
+ }
+
+ // Check for compliance against the defined AlgorithmSuite
+ AlgorithmSuite algorithmSuite = null;
+ if (assertion.getSaml2() != null) {
+ algorithmSuite = data.getAlgorithmSuiteMap().get(WSSecurityEngine.SAML2_TOKEN);
+ } else {
+ algorithmSuite = data.getAlgorithmSuiteMap().get(WSSecurityEngine.SAML_TOKEN);
+ }
+
+ KeyInfo keyInfo = sig.getKeyInfo();
+ SAMLKeyInfo samlKeyInfo =
+ SAMLUtil.getCredentialFromKeyInfo(
+ keyInfo.getDOM(),
+ new WSSSAMLKeyInfoProcessor(data, docInfo),
+ data.getSigVerCrypto()
+ );
+
+ if (algorithmSuite != null) {
+ AlgorithmSuiteValidator algorithmSuiteValidator = new
+ AlgorithmSuiteValidator(algorithmSuite);
+
+ PublicKey key = null;
+ if (samlKeyInfo.getCerts() != null && samlKeyInfo.getCerts()[0] != null) {
+ key = samlKeyInfo.getCerts()[0].getPublicKey();
+ } else if (samlKeyInfo.getPublicKey() != null) {
+ key = samlKeyInfo.getPublicKey();
+ } else {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity",
+ new Object[]{"cannot get certificate or key"}
+ );
+ }
+
+ // Not checking signature here, just marshalling into an XMLSignature
+ // structure for testing the transform/digest algorithms etc.
+ XMLValidateContext context = new DOMValidateContext(key, sig.getDOM());
+ context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+
+ XMLSignature xmlSignature;
+ try {
+ xmlSignature = signatureFactory.unmarshalXMLSignature(context);
+ } catch (MarshalException ex) {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.FAILED_CHECK, "invalidSAMLsecurity",
+ new Object[]{"cannot get certificate or key"}, ex
+ );
+ }
+
+ algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
+ algorithmSuiteValidator.checkAsymmetricKeyLength(key);
+ }
+
+ assertion.verifySignature(samlKeyInfo);
}
// Parse the HOK subject if it exists
assertion.parseHOKSubject(
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java Wed Nov 21 17:18:49 2012
@@ -52,13 +52,20 @@ import javax.xml.crypto.dsig.keyinfo.Key
import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
import javax.xml.crypto.dsig.spec.HMACParameterSpec;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
import org.apache.ws.security.common.crypto.Crypto;
import org.apache.ws.security.common.crypto.CryptoType;
import org.apache.ws.security.common.ext.WSSecurityException;
import org.apache.ws.security.dom.PublicKeyPrincipal;
import org.apache.ws.security.dom.WSConstants;
import org.apache.ws.security.dom.WSDataRef;
+import org.apache.ws.security.dom.WSDerivedKeyTokenPrincipal;
import org.apache.ws.security.dom.WSDocInfo;
import org.apache.ws.security.dom.WSSecurityEngine;
import org.apache.ws.security.dom.WSSecurityEngineResult;
@@ -79,9 +86,6 @@ import org.apache.ws.security.dom.util.W
import org.apache.ws.security.dom.util.XmlSchemaDateFormat;
import org.apache.ws.security.dom.validate.Credential;
import org.apache.ws.security.dom.validate.Validator;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
public class SignatureProcessor implements Processor {
private static final org.apache.commons.logging.Log LOG =
@@ -197,6 +201,35 @@ public class SignatureProcessor implemen
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
}
+ // Check for compliance against the defined AlgorithmSuite
+ AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+ if (algorithmSuite != null ) {
+ AlgorithmSuiteValidator algorithmSuiteValidator = new
+ AlgorithmSuiteValidator(algorithmSuite);
+
+ if (principal instanceof WSDerivedKeyTokenPrincipal) {
+ algorithmSuiteValidator.checkDerivedKeyAlgorithm(
+ ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
+ );
+ algorithmSuiteValidator.checkSignatureDerivedKeyLength(
+ ((WSDerivedKeyTokenPrincipal)principal).getLength()
+ );
+ } else {
+ Key key = null;
+ if (certs != null && certs[0] != null) {
+ key = certs[0].getPublicKey();
+ } else if (publicKey != null) {
+ key = publicKey;
+ }
+
+ if (key instanceof PublicKey) {
+ algorithmSuiteValidator.checkAsymmetricKeyLength((PublicKey)key);
+ } else {
+ algorithmSuiteValidator.checkSymmetricKeyLength(secretKey.length);
+ }
+ }
+ }
+
XMLSignature xmlSignature =
verifyXMLSignature(elem, certs, publicKey, secretKey, signatureMethod, data, wsDocInfo);
byte[] signatureValue = xmlSignature.getSignatureValue().getValue();
@@ -371,6 +404,14 @@ public class SignatureProcessor implemen
XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(context);
checkBSPCompliance(xmlSignature, data.getBSPEnforcer());
+ // Check for compliance against the defined AlgorithmSuite
+ AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+ if (algorithmSuite != null) {
+ AlgorithmSuiteValidator algorithmSuiteValidator = new
+ AlgorithmSuiteValidator(algorithmSuite);
+ algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
+ }
+
// Test for replay attacks
testMessageReplay(elem, xmlSignature.getSignatureValue().getValue(), data, wsDocInfo);
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java Wed Nov 21 17:18:49 2012
@@ -61,6 +61,7 @@ public class SecurityTokenRefSTRParser i
public static final String SIGNATURE_METHOD = "signature_method";
private byte[] secretKey;
+ private Principal principal;
/**
* Parse a SecurityTokenReference element and extract credentials.
@@ -190,7 +191,7 @@ public class SecurityTokenRefSTRParser i
* @return the Principal associated with this SecurityTokenReference
*/
public Principal getPrincipal() {
- return null;
+ return principal;
}
/**
@@ -307,6 +308,7 @@ public class SecurityTokenRefSTRParser i
(byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
String algorithm = (String)parameters.get(SIGNATURE_METHOD);
secretKey = dkt.deriveKey(WSSecurityUtil.getKeyLength(algorithm), secret);
+ principal = dkt.createPrincipal();
} else if (WSConstants.ST_UNSIGNED == action || WSConstants.ST_SIGNED == action) {
AssertionWrapper assertion =
(AssertionWrapper)result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
Added: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java?rev=1412201&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java (added)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java Wed Nov 21 17:18:49 2012
@@ -0,0 +1,253 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.security.dom.message;
+
+import java.util.List;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.Crypto;
+import org.apache.ws.security.common.crypto.CryptoFactory;
+import org.apache.ws.security.common.ext.WSSecurityException;
+import org.apache.ws.security.common.util.XMLUtils;
+import org.apache.ws.security.dom.WSConstants;
+import org.apache.ws.security.dom.WSSConfig;
+import org.apache.ws.security.dom.WSSecurityEngine;
+import org.apache.ws.security.dom.WSSecurityEngineResult;
+import org.apache.ws.security.dom.common.KeystoreCallbackHandler;
+import org.apache.ws.security.dom.common.SOAPUtil;
+import org.apache.ws.security.dom.common.SecretKeyCallbackHandler;
+import org.apache.ws.security.dom.handler.RequestData;
+import org.apache.ws.security.dom.util.WSSecurityUtil;
+import org.apache.xml.security.utils.Base64;
+
+/**
+ * A set of test-cases for encrypting and decrypting SOAP requests when specifying an
+ * AlgorithmSuite policy.
+ */
+public class EncryptionAlgorithmSuiteTest extends org.junit.Assert {
+ private static final org.apache.commons.logging.Log LOG =
+ org.apache.commons.logging.LogFactory.getLog(EncryptionAlgorithmSuiteTest.class);
+
+ private Crypto crypto = null;
+
+ public EncryptionAlgorithmSuiteTest() throws Exception {
+ WSSConfig.init();
+ crypto = CryptoFactory.getInstance();
+ }
+
+ @org.junit.Test
+ public void testEncryption() throws Exception {
+ WSSecEncrypt builder = new WSSecEncrypt();
+ builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");
+ builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+ builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document encryptedDoc = builder.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(encryptedDoc);
+ LOG.debug(outputString);
+ }
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ verify(securityHeader, algorithmSuite, crypto);
+
+ algorithmSuite.setMinimumAsymmetricKeyLength(1024);
+
+ try {
+ verify(securityHeader, algorithmSuite, crypto);
+ fail("Expected failure as 512-bit keys are not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testEncryptionKeyTransportRSAOAEP() throws Exception {
+
+ Crypto wssCrypto = CryptoFactory.getInstance("wss40.properties");
+
+ WSSecEncrypt builder = new WSSecEncrypt();
+ builder.setUserInfo("wss40");
+ builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+ builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
+ builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOEP);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document encryptedDoc = builder.build(doc, wssCrypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(encryptedDoc);
+ LOG.debug(outputString);
+ }
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ try {
+ verify(securityHeader, algorithmSuite, wssCrypto);
+ fail("Expected failure as RSA OAEP is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ algorithmSuite.addKeyWrapAlgorithm(WSConstants.KEYTRANSPORT_RSAOEP);
+ verify(securityHeader, algorithmSuite, wssCrypto);
+ }
+
+ @org.junit.Test
+ public void testEncryptionMethodAES128() throws Exception {
+
+ Crypto wssCrypto = CryptoFactory.getInstance("wss40.properties");
+
+ WSSecEncrypt builder = new WSSecEncrypt();
+ builder.setUserInfo("wss40");
+ builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+ builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document encryptedDoc = builder.build(doc, wssCrypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(encryptedDoc);
+ LOG.debug(outputString);
+ }
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ try {
+ verify(securityHeader, algorithmSuite, wssCrypto);
+ fail("Expected failure as AES 128 is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ algorithmSuite.addEncryptionMethod(WSConstants.AES_128);
+ verify(securityHeader, algorithmSuite, wssCrypto);
+ }
+
+ @org.junit.Test
+ public void testSymmetricEncryption() throws Exception {
+
+ KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+ keyGen.init(128);
+ SecretKey key = keyGen.generateKey();
+ byte[] keyData = key.getEncoded();
+
+ WSSecEncrypt builder = new WSSecEncrypt();
+ builder.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
+ builder.setSymmetricKey(key);
+ builder.setEncryptSymmKey(false);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document encryptedDoc = builder.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(encryptedDoc);
+ LOG.debug(outputString);
+ }
+
+ byte[] encodedBytes = WSSecurityUtil.generateDigest(keyData);
+ String identifier = Base64.encode(encodedBytes);
+ SecretKeyCallbackHandler secretKeyCallbackHandler = new SecretKeyCallbackHandler();
+ secretKeyCallbackHandler.addSecretKey(identifier, keyData);
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ WSSecurityEngine secEngine = new WSSecurityEngine();
+ RequestData data = new RequestData();
+ data.setDecCrypto(crypto);
+ data.setCallbackHandler(secretKeyCallbackHandler);
+
+ data.setAlgorithmSuite(algorithmSuite);
+
+ algorithmSuite.addEncryptionMethod(WSConstants.AES_128);
+ secEngine.processSecurityHeader(securityHeader, data);
+
+ algorithmSuite.setMinimumSymmetricKeyLength(256);
+ try {
+ secEngine.processSecurityHeader(securityHeader, data);
+ fail("Expected failure as a 128 bit key is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ algorithmSuite.setMinimumSymmetricKeyLength(64);
+ algorithmSuite.setMaximumSymmetricKeyLength(120);
+ try {
+ secEngine.processSecurityHeader(securityHeader, data);
+ fail("Expected failure as a 128 bit key is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+
+ private AlgorithmSuite createAlgorithmSuite() {
+ AlgorithmSuite algorithmSuite = new AlgorithmSuite();
+ algorithmSuite.setMinimumAsymmetricKeyLength(512);
+ algorithmSuite.addKeyWrapAlgorithm(WSConstants.KEYTRANSPORT_RSA15);
+ algorithmSuite.addEncryptionMethod(WSConstants.TRIPLE_DES);
+
+ return algorithmSuite;
+ }
+
+ private List<WSSecurityEngineResult> verify(
+ Element securityHeader, AlgorithmSuite algorithmSuite, Crypto decCrypto
+ ) throws Exception {
+ WSSecurityEngine secEngine = new WSSecurityEngine();
+ RequestData data = new RequestData();
+ data.setDecCrypto(decCrypto);
+
+ data.setAlgorithmSuite(algorithmSuite);
+
+ data.setCallbackHandler(new KeystoreCallbackHandler());
+
+ return secEngine.processSecurityHeader(securityHeader, data);
+ }
+
+}
Added: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java?rev=1412201&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java (added)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java Wed Nov 21 17:18:49 2012
@@ -0,0 +1,289 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.security.dom.message;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.xml.crypto.dsig.SignatureMethod;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.Crypto;
+import org.apache.ws.security.common.crypto.CryptoFactory;
+import org.apache.ws.security.common.ext.WSSecurityException;
+import org.apache.ws.security.common.util.XMLUtils;
+import org.apache.ws.security.dom.WSConstants;
+import org.apache.ws.security.dom.WSSConfig;
+import org.apache.ws.security.dom.WSSecurityEngine;
+import org.apache.ws.security.dom.WSSecurityEngineResult;
+import org.apache.ws.security.dom.common.SOAPUtil;
+import org.apache.ws.security.dom.common.SecretKeyCallbackHandler;
+import org.apache.ws.security.dom.handler.RequestData;
+import org.apache.ws.security.dom.util.WSSecurityUtil;
+import org.apache.xml.security.utils.Base64;
+
+/**
+ * A set of test-cases for signing and verifying SOAP requests when specifying an
+ * AlgorithmSuite policy.
+ */
+public class SignatureAlgorithmSuiteTest extends org.junit.Assert {
+ private static final org.apache.commons.logging.Log LOG =
+ org.apache.commons.logging.LogFactory.getLog(SignatureAlgorithmSuiteTest.class);
+
+ private Crypto crypto = null;
+
+ public SignatureAlgorithmSuiteTest() throws Exception {
+ WSSConfig.init();
+ crypto = CryptoFactory.getInstance();
+ }
+
+ @org.junit.Test
+ public void testSignature() throws Exception {
+ WSSecSignature builder = new WSSecSignature();
+ builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+ builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+ builder.setSignatureAlgorithm(WSConstants.RSA_SHA1);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc = builder.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ verify(securityHeader, algorithmSuite, crypto);
+
+ algorithmSuite.setMinimumAsymmetricKeyLength(1024);
+
+ try {
+ verify(securityHeader, algorithmSuite, crypto);
+ fail("Expected failure as 512-bit keys are not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testSignatureMethodDSA() throws Exception {
+ Crypto dsaCrypto = CryptoFactory.getInstance("wss40.properties");
+
+ WSSecSignature builder = new WSSecSignature();
+ builder.setUserInfo("wss40DSA", "security");
+ builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+ builder.setSignatureAlgorithm(WSConstants.DSA);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc = builder.build(doc, dsaCrypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ try {
+ verify(securityHeader, algorithmSuite, dsaCrypto);
+ fail("Expected failure as DSA is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ algorithmSuite.addSignatureMethod(WSConstants.DSA);
+ verify(securityHeader, algorithmSuite, dsaCrypto);
+ }
+
+ @org.junit.Test
+ public void testSymmetricKey() throws Exception {
+
+ KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+ keyGen.init(128);
+ SecretKey key = keyGen.generateKey();
+ byte[] keyData = key.getEncoded();
+
+ WSSecSignature builder = new WSSecSignature();
+ builder.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
+ builder.setSecretKey(keyData);
+ builder.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc = builder.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ byte[] encodedBytes = WSSecurityUtil.generateDigest(keyData);
+ String identifier = Base64.encode(encodedBytes);
+ SecretKeyCallbackHandler secretKeyCallbackHandler = new SecretKeyCallbackHandler();
+ secretKeyCallbackHandler.addSecretKey(identifier, keyData);
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ WSSecurityEngine secEngine = new WSSecurityEngine();
+ RequestData data = new RequestData();
+ data.setSigCrypto(crypto);
+ data.setCallbackHandler(secretKeyCallbackHandler);
+ data.setAlgorithmSuite(algorithmSuite);
+
+ try {
+ secEngine.processSecurityHeader(securityHeader, data);
+ fail("Expected failure as HMAC-SHA1 is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ algorithmSuite.addSignatureMethod(WSConstants.HMAC_SHA1);
+ secEngine.processSecurityHeader(securityHeader, data);
+
+ algorithmSuite.setMinimumSymmetricKeyLength(256);
+ try {
+ secEngine.processSecurityHeader(securityHeader, data);
+ fail("Expected failure as a 128 bit key is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ algorithmSuite.setMinimumSymmetricKeyLength(64);
+ algorithmSuite.setMaximumSymmetricKeyLength(120);
+ try {
+ secEngine.processSecurityHeader(securityHeader, data);
+ fail("Expected failure as a 128 bit key is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testC14nMethod() throws Exception {
+ WSSecSignature builder = new WSSecSignature();
+ builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+ builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+ builder.setSignatureAlgorithm(WSConstants.RSA_SHA1);
+ builder.setSigCanonicalization(WSConstants.C14N_EXCL_WITH_COMMENTS);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc = builder.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ try {
+ verify(securityHeader, algorithmSuite, crypto);
+ fail("Expected failure as C14n algorithm is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ algorithmSuite.addC14nAlgorithm(WSConstants.C14N_EXCL_WITH_COMMENTS);
+ verify(securityHeader, algorithmSuite, crypto);
+ }
+
+ @org.junit.Test
+ public void testDigestMethod() throws Exception {
+ WSSecSignature builder = new WSSecSignature();
+ builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+ builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+ builder.setSignatureAlgorithm(WSConstants.RSA_SHA1);
+ builder.setDigestAlgo(WSConstants.SHA256);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+ Document signedDoc = builder.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+ AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+
+ try {
+ verify(securityHeader, algorithmSuite, crypto);
+ fail("Expected failure as Digest algorithm is not allowed");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ algorithmSuite.addDigestAlgorithm(WSConstants.SHA256);
+ verify(securityHeader, algorithmSuite, crypto);
+ }
+
+ private AlgorithmSuite createAlgorithmSuite() {
+ AlgorithmSuite algorithmSuite = new AlgorithmSuite();
+ algorithmSuite.addSignatureMethod(WSConstants.RSA_SHA1);
+ algorithmSuite.setMinimumAsymmetricKeyLength(512);
+ algorithmSuite.addC14nAlgorithm(WSConstants.C14N_EXCL_OMIT_COMMENTS);
+ algorithmSuite.addDigestAlgorithm(WSConstants.SHA1);
+
+ return algorithmSuite;
+ }
+
+ private List<WSSecurityEngineResult> verify(
+ Element securityHeader, AlgorithmSuite algorithmSuite, Crypto sigVerCrypto
+ ) throws Exception {
+ WSSecurityEngine secEngine = new WSSecurityEngine();
+ RequestData data = new RequestData();
+ data.setSigVerCrypto(sigVerCrypto);
+
+ data.setAlgorithmSuite(algorithmSuite);
+
+ List<BSPRule> ignoredRules = new ArrayList<BSPRule>();
+ ignoredRules.add(BSPRule.R5404);
+ ignoredRules.add(BSPRule.R5406);
+ data.setIgnoredBSPRules(ignoredRules);
+
+ return secEngine.processSecurityHeader(securityHeader, data);
+ }
+
+}