diff --git a/src/share/classes/java/security/AlgorithmConstraints.java b/src/share/classes/java/security/AlgorithmConstraints.java
new file mode 100644
index 0000000000000000000000000000000000000000..7341603dc7cf65d3941cee8dce0e38194ed1a560
--- /dev/null
+++ b/src/share/classes/java/security/AlgorithmConstraints.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010, 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 java.security;
+
+import java.util.Set;
+
+/**
+ * This interface specifies constraints for cryptographic algorithms,
+ * keys (key sizes), and other algorithm parameters.
+ *
+ * {@code AlgorithmConstraints} objects are immutable. An implementation
+ * of this interface should not provide methods that can change the state
+ * of an instance once it has been created.
+ *
+ * Note that {@code AlgorithmConstraints} can be used to represent the
+ * restrictions described by the security properties
+ * {@code jdk.certpath.disabledAlgorithms} and
+ * {@code jdk.tls.disabledAlgorithms}, or could be used by a
+ * concrete {@code PKIXCertPathChecker} to check whether a specified
+ * certificate in the certification path contains the required algorithm
+ * constraints.
+ *
+ * @see javax.net.ssl.SSLParameters#getAlgorithmConstraints
+ * @see javax.net.ssl.SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+ *
+ * @since 1.7
+ */
+
+public interface AlgorithmConstraints {
+
+ /**
+ * Determines whether an algorithm is granted permission for the
+ * specified cryptographic primitives.
+ *
+ * @param primitives a set of cryptographic primitives
+ * @param algorithm the algorithm name
+ * @param parameters the algorithm parameters, or null if no additional
+ * parameters
+ *
+ * @return true if the algorithm is permitted and can be used for all
+ * of the specified cryptographic primitives
+ *
+ * @throws IllegalArgumentException if primitives or algorithm is null
+ * or empty
+ */
+ public boolean permits(Set primitives,
+ String algorithm, AlgorithmParameters parameters);
+
+ /**
+ * Determines whether a key is granted permission for the specified
+ * cryptographic primitives.
+ *
+ * This method is usually used to check key size and key usage.
+ *
+ * @param primitives a set of cryptographic primitives
+ * @param key the key
+ *
+ * @return true if the key can be used for all of the specified
+ * cryptographic primitives
+ *
+ * @throws IllegalArgumentException if primitives is null or empty,
+ * or the key is null
+ */
+ public boolean permits(Set primitives, Key key);
+
+ /**
+ * Determines whether an algorithm and the corresponding key are granted
+ * permission for the specified cryptographic primitives.
+ *
+ * @param primitives a set of cryptographic primitives
+ * @param algorithm the algorithm name
+ * @param key the key
+ * @param parameters the algorithm parameters, or null if no additional
+ * parameters
+ *
+ * @return true if the key and the algorithm can be used for all of the
+ * specified cryptographic primitives
+ *
+ * @throws IllegalArgumentException if primitives or algorithm is null
+ * or empty, or the key is null
+ */
+ public boolean permits(Set primitives,
+ String algorithm, Key key, AlgorithmParameters parameters);
+
+}
diff --git a/src/share/classes/java/security/CryptoPrimitive.java b/src/share/classes/java/security/CryptoPrimitive.java
new file mode 100644
index 0000000000000000000000000000000000000000..158643b9574cac1cc2ab55c068490b73a969d20f
--- /dev/null
+++ b/src/share/classes/java/security/CryptoPrimitive.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010, 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 java.security;
+
+/**
+ * An enumeration of cryptographic primitives.
+ *
+ * @since 1.7
+ */
+public enum CryptoPrimitive {
+ /**
+ * Hash function
+ */
+ MESSAGE_DIGEST,
+
+ /**
+ * Cryptographic random number generator
+ */
+ SECURE_RANDOM,
+
+ /**
+ * Symmetric primitive: block cipher
+ */
+ BLOCK_CIPHER,
+
+ /**
+ * Symmetric primitive: stream cipher
+ */
+ STREAM_CIPHER,
+
+ /**
+ * Symmetric primitive: message authentication code
+ */
+ MAC,
+
+ /**
+ * Symmetric primitive: key wrap
+ */
+ KEY_WRAP,
+
+ /**
+ * Asymmetric primitive: public key encryption
+ */
+ PUBLIC_KEY_ENCRYPTION,
+
+ /**
+ * Asymmetric primitive: signature scheme
+ */
+ SIGNATURE,
+
+ /**
+ * Asymmetric primitive: key encapsulation mechanism
+ */
+ KEY_ENCAPSULATION,
+
+ /**
+ * Asymmetric primitive: key agreement and key distribution
+ */
+ KEY_AGREEMENT
+}
diff --git a/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java b/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java
index eb18820b2b8c9c0745ae0dbf781196ee7efd6a23..69e560ed4bf8489ea420808c9d73cf24af07893a 100644
--- a/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java
+++ b/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2010, 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
@@ -25,95 +25,336 @@
package sun.security.provider.certpath;
-import java.util.Set;
+import java.security.AlgorithmConstraints;
+import java.security.CryptoPrimitive;
import java.util.Collection;
-import java.util.Locale;
+import java.util.Collections;
+import java.util.Set;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.security.KeyFactory;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+import java.security.GeneralSecurityException;
import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
import java.security.cert.X509CRL;
-import java.security.cert.CertPathValidatorException;
+import java.security.cert.X509Certificate;
import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.TrustAnchor;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertPathValidatorException;
+import java.io.IOException;
+import java.security.interfaces.*;
+import java.security.spec.*;
+import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.x509.X509CertImpl;
+import sun.security.x509.X509CRLImpl;
import sun.security.x509.AlgorithmId;
/**
- * AlgorithmChecker is a PKIXCertPathChecker
that checks that
- * the signature algorithm of the specified certificate is not disabled.
+ * A PKIXCertPathChecker
implementation to check whether a
+ * specified certificate contains the required algorithm constraints.
+ *
+ * Certificate fields such as the subject public key, the signature
+ * algorithm, key usage, extended key usage, etc. need to conform to
+ * the specified algorithm constraints.
*
- * @author Xuelei Fan
+ * @see PKIXCertPathChecker
+ * @see PKIXParameters
*/
final public class AlgorithmChecker extends PKIXCertPathChecker {
- // the disabled algorithms
- private static final String[] disabledAlgorithms = new String[] {"md2"};
+ private final AlgorithmConstraints constraints;
+ private final PublicKey trustedPubKey;
+ private PublicKey prevPubKey;
+
+ private final static Set SIGNATURE_PRIMITIVE_SET =
+ EnumSet.of(CryptoPrimitive.SIGNATURE);
- // singleton instance
- static final AlgorithmChecker INSTANCE = new AlgorithmChecker();
+ private final static DisabledAlgorithmConstraints
+ certPathDefaultConstraints = new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
/**
- * Default Constructor
+ * Create a new AlgorithmChecker
with the algorithm
+ * constraints specified in security property
+ * "jdk.certpath.disabledAlgorithms".
+ *
+ * @param anchor the trust anchor selected to validate the target
+ * certificate
*/
- private AlgorithmChecker() {
- // do nothing
+ public AlgorithmChecker(TrustAnchor anchor) {
+ this(anchor, certPathDefaultConstraints);
}
/**
- * Return a AlgorithmChecker instance.
+ * Create a new AlgorithmChecker
with the
+ * given {@code AlgorithmConstraints}.
+ *
+ * Note that this constructor will be used to check a certification
+ * path where the trust anchor is unknown, or a certificate list which may
+ * contain the trust anchor. This constructor is used by SunJSSE.
+ *
+ * @param constraints the algorithm constraints (or null)
*/
- static AlgorithmChecker getInstance() {
- return INSTANCE;
+ public AlgorithmChecker(AlgorithmConstraints constraints) {
+ this.prevPubKey = null;
+ this.trustedPubKey = null;
+ this.constraints = constraints;
}
/**
- * Initializes the internal state of the checker from parameters
- * specified in the constructor.
+ * Create a new AlgorithmChecker
with the
+ * given TrustAnchor
and AlgorithmConstraints
.
+ *
+ * @param anchor the trust anchor selected to validate the target
+ * certificate
+ * @param constraints the algorithm constraints (or null)
+ *
+ * @throws IllegalArgumentException if the anchor
is null
*/
+ public AlgorithmChecker(TrustAnchor anchor,
+ AlgorithmConstraints constraints) {
+
+ if (anchor == null) {
+ throw new IllegalArgumentException(
+ "The trust anchor cannot be null");
+ }
+
+ if (anchor.getTrustedCert() != null) {
+ this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+ } else {
+ this.trustedPubKey = anchor.getCAPublicKey();
+ }
+
+ this.prevPubKey = trustedPubKey;
+ this.constraints = constraints;
+ }
+
+ @Override
public void init(boolean forward) throws CertPathValidatorException {
- // do nothing
+ // Note that this class does not support forward mode.
+ if (!forward) {
+ if (trustedPubKey != null) {
+ prevPubKey = trustedPubKey;
+ } else {
+ prevPubKey = null;
+ }
+ } else {
+ throw new
+ CertPathValidatorException("forward checking not supported");
+ }
}
+ @Override
public boolean isForwardCheckingSupported() {
+ // Note that as this class does not support forward mode, the method
+ // will always returns false.
return false;
}
+ @Override
public Set getSupportedExtensions() {
return null;
}
- /**
- * Checks the signature algorithm of the specified certificate.
- */
- public void check(Certificate cert, Collection unresolvedCritExts)
+ @Override
+ public void check(Certificate cert,
+ Collection unresolvedCritExts)
throws CertPathValidatorException {
- check(cert);
- }
- public static void check(Certificate cert)
- throws CertPathValidatorException {
- X509Certificate xcert = (X509Certificate)cert;
- check(xcert.getSigAlgName());
- }
+ if (!(cert instanceof X509Certificate) || constraints == null) {
+ // ignore the check for non-x.509 certificate or null constraints
+ 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);
+ }
- static void check(AlgorithmId aid) throws CertPathValidatorException {
- check(aid.getName());
+ 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);
+ }
+
+ // check the key usage and key size
+ boolean[] keyUsage = x509Cert.getKeyUsage();
+ if (keyUsage != null && keyUsage.length < 9) {
+ throw new CertPathValidatorException(
+ "incorrect KeyUsage extension");
+ }
+
+ if (keyUsage != null) {
+ Set primitives =
+ EnumSet.noneOf(CryptoPrimitive.class);
+
+ if (keyUsage[0] || keyUsage[1] || keyUsage[5] || keyUsage[6]) {
+ // keyUsage[0]: KeyUsage.digitalSignature
+ // keyUsage[1]: KeyUsage.nonRepudiation
+ // keyUsage[5]: KeyUsage.keyCertSign
+ // keyUsage[6]: KeyUsage.cRLSign
+ primitives.add(CryptoPrimitive.SIGNATURE);
+ }
+
+ if (keyUsage[2]) { // KeyUsage.keyEncipherment
+ primitives.add(CryptoPrimitive.KEY_ENCAPSULATION);
+ }
+
+ if (keyUsage[3]) { // KeyUsage.dataEncipherment
+ primitives.add(CryptoPrimitive.PUBLIC_KEY_ENCRYPTION);
+ }
+
+ if (keyUsage[4]) { // KeyUsage.keyAgreement
+ primitives.add(CryptoPrimitive.KEY_AGREEMENT);
+ }
+
+ // KeyUsage.encipherOnly and KeyUsage.decipherOnly are
+ // undefined in the absence of the keyAgreement bit.
+
+ if (!primitives.isEmpty()) {
+ if (!constraints.permits(primitives, currPubKey)) {
+ throw new CertPathValidatorException(
+ "algorithm constraints check failed");
+ }
+ }
+ }
+
+ // Check with previous cert for signature algorithm and public key
+ if (prevPubKey != null) {
+ if (currSigAlg != null) {
+ if (!constraints.permits(
+ SIGNATURE_PRIMITIVE_SET,
+ currSigAlg, prevPubKey, currSigAlgParams)) {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed: " + currSigAlg);
+ }
+ }
+
+ // Inherit key parameters from previous key
+ if (currPubKey instanceof DSAPublicKey &&
+ ((DSAPublicKey)currPubKey).getParams() == null) {
+ // Inherit DSA parameters from previous key
+ if (!(prevPubKey instanceof DSAPublicKey)) {
+ throw new CertPathValidatorException("Input key is not " +
+ "of a appropriate type for inheriting parameters");
+ }
+
+ DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
+ if (params == null) {
+ throw new CertPathValidatorException(
+ "Key parameters missing");
+ }
+
+ try {
+ BigInteger y = ((DSAPublicKey)currPubKey).getY();
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
+ params.getP(),
+ params.getQ(),
+ params.getG());
+ currPubKey = kf.generatePublic(ks);
+ } catch (GeneralSecurityException e) {
+ throw new CertPathValidatorException("Unable to generate " +
+ "key with inherited parameters: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ // reset the previous public key
+ prevPubKey = currPubKey;
+
+ // check the extended key usage, ignore the check now
+ // List extendedKeyUsages = x509Cert.getExtendedKeyUsage();
+
+ // DO NOT remove any unresolved critical extensions
}
- static void check(X509CRL crl) throws CertPathValidatorException {
- check(crl.getSigAlgName());
+ /**
+ * Try to set the trust anchor of the checker.
+ *
+ * If there is no trust anchor specified and the checker has not started,
+ * set the trust anchor.
+ *
+ * @param anchor the trust anchor selected to validate the target
+ * certificate
+ */
+ void trySetTrustAnchor(TrustAnchor anchor) {
+ // Don't bother if the check has started or trust anchor has already
+ // specified.
+ if (prevPubKey == null) {
+ if (anchor == null) {
+ throw new IllegalArgumentException(
+ "The trust anchor cannot be null");
+ }
+
+ // Don't bother to change the trustedPubKey.
+ if (anchor.getTrustedCert() != null) {
+ prevPubKey = anchor.getTrustedCert().getPublicKey();
+ } else {
+ prevPubKey = anchor.getCAPublicKey();
+ }
+ }
}
- private static void check(String algName)
- throws CertPathValidatorException {
+ /**
+ * Check the signature algorithm with the specified public key.
+ *
+ * @param key the public key to verify the CRL signature
+ * @param crl the target CRL
+ */
+ static void check(PublicKey key, X509CRL crl)
+ throws CertPathValidatorException {
- String lowerCaseAlgName = algName.toLowerCase(Locale.ENGLISH);
+ X509CRLImpl x509CRLImpl = null;
+ try {
+ x509CRLImpl = X509CRLImpl.toImpl(crl);
+ } catch (CRLException ce) {
+ throw new CertPathValidatorException(ce);
+ }
- for (String disabled : disabledAlgorithms) {
- // checking the signature algorithm name
- if (lowerCaseAlgName.indexOf(disabled) != -1) {
- throw new CertPathValidatorException(
- "algorithm check failed: " + algName + " is disabled");
- }
+ AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
+ check(key, algorithmId);
+ }
+
+ /**
+ * Check the signature algorithm with the specified public key.
+ *
+ * @param key the public key to verify the CRL signature
+ * @param crl the target CRL
+ */
+ static void check(PublicKey key, AlgorithmId algorithmId)
+ throws CertPathValidatorException {
+ String sigAlgName = algorithmId.getName();
+ AlgorithmParameters sigAlgParams = algorithmId.getParameters();
+
+ if (!certPathDefaultConstraints.permits(
+ SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
+ throw new CertPathValidatorException(
+ "algorithm check failed: " + sigAlgName + " is disabled");
}
}
}
+
diff --git a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
index 4dd29710ef1fbabdbf4e0928e8b8efe5e9d07682..a980e7d16573d083049a5ef52a41efb389f1a661 100644
--- a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
+++ b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -289,16 +289,6 @@ class DistributionPointFetcher {
X500Name certIssuer = (X500Name) certImpl.getIssuerDN();
X500Name crlIssuer = (X500Name) crlImpl.getIssuerDN();
- // check the crl signature algorithm
- try {
- AlgorithmChecker.check(crl);
- } catch (CertPathValidatorException cpve) {
- if (debug != null) {
- debug.println("CRL signature algorithm check failed: " + cpve);
- }
- return false;
- }
-
// if crlIssuer is set, verify that it matches the issuer of the
// CRL and the CRL contains an IDP extension with the indirectCRL
// boolean asserted. Otherwise, verify that the CRL issuer matches the
@@ -637,6 +627,16 @@ class DistributionPointFetcher {
}
}
+ // check the crl signature algorithm
+ try {
+ AlgorithmChecker.check(prevKey, crl);
+ } catch (CertPathValidatorException cpve) {
+ if (debug != null) {
+ debug.println("CRL signature algorithm check failed: " + cpve);
+ }
+ return false;
+ }
+
// validate the signature on the CRL
try {
crl.verify(prevKey, provider);
diff --git a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
index ae7ccd3884684e68b89420bb64571606d448bca2..7e828884940bcacf8e3a75601ec449117c05b39e 100644
--- a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
+++ b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -718,11 +718,6 @@ class ForwardBuilder extends Builder {
/* we don't perform any validation of the trusted cert */
if (!isTrustedCert) {
- /*
- * check that the signature algorithm is not disabled.
- */
- AlgorithmChecker.check(cert);
-
/*
* Check CRITICAL private extensions for user checkers that
* support forward checking (forwardCheckers) and remove
diff --git a/src/share/classes/sun/security/provider/certpath/OCSPChecker.java b/src/share/classes/sun/security/provider/certpath/OCSPChecker.java
index b72cd79a31cf6dccfa7556460e215dc109df613f..d734ff90408f9eaeb6248c31d867860def3db481 100644
--- a/src/share/classes/sun/security/provider/certpath/OCSPChecker.java
+++ b/src/share/classes/sun/security/provider/certpath/OCSPChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -327,6 +327,10 @@ class OCSPChecker extends PKIXCertPathChecker {
"(set using the OCSP security properties).");
}
+ // The algorithm constraints of the OCSP trusted responder certificate
+ // does not need to be checked in this code. The constraints will be
+ // checked when the responder's certificate is validated.
+
CertId certId = null;
OCSPResponse response = null;
try {
diff --git a/src/share/classes/sun/security/provider/certpath/OCSPResponse.java b/src/share/classes/sun/security/provider/certpath/OCSPResponse.java
index 0b64e412cf688a02cb9964a3cd1ecc89dd67aa3d..63566dd555879a8f378873a8daab0f7d241e6e06 100644
--- a/src/share/classes/sun/security/provider/certpath/OCSPResponse.java
+++ b/src/share/classes/sun/security/provider/certpath/OCSPResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -32,6 +32,7 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CRLReason;
+import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Date;
@@ -371,6 +372,13 @@ public final class OCSPResponse {
"OCSP responses", cpe);
}
+ // Check algorithm constraints specified in security property
+ // "jdk.certpath.disabledAlgorithms".
+ AlgorithmChecker algChecker = new AlgorithmChecker(
+ new TrustAnchor(responderCert, null));
+ algChecker.init(false);
+ algChecker.check(cert, Collections.emptySet());
+
// check the validity
try {
if (dateCheckedAgainst == null) {
@@ -422,6 +430,10 @@ public final class OCSPResponse {
// Confirm that the signed response was generated using the public
// key from the trusted responder cert
if (responderCert != null) {
+ // Check algorithm constraints specified in security property
+ // "jdk.certpath.disabledAlgorithms".
+ AlgorithmChecker.check(responderCert.getPublicKey(), sigAlgId);
+
if (!verifyResponse(responseDataDer, responderCert,
sigAlgId, signature)) {
throw new CertPathValidatorException(
diff --git a/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java b/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java
index fa954ce2fded91a83687f30c10716d9fe9d5d98e..d8fbadf199a4d1ff653a15e0f5fa8c6a6a4ab0a3 100644
--- a/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java
+++ b/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -275,7 +275,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
int certPathLen = certList.size();
basicChecker = new BasicChecker(anchor, testDate, sigProvider, false);
- AlgorithmChecker algorithmChecker= AlgorithmChecker.getInstance();
+ AlgorithmChecker algorithmChecker = new AlgorithmChecker(anchor);
KeyChecker keyChecker = new KeyChecker(certPathLen,
pkixParam.getTargetCertConstraints());
ConstraintsChecker constraintsChecker =
diff --git a/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java b/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java
index 7705dcf363d46470fd19d39afe2a32caba96c750..7bb5ee632d926b606e90b780de4862d51de960b4 100644
--- a/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java
+++ b/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -347,9 +347,6 @@ class ReverseBuilder extends Builder {
return;
}
- /* check that the signature algorithm is not disabled. */
- AlgorithmChecker.check(cert);
-
/*
* check for looping - abort a loop if
* ((we encounter the same certificate twice) AND
@@ -470,9 +467,16 @@ class ReverseBuilder extends Builder {
if (unresolvedCritExts == null) {
unresolvedCritExts = Collections.emptySet();
}
+
+ /*
+ * Check that the signature algorithm is not disabled.
+ */
+ currentState.algorithmChecker.check(cert, unresolvedCritExts);
+
for (PKIXCertPathChecker checker : currentState.userCheckers) {
checker.check(cert, unresolvedCritExts);
}
+
/*
* Look at the remaining extensions and remove any ones we have
* already checked. If there are any left, throw an exception!
diff --git a/src/share/classes/sun/security/provider/certpath/ReverseState.java b/src/share/classes/sun/security/provider/certpath/ReverseState.java
index 0b795c3b0f39b512880d4934f345d52fd1bec50e..b7285a140a5e2821247dd5a4b48554e454252445 100644
--- a/src/share/classes/sun/security/provider/certpath/ReverseState.java
+++ b/src/share/classes/sun/security/provider/certpath/ReverseState.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -96,6 +96,9 @@ class ReverseState implements State {
/* the checker used for revocation status */
public CrlRevocationChecker crlChecker;
+ /* the algorithm checker */
+ AlgorithmChecker algorithmChecker;
+
/* the trust anchor used to validate the path */
TrustAnchor trustAnchor;
@@ -241,6 +244,14 @@ class ReverseState implements State {
updateState(anchor.getCAPublicKey(), caName);
}
+ // The user specified AlgorithmChecker may not be
+ // able to set the trust anchor until now.
+ for (PKIXCertPathChecker checker : userCheckers) {
+ if (checker instanceof AlgorithmChecker) {
+ ((AlgorithmChecker)checker).trySetTrustAnchor(anchor);
+ }
+ }
+
init = false;
}
diff --git a/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java b/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java
index 85a9c01015aeb7620f7a4c430a41a8e04bb91d45..b4dac76ae31e3458a9951f85205021168d734000 100644
--- a/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java
+++ b/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -302,6 +302,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
// init the crl checker
currentState.crlChecker =
new CrlRevocationChecker(null, buildParams, null, onlyEECert);
+ currentState.algorithmChecker = new AlgorithmChecker(anchor);
try {
depthFirstSearchReverse(null, currentState,
new ReverseBuilder(buildParams, targetSubjectDN), adjacencyList,
@@ -475,29 +476,41 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
userCheckers.add(mustCheck, policyChecker);
mustCheck++;
+ // add the algorithm checker
+ userCheckers.add(mustCheck,
+ new AlgorithmChecker(builder.trustAnchor));
+ mustCheck++;
+
if (nextState.keyParamsNeeded()) {
PublicKey rootKey = cert.getPublicKey();
if (builder.trustAnchor.getTrustedCert() == null) {
rootKey = builder.trustAnchor.getCAPublicKey();
if (debug != null)
- debug.println("SunCertPathBuilder.depthFirstSearchForward" +
- " using buildParams public key: " +
- rootKey.toString());
+ debug.println(
+ "SunCertPathBuilder.depthFirstSearchForward " +
+ "using buildParams public key: " +
+ rootKey.toString());
}
TrustAnchor anchor = new TrustAnchor
(cert.getSubjectX500Principal(), rootKey, null);
+
+ // add the basic checker
basicChecker = new BasicChecker(anchor,
builder.date,
buildParams.getSigProvider(),
true);
userCheckers.add(mustCheck, basicChecker);
mustCheck++;
+
+ // add the crl revocation checker
if (buildParams.isRevocationEnabled()) {
userCheckers.add(mustCheck, new CrlRevocationChecker
(anchor, buildParams, null, onlyEECert));
mustCheck++;
}
}
+ // Why we don't need BasicChecker and CrlRevocationChecker
+ // if nextState.keyParamsNeeded() is false?
for (int i=0; i= mustCheck &&
+ currChecker instanceof AlgorithmChecker) {
+ ((AlgorithmChecker)currChecker).
+ trySetTrustAnchor(builder.trustAnchor);
+ }
}
try {
diff --git a/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java b/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
new file mode 100644
index 0000000000000000000000000000000000000000..a537c55485422f0d3b957fbe6144b1cd5929f34e
--- /dev/null
+++ b/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2010, 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.AlgorithmConstraints;
+import java.security.CryptoPrimitive;
+import java.security.AlgorithmParameters;
+
+import java.security.Key;
+import java.security.Security;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.DSAKey;
+import javax.crypto.SecretKey;
+import javax.crypto.interfaces.DHKey;
+
+import java.util.Locale;
+import java.util.Set;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Algorithm constraints for disabled algorithms property
+ *
+ * See the "jdk.certpath.disabledAlgorithms" specification in java.security
+ * for the syntax of the disabled algorithm string.
+ */
+public class DisabledAlgorithmConstraints implements AlgorithmConstraints {
+
+ // the known security property, jdk.certpath.disabledAlgorithms
+ public final static String PROPERTY_CERTPATH_DISABLED_ALGS =
+ "jdk.certpath.disabledAlgorithms";
+
+ // the known security property, jdk.tls.disabledAlgorithms
+ public final static String PROPERTY_TLS_DISABLED_ALGS =
+ "jdk.tls.disabledAlgorithms";
+
+ private static Map disabledAlgorithmsMap =
+ Collections.synchronizedMap(new HashMap());
+ private static Map keySizeConstraintsMap =
+ Collections.synchronizedMap(new HashMap());
+
+ private String[] disabledAlgorithms;
+ private KeySizeConstraints keySizeConstraints;
+
+ /**
+ * Initialize algorithm constraints with the specified security property.
+ *
+ * @param propertyName the security property name that define the disabled
+ * algorithm constraints
+ */
+ public DisabledAlgorithmConstraints(String propertyName) {
+ synchronized (disabledAlgorithmsMap) {
+ if(!disabledAlgorithmsMap.containsKey(propertyName)) {
+ loadDisabledAlgorithmsMap(propertyName);
+ }
+
+ disabledAlgorithms = disabledAlgorithmsMap.get(propertyName);
+ keySizeConstraints = keySizeConstraintsMap.get(propertyName);
+ }
+ }
+
+ @Override
+ final public boolean permits(Set primitives,
+ String algorithm, AlgorithmParameters parameters) {
+
+ if (algorithm == null || algorithm.length() == 0) {
+ throw new IllegalArgumentException("No algorithm name specified");
+ }
+
+ if (primitives == null || primitives.isEmpty()) {
+ throw new IllegalArgumentException(
+ "No cryptographic primitive specified");
+ }
+
+ Set elements = null;
+ for (String disabled : disabledAlgorithms) {
+ if (disabled == null || disabled.isEmpty()) {
+ continue;
+ }
+
+ // check the full name
+ if (disabled.equalsIgnoreCase(algorithm)) {
+ return false;
+ }
+
+ // decompose the algorithm into sub-elements
+ if (elements == null) {
+ elements = decomposes(algorithm);
+ }
+
+ // check the items of the algorithm
+ for (String element : elements) {
+ if (disabled.equalsIgnoreCase(element)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ final public boolean permits(Set primitives, Key key) {
+ return checkConstraints(primitives, "", key, null);
+ }
+
+ @Override
+ final public boolean permits(Set primitives,
+ String algorithm, Key key, AlgorithmParameters parameters) {
+
+ if (algorithm == null || algorithm.length() == 0) {
+ throw new IllegalArgumentException("No algorithm name specified");
+ }
+
+ return checkConstraints(primitives, algorithm, key, parameters);
+ }
+
+ /**
+ * Decompose the standard algorithm name into sub-elements.
+ *
+ * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
+ * so that we can check the "SHA1" and "RSA" algorithm constraints
+ * separately.
+ *
+ * Please override the method if need to support more name pattern.
+ */
+ protected Set decomposes(String algorithm) {
+ if (algorithm == null || algorithm.length() == 0) {
+ return new HashSet();
+ }
+
+ // algorithm/mode/padding
+ Pattern transPattern = Pattern.compile("/");
+ String[] transTockens = transPattern.split(algorithm);
+
+ Set elements = new HashSet();
+ for (String transTocken : transTockens) {
+ if (transTocken == null || transTocken.length() == 0) {
+ continue;
+ }
+
+ // PBEWithAnd
+ // PBEWithAnd
+ // OAEPWithAndPadding
+ // with
+ // withand
+ Pattern pattern =
+ Pattern.compile("with|and", Pattern.CASE_INSENSITIVE);
+ String[] tokens = pattern.split(transTocken);
+
+ for (String token : tokens) {
+ if (token == null || token.length() == 0) {
+ continue;
+ }
+
+ elements.add(token);
+ }
+ }
+
+ // In Java standard algorithm name specification, for different
+ // purpose, the SHA-1 and SHA-2 algorithm names are different. For
+ // example, for MessageDigest, the standard name is "SHA-256", while
+ // for Signature, the digest algorithm component is "SHA256" for
+ // signature algorithm "SHA256withRSA". So we need to check both
+ // "SHA-256" and "SHA256" to make the right constraint checking.
+
+ // handle special name: SHA-1 and SHA1
+ if (elements.contains("SHA1") && !elements.contains("SHA-1")) {
+ elements.add("SHA-1");
+ }
+ if (elements.contains("SHA-1") && !elements.contains("SHA1")) {
+ elements.add("SHA1");
+ }
+
+ // handle special name: SHA-224 and SHA224
+ if (elements.contains("SHA224") && !elements.contains("SHA-224")) {
+ elements.add("SHA-224");
+ }
+ if (elements.contains("SHA-224") && !elements.contains("SHA224")) {
+ elements.add("SHA224");
+ }
+
+ // handle special name: SHA-256 and SHA256
+ if (elements.contains("SHA256") && !elements.contains("SHA-256")) {
+ elements.add("SHA-256");
+ }
+ if (elements.contains("SHA-256") && !elements.contains("SHA256")) {
+ elements.add("SHA256");
+ }
+
+ // handle special name: SHA-384 and SHA384
+ if (elements.contains("SHA384") && !elements.contains("SHA-384")) {
+ elements.add("SHA-384");
+ }
+ if (elements.contains("SHA-384") && !elements.contains("SHA384")) {
+ elements.add("SHA384");
+ }
+
+ // handle special name: SHA-512 and SHA512
+ if (elements.contains("SHA512") && !elements.contains("SHA-512")) {
+ elements.add("SHA-512");
+ }
+ if (elements.contains("SHA-512") && !elements.contains("SHA512")) {
+ elements.add("SHA512");
+ }
+
+ return elements;
+ }
+
+ // Check algorithm constraints
+ private boolean checkConstraints(Set primitives,
+ String algorithm, Key key, AlgorithmParameters parameters) {
+
+ // check the key parameter, it cannot be null.
+ if (key == null) {
+ throw new IllegalArgumentException("The key cannot be null");
+ }
+
+ // check the target algorithm
+ if (algorithm != null && algorithm.length() != 0) {
+ if (!permits(primitives, algorithm, parameters)) {
+ return false;
+ }
+ }
+
+ // check the key algorithm
+ if (!permits(primitives, key.getAlgorithm(), null)) {
+ return false;
+ }
+
+ // check the key constraints
+ if (keySizeConstraints.disables(key)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ // Get disabled algorithm constraints from the specified security property.
+ private static void loadDisabledAlgorithmsMap(
+ final String propertyName) {
+
+ String property = AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public String run() {
+ return Security.getProperty(propertyName);
+ }
+ });
+
+ String[] algorithmsInProperty = null;
+
+ if (property != null && !property.isEmpty()) {
+
+ // remove double quote marks from beginning/end of the property
+ if (property.charAt(0) == '"' &&
+ property.charAt(property.length() - 1) == '"') {
+ property = property.substring(1, property.length() - 1);
+ }
+
+ algorithmsInProperty = property.split(",");
+ for (int i = 0; i < algorithmsInProperty.length; i++) {
+ algorithmsInProperty[i] = algorithmsInProperty[i].trim();
+ }
+ }
+
+ // map the disabled algorithms
+ if (algorithmsInProperty == null) {
+ algorithmsInProperty = new String[0];
+ }
+ disabledAlgorithmsMap.put(propertyName, algorithmsInProperty);
+
+ // map the key constraints
+ KeySizeConstraints keySizeConstraints =
+ new KeySizeConstraints(algorithmsInProperty);
+ keySizeConstraintsMap.put(propertyName, keySizeConstraints);
+ }
+
+ /**
+ * key constraints
+ */
+ private static class KeySizeConstraints {
+ private static final Pattern pattern = Pattern.compile(
+ "(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
+
+ private Map> constraintsMap =
+ Collections.synchronizedMap(
+ new HashMap>());
+
+ public KeySizeConstraints(String[] restrictions) {
+ for (String restriction : restrictions) {
+ if (restriction == null || restriction.isEmpty()) {
+ continue;
+ }
+
+ Matcher matcher = pattern.matcher(restriction);
+ if (matcher.matches()) {
+ String algorithm = matcher.group(1);
+
+ KeySizeConstraint.Operator operator =
+ KeySizeConstraint.Operator.of(matcher.group(2));
+ int length = Integer.parseInt(matcher.group(3));
+
+ algorithm = algorithm.toLowerCase(Locale.ENGLISH);
+
+ synchronized (constraintsMap) {
+ if (!constraintsMap.containsKey(algorithm)) {
+ constraintsMap.put(algorithm,
+ new HashSet());
+ }
+
+ Set constraintSet =
+ constraintsMap.get(algorithm);
+ KeySizeConstraint constraint =
+ new KeySizeConstraint(operator, length);
+ constraintSet.add(constraint);
+ }
+ }
+ }
+ }
+
+ // Does this KeySizeConstraints disable the specified key?
+ public boolean disables(Key key) {
+ String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH);
+ synchronized (constraintsMap) {
+ if (constraintsMap.containsKey(algorithm)) {
+ Set constraintSet =
+ constraintsMap.get(algorithm);
+ for (KeySizeConstraint constraint : constraintSet) {
+ if (constraint.disables(key)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * Key size constraint.
+ *
+ * e.g. "keysize <= 1024"
+ */
+ private static class KeySizeConstraint {
+ // operator
+ static enum Operator {
+ EQ, // "=="
+ NE, // "!="
+ LT, // "<"
+ LE, // "<="
+ GT, // ">"
+ GE; // ">="
+
+ static Operator of(String s) {
+ switch (s) {
+ case "==":
+ return EQ;
+ case "!=":
+ return NE;
+ case "<":
+ return LT;
+ case "<=":
+ return LE;
+ case ">":
+ return GT;
+ case ">=":
+ return GE;
+ }
+
+ throw new IllegalArgumentException(
+ s + " is not a legal Operator");
+ }
+ }
+
+ private int minSize; // the minimal available key size
+ private int maxSize; // the maximal available key size
+ private int prohibitedSize = -1; // unavailable key sizes
+
+ public KeySizeConstraint(Operator operator, int length) {
+ switch (operator) {
+ case EQ: // an unavailable key size
+ this.minSize = 0;
+ this.maxSize = Integer.MAX_VALUE;
+ prohibitedSize = length;
+ break;
+ case NE:
+ this.minSize = length;
+ this.maxSize = length;
+ break;
+ case LT:
+ this.minSize = length;
+ this.maxSize = Integer.MAX_VALUE;
+ break;
+ case LE:
+ this.minSize = length + 1;
+ this.maxSize = Integer.MAX_VALUE;
+ break;
+ case GT:
+ this.minSize = 0;
+ this.maxSize = length;
+ break;
+ case GE:
+ this.minSize = 0;
+ this.maxSize = length > 1 ? (length - 1) : 0;
+ break;
+ default:
+ // unlikely to happen
+ this.minSize = Integer.MAX_VALUE;
+ this.maxSize = -1;
+ }
+ }
+
+ // Does this key constraint disable the specified key?
+ public boolean disables(Key key) {
+ int size = -1;
+
+ // it is a SecretKey
+ if (key instanceof SecretKey) {
+ SecretKey sk = (SecretKey)key;
+ if (sk.getFormat().equals("RAW") && sk.getEncoded() != null) {
+ size = sk.getEncoded().length * 8;
+
+ }
+ }
+
+ // it is an asymmetric key
+ if (key instanceof RSAKey) {
+ RSAKey pubk = (RSAKey)key;
+ size = pubk.getModulus().bitLength();
+ } else if (key instanceof ECKey) {
+ ECKey pubk = (ECKey)key;
+ size = pubk.getParams().getOrder().bitLength();
+ } else if (key instanceof DSAKey) {
+ DSAKey pubk = (DSAKey)key;
+ size = pubk.getParams().getP().bitLength();
+ } else if (key instanceof DHKey) {
+ DHKey pubk = (DHKey)key;
+ size = pubk.getParams().getP().bitLength();
+ } // else, it is not a key we know.
+
+ if (size == 0) {
+ return true; // we don't allow any key of size 0.
+ }
+
+ if (size >= 0) {
+ return ((size < minSize) || (size > maxSize) ||
+ (prohibitedSize == size));
+ }
+
+ return false;
+ }
+ }
+
+}
+
diff --git a/src/share/classes/sun/security/validator/PKIXValidator.java b/src/share/classes/sun/security/validator/PKIXValidator.java
index 59daa9eefb89be02ebcd53659fca8f739005b101..a1860a732a89efe3fa1532941b074365bf57f147 100644
--- a/src/share/classes/sun/security/validator/PKIXValidator.java
+++ b/src/share/classes/sun/security/validator/PKIXValidator.java
@@ -31,20 +31,35 @@ import java.security.*;
import java.security.cert.*;
import javax.security.auth.x500.X500Principal;
+import sun.security.action.GetBooleanAction;
+import sun.security.provider.certpath.AlgorithmChecker;
/**
* Validator implementation built on the PKIX CertPath API. This
* implementation will be emphasized going forward.
- *
+ *
* Note that the validate() implementation tries to use a PKIX validator
* if that appears possible and a PKIX builder otherwise. This increases
* performance and currently also leads to better exception messages
* in case of failures.
+ *
+ * {@code PKIXValidator} objects are immutable once they have been created.
+ * Please DO NOT add methods that can change the state of an instance once
+ * it has been created.
*
* @author Andreas Sterbenz
*/
public final class PKIXValidator extends Validator {
+ /**
+ * Flag indicating whether to enable revocation check for the PKIX trust
+ * manager. Typically, this will only work if the PKIX implementation
+ * supports CRL distribution points as we do not manually setup CertStores.
+ */
+ private final static boolean checkTLSRevocation =
+ AccessController.doPrivileged
+ (new GetBooleanAction("com.sun.net.ssl.checkRevocation"));
+
// enable use of the validator if possible
private final static boolean TRY_VALIDATOR = true;
@@ -53,10 +68,10 @@ public final class PKIXValidator extends Validator {
private int certPathLength = -1;
// needed only for the validator
- private Map> trustedSubjects;
- private CertificateFactory factory;
+ private final Map> trustedSubjects;
+ private final CertificateFactory factory;
- private boolean plugin = false;
+ private final boolean plugin;
PKIXValidator(String variant, Collection trustedCerts) {
super(TYPE_PKIX, variant);
@@ -75,7 +90,33 @@ public final class PKIXValidator extends Validator {
throw new RuntimeException("Unexpected error: " + e.toString(), e);
}
setDefaultParameters(variant);
- initCommon();
+
+ // initCommon();
+ if (TRY_VALIDATOR) {
+ if (TRY_VALIDATOR == false) {
+ return;
+ }
+ trustedSubjects = new HashMap>();
+ for (X509Certificate cert : trustedCerts) {
+ X500Principal dn = cert.getSubjectX500Principal();
+ List keys;
+ if (trustedSubjects.containsKey(dn)) {
+ keys = trustedSubjects.get(dn);
+ } else {
+ keys = new ArrayList();
+ trustedSubjects.put(dn, keys);
+ }
+ keys.add(cert.getPublicKey());
+ }
+ try {
+ factory = CertificateFactory.getInstance("X.509");
+ } catch (CertificateException e) {
+ throw new RuntimeException("Internal error", e);
+ }
+ plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
+ } else {
+ plugin = false;
+ }
}
PKIXValidator(String variant, PKIXBuilderParameters params) {
@@ -88,31 +129,33 @@ public final class PKIXValidator extends Validator {
}
}
parameterTemplate = params;
- initCommon();
- }
- private void initCommon() {
- if (TRY_VALIDATOR == false) {
- return;
- }
- trustedSubjects = new HashMap>();
- for (X509Certificate cert : trustedCerts) {
- X500Principal dn = cert.getSubjectX500Principal();
- List keys;
- if (trustedSubjects.containsKey(dn)) {
- keys = trustedSubjects.get(dn);
- } else {
- keys = new ArrayList();
- trustedSubjects.put(dn, keys);
+ // initCommon();
+ if (TRY_VALIDATOR) {
+ if (TRY_VALIDATOR == false) {
+ return;
}
- keys.add(cert.getPublicKey());
- }
- try {
- factory = CertificateFactory.getInstance("X.509");
- } catch (CertificateException e) {
- throw new RuntimeException("Internal error", e);
+ trustedSubjects = new HashMap>();
+ for (X509Certificate cert : trustedCerts) {
+ X500Principal dn = cert.getSubjectX500Principal();
+ List keys;
+ if (trustedSubjects.containsKey(dn)) {
+ keys = trustedSubjects.get(dn);
+ } else {
+ keys = new ArrayList();
+ trustedSubjects.put(dn, keys);
+ }
+ keys.add(cert.getPublicKey());
+ }
+ try {
+ factory = CertificateFactory.getInstance("X.509");
+ } catch (CertificateException e) {
+ throw new RuntimeException("Internal error", e);
+ }
+ plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
+ } else {
+ plugin = false;
}
- plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
}
public Collection getTrustedCertificates() {
@@ -129,7 +172,7 @@ public final class PKIXValidator extends Validator {
* @return the length of the last certification path passed to
* CertPathValidator.validate, or -1 if it has not been invoked yet
*/
- public int getCertPathLength() {
+ public int getCertPathLength() { // mutable, should be private
return certPathLength;
}
@@ -138,7 +181,12 @@ public final class PKIXValidator extends Validator {
* revocation checking. In the future, this should be configurable.
*/
private void setDefaultParameters(String variant) {
- parameterTemplate.setRevocationEnabled(false);
+ if ((variant == Validator.VAR_TLS_SERVER) ||
+ (variant == Validator.VAR_TLS_CLIENT)) {
+ parameterTemplate.setRevocationEnabled(checkTLSRevocation);
+ } else {
+ parameterTemplate.setRevocationEnabled(false);
+ }
}
/**
@@ -146,17 +194,29 @@ public final class PKIXValidator extends Validator {
* modify the parameters but must make sure not to perform any concurrent
* validations.
*/
- public PKIXBuilderParameters getParameters() {
+ public PKIXBuilderParameters getParameters() { // mutable, should be private
return parameterTemplate;
}
+ @Override
X509Certificate[] engineValidate(X509Certificate[] chain,
- Collection otherCerts, Object parameter)
- throws CertificateException {
+ Collection otherCerts,
+ AlgorithmConstraints constraints,
+ Object parameter) throws CertificateException {
if ((chain == null) || (chain.length == 0)) {
throw new CertificateException
("null or zero-length certificate chain");
}
+
+ // add new algorithm constraints checker
+ PKIXBuilderParameters pkixParameters =
+ (PKIXBuilderParameters) parameterTemplate.clone();
+ AlgorithmChecker algorithmChecker = null;
+ if (constraints != null) {
+ algorithmChecker = new AlgorithmChecker(constraints);
+ pkixParameters.addCertPathChecker(algorithmChecker);
+ }
+
if (TRY_VALIDATOR) {
// check that chain is in correct order and check if chain contains
// trust anchor
@@ -167,7 +227,7 @@ public final class PKIXValidator extends Validator {
if (i != 0 &&
!dn.equals(prevIssuer)) {
// chain is not ordered correctly, call builder instead
- return doBuild(chain, otherCerts);
+ return doBuild(chain, otherCerts, pkixParameters);
}
// Check if chain[i] is already trusted. It may be inside
@@ -186,7 +246,7 @@ public final class PKIXValidator extends Validator {
// Remove and call validator on partial chain [0 .. i-1]
X509Certificate[] newChain = new X509Certificate[i];
System.arraycopy(chain, 0, newChain, 0, i);
- return doValidate(newChain);
+ return doValidate(newChain, pkixParameters);
}
prevIssuer = cert.getIssuerX500Principal();
}
@@ -197,7 +257,7 @@ public final class PKIXValidator extends Validator {
X500Principal subject = last.getSubjectX500Principal();
if (trustedSubjects.containsKey(issuer) &&
isSignatureValid(trustedSubjects.get(issuer), last)) {
- return doValidate(chain);
+ return doValidate(chain, pkixParameters);
}
// don't fallback to builder if called from plugin/webstart
@@ -209,18 +269,17 @@ public final class PKIXValidator extends Validator {
X509Certificate[] newChain =
new X509Certificate[chain.length-1];
System.arraycopy(chain, 0, newChain, 0, newChain.length);
+
// temporarily set last cert as sole trust anchor
- PKIXBuilderParameters params =
- (PKIXBuilderParameters) parameterTemplate.clone();
try {
- params.setTrustAnchors
+ pkixParameters.setTrustAnchors
(Collections.singleton(new TrustAnchor
(chain[chain.length-1], null)));
} catch (InvalidAlgorithmParameterException iape) {
// should never occur, but ...
throw new CertificateException(iape);
}
- doValidate(newChain, params);
+ doValidate(newChain, pkixParameters);
}
// if the rest of the chain is valid, throw exception
// indicating no trust anchor was found
@@ -230,10 +289,11 @@ public final class PKIXValidator extends Validator {
// otherwise, fall back to builder
}
- return doBuild(chain, otherCerts);
+ return doBuild(chain, otherCerts, pkixParameters);
}
- private boolean isSignatureValid(List keys, X509Certificate sub) {
+ private boolean isSignatureValid(List keys,
+ X509Certificate sub) {
if (plugin) {
for (PublicKey key: keys) {
try {
@@ -273,13 +333,6 @@ public final class PKIXValidator extends Validator {
}
}
- private X509Certificate[] doValidate(X509Certificate[] chain)
- throws CertificateException {
- PKIXBuilderParameters params =
- (PKIXBuilderParameters)parameterTemplate.clone();
- return doValidate(chain, params);
- }
-
private X509Certificate[] doValidate(X509Certificate[] chain,
PKIXBuilderParameters params) throws CertificateException {
try {
@@ -300,11 +353,10 @@ public final class PKIXValidator extends Validator {
}
private X509Certificate[] doBuild(X509Certificate[] chain,
- Collection otherCerts) throws CertificateException {
+ Collection otherCerts,
+ PKIXBuilderParameters params) throws CertificateException {
try {
- PKIXBuilderParameters params =
- (PKIXBuilderParameters)parameterTemplate.clone();
setDate(params);
// setup target constraints
diff --git a/src/share/classes/sun/security/validator/SimpleValidator.java b/src/share/classes/sun/security/validator/SimpleValidator.java
index 8c94376f35aa09c72eec9c1767965fc04ddc0461..f825a4d6867dcb57eb60e46e0ae65f576b0bcb9e 100644
--- a/src/share/classes/sun/security/validator/SimpleValidator.java
+++ b/src/share/classes/sun/security/validator/SimpleValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -48,6 +48,10 @@ import sun.security.provider.certpath.AlgorithmChecker;
* deployed certificates and previous J2SE versions. It will never support
* more advanced features and will be deemphasized in favor of the PKIX
* validator going forward.
+ *
+ * {@code SimpleValidator} objects are immutable once they have been created.
+ * Please DO NOT add methods that can change the state of an instance once
+ * it has been created.
*
* @author Andreas Sterbenz
*/
@@ -80,13 +84,14 @@ public final class SimpleValidator extends Validator {
* The list is used because there may be multiple certificates
* with an identical subject DN.
*/
- private Map> trustedX500Principals;
+ private final Map>
+ trustedX500Principals;
/**
* Set of the trusted certificates. Present only for
* getTrustedCertificates().
*/
- private Collection trustedCerts;
+ private final Collection trustedCerts;
SimpleValidator(String variant, Collection trustedCerts) {
super(TYPE_SIMPLE, variant);
@@ -114,9 +119,11 @@ public final class SimpleValidator extends Validator {
* Perform simple validation of chain. The arguments otherCerts and
* parameter are ignored.
*/
+ @Override
X509Certificate[] engineValidate(X509Certificate[] chain,
- Collection otherCerts, Object parameter)
- throws CertificateException {
+ Collection otherCerts,
+ AlgorithmConstraints constraints,
+ Object parameter) throws CertificateException {
if ((chain == null) || (chain.length == 0)) {
throw new CertificateException
("null or zero-length certificate chain");
@@ -129,6 +136,17 @@ public final class SimpleValidator extends Validator {
if (date == null) {
date = new Date();
}
+
+ // create default algorithm constraints checker
+ TrustAnchor anchor = new TrustAnchor(chain[chain.length - 1], null);
+ AlgorithmChecker defaultAlgChecker = new AlgorithmChecker(anchor);
+
+ // create application level algorithm constraints checker
+ AlgorithmChecker appAlgChecker = null;
+ if (constraints != null) {
+ appAlgChecker = new AlgorithmChecker(anchor, constraints);
+ }
+
// verify top down, starting at the certificate issued by
// the trust anchor
int maxPathLength = chain.length - 1;
@@ -138,7 +156,12 @@ public final class SimpleValidator extends Validator {
// check certificate algorithm
try {
- AlgorithmChecker.check(cert);
+ // Algorithm checker don't care about the unresolved critical
+ // extensions.
+ defaultAlgChecker.check(cert, Collections.emptySet());
+ if (appAlgChecker != null) {
+ appAlgChecker.check(cert, Collections.emptySet());
+ }
} catch (CertPathValidatorException cpve) {
throw new ValidatorException
(ValidatorException.T_ALGORITHM_DISABLED, cert, cpve);
diff --git a/src/share/classes/sun/security/validator/Validator.java b/src/share/classes/sun/security/validator/Validator.java
index 0e21397aeaa67ac3ecb9c2466c41a6515e2292ad..863566c73571fb43e5462cbad18fc97515a64a78 100644
--- a/src/share/classes/sun/security/validator/Validator.java
+++ b/src/share/classes/sun/security/validator/Validator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -27,6 +27,7 @@ package sun.security.validator;
import java.util.*;
+import java.security.AlgorithmConstraints;
import java.security.KeyStore;
import java.security.cert.*;
@@ -232,16 +233,44 @@ public abstract class Validator {
public final X509Certificate[] validate(X509Certificate[] chain,
Collection otherCerts, Object parameter)
throws CertificateException {
- chain = engineValidate(chain, otherCerts, parameter);
+ return validate(chain, otherCerts, null, parameter);
+ }
+
+ /**
+ * Validate the given certificate chain.
+ *
+ * @param chain the target certificate chain
+ * @param otherCerts a Collection of additional X509Certificates that
+ * could be helpful for path building (or null)
+ * @param constraints algorithm constraints for certification path
+ * processing
+ * @param parameter an additional parameter with variant specific meaning.
+ * Currently, it is only defined for TLS_SERVER variant validators,
+ * where it must be non null and the name of the TLS key exchange
+ * algorithm being used (see JSSE X509TrustManager specification).
+ * In the future, it could be used to pass in a PKCS#7 object for
+ * code signing to check time stamps.
+ * @return a non-empty chain that was used to validate the path. The
+ * end entity cert is at index 0, the trust anchor at index n-1.
+ */
+ public final X509Certificate[] validate(X509Certificate[] chain,
+ Collection otherCerts,
+ AlgorithmConstraints constraints,
+ Object parameter) throws CertificateException {
+ chain = engineValidate(chain, otherCerts, constraints, parameter);
+
// omit EE extension check if EE cert is also trust anchor
if (chain.length > 1) {
endEntityChecker.check(chain[0], parameter);
}
+
return chain;
}
abstract X509Certificate[] engineValidate(X509Certificate[] chain,
- Collection otherCerts, Object parameter) throws CertificateException;
+ Collection otherCerts,
+ AlgorithmConstraints constraints,
+ Object parameter) throws CertificateException;
/**
* Returns an immutable Collection of the X509Certificates this instance
diff --git a/src/share/classes/sun/security/x509/X509CRLImpl.java b/src/share/classes/sun/security/x509/X509CRLImpl.java
index 404826b6d61d29cc4114a083e8517df1b27b8507..b99bc448bbdd2cbf38009782144c96aa038b52d6 100644
--- a/src/share/classes/sun/security/x509/X509CRLImpl.java
+++ b/src/share/classes/sun/security/x509/X509CRLImpl.java
@@ -763,6 +763,15 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
}
}
+ /**
+ * Gets the signature AlgorithmId from the CRL.
+ *
+ * @return the signature AlgorithmId
+ */
+ public AlgorithmId getSigAlgId() {
+ return sigAlgId;
+ }
+
/**
* return the AuthorityKeyIdentifier, if any.
*
diff --git a/src/share/lib/security/java.security b/src/share/lib/security/java.security
index 1c9404f60af4caea46f99a296adcc054ac61bd4a..5a0726de0a7dcee58173c99baf5c517faf3440ca 100644
--- a/src/share/lib/security/java.security
+++ b/src/share/lib/security/java.security
@@ -282,3 +282,95 @@ networkaddress.cache.negative.ttl=10
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+# Algorithm restrictions for certification path (CertPath) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for certification path building and validation. For example, "MD2" is
+# generally no longer considered to be a secure hash algorithm. This section
+# describes the mechanism for disabling algorithms based on algorithm name
+# and/or key length. This includes algorithms used in certificates, as well
+# as revocation information such as CRLs and signed OCSP Responses.
+#
+# The syntax of the disabled algorithm string is described as this Java
+# BNF-style:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator DecimalInteger
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# DecimalInteger:
+# DecimalDigits
+#
+# DecimalDigits:
+# DecimalDigit {DecimalDigit}
+#
+# DecimalDigit: one of
+# 1 2 3 4 5 6 7 8 9 0
+#
+# The "AlgorithmName" is the standard algorithm name of the disabled
+# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
+# Documentation" for information about Standard Algorithm Names. Matching
+# is performed using a case-insensitive sub-element matching rule. (For
+# example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and
+# "ECDSA" for signatures.) If the assertion "AlgorithmName" is a
+# sub-element of the certificate algorithm name, the algorithm will be
+# rejected during certification path building and validation. For example,
+# the assertion algorithm name "DSA" will disable all certificate algorithms
+# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
+# will not disable algorithms related to "ECDSA".
+#
+# A "Constraint" provides further guidance for the algorithm being specified.
+# The "KeySizeConstraint" requires a key of a valid size range if the
+# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
+# key size specified in number of bits. For example, "RSA keySize <= 1024"
+# indicates that any RSA key with key size less than or equal to 1024 bits
+# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
+# that any RSA key with key size less than 1024 or greater than 2048 should
+# be disabled. Note that the "KeySizeConstraint" only makes sense to key
+# algorithms.
+#
+# Note: This property is currently used by Oracle's PKIX implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
+#
+#
+jdk.certpath.disabledAlgorithms=MD2
+
+# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
+# (SSL/TLS) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# when using SSL/TLS. This section describes the mechanism for disabling
+# algorithms during SSL/TLS security parameters negotiation, including cipher
+# suites selection, peer authentication and key exchange mechanisms.
+#
+# For PKI-based peer authentication and key exchange mechanisms, this list
+# of disabled algorithms will also be checked during certification path
+# building and validation, including algorithms used in certificates, as
+# well as revocation information such as CRLs and signed OCSP Responses.
+# This is in addition to the jdk.certpath.disabledAlgorithms property above.
+#
+# See the specification of "jdk.certpath.disabledAlgorithms" for the
+# syntax of the disabled algorithm string.
+#
+# Note: This property is currently used by Oracle's JSSE implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+
diff --git a/src/share/lib/security/java.security-solaris b/src/share/lib/security/java.security-solaris
index 43621a48511850356b561743506c095bdf9aa45e..0c832c333e328f8315c42398eb950a1414f5830e 100644
--- a/src/share/lib/security/java.security-solaris
+++ b/src/share/lib/security/java.security-solaris
@@ -56,10 +56,10 @@ security.provider.10=sun.security.smartcardio.SunPCSC
#
# Select the source of seed data for SecureRandom. By default an
-# attempt is made to use the entropy gathering device specified by
+# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
-# accessing the URL then the traditional system/thread activity
-# algorithm is used.
+# accessing the URL then the traditional system/thread activity
+# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
@@ -73,7 +73,7 @@ securerandom.source=file:/dev/urandom
# The entropy gathering device is described as a URL and can also
# be specified with the system property "java.security.egd". For example,
# -Djava.security.egd=file:/dev/urandom
-# Specifying this system property will override the securerandom.source
+# Specifying this system property will override the securerandom.source
# setting.
#
@@ -150,7 +150,7 @@ package.access=sun.,com.sun.imageio.
security.overridePropertiesFile=true
#
-# Determines the default key and trust manager factory algorithms for
+# Determines the default key and trust manager factory algorithms for
# the javax.net.ssl package.
#
ssl.KeyManagerFactory.algorithm=SunX509
@@ -165,13 +165,14 @@ ssl.TrustManagerFactory.algorithm=PKIX
#
# default value is forever (FOREVER). For security reasons, this
# caching is made forever when a security manager is set. When a security
-# manager is not set, the default behavior is to cache for 30 seconds.
+# manager is not set, the default behavior in this implementation
+# is to cache for 30 seconds.
#
# NOTE: setting this to anything other than the default value can have
-# serious security implications. Do not set it unless
+# serious security implications. Do not set it unless
# you are sure you are not exposed to DNS spoofing attack.
#
-#networkaddress.cache.ttl=-1
+#networkaddress.cache.ttl=-1
# The Java-level namelookup cache policy for failed lookups:
#
@@ -183,7 +184,7 @@ ssl.TrustManagerFactory.algorithm=PKIX
# the WINS name service in addition to DNS, name service lookups
# that fail may take a noticeably long time to return (approx. 5 seconds).
# For this reason the default caching policy is to maintain these
-# results for 10 seconds.
+# results for 10 seconds.
#
#
networkaddress.cache.negative.ttl=10
@@ -192,7 +193,7 @@ networkaddress.cache.negative.ttl=10
# Properties to configure OCSP for certificate revocation checking
#
-# Enable OCSP
+# Enable OCSP
#
# By default, OCSP is not used for certificate revocation checking.
# This property enables the use of OCSP when set to the value "true".
@@ -201,7 +202,7 @@ networkaddress.cache.negative.ttl=10
#
# Example,
# ocsp.enable=true
-
+
#
# Location of the OCSP responder
#
@@ -213,15 +214,15 @@ networkaddress.cache.negative.ttl=10
#
# Example,
# ocsp.responderURL=http://ocsp.example.net:80
-
+
#
# Subject name of the OCSP responder's certificate
#
# By default, the certificate of the OCSP responder is that of the issuer
# of the certificate being validated. This property identifies the certificate
-# of the OCSP responder when the default does not apply. Its value is a string
-# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. In cases where
+# of the OCSP responder when the default does not apply. Its value is a string
+# distinguished name (defined in RFC 2253) which identifies a certificate in
+# the set of certificates supplied during cert path validation. In cases where
# the subject name alone is not sufficient to uniquely identify the certificate
# then both the "ocsp.responderCertIssuerName" and
# "ocsp.responderCertSerialNumber" properties must be used instead. When this
@@ -237,14 +238,14 @@ networkaddress.cache.negative.ttl=10
# of the certificate being validated. This property identifies the certificate
# of the OCSP responder when the default does not apply. Its value is a string
# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. When this
-# property is set then the "ocsp.responderCertSerialNumber" property must also
-# be set. When the "ocsp.responderCertSubjectName" property is set then this
+# the set of certificates supplied during cert path validation. When this
+# property is set then the "ocsp.responderCertSerialNumber" property must also
+# be set. When the "ocsp.responderCertSubjectName" property is set then this
# property is ignored.
#
# Example,
# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"
-
+
#
# Serial number of the OCSP responder's certificate
#
@@ -259,7 +260,7 @@ networkaddress.cache.negative.ttl=10
#
# Example,
# ocsp.responderCertSerialNumber=2A:FF:00
-
+
#
# Policy for failed Kerberos KDC lookups:
#
@@ -287,3 +288,95 @@ networkaddress.cache.negative.ttl=10
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+# Algorithm restrictions for certification path (CertPath) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for certification path building and validation. For example, "MD2" is
+# generally no longer considered to be a secure hash algorithm. This section
+# describes the mechanism for disabling algorithms based on algorithm name
+# and/or key length. This includes algorithms used in certificates, as well
+# as revocation information such as CRLs and signed OCSP Responses.
+#
+# The syntax of the disabled algorithm string is described as this Java
+# BNF-style:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator DecimalInteger
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# DecimalInteger:
+# DecimalDigits
+#
+# DecimalDigits:
+# DecimalDigit {DecimalDigit}
+#
+# DecimalDigit: one of
+# 1 2 3 4 5 6 7 8 9 0
+#
+# The "AlgorithmName" is the standard algorithm name of the disabled
+# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
+# Documentation" for information about Standard Algorithm Names. Matching
+# is performed using a case-insensitive sub-element matching rule. (For
+# example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and
+# "ECDSA" for signatures.) If the assertion "AlgorithmName" is a
+# sub-element of the certificate algorithm name, the algorithm will be
+# rejected during certification path building and validation. For example,
+# the assertion algorithm name "DSA" will disable all certificate algorithms
+# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
+# will not disable algorithms related to "ECDSA".
+#
+# A "Constraint" provides further guidance for the algorithm being specified.
+# The "KeySizeConstraint" requires a key of a valid size range if the
+# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
+# key size specified in number of bits. For example, "RSA keySize <= 1024"
+# indicates that any RSA key with key size less than or equal to 1024 bits
+# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
+# that any RSA key with key size less than 1024 or greater than 2048 should
+# be disabled. Note that the "KeySizeConstraint" only makes sense to key
+# algorithms.
+#
+# Note: This property is currently used by Oracle's PKIX implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
+#
+#
+jdk.certpath.disabledAlgorithms=MD2
+
+# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
+# (SSL/TLS) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# when using SSL/TLS. This section describes the mechanism for disabling
+# algorithms during SSL/TLS security parameters negotiation, including cipher
+# suites selection, peer authentication and key exchange mechanisms.
+#
+# For PKI-based peer authentication and key exchange mechanisms, this list
+# of disabled algorithms will also be checked during certification path
+# building and validation, including algorithms used in certificates, as
+# well as revocation information such as CRLs and signed OCSP Responses.
+# This is in addition to the jdk.certpath.disabledAlgorithms property above.
+#
+# See the specification of "jdk.certpath.disabledAlgorithms" for the
+# syntax of the disabled algorithm string.
+#
+# Note: This property is currently used by Oracle's JSSE implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+
diff --git a/src/share/lib/security/java.security-windows b/src/share/lib/security/java.security-windows
index 21573b7d23bbeb368e16fd8c2e783bcfb419c311..366753cf37fdf9378531b184e01ebb3747d85e62 100644
--- a/src/share/lib/security/java.security-windows
+++ b/src/share/lib/security/java.security-windows
@@ -56,10 +56,10 @@ security.provider.10=sun.security.mscapi.SunMSCAPI
#
# Select the source of seed data for SecureRandom. By default an
-# attempt is made to use the entropy gathering device specified by
+# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
-# accessing the URL then the traditional system/thread activity
-# algorithm is used.
+# accessing the URL then the traditional system/thread activity
+# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
@@ -73,7 +73,7 @@ securerandom.source=file:/dev/urandom
# The entropy gathering device is described as a URL and can also
# be specified with the system property "java.security.egd". For example,
# -Djava.security.egd=file:/dev/urandom
-# Specifying this system property will override the securerandom.source
+# Specifying this system property will override the securerandom.source
# setting.
#
@@ -150,7 +150,7 @@ package.access=sun.,com.sun.imageio.
security.overridePropertiesFile=true
#
-# Determines the default key and trust manager factory algorithms for
+# Determines the default key and trust manager factory algorithms for
# the javax.net.ssl package.
#
ssl.KeyManagerFactory.algorithm=SunX509
@@ -165,13 +165,14 @@ ssl.TrustManagerFactory.algorithm=PKIX
#
# default value is forever (FOREVER). For security reasons, this
# caching is made forever when a security manager is set. When a security
-# manager is not set, the default behavior is to cache for 30 seconds.
+# manager is not set, the default behavior in this implementation
+# is to cache for 30 seconds.
#
# NOTE: setting this to anything other than the default value can have
-# serious security implications. Do not set it unless
+# serious security implications. Do not set it unless
# you are sure you are not exposed to DNS spoofing attack.
#
-#networkaddress.cache.ttl=-1
+#networkaddress.cache.ttl=-1
# The Java-level namelookup cache policy for failed lookups:
#
@@ -183,7 +184,7 @@ ssl.TrustManagerFactory.algorithm=PKIX
# the WINS name service in addition to DNS, name service lookups
# that fail may take a noticeably long time to return (approx. 5 seconds).
# For this reason the default caching policy is to maintain these
-# results for 10 seconds.
+# results for 10 seconds.
#
#
networkaddress.cache.negative.ttl=10
@@ -192,7 +193,7 @@ networkaddress.cache.negative.ttl=10
# Properties to configure OCSP for certificate revocation checking
#
-# Enable OCSP
+# Enable OCSP
#
# By default, OCSP is not used for certificate revocation checking.
# This property enables the use of OCSP when set to the value "true".
@@ -201,7 +202,7 @@ networkaddress.cache.negative.ttl=10
#
# Example,
# ocsp.enable=true
-
+
#
# Location of the OCSP responder
#
@@ -213,15 +214,15 @@ networkaddress.cache.negative.ttl=10
#
# Example,
# ocsp.responderURL=http://ocsp.example.net:80
-
+
#
# Subject name of the OCSP responder's certificate
#
# By default, the certificate of the OCSP responder is that of the issuer
# of the certificate being validated. This property identifies the certificate
-# of the OCSP responder when the default does not apply. Its value is a string
-# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. In cases where
+# of the OCSP responder when the default does not apply. Its value is a string
+# distinguished name (defined in RFC 2253) which identifies a certificate in
+# the set of certificates supplied during cert path validation. In cases where
# the subject name alone is not sufficient to uniquely identify the certificate
# then both the "ocsp.responderCertIssuerName" and
# "ocsp.responderCertSerialNumber" properties must be used instead. When this
@@ -237,14 +238,14 @@ networkaddress.cache.negative.ttl=10
# of the certificate being validated. This property identifies the certificate
# of the OCSP responder when the default does not apply. Its value is a string
# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. When this
-# property is set then the "ocsp.responderCertSerialNumber" property must also
-# be set. When the "ocsp.responderCertSubjectName" property is set then this
+# the set of certificates supplied during cert path validation. When this
+# property is set then the "ocsp.responderCertSerialNumber" property must also
+# be set. When the "ocsp.responderCertSubjectName" property is set then this
# property is ignored.
#
# Example,
# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"
-
+
#
# Serial number of the OCSP responder's certificate
#
@@ -259,7 +260,7 @@ networkaddress.cache.negative.ttl=10
#
# Example,
# ocsp.responderCertSerialNumber=2A:FF:00
-
+
#
# Policy for failed Kerberos KDC lookups:
#
@@ -287,3 +288,95 @@ networkaddress.cache.negative.ttl=10
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+# Algorithm restrictions for certification path (CertPath) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for certification path building and validation. For example, "MD2" is
+# generally no longer considered to be a secure hash algorithm. This section
+# describes the mechanism for disabling algorithms based on algorithm name
+# and/or key length. This includes algorithms used in certificates, as well
+# as revocation information such as CRLs and signed OCSP Responses.
+#
+# The syntax of the disabled algorithm string is described as this Java
+# BNF-style:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator DecimalInteger
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# DecimalInteger:
+# DecimalDigits
+#
+# DecimalDigits:
+# DecimalDigit {DecimalDigit}
+#
+# DecimalDigit: one of
+# 1 2 3 4 5 6 7 8 9 0
+#
+# The "AlgorithmName" is the standard algorithm name of the disabled
+# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
+# Documentation" for information about Standard Algorithm Names. Matching
+# is performed using a case-insensitive sub-element matching rule. (For
+# example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and
+# "ECDSA" for signatures.) If the assertion "AlgorithmName" is a
+# sub-element of the certificate algorithm name, the algorithm will be
+# rejected during certification path building and validation. For example,
+# the assertion algorithm name "DSA" will disable all certificate algorithms
+# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
+# will not disable algorithms related to "ECDSA".
+#
+# A "Constraint" provides further guidance for the algorithm being specified.
+# The "KeySizeConstraint" requires a key of a valid size range if the
+# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
+# key size specified in number of bits. For example, "RSA keySize <= 1024"
+# indicates that any RSA key with key size less than or equal to 1024 bits
+# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
+# that any RSA key with key size less than 1024 or greater than 2048 should
+# be disabled. Note that the "KeySizeConstraint" only makes sense to key
+# algorithms.
+#
+# Note: This property is currently used by Oracle's PKIX implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
+#
+#
+jdk.certpath.disabledAlgorithms=MD2
+
+# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
+# (SSL/TLS) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# when using SSL/TLS. This section describes the mechanism for disabling
+# algorithms during SSL/TLS security parameters negotiation, including cipher
+# suites selection, peer authentication and key exchange mechanisms.
+#
+# For PKI-based peer authentication and key exchange mechanisms, this list
+# of disabled algorithms will also be checked during certification path
+# building and validation, including algorithms used in certificates, as
+# well as revocation information such as CRLs and signed OCSP Responses.
+# This is in addition to the jdk.certpath.disabledAlgorithms property above.
+#
+# See the specification of "jdk.certpath.disabledAlgorithms" for the
+# syntax of the disabled algorithm string.
+#
+# Note: This property is currently used by Oracle's JSSE implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+