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 +