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 2020/02/12 11:29:26 UTC
[ws-wss4j] branch master updated: Extend automatic signature
algorithm detection with support for EC keys (WSS-663) (#4)
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git
The following commit(s) were added to refs/heads/master by this push:
new 03b5ff5 Extend automatic signature algorithm detection with support for EC keys (WSS-663) (#4)
03b5ff5 is described below
commit 03b5ff5504c08240766aa5d1f281f4c2b7f98a50
Author: Thomas Papke <we...@thopap.de>
AuthorDate: Wed Feb 12 12:29:07 2020 +0100
Extend automatic signature algorithm detection with support for EC keys (WSS-663) (#4)
* Extend automatic signature algorithm detection with support for EC keys
* WSS-663 Missing ECC key support
* Adapt alogrithmSuiteValidator with support for EC keys
* #4 Extend automatic signature algorithm detection with support for EC
keys (WSS-663)
* Apply review feedback regarding validity of the test key
* Adding better default key length validation defaults for EC keys
---
.../org/apache/wss4j/common/WSS4JConstants.java | 8 ++++
.../apache/wss4j/common/crypto/AlgorithmSuite.java | 18 ++++++++
.../common/crypto/AlgorithmSuiteValidator.java | 10 +++++
.../src/test/resources/keys/wss40.jks | Bin 7420 -> 8131 bytes
.../apache/wss4j/dom/message/WSSecSignature.java | 2 +
.../wss4j/dom/message/SignatureKeyValueTest.java | 38 +++++++++++++++++
.../wss4j/dom/saml/SamlAlgorithmSuiteTest.java | 47 +++++++++++++++++++++
7 files changed, 123 insertions(+)
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java b/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java
index 82b7ac1..d3768b2 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java
@@ -148,6 +148,14 @@ public class WSS4JConstants {
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha512";
public static final String HMAC_MD5 =
"http://www.w3.org/2001/04/xmldsig-more#hmac-md5";
+ public static final String ECDSA_SHA1 =
+ "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1";
+ public static final String ECDSA_SHA384 =
+ "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384";
+ public static final String ECDSA_SHA256 =
+ "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
+ public static final String ECDSA_SHA512 =
+ "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512";
public static final String MGF_SHA1 = "http://www.w3.org/2009/xmlenc11#mgf1sha1";
public static final String MGF_SHA224 = "http://www.w3.org/2009/xmlenc11#mgf1sha224";
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/AlgorithmSuite.java b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/AlgorithmSuite.java
index 75039e1..b854eed 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/AlgorithmSuite.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/AlgorithmSuite.java
@@ -44,6 +44,8 @@ public class AlgorithmSuite {
private int minimumSymmetricKeyLength = 128;
private int maximumAsymmetricKeyLength = 4096;
private int minimumAsymmetricKeyLength = 1024;
+ private int maximumEllipticCurveKeyLength = 512;
+ private int minimumEllipticCurveKeyLength = 160;
private int signatureDerivedKeyLength;
private int encryptionDerivedKeyLength;
@@ -173,4 +175,20 @@ public class AlgorithmSuite {
this.minimumSymmetricKeyLength = minimumSymmetricKeyLength;
}
+ public int getMaximumEllipticCurveKeyLength() {
+ return maximumEllipticCurveKeyLength;
+ }
+
+ public void setMaximumEllipticCurveKeyLength(int maximumEllipticCurveKeyLength) {
+ this.maximumEllipticCurveKeyLength = maximumEllipticCurveKeyLength;
+ }
+
+ public int getMinimumEllipticCurveKeyLength() {
+ return minimumEllipticCurveKeyLength;
+ }
+
+ public void setMinimumEllipticCurveKeyLength(int minimumEllipticCurveKeyLength) {
+ this.minimumEllipticCurveKeyLength = minimumEllipticCurveKeyLength;
+ }
+
}
\ No newline at end of file
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/AlgorithmSuiteValidator.java b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/AlgorithmSuiteValidator.java
index 7b4ae29..714101f 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/AlgorithmSuiteValidator.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/AlgorithmSuiteValidator.java
@@ -22,6 +22,7 @@ package org.apache.wss4j.common.crypto;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Set;
@@ -205,6 +206,15 @@ public class AlgorithmSuiteValidator {
);
throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
}
+ } else if (publicKey instanceof ECPublicKey) {
+ final ECPublicKey ecpriv = (ECPublicKey) publicKey;
+ final java.security.spec.ECParameterSpec spec = ecpriv.getParams();
+ int length = spec.getOrder().bitLength();
+ if (length < algorithmSuite.getMinimumEllipticCurveKeyLength()
+ || length > algorithmSuite.getMaximumEllipticCurveKeyLength()) {
+ LOG.warn("The elliptic curve key length does not match the requirement");
+ throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
} else {
LOG.warn(
"An unknown public key was provided"
diff --git a/ws-security-common/src/test/resources/keys/wss40.jks b/ws-security-common/src/test/resources/keys/wss40.jks
index 3cb01db..73ead31 100644
Binary files a/ws-security-common/src/test/resources/keys/wss40.jks and b/ws-security-common/src/test/resources/keys/wss40.jks differ
diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecSignature.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecSignature.java
index 9634ac8..60c1f25 100644
--- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecSignature.java
+++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecSignature.java
@@ -905,6 +905,8 @@ public class WSSecSignature extends WSSecSignatureBase {
sigAlgo = WSConstants.DSA;
} else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
sigAlgo = WSConstants.RSA;
+ } else if (pubKeyAlgo.equalsIgnoreCase("EC")) {
+ sigAlgo = WSConstants.ECDSA_SHA256;
} else {
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE,
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/SignatureKeyValueTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/SignatureKeyValueTest.java
index 39d9aaa..d91fc10 100644
--- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/SignatureKeyValueTest.java
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/SignatureKeyValueTest.java
@@ -181,5 +181,43 @@ public class SignatureKeyValueTest {
((PublicKeyPrincipal)principal).getPublicKey();
assertTrue(publicKey instanceof java.security.interfaces.DSAPublicKey);
}
+
+ /**
+ * Successful ECKeyValue test.
+ */
+ @Test
+ public void testECKeyValue() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader(doc);
+ secHeader.insertSecurityHeader();
+
+ WSSecSignature builder = new WSSecSignature(secHeader);
+ builder.setUserInfo("wss40ec", "security");
+ builder.setKeyIdentifierType(WSConstants.KEY_VALUE);
+ Document signedDoc = builder.build(crypto);
+
+ String outputString =
+ XMLUtils.prettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ assertTrue(outputString.contains("ECKeyValue"));
+
+ WSSecurityEngine secEngine = new WSSecurityEngine();
+ RequestData data = new RequestData();
+ data.setSigVerCrypto(crypto);
+ data.setIgnoredBSPRules(Collections.singletonList(BSPRule.R5417));
+ final WSHandlerResult results =
+ secEngine.processSecurityHeader(signedDoc, data);
+
+ WSSecurityEngineResult actionResult =
+ results.getActionResults().get(WSConstants.SIGN).get(0);
+ assertNotNull(actionResult);
+
+ java.security.Principal principal =
+ (java.security.Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+ assertTrue(principal instanceof PublicKeyPrincipal);
+ java.security.PublicKey publicKey =
+ ((PublicKeyPrincipal)principal).getPublicKey();
+ assertTrue(publicKey instanceof java.security.interfaces.ECPublicKey);
+ }
}
\ No newline at end of file
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlAlgorithmSuiteTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlAlgorithmSuiteTest.java
index df23033..0efdc08 100644
--- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlAlgorithmSuiteTest.java
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlAlgorithmSuiteTest.java
@@ -19,6 +19,7 @@
package org.apache.wss4j.dom.saml;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -195,6 +196,52 @@ public class SamlAlgorithmSuiteTest {
verify(securityHeader, algorithmSuite, crypto);
}
+ @Test
+ public void signWithEcdsaAlgorithm() throws Exception {
+ crypto = CryptoFactory.getInstance("wss40.properties");
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+ callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
+ callbackHandler.setIssuer("www.example.com");
+
+ SAMLCallback samlCallback = new SAMLCallback();
+ SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
+ SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
+
+ samlAssertion.signAssertion(
+ "wss40ec", "security", crypto, false,
+ CanonicalizationMethod.EXCLUSIVE, WSConstants.ECDSA_SHA256);
+
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader(doc);
+ secHeader.insertSecurityHeader();
+
+ WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
+
+ Document signedDoc = wsSign.build(samlAssertion);
+
+ 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) {
+ assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
+ }
+
+ algorithmSuite.addSignatureMethod(WSConstants.ECDSA_SHA1);
+
+ verify(securityHeader, algorithmSuite, crypto);
+ }
+
private AlgorithmSuite createAlgorithmSuite() {
AlgorithmSuite algorithmSuite = new AlgorithmSuite();
algorithmSuite.addSignatureMethod(WSConstants.RSA_SHA1);