--- a/jdk/src/java.base/share/classes/module-info.java Tue Sep 27 16:35:28 2016 +0300
+++ b/jdk/src/java.base/share/classes/module-info.java Tue Oct 04 17:15:49 2016 -0400
@@ -279,6 +279,7 @@
java.security.jgss,
java.security.sasl,
java.smartcardio,
+ java.xml.crypto,
jdk.crypto.ec,
jdk.crypto.token,
jdk.jartool,
--- a/jdk/src/java.base/share/conf/security/java.security Tue Sep 27 16:35:28 2016 +0300
+++ b/jdk/src/java.base/share/conf/security/java.security Tue Oct 04 17:15:49 2016 -0400
@@ -913,7 +913,7 @@
# Constraint {"," Constraint }
# Constraint:
# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint |
-# ReferenceUriSchemeConstraint | OtherConstraint
+# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint
# AlgConstraint
# "disallowAlg" Uri
# MaxTransformsConstraint:
@@ -922,12 +922,16 @@
# "maxReferences" Integer
# ReferenceUriSchemeConstraint:
# "disallowReferenceUriSchemes" String { String }
+# KeySizeConstraint:
+# "minKeySize" KeyAlg Integer
# OtherConstraint:
# "noDuplicateIds" | "noRetrievalMethodLoops"
#
# For AlgConstraint, Uri is the algorithm URI String that is not allowed.
# See the XML Signature Recommendation for more information on algorithm
-# URI Identifiers. If the MaxTransformsConstraint or MaxReferencesConstraint is
+# URI Identifiers. For KeySizeConstraint, KeyAlg is the standard algorithm
+# name of the key type (ex: "RSA"). If the MaxTransformsConstraint,
+# MaxReferencesConstraint or KeySizeConstraint (for the same key type) is
# specified more than once, only the last entry is enforced.
#
# Note: This property is currently used by the JDK Reference implementation. It
@@ -941,6 +945,8 @@
maxTransforms 5,\
maxReferences 30,\
disallowReferenceUriSchemes file http https,\
+ minKeySize RSA 1024,\
+ minKeySize DSA 1024,\
noDuplicateIds,\
noRetrievalMethodLoops
--- a/jdk/src/java.base/share/lib/security/default.policy Tue Sep 27 16:35:28 2016 +0300
+++ b/jdk/src/java.base/share/lib/security/default.policy Tue Oct 04 17:15:49 2016 -0400
@@ -81,6 +81,8 @@
};
grant codeBase "jrt:/java.xml.crypto" {
+ permission java.lang.RuntimePermission
+ "accessClassInPackage.sun.security.util";
permission java.util.PropertyPermission "*", "read";
permission java.security.SecurityPermission "putProviderProperty.XMLDSig";
permission java.security.SecurityPermission
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java Tue Sep 27 16:35:28 2016 +0300
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java Tue Oct 04 17:15:49 2016 -0400
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: DOMSignatureMethod.java 1333415 2012-05-03 12:03:51Z coheigea $
@@ -41,6 +41,7 @@
import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA;
import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
import org.jcp.xml.dsig.internal.SignerOutputStream;
+import sun.security.util.KeyUtil;
/**
* DOM-based abstract implementation of SignatureMethod.
@@ -207,6 +208,7 @@
if (!(key instanceof PublicKey)) {
throw new InvalidKeyException("key must be PublicKey");
}
+ checkKeySize(context, key);
if (signature == null) {
Provider p = (Provider)context.getProperty(
"org.jcp.xml.dsig.internal.dom.SignatureProvider");
@@ -234,6 +236,37 @@
return signature.verify(s);
}
+ /**
+ * If secure validation mode is enabled, checks that the key size is
+ * restricted.
+ *
+ * @param context the context
+ * @param key the key to check
+ * @throws XMLSignatureException if the key size is restricted
+ */
+ private static void checkKeySize(XMLCryptoContext context, Key key)
+ throws XMLSignatureException {
+ if (Utils.secureValidation(context)) {
+ int size = KeyUtil.getKeySize(key);
+ if (size == -1) {
+ // key size cannot be determined, so we cannot check against
+ // restrictions. Note that a DSA key w/o params will be
+ // rejected later if the certificate chain is validated.
+ if (log.isLoggable(java.util.logging.Level.FINE)) {
+ log.log(java.util.logging.Level.FINE, "Size for " +
+ key.getAlgorithm() + " key cannot be determined");
+ }
+ return;
+ }
+ if (Policy.restrictKey(key.getAlgorithm(), size)) {
+ throw new XMLSignatureException(key.getAlgorithm() +
+ " keys less than " +
+ Policy.minKeySize(key.getAlgorithm()) + " bits are" +
+ " forbidden when secure validation is enabled");
+ }
+ }
+ }
+
byte[] sign(Key key, SignedInfo si, XMLSignContext context)
throws InvalidKeyException, XMLSignatureException
{
@@ -244,6 +277,7 @@
if (!(key instanceof PrivateKey)) {
throw new InvalidKeyException("key must be PrivateKey");
}
+ checkKeySize(context, key);
if (signature == null) {
Provider p = (Provider)context.getProperty(
"org.jcp.xml.dsig.internal.dom.SignatureProvider");
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java Tue Sep 27 16:35:28 2016 +0300
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java Tue Oct 04 17:15:49 2016 -0400
@@ -31,8 +31,10 @@
import java.security.PrivilegedAction;
import java.security.Security;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
/**
@@ -46,6 +48,7 @@
private static int maxTrans = Integer.MAX_VALUE;
private static int maxRefs = Integer.MAX_VALUE;
private static Set<String> disallowedRefUriSchemes = new HashSet<>();
+ private static Map<String, Integer> minKeyMap = new HashMap<>();
private static boolean noDuplicateIds = false;
private static boolean noRMLoops = false;
@@ -101,6 +104,13 @@
scheme.toLowerCase(Locale.ROOT));
}
break;
+ case "minKeySize":
+ if (tokens.length != 3) {
+ error(entry);
+ }
+ minKeyMap.put(tokens[1],
+ Integer.parseUnsignedInt(tokens[2]));
+ break;
case "noDuplicateIds":
if (tokens.length != 1) {
error(entry);
@@ -147,6 +157,10 @@
return false;
}
+ public static boolean restrictKey(String type, int size) {
+ return (size < minKeyMap.getOrDefault(type, 0));
+ }
+
public static boolean restrictDuplicateIds() {
return noDuplicateIds;
}
@@ -171,6 +185,10 @@
return Collections.<String>unmodifiableSet(disallowedRefUriSchemes);
}
+ public static int minKeySize(String type) {
+ return minKeyMap.getOrDefault(type, 0);
+ }
+
private static void error(String entry) {
throw new IllegalArgumentException(
"Invalid jdk.xml.dsig.secureValidationPolicy entry: " + entry);