8140353: Improve signature checking
Reviewed-by: xuelei, ahgross, mchung
This commit is contained in:
parent
79f1e4263b
commit
09a11f3b87
@ -279,6 +279,7 @@ module java.base {
|
||||
java.security.jgss,
|
||||
java.security.sasl,
|
||||
java.smartcardio,
|
||||
java.xml.crypto,
|
||||
jdk.crypto.ec,
|
||||
jdk.crypto.token,
|
||||
jdk.jartool,
|
||||
|
@ -913,7 +913,7 @@ crypto.policy=crypto.policydir-tbd
|
||||
# Constraint {"," Constraint }
|
||||
# Constraint:
|
||||
# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint |
|
||||
# ReferenceUriSchemeConstraint | OtherConstraint
|
||||
# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint
|
||||
# AlgConstraint
|
||||
# "disallowAlg" Uri
|
||||
# MaxTransformsConstraint:
|
||||
@ -922,12 +922,16 @@ crypto.policy=crypto.policydir-tbd
|
||||
# "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 @@ jdk.xml.dsig.secureValidationPolicy=\
|
||||
maxTransforms 5,\
|
||||
maxReferences 30,\
|
||||
disallowReferenceUriSchemes file http https,\
|
||||
minKeySize RSA 1024,\
|
||||
minKeySize DSA 1024,\
|
||||
noDuplicateIds,\
|
||||
noRetrievalMethodLoops
|
||||
|
||||
|
@ -81,6 +81,8 @@ grant codeBase "jrt:/java.xml.bind" {
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -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 org.w3c.dom.Element;
|
||||
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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
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");
|
||||
|
@ -31,8 +31,10 @@ import java.security.AccessController;
|
||||
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 @@ public final class Policy {
|
||||
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 @@ public final class Policy {
|
||||
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 @@ public final class Policy {
|
||||
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 @@ public final class Policy {
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user