提交 c5df4fc8 编写于 作者: R robm

8140422: Add mechanism to allow non default root CAs to be not subject to algorithm restrictions

Reviewed-by: ascarpino
上级 4a0b431d
/* /*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,12 +31,10 @@ import java.util.Collection; ...@@ -31,12 +31,10 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509CRL; import java.security.cert.X509CRL;
...@@ -48,10 +46,13 @@ import java.security.cert.CertificateException; ...@@ -48,10 +46,13 @@ import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.PKIXReason; import java.security.cert.PKIXReason;
import java.io.IOException; import java.security.interfaces.DSAParams;
import java.security.interfaces.*; import java.security.interfaces.DSAPublicKey;
import java.security.spec.*; import java.security.spec.DSAPublicKeySpec;
import sun.security.util.AnchorCertificates;
import sun.security.util.CertConstraintParameters;
import sun.security.util.Debug;
import sun.security.util.DisabledAlgorithmConstraints; import sun.security.util.DisabledAlgorithmConstraints;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CRLImpl; import sun.security.x509.X509CRLImpl;
...@@ -69,6 +70,7 @@ import sun.security.x509.AlgorithmId; ...@@ -69,6 +70,7 @@ import sun.security.x509.AlgorithmId;
* @see PKIXParameters * @see PKIXParameters
*/ */
final public class AlgorithmChecker extends PKIXCertPathChecker { final public class AlgorithmChecker extends PKIXCertPathChecker {
private static final Debug debug = Debug.getInstance("certpath");
private final AlgorithmConstraints constraints; private final AlgorithmConstraints constraints;
private final PublicKey trustedPubKey; private final PublicKey trustedPubKey;
...@@ -88,6 +90,14 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -88,6 +90,14 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
certPathDefaultConstraints = new DisabledAlgorithmConstraints( certPathDefaultConstraints = new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
// If there is no "cacerts" keyword, then disable anchor checking
private static final boolean publicCALimits =
certPathDefaultConstraints.checkProperty("jdkCA");
// If anchor checking enabled, this will be true if the trust anchor
// has a match in the cacerts file
private boolean trustedMatch = false;
/** /**
* Create a new <code>AlgorithmChecker</code> with the algorithm * Create a new <code>AlgorithmChecker</code> with the algorithm
* constraints specified in security property * constraints specified in security property
...@@ -136,6 +146,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -136,6 +146,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
if (anchor.getTrustedCert() != null) { if (anchor.getTrustedCert() != null) {
this.trustedPubKey = anchor.getTrustedCert().getPublicKey(); this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
// Check for anchor certificate restrictions
trustedMatch = checkFingerprint(anchor.getTrustedCert());
if (trustedMatch && debug != null) {
debug.println("trustedMatch = true");
}
} else { } else {
this.trustedPubKey = anchor.getCAPublicKey(); this.trustedPubKey = anchor.getCAPublicKey();
} }
...@@ -144,6 +159,19 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -144,6 +159,19 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
this.constraints = constraints; this.constraints = constraints;
} }
// Check this 'cert' for restrictions in the AnchorCertificates
// trusted certificates list
private static boolean checkFingerprint(X509Certificate cert) {
if (!publicCALimits) {
return false;
}
if (debug != null) {
debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName());
}
return AnchorCertificates.contains(cert);
}
@Override @Override
public void init(boolean forward) throws CertPathValidatorException { public void init(boolean forward) throws CertPathValidatorException {
// Note that this class does not support forward mode. // Note that this class does not support forward mode.
...@@ -181,36 +209,8 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -181,36 +209,8 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
return; return;
} }
X509CertImpl x509Cert = null;
try {
x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
PublicKey currPubKey = x509Cert.getPublicKey();
String currSigAlg = x509Cert.getSigAlgName();
AlgorithmId algorithmId = null;
try {
algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
// Check the current signature algorithm
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
// check the key usage and key size // check the key usage and key size
boolean[] keyUsage = x509Cert.getKeyUsage(); boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage();
if (keyUsage != null && keyUsage.length < 9) { if (keyUsage != null && keyUsage.length < 9) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"incorrect KeyUsage extension", "incorrect KeyUsage extension",
...@@ -248,28 +248,68 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -248,28 +248,68 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
if (primitives.isEmpty()) { if (primitives.isEmpty()) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"incorrect KeyUsage extension", "incorrect KeyUsage extension bits",
null, null, -1, PKIXReason.INVALID_KEY_USAGE); null, null, -1, PKIXReason.INVALID_KEY_USAGE);
} }
} }
PublicKey currPubKey = cert.getPublicKey();
// Check against DisabledAlgorithmConstraints certpath constraints.
// permits() will throw exception on failure.
certPathDefaultConstraints.permits(primitives,
new CertConstraintParameters((X509Certificate)cert,
trustedMatch));
// new CertConstraintParameters(x509Cert, trustedMatch));
// If there is no previous key, set one and exit
if (prevPubKey == null) {
prevPubKey = currPubKey;
return;
}
X509CertImpl x509Cert;
AlgorithmId algorithmId;
try {
x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
String currSigAlg = x509Cert.getSigAlgName();
// If 'constraints' is not of DisabledAlgorithmConstraints, check all
// everything individually
if (!(constraints instanceof DisabledAlgorithmConstraints)) {
// Check the current signature algorithm
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on signature " +
"algorithm: " + currSigAlg, null, null, -1,
BasicReason.ALGORITHM_CONSTRAINED);
}
if (!constraints.permits(primitives, currPubKey)) { if (!constraints.permits(primitives, currPubKey)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"algorithm constraints check failed", "Algorithm constraints check failed on keysize: " +
sun.security.util.KeyUtil.getKeySize(currPubKey),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
}
// Check with previous cert for signature algorithm and public key // Check with previous cert for signature algorithm and public key
if (prevPubKey != null) { if (prevPubKey != null) {
if (currSigAlg != null) {
if (!constraints.permits( if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET, SIGNATURE_PRIMITIVE_SET,
currSigAlg, prevPubKey, currSigAlgParams)) { currSigAlg, prevPubKey, currSigAlgParams)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"Algorithm constraints check failed: " + currSigAlg, "Algorithm constraints check failed on " +
"signature algorithm: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
}
// Inherit key parameters from previous key // Inherit key parameters from previous key
if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) { if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
...@@ -282,7 +322,7 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -282,7 +322,7 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
DSAParams params = ((DSAPublicKey)prevPubKey).getParams(); DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
if (params == null) { if (params == null) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"Key parameters missing"); "Key parameters missing from public key.");
} }
try { try {
...@@ -330,6 +370,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -330,6 +370,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
// Don't bother to change the trustedPubKey. // Don't bother to change the trustedPubKey.
if (anchor.getTrustedCert() != null) { if (anchor.getTrustedCert() != null) {
prevPubKey = anchor.getTrustedCert().getPublicKey(); prevPubKey = anchor.getTrustedCert().getPublicKey();
// Check for anchor certificate restrictions
trustedMatch = checkFingerprint(anchor.getTrustedCert());
if (trustedMatch && debug != null) {
debug.println("trustedMatch = true");
}
} else { } else {
prevPubKey = anchor.getCAPublicKey(); prevPubKey = anchor.getCAPublicKey();
} }
...@@ -370,7 +415,8 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -370,7 +415,8 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
if (!certPathDefaultConstraints.permits( if (!certPathDefaultConstraints.permits(
SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) { SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"algorithm check failed: " + sigAlgName + " is disabled", "Algorithm constraints check failed on signature algorithm: " +
sigAlgName + " is disabled",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
} }
......
...@@ -131,8 +131,8 @@ class PKIXMasterCertPathValidator { ...@@ -131,8 +131,8 @@ class PKIXMasterCertPathValidator {
} catch (CertPathValidatorException cpve) { } catch (CertPathValidatorException cpve) {
throw new CertPathValidatorException(cpve.getMessage(), throw new CertPathValidatorException(cpve.getMessage(),
cpve.getCause(), cpOriginal, cpSize - (i + 1), (cpve.getCause() != null) ? cpve.getCause() : cpve,
cpve.getReason()); cpOriginal, cpSize - (i + 1), cpve.getReason());
} }
} }
......
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,7 +29,6 @@ import java.security.AccessController; ...@@ -29,7 +29,6 @@ import java.security.AccessController;
import java.security.AlgorithmConstraints; import java.security.AlgorithmConstraints;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.Security; import java.security.Security;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
...@@ -45,8 +44,7 @@ public abstract class AbstractAlgorithmConstraints ...@@ -45,8 +44,7 @@ public abstract class AbstractAlgorithmConstraints
} }
// Get algorithm constraints from the specified security property. // Get algorithm constraints from the specified security property.
private static void loadAlgorithmsMap(Map<String, String[]> algorithmsMap, static String[] getAlgorithms(String propertyName) {
String propertyName) {
String property = AccessController.doPrivileged( String property = AccessController.doPrivileged(
new PrivilegedAction<String>() { new PrivilegedAction<String>() {
@Override @Override
...@@ -72,18 +70,7 @@ public abstract class AbstractAlgorithmConstraints ...@@ -72,18 +70,7 @@ public abstract class AbstractAlgorithmConstraints
if (algorithmsInProperty == null) { if (algorithmsInProperty == null) {
algorithmsInProperty = new String[0]; algorithmsInProperty = new String[0];
} }
algorithmsMap.put(propertyName, algorithmsInProperty); return algorithmsInProperty;
}
static String[] getAlgorithms(Map<String, String[]> algorithmsMap,
String propertyName) {
synchronized (algorithmsMap) {
if (!algorithmsMap.containsKey(propertyName)) {
loadAlgorithmsMap(algorithmsMap, propertyName);
}
return algorithmsMap.get(propertyName);
}
} }
static boolean checkAlgorithm(String[] algorithms, String algorithm, static boolean checkAlgorithm(String[] algorithms, String algorithm,
......
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -38,19 +38,7 @@ public class AlgorithmDecomposer { ...@@ -38,19 +38,7 @@ public class AlgorithmDecomposer {
private static final Pattern pattern = private static final Pattern pattern =
Pattern.compile("with|and", Pattern.CASE_INSENSITIVE); Pattern.compile("with|and", Pattern.CASE_INSENSITIVE);
/** private static Set<String> decomposeImpl(String algorithm) {
* Decompose the standard algorithm name into sub-elements.
* <p>
* For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
* so that we can check the "SHA1" and "RSA" algorithm constraints
* separately.
* <p>
* Please override the method if need to support more name pattern.
*/
public Set<String> decompose(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
// algorithm/mode/padding // algorithm/mode/padding
String[] transTockens = transPattern.split(algorithm); String[] transTockens = transPattern.split(algorithm);
...@@ -76,6 +64,24 @@ public class AlgorithmDecomposer { ...@@ -76,6 +64,24 @@ public class AlgorithmDecomposer {
elements.add(token); elements.add(token);
} }
} }
return elements;
}
/**
* Decompose the standard algorithm name into sub-elements.
* <p>
* For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
* so that we can check the "SHA1" and "RSA" algorithm constraints
* separately.
* <p>
* Please override the method if need to support more name pattern.
*/
public Set<String> decompose(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
Set<String> elements = decomposeImpl(algorithm);
// In Java standard algorithm name specification, for different // In Java standard algorithm name specification, for different
// purpose, the SHA-1 and SHA-2 algorithm names are different. For // purpose, the SHA-1 and SHA-2 algorithm names are different. For
...@@ -127,4 +133,40 @@ public class AlgorithmDecomposer { ...@@ -127,4 +133,40 @@ public class AlgorithmDecomposer {
return elements; return elements;
} }
private static void hasLoop(Set<String> elements, String find, String replace) {
if (elements.contains(find)) {
if (!elements.contains(replace)) {
elements.add(replace);
}
elements.remove(find);
}
}
/*
* This decomposes a standard name into sub-elements with a consistent
* message digest algorithm name to avoid overly complicated checking.
*/
public static Set<String> decomposeOneHash(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
Set<String> elements = decomposeImpl(algorithm);
hasLoop(elements, "SHA-1", "SHA1");
hasLoop(elements, "SHA-224", "SHA224");
hasLoop(elements, "SHA-256", "SHA256");
hasLoop(elements, "SHA-384", "SHA384");
hasLoop(elements, "SHA-512", "SHA512");
return elements;
}
/*
* The provided message digest algorithm name will return a consistent
* naming scheme.
*/
public static String hashName(String algorithm) {
return algorithm.replace("-", "");
}
} }
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.File;
import java.io.FileInputStream;
import java.security.AccessController;
import java.security.KeyStore;
import java.security.PrivilegedAction;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashSet;
import sun.security.x509.X509CertImpl;
/**
* The purpose of this class is to determine the trust anchor certificates is in
* the cacerts file. This is used for PKIX CertPath checking.
*/
public class AnchorCertificates {
private static final Debug debug = Debug.getInstance("certpath");
private static final String HASH = "SHA-256";
private static HashSet<String> certs;
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
File f = new File(System.getProperty("java.home"),
"lib/security/cacerts");
KeyStore cacerts;
try {
cacerts = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream(f)) {
cacerts.load(fis, "changeit".toCharArray());
certs = new HashSet<>();
Enumeration<String> list = cacerts.aliases();
String alias;
while (list.hasMoreElements()) {
alias = list.nextElement();
// Check if this cert is labeled a trust anchor.
if (alias.contains(" [jdk")) {
X509Certificate cert = (X509Certificate) cacerts
.getCertificate(alias);
certs.add(X509CertImpl.getFingerprint(HASH, cert));
}
}
}
} catch (Exception e) {
if (debug != null) {
debug.println("Error parsing cacerts");
}
e.printStackTrace();
}
return null;
}
});
}
/**
* Checks if a certificate is a trust anchor.
*
* @param cert the certificate to check
* @return true if the certificate is trusted.
*/
public static boolean contains(X509Certificate cert) {
String key = X509CertImpl.getFingerprint(HASH, cert);
boolean result = certs.contains(key);
if (result && debug != null) {
debug.println("AnchorCertificate.contains: matched " +
cert.getSubjectDN());
}
return result;
}
private AnchorCertificates() {}
}
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.security.cert.X509Certificate;
/**
* This class is a wrapper for keeping state and passing objects between PKIX,
* AlgorithmChecker, and DisabledAlgorithmConstraints.
*/
public class CertConstraintParameters {
// A certificate being passed to check against constraints.
private final X509Certificate cert;
// This is true if the trust anchor in the certificate chain matches a cert
// in AnchorCertificates
private final boolean trustedMatch;
public CertConstraintParameters(X509Certificate c, boolean match) {
cert = c;
trustedMatch = match;
}
public CertConstraintParameters(X509Certificate c) {
this(c, false);
}
// Returns if the trust anchor has a match if anchor checking is enabled.
public boolean isTrustedMatch() {
return trustedMatch;
}
public X509Certificate getCertificate() {
return cert;
}
}
/* /*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,12 +28,14 @@ package sun.security.util; ...@@ -28,12 +28,14 @@ package sun.security.util;
import java.security.CryptoPrimitive; import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.Key; import java.security.Key;
import java.util.Locale; import java.security.cert.CertPathValidatorException;
import java.util.Set; import java.security.cert.CertPathValidatorException.BasicReason;
import java.util.Collections; import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.Matcher; import java.util.regex.Matcher;
...@@ -44,6 +46,7 @@ import java.util.regex.Matcher; ...@@ -44,6 +46,7 @@ import java.util.regex.Matcher;
* for the syntax of the disabled algorithm string. * for the syntax of the disabled algorithm string.
*/ */
public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
private static final Debug debug = Debug.getInstance("certpath");
// the known security property, jdk.certpath.disabledAlgorithms // the known security property, jdk.certpath.disabledAlgorithms
public final static String PROPERTY_CERTPATH_DISABLED_ALGS = public final static String PROPERTY_CERTPATH_DISABLED_ALGS =
...@@ -53,17 +56,12 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -53,17 +56,12 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
public final static String PROPERTY_TLS_DISABLED_ALGS = public final static String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms"; "jdk.tls.disabledAlgorithms";
private final static Map<String, String[]> disabledAlgorithmsMap =
new HashMap<>();
private final static Map<String, KeySizeConstraints> keySizeConstraintsMap =
new HashMap<>();
// the known security property, jdk.jar.disabledAlgorithms // the known security property, jdk.jar.disabledAlgorithms
public static final String PROPERTY_JAR_DISABLED_ALGS = public static final String PROPERTY_JAR_DISABLED_ALGS =
"jdk.jar.disabledAlgorithms"; "jdk.jar.disabledAlgorithms";
private final String[] disabledAlgorithms; private final String[] disabledAlgorithms;
private final KeySizeConstraints keySizeConstraints; private final Constraints algorithmConstraints;
/** /**
* Initialize algorithm constraints with the specified security property. * Initialize algorithm constraints with the specified security property.
...@@ -86,11 +84,14 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -86,11 +84,14 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
public DisabledAlgorithmConstraints(String propertyName, public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) { AlgorithmDecomposer decomposer) {
super(decomposer); super(decomposer);
disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName); disabledAlgorithms = getAlgorithms(propertyName);
keySizeConstraints = getKeySizeConstraints(disabledAlgorithms, algorithmConstraints = new Constraints(disabledAlgorithms);
propertyName);
} }
/*
* This only checks if the algorithm has been completely disabled. If
* there are keysize or other limit, this method allow the algorithm.
*/
@Override @Override
final public boolean permits(Set<CryptoPrimitive> primitives, final public boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters) { String algorithm, AlgorithmParameters parameters) {
...@@ -103,11 +104,19 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -103,11 +104,19 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return checkAlgorithm(disabledAlgorithms, algorithm, decomposer); return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
} }
/*
* Checks if the key algorithm has been disabled or constraints have been
* placed on the key.
*/
@Override @Override
final public boolean permits(Set<CryptoPrimitive> primitives, Key key) { final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
return checkConstraints(primitives, "", key, null); return checkConstraints(primitives, "", key, null);
} }
/*
* Checks if the key algorithm has been disabled or if constraints have
* been placed on the key.
*/
@Override @Override
final public boolean permits(Set<CryptoPrimitive> primitives, final public boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) { String algorithm, Key key, AlgorithmParameters parameters) {
...@@ -119,7 +128,39 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -119,7 +128,39 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return checkConstraints(primitives, algorithm, key, parameters); return checkConstraints(primitives, algorithm, key, parameters);
} }
// Check algorithm constraints /*
* Check if a x509Certificate object is permitted. Check if all
* algorithms are allowed, certificate constraints, and the
* public key against key constraints.
*
* Uses new style permit() which throws exceptions.
*/
public final void permits(Set<CryptoPrimitive> primitives,
CertConstraintParameters cp) throws CertPathValidatorException {
checkConstraints(primitives, cp);
}
/*
* Check if Certificate object is within the constraints.
* Uses new style permit() which throws exceptions.
*/
public final void permits(Set<CryptoPrimitive> primitives,
X509Certificate cert) throws CertPathValidatorException {
checkConstraints(primitives, new CertConstraintParameters(cert));
}
// Check if a string is contained inside the property
public boolean checkProperty(String param) {
param = param.toLowerCase(Locale.ENGLISH);
for (String block : disabledAlgorithms) {
if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
return true;
}
}
return false;
}
// Check algorithm constraints with key and algorithm
private boolean checkConstraints(Set<CryptoPrimitive> primitives, private boolean checkConstraints(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) { String algorithm, Key key, AlgorithmParameters parameters) {
...@@ -128,7 +169,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -128,7 +169,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
throw new IllegalArgumentException("The key cannot be null"); throw new IllegalArgumentException("The key cannot be null");
} }
// check the target algorithm // check the signature algorithm
if (algorithm != null && algorithm.length() != 0) { if (algorithm != null && algorithm.length() != 0) {
if (!permits(primitives, algorithm, parameters)) { if (!permits(primitives, algorithm, parameters)) {
return false; return false;
...@@ -141,97 +182,203 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -141,97 +182,203 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
// check the key constraints // check the key constraints
if (keySizeConstraints.disables(key)) { return algorithmConstraints.permits(key);
return false;
} }
return true; /*
} * Check algorithm constraints with Certificate
* Uses new style permit() which throws exceptions.
*/
private void checkConstraints(Set<CryptoPrimitive> primitives,
CertConstraintParameters cp) throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
String algorithm = cert.getSigAlgName();
private static KeySizeConstraints getKeySizeConstraints( // Check signature algorithm is not disabled
String[] disabledAlgorithms, String propertyName) { if (!permits(primitives, algorithm, null)) {
synchronized (keySizeConstraintsMap) { throw new CertPathValidatorException(
if(!keySizeConstraintsMap.containsKey(propertyName)) { "Algorithm constraints check failed on disabled "+
// map the key constraints "signature algorithm: " + algorithm,
KeySizeConstraints keySizeConstraints = null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
new KeySizeConstraints(disabledAlgorithms);
keySizeConstraintsMap.put(propertyName, keySizeConstraints);
} }
return keySizeConstraintsMap.get(propertyName); // Check key algorithm is not disabled
if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on disabled "+
"public key algorithm: " + algorithm,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
// Check the certificate and key constraints
algorithmConstraints.permits(cp);
} }
/** /**
* key constraints * Key and Certificate Constraints
*
* The complete disabling of an algorithm is not handled by Constraints or
* Constraint classes. That is addressed with
* permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
*
* When passing a Key to permit(), the boolean return values follow the
* same as the interface class AlgorithmConstraints.permit(). This is to
* maintain compatibility:
* 'true' means the operation is allowed.
* 'false' means it failed the constraints and is disallowed.
*
* When passing CertConstraintParameters through permit(), an exception
* will be thrown on a failure to better identify why the operation was
* disallowed.
*/ */
private static class KeySizeConstraints {
private static final Pattern pattern = Pattern.compile(
"(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
private Map<String, Set<KeySizeConstraint>> constraintsMap = private static class Constraints {
Collections.synchronizedMap( private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
new HashMap<String, Set<KeySizeConstraint>>()); private static final Pattern keySizePattern = Pattern.compile(
"keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
public KeySizeConstraints(String[] restrictions) { public Constraints(String[] constraintArray) {
for (String restriction : restrictions) { for (String constraintEntry : constraintArray) {
if (restriction == null || restriction.isEmpty()) { if (constraintEntry == null || constraintEntry.isEmpty()) {
continue; continue;
} }
Matcher matcher = pattern.matcher(restriction); constraintEntry = constraintEntry.trim();
if (matcher.matches()) { if (debug != null) {
String algorithm = matcher.group(1); debug.println("Constraints: " + constraintEntry);
}
// Check if constraint is a complete disabling of an
// algorithm or has conditions.
String algorithm;
String policy;
int space = constraintEntry.indexOf(' ');
if (space > 0) {
algorithm = AlgorithmDecomposer.hashName(
constraintEntry.substring(0, space).
toUpperCase(Locale.ENGLISH));
policy = constraintEntry.substring(space + 1);
} else {
constraintsMap.computeIfAbsent(
constraintEntry.toUpperCase(Locale.ENGLISH),
k -> new HashSet<>());
continue;
}
KeySizeConstraint.Operator operator = // Convert constraint conditions into Constraint classes
KeySizeConstraint.Operator.of(matcher.group(2)); Constraint c, lastConstraint = null;
int length = Integer.parseInt(matcher.group(3)); // Allow only one jdkCA entry per constraint entry
boolean jdkCALimit = false;
algorithm = algorithm.toLowerCase(Locale.ENGLISH); for (String entry : policy.split("&")) {
entry = entry.trim();
synchronized (constraintsMap) { Matcher matcher = keySizePattern.matcher(entry);
if (!constraintsMap.containsKey(algorithm)) { if (matcher.matches()) {
constraintsMap.put(algorithm, if (debug != null) {
new HashSet<KeySizeConstraint>()); debug.println("Constraints set to keySize: " +
entry);
} }
c = new KeySizeConstraint(algorithm,
KeySizeConstraint.Operator.of(matcher.group(1)),
Integer.parseInt(matcher.group(2)));
Set<KeySizeConstraint> constraintSet = } else if (entry.equalsIgnoreCase("jdkCA")) {
constraintsMap.get(algorithm); if (debug != null) {
KeySizeConstraint constraint = debug.println("Constraints set to jdkCA.");
new KeySizeConstraint(operator, length); }
constraintSet.add(constraint); if (jdkCALimit) {
throw new IllegalArgumentException("Only one " +
"jdkCA entry allowed in property. " +
"Constraint: " + constraintEntry);
} }
c = new jdkCAConstraint(algorithm);
jdkCALimit = true;
} else {
throw new IllegalArgumentException("Error in security" +
" property. Constraint unknown: " + entry);
}
// Link multiple conditions for a single constraint
// into a linked list.
if (lastConstraint == null) {
if (!constraintsMap.containsKey(algorithm)) {
constraintsMap.putIfAbsent(algorithm,
new HashSet<>());
} }
constraintsMap.get(algorithm).add(c);
} else {
lastConstraint.nextConstraint = c;
} }
lastConstraint = c;
}
}
}
// Get applicable constraints based off the signature algorithm
private Set<Constraint> getConstraints(String algorithm) {
return constraintsMap.get(algorithm);
} }
// Does this KeySizeConstraints disable the specified key? // Check if KeySizeConstraints permit the specified key
public boolean disables(Key key) { public boolean permits(Key key) {
String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH); Set<Constraint> set = getConstraints(key.getAlgorithm());
synchronized (constraintsMap) { if (set == null) {
if (constraintsMap.containsKey(algorithm)) {
Set<KeySizeConstraint> constraintSet =
constraintsMap.get(algorithm);
for (KeySizeConstraint constraint : constraintSet) {
if (constraint.disables(key)) {
return true; return true;
} }
for (Constraint constraint : set) {
if (!constraint.permits(key)) {
if (debug != null) {
debug.println("keySizeConstraint: failed key " +
"constraint check " + KeyUtil.getKeySize(key));
}
return false;
} }
} }
return true;
} }
return false; // Check if constraints permit this cert.
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
if (debug != null) {
debug.println("Constraints.permits(): " + cert.getSigAlgName());
} }
// Get all signature algorithms to check for constraints
Set<String> algorithms =
AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
if (algorithms == null || algorithms.isEmpty()) {
return;
} }
/** // Attempt to add the public key algorithm to the set
* Key size constraint. algorithms.add(cert.getPublicKey().getAlgorithm());
*
* e.g. "keysize <= 1024" // Check all applicable constraints
*/ for (String algorithm : algorithms) {
private static class KeySizeConstraint { Set<Constraint> set = getConstraints(algorithm);
if (set == null) {
continue;
}
for (Constraint constraint : set) {
constraint.permits(cp);
}
}
}
}
// Abstract class for algorithm constraint checking
private abstract static class Constraint {
String algorithm;
Constraint nextConstraint = null;
// operator // operator
static enum Operator { enum Operator {
EQ, // "==" EQ, // "=="
NE, // "!=" NE, // "!="
LT, // "<" LT, // "<"
...@@ -255,16 +402,77 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -255,16 +402,77 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return GE; return GE;
} }
throw new IllegalArgumentException( throw new IllegalArgumentException("Error in security " +
s + " is not a legal Operator"); "property. " + s + " is not a legal Operator");
}
}
/**
* Check if an algorithm constraint permit this key to be used.
* @param key Public key
* @return true if constraints do not match
*/
public boolean permits(Key key) {
return true;
}
/**
* Check if an algorithm constraint is permit this certificate to
* be used.
* @param cp CertificateParameter containing certificate and state info
* @return true if constraints do not match
*/
public abstract void permits(CertConstraintParameters cp)
throws CertPathValidatorException;
}
/*
* This class contains constraints dealing with the certificate chain
* of the certificate.
*/
private static class jdkCAConstraint extends Constraint {
jdkCAConstraint(String algo) {
algorithm = algo;
}
/*
* Check if each constraint fails and check if there is a linked
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
if (debug != null) {
debug.println("jdkCAConstraints.permits(): " + algorithm);
}
// Return false if the chain has a trust anchor in cacerts
if (cp.isTrustedMatch()) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
"anchor limits",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
} }
}
/*
* This class contains constraints dealing with the key size
* support limits per algorithm. e.g. "keySize <= 1024"
*/
private static class KeySizeConstraint extends Constraint {
private int minSize; // the minimal available key size private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes private int prohibitedSize = -1; // unavailable key sizes
public KeySizeConstraint(Operator operator, int length) { public KeySizeConstraint(String algo, Operator operator, int length) {
algorithm = algo;
switch (operator) { switch (operator) {
case EQ: // an unavailable key size case EQ: // an unavailable key size
this.minSize = 0; this.minSize = 0;
...@@ -298,21 +506,59 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -298,21 +506,59 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
} }
// Does this key constraint disable the specified key? /*
public boolean disables(Key key) { * If we are passed a certificate, extract the public key and use it.
int size = KeyUtil.getKeySize(key); *
* Check if each constraint fails and check if there is a linked
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
if (!permitsImpl(cp.getCertificate().getPublicKey())) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on keysize limits",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
// Check if key constraint disable the specified key
// Uses old style permit()
public boolean permits(Key key) {
// If we recursively find a constraint that permits us to use
// this key, return true and skip any other constraint checks.
if (nextConstraint != null && nextConstraint.permits(key)) {
return true;
}
if (debug != null) {
debug.println("KeySizeConstraints.permits(): " + algorithm);
}
return permitsImpl(key);
}
private boolean permitsImpl(Key key) {
// Verify this constraint is for this public key algorithm
if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
return true;
}
int size = KeyUtil.getKeySize(key);
if (size == 0) { if (size == 0) {
return true; // we don't allow any key of size 0. return false; // we don't allow any key of size 0.
} else if (size > 0) { } else if (size > 0) {
return ((size < minSize) || (size > maxSize) || return !((size < minSize) || (size > maxSize) ||
(prohibitedSize == size)); (prohibitedSize == size));
} // Otherwise, the key size is not accessible. Conservatively, } // Otherwise, the key size is not accessible. Conservatively,
// please don't disable such keys. // please don't disable such keys.
return false; return true;
}
} }
} }
}
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,8 +28,6 @@ package sun.security.util; ...@@ -28,8 +28,6 @@ package sun.security.util;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.CryptoPrimitive; import java.security.CryptoPrimitive;
import java.security.Key; import java.security.Key;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms; import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms;
...@@ -42,15 +40,12 @@ public class LegacyAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -42,15 +40,12 @@ public class LegacyAlgorithmConstraints extends AbstractAlgorithmConstraints {
public final static String PROPERTY_TLS_LEGACY_ALGS = public final static String PROPERTY_TLS_LEGACY_ALGS =
"jdk.tls.legacyAlgorithms"; "jdk.tls.legacyAlgorithms";
private final static Map<String, String[]> legacyAlgorithmsMap =
new HashMap<>();
private final String[] legacyAlgorithms; private final String[] legacyAlgorithms;
public LegacyAlgorithmConstraints(String propertyName, public LegacyAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) { AlgorithmDecomposer decomposer) {
super(decomposer); super(decomposer);
legacyAlgorithms = getAlgorithms(legacyAlgorithmsMap, propertyName); legacyAlgorithms = getAlgorithms(propertyName);
} }
@Override @Override
......
...@@ -1932,18 +1932,19 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { ...@@ -1932,18 +1932,19 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
public String getFingerprint(String algorithm) { public String getFingerprint(String algorithm) {
return fingerprints.computeIfAbsent(algorithm, return fingerprints.computeIfAbsent(algorithm,
x -> getCertificateFingerPrint(x)); x -> getFingerprint(x, this));
} }
/** /**
* Gets the requested finger print of the certificate. The result * Gets the requested finger print of the certificate. The result
* only contains 0-9 and A-F. No small case, no colon. * only contains 0-9 and A-F. No small case, no colon.
*/ */
private String getCertificateFingerPrint(String mdAlg) { public static String getFingerprint(String algorithm,
X509Certificate cert) {
String fingerPrint = ""; String fingerPrint = "";
try { try {
byte[] encCertInfo = getEncoded(); byte[] encCertInfo = cert.getEncoded();
MessageDigest md = MessageDigest.getInstance(mdAlg); MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] digest = md.digest(encCertInfo); byte[] digest = md.digest(encCertInfo);
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
for (int i = 0; i < digest.length; i++) { for (int i = 0; i < digest.length; i++) {
......
...@@ -429,13 +429,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -429,13 +429,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -452,6 +452,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -452,6 +452,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -474,6 +477,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -474,6 +477,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
......
...@@ -429,13 +429,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -429,13 +429,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -452,6 +452,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -452,6 +452,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -474,6 +477,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -474,6 +477,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
......
...@@ -432,13 +432,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -432,13 +432,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -455,6 +455,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -455,6 +455,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -477,6 +480,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -477,6 +480,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
......
...@@ -431,13 +431,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -431,13 +431,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -454,6 +454,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -454,6 +454,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -476,6 +479,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -476,6 +479,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
......
...@@ -432,13 +432,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -432,13 +432,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -455,6 +455,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -455,6 +455,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -477,6 +480,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -477,6 +480,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册