提交 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) 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.
先完成此消息的编辑!
想要评论请 注册