From 8710f2c02e8ad354292fba6cb915bd0e8f8b1222 Mon Sep 17 00:00:00 2001 From: robm Date: Thu, 13 Oct 2016 15:35:48 +0100 Subject: [PATCH] 8140353: Improve signature checking Reviewed-by: mullan --- .../dsig/internal/dom/DOMSignatureMethod.java | 36 ++++++++++++++++++- .../org/jcp/xml/dsig/internal/dom/Policy.java | 18 ++++++++++ src/share/lib/security/java.security-aix | 10 ++++-- src/share/lib/security/java.security-linux | 10 ++++-- src/share/lib/security/java.security-macosx | 10 ++++-- src/share/lib/security/java.security-solaris | 10 ++++-- src/share/lib/security/java.security-windows | 10 ++++-- 7 files changed, 93 insertions(+), 11 deletions(-) diff --git a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java index bb615d2b2..bc90eab2f 100644 --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java @@ -21,7 +21,7 @@ * under the License. */ /* - * Copyright (c) 2005, 2014, 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. @@ -162,6 +163,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod { if (!(key instanceof PublicKey)) { throw new InvalidKeyException("key must be PublicKey"); } + checkKeySize(context, key); if (signature == null) { try { Provider p = (Provider)context.getProperty @@ -197,6 +199,37 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod { } } + /** + * 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 { @@ -207,6 +240,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod { if (!(key instanceof PrivateKey)) { throw new InvalidKeyException("key must be PrivateKey"); } + checkKeySize(context, key); if (signature == null) { try { Provider p = (Provider)context.getProperty diff --git a/src/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java b/src/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java index af9bea408..1608ad848 100644 --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java @@ -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 disallowedRefUriSchemes = new HashSet<>(); + private static Map 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.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); diff --git a/src/share/lib/security/java.security-aix b/src/share/lib/security/java.security-aix index e00145eda..fd0e680c1 100644 --- a/src/share/lib/security/java.security-aix +++ b/src/share/lib/security/java.security-aix @@ -674,7 +674,7 @@ jdk.tls.legacyAlgorithms= \ # Constraint {"," Constraint } # Constraint: # AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | -# ReferenceUriSchemeConstraint | OtherConstraint +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint # AlgConstraint # "disallowAlg" Uri # MaxTransformsConstraint: @@ -683,12 +683,16 @@ jdk.tls.legacyAlgorithms= \ # "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 @@ -702,6 +706,8 @@ jdk.xml.dsig.secureValidationPolicy=\ maxTransforms 5,\ maxReferences 30,\ disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ noDuplicateIds,\ noRetrievalMethodLoops diff --git a/src/share/lib/security/java.security-linux b/src/share/lib/security/java.security-linux index e00145eda..fd0e680c1 100644 --- a/src/share/lib/security/java.security-linux +++ b/src/share/lib/security/java.security-linux @@ -674,7 +674,7 @@ jdk.tls.legacyAlgorithms= \ # Constraint {"," Constraint } # Constraint: # AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | -# ReferenceUriSchemeConstraint | OtherConstraint +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint # AlgConstraint # "disallowAlg" Uri # MaxTransformsConstraint: @@ -683,12 +683,16 @@ jdk.tls.legacyAlgorithms= \ # "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 @@ -702,6 +706,8 @@ jdk.xml.dsig.secureValidationPolicy=\ maxTransforms 5,\ maxReferences 30,\ disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ noDuplicateIds,\ noRetrievalMethodLoops diff --git a/src/share/lib/security/java.security-macosx b/src/share/lib/security/java.security-macosx index d18678eda..3a177cb21 100644 --- a/src/share/lib/security/java.security-macosx +++ b/src/share/lib/security/java.security-macosx @@ -677,7 +677,7 @@ jdk.tls.legacyAlgorithms= \ # Constraint {"," Constraint } # Constraint: # AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | -# ReferenceUriSchemeConstraint | OtherConstraint +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint # AlgConstraint # "disallowAlg" Uri # MaxTransformsConstraint: @@ -686,12 +686,16 @@ jdk.tls.legacyAlgorithms= \ # "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 @@ -705,6 +709,8 @@ jdk.xml.dsig.secureValidationPolicy=\ maxTransforms 5,\ maxReferences 30,\ disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ noDuplicateIds,\ noRetrievalMethodLoops diff --git a/src/share/lib/security/java.security-solaris b/src/share/lib/security/java.security-solaris index cb34de0b2..07470f6be 100644 --- a/src/share/lib/security/java.security-solaris +++ b/src/share/lib/security/java.security-solaris @@ -676,7 +676,7 @@ jdk.tls.legacyAlgorithms= \ # Constraint {"," Constraint } # Constraint: # AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | -# ReferenceUriSchemeConstraint | OtherConstraint +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint # AlgConstraint # "disallowAlg" Uri # MaxTransformsConstraint: @@ -685,12 +685,16 @@ jdk.tls.legacyAlgorithms= \ # "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 @@ -704,6 +708,8 @@ jdk.xml.dsig.secureValidationPolicy=\ maxTransforms 5,\ maxReferences 30,\ disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ noDuplicateIds,\ noRetrievalMethodLoops diff --git a/src/share/lib/security/java.security-windows b/src/share/lib/security/java.security-windows index a96541994..d53d7682c 100644 --- a/src/share/lib/security/java.security-windows +++ b/src/share/lib/security/java.security-windows @@ -677,7 +677,7 @@ jdk.tls.legacyAlgorithms= \ # Constraint {"," Constraint } # Constraint: # AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint | -# ReferenceUriSchemeConstraint | OtherConstraint +# ReferenceUriSchemeConstraint | KeySizeConstraint | OtherConstraint # AlgConstraint # "disallowAlg" Uri # MaxTransformsConstraint: @@ -686,12 +686,16 @@ jdk.tls.legacyAlgorithms= \ # "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 @@ -705,6 +709,8 @@ jdk.xml.dsig.secureValidationPolicy=\ maxTransforms 5,\ maxReferences 30,\ disallowReferenceUriSchemes file http https,\ + minKeySize RSA 1024,\ + minKeySize DSA 1024,\ noDuplicateIds,\ noRetrievalMethodLoops -- GitLab