Mercurial > hg > openjdk > jdk8u > jdk
changeset 12107:5f0839ac7e0d jdk8u121-b01
Merge
author | asaha |
---|---|
date | Mon, 19 Sep 2016 11:21:02 -0700 |
parents | 1f5412ac6bd8 (current diff) 8dc49b3c8953 (diff) |
children | 17a829050ae5 |
files | |
diffstat | 38 files changed, 1828 insertions(+), 526 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/net/SocketInputStream.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/java/net/SocketInputStream.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,11 +155,12 @@ } // bounds check - if (length <= 0 || off < 0 || off + length > b.length) { + if (length <= 0 || off < 0 || length > b.length - off) { if (length == 0) { return 0; } - throw new ArrayIndexOutOfBoundsException(); + throw new ArrayIndexOutOfBoundsException("length == " + length + + " off == " + off + " buffer length == " + b.length); } boolean gotReset = false;
--- a/src/share/classes/java/net/SocketOutputStream.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/java/net/SocketOutputStream.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,11 +97,13 @@ */ private void socketWrite(byte b[], int off, int len) throws IOException { - if (len <= 0 || off < 0 || off + len > b.length) { + + if (len <= 0 || off < 0 || len > b.length - off) { if (len == 0) { return; } - throw new ArrayIndexOutOfBoundsException(); + throw new ArrayIndexOutOfBoundsException("len == " + len + + " off == " + off + " buffer length == " + b.length); } FileDescriptor fd = impl.acquireFD();
--- a/src/share/classes/sun/security/pkcs/SignerInfo.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/pkcs/SignerInfo.java Mon Sep 19 11:21:02 2016 -0700 @@ -55,6 +55,7 @@ import sun.security.util.DerOutputStream; import sun.security.util.DerValue; import sun.security.util.DisabledAlgorithmConstraints; +import sun.security.util.KeyUtil; import sun.security.util.ObjectIdentifier; import sun.security.x509.AlgorithmId; import sun.security.x509.X500Name; @@ -399,7 +400,9 @@ // check if the public key is restricted if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { throw new SignatureException("Public key check failed. " + - "Disabled algorithm used: " + key.getAlgorithm()); + "Disabled key used: " + + KeyUtil.getKeySize(key) + " bit " + + key.getAlgorithm()); } if (cert.hasUnsupportedCriticalExtension()) {
--- a/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,12 +31,10 @@ 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.X509CRL; @@ -48,10 +46,13 @@ import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.PKIXReason; -import java.io.IOException; -import java.security.interfaces.*; -import java.security.spec.*; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPublicKey; +import java.security.spec.DSAPublicKeySpec; +import sun.security.util.AnchorCertificates; +import sun.security.util.CertConstraintParameters; +import sun.security.util.Debug; import sun.security.util.DisabledAlgorithmConstraints; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CRLImpl; @@ -69,6 +70,7 @@ * @see PKIXParameters */ final public class AlgorithmChecker extends PKIXCertPathChecker { + private static final Debug debug = Debug.getInstance("certpath"); private final AlgorithmConstraints constraints; private final PublicKey trustedPubKey; @@ -88,6 +90,14 @@ certPathDefaultConstraints = new DisabledAlgorithmConstraints( DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); + // If there is no "cacerts" keyword, then disable anchor checking + private static final boolean publicCALimits = + certPathDefaultConstraints.checkProperty("jdkCA"); + + // If anchor checking enabled, this will be true if the trust anchor + // has a match in the cacerts file + private boolean trustedMatch = false; + /** * Create a new <code>AlgorithmChecker</code> with the algorithm * constraints specified in security property @@ -136,6 +146,11 @@ if (anchor.getTrustedCert() != null) { this.trustedPubKey = anchor.getTrustedCert().getPublicKey(); + // Check for anchor certificate restrictions + trustedMatch = checkFingerprint(anchor.getTrustedCert()); + if (trustedMatch && debug != null) { + debug.println("trustedMatch = true"); + } } else { this.trustedPubKey = anchor.getCAPublicKey(); } @@ -144,6 +159,19 @@ this.constraints = constraints; } + // Check this 'cert' for restrictions in the AnchorCertificates + // trusted certificates list + private static boolean checkFingerprint(X509Certificate cert) { + if (!publicCALimits) { + return false; + } + + if (debug != null) { + debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName()); + } + return AnchorCertificates.contains(cert); + } + @Override public void init(boolean forward) throws CertPathValidatorException { // Note that this class does not support forward mode. @@ -181,36 +209,8 @@ return; } - X509CertImpl x509Cert = null; - try { - x509Cert = X509CertImpl.toImpl((X509Certificate)cert); - } catch (CertificateException ce) { - throw new CertPathValidatorException(ce); - } - - PublicKey currPubKey = x509Cert.getPublicKey(); - String currSigAlg = x509Cert.getSigAlgName(); - - AlgorithmId algorithmId = null; - try { - algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG); - } catch (CertificateException ce) { - throw new CertPathValidatorException(ce); - } - - AlgorithmParameters currSigAlgParams = algorithmId.getParameters(); - - // Check the current signature algorithm - if (!constraints.permits( - SIGNATURE_PRIMITIVE_SET, - currSigAlg, currSigAlgParams)) { - throw new CertPathValidatorException( - "Algorithm constraints check failed: " + currSigAlg, - null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); - } - // check the key usage and key size - boolean[] keyUsage = x509Cert.getKeyUsage(); + boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage(); if (keyUsage != null && keyUsage.length < 9) { throw new CertPathValidatorException( "incorrect KeyUsage extension", @@ -248,28 +248,68 @@ if (primitives.isEmpty()) { throw new CertPathValidatorException( - "incorrect KeyUsage extension", + "incorrect KeyUsage extension bits", null, null, -1, PKIXReason.INVALID_KEY_USAGE); } } + PublicKey currPubKey = cert.getPublicKey(); + + // Check against DisabledAlgorithmConstraints certpath constraints. + // permits() will throw exception on failure. + certPathDefaultConstraints.permits(primitives, + new CertConstraintParameters((X509Certificate)cert, + trustedMatch)); + // new CertConstraintParameters(x509Cert, trustedMatch)); + // If there is no previous key, set one and exit + if (prevPubKey == null) { + prevPubKey = currPubKey; + return; + } + + X509CertImpl x509Cert; + AlgorithmId algorithmId; + try { + x509Cert = X509CertImpl.toImpl((X509Certificate)cert); + algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG); + } catch (CertificateException ce) { + throw new CertPathValidatorException(ce); + } + + AlgorithmParameters currSigAlgParams = algorithmId.getParameters(); + String currSigAlg = x509Cert.getSigAlgName(); + + // If 'constraints' is not of DisabledAlgorithmConstraints, check all + // everything individually + if (!(constraints instanceof DisabledAlgorithmConstraints)) { + // Check the current signature algorithm + if (!constraints.permits( + SIGNATURE_PRIMITIVE_SET, + currSigAlg, currSigAlgParams)) { + throw new CertPathValidatorException( + "Algorithm constraints check failed on signature " + + "algorithm: " + currSigAlg, null, null, -1, + BasicReason.ALGORITHM_CONSTRAINED); + } + if (!constraints.permits(primitives, currPubKey)) { throw new CertPathValidatorException( - "algorithm constraints check failed", + "Algorithm constraints check failed on keysize: " + + sun.security.util.KeyUtil.getKeySize(currPubKey), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } + } // 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, + "Algorithm constraints check failed on " + + "signature algorithm: " + currSigAlg, null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } - } // Inherit key parameters from previous key if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) { @@ -282,7 +322,7 @@ DSAParams params = ((DSAPublicKey)prevPubKey).getParams(); if (params == null) { throw new CertPathValidatorException( - "Key parameters missing"); + "Key parameters missing from public key."); } try { @@ -330,6 +370,11 @@ // Don't bother to change the trustedPubKey. if (anchor.getTrustedCert() != null) { prevPubKey = anchor.getTrustedCert().getPublicKey(); + // Check for anchor certificate restrictions + trustedMatch = checkFingerprint(anchor.getTrustedCert()); + if (trustedMatch && debug != null) { + debug.println("trustedMatch = true"); + } } else { prevPubKey = anchor.getCAPublicKey(); } @@ -370,7 +415,8 @@ if (!certPathDefaultConstraints.permits( SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) { throw new CertPathValidatorException( - "algorithm check failed: " + sigAlgName + " is disabled", + "Algorithm constraints check failed on signature algorithm: " + + sigAlgName + " is disabled", null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } }
--- a/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java Mon Sep 19 11:21:02 2016 -0700 @@ -131,8 +131,8 @@ } catch (CertPathValidatorException cpve) { throw new CertPathValidatorException(cpve.getMessage(), - cpve.getCause(), cpOriginal, cpSize - (i + 1), - cpve.getReason()); + (cpve.getCause() != null) ? cpve.getCause() : cpve, + cpOriginal, cpSize - (i + 1), cpve.getReason()); } }
--- a/src/share/classes/sun/security/ssl/CipherSuite.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/CipherSuite.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -326,36 +326,38 @@ static enum KeyExchange { // key exchange algorithms - K_NULL ("NULL", false), - K_RSA ("RSA", true), - K_RSA_EXPORT ("RSA_EXPORT", true), - K_DH_RSA ("DH_RSA", false), - K_DH_DSS ("DH_DSS", false), - K_DHE_DSS ("DHE_DSS", true), - K_DHE_RSA ("DHE_RSA", true), - K_DH_ANON ("DH_anon", true), + K_NULL ("NULL", false, false), + K_RSA ("RSA", true, false), + K_RSA_EXPORT ("RSA_EXPORT", true, false), + K_DH_RSA ("DH_RSA", false, false), + K_DH_DSS ("DH_DSS", false, false), + K_DHE_DSS ("DHE_DSS", true, false), + K_DHE_RSA ("DHE_RSA", true, false), + K_DH_ANON ("DH_anon", true, false), - K_ECDH_ECDSA ("ECDH_ECDSA", ALLOW_ECC), - K_ECDH_RSA ("ECDH_RSA", ALLOW_ECC), - K_ECDHE_ECDSA("ECDHE_ECDSA", ALLOW_ECC), - K_ECDHE_RSA ("ECDHE_RSA", ALLOW_ECC), - K_ECDH_ANON ("ECDH_anon", ALLOW_ECC), + K_ECDH_ECDSA ("ECDH_ECDSA", ALLOW_ECC, true), + K_ECDH_RSA ("ECDH_RSA", ALLOW_ECC, true), + K_ECDHE_ECDSA("ECDHE_ECDSA", ALLOW_ECC, true), + K_ECDHE_RSA ("ECDHE_RSA", ALLOW_ECC, true), + K_ECDH_ANON ("ECDH_anon", ALLOW_ECC, true), // Kerberos cipher suites - K_KRB5 ("KRB5", true), - K_KRB5_EXPORT("KRB5_EXPORT", true), + K_KRB5 ("KRB5", true, false), + K_KRB5_EXPORT("KRB5_EXPORT", true, false), // renegotiation protection request signaling cipher suite - K_SCSV ("SCSV", true); + K_SCSV ("SCSV", true, false); // name of the key exchange algorithm, e.g. DHE_DSS final String name; final boolean allowed; + final boolean isEC; private final boolean alwaysAvailable; - KeyExchange(String name, boolean allowed) { + KeyExchange(String name, boolean allowed, boolean isEC) { this.name = name; this.allowed = allowed; + this.isEC = isEC; this.alwaysAvailable = allowed && (!name.startsWith("EC")) && (!name.startsWith("KRB")); } @@ -365,7 +367,7 @@ return true; } - if (name.startsWith("EC")) { + if (isEC) { return (allowed && JsseJce.isEcAvailable()); } else if (name.startsWith("KRB")) { return (allowed && JsseJce.isKerberosAvailable());
--- a/src/share/classes/sun/security/ssl/CipherSuiteList.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,20 +112,15 @@ boolean containsEC() { if (containsEC == null) { for (CipherSuite c : cipherSuites) { - switch (c.keyExchange) { - case K_ECDH_ECDSA: - case K_ECDH_RSA: - case K_ECDHE_ECDSA: - case K_ECDHE_RSA: - case K_ECDH_ANON: + if (c.keyExchange.isEC) { containsEC = true; return true; - default: - break; } } + containsEC = false; } + return containsEC; }
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java Mon Sep 19 11:21:02 2016 -0700 @@ -762,30 +762,33 @@ String typeName; switch (certRequest.types[i]) { - case CertificateRequest.cct_rsa_sign: - typeName = "RSA"; - break; + case CertificateRequest.cct_rsa_sign: + typeName = "RSA"; + break; - case CertificateRequest.cct_dss_sign: - typeName = "DSA"; - break; + case CertificateRequest.cct_dss_sign: + typeName = "DSA"; + break; + + case CertificateRequest.cct_ecdsa_sign: + // ignore if we do not have EC crypto available + typeName = JsseJce.isEcAvailable() ? "EC" : null; + break; - case CertificateRequest.cct_ecdsa_sign: - // ignore if we do not have EC crypto available - typeName = JsseJce.isEcAvailable() ? "EC" : null; - break; - - // Fixed DH/ECDH client authentication not supported - case CertificateRequest.cct_rsa_fixed_dh: - case CertificateRequest.cct_dss_fixed_dh: - case CertificateRequest.cct_rsa_fixed_ecdh: - case CertificateRequest.cct_ecdsa_fixed_ecdh: - // Any other values (currently not used in TLS) - case CertificateRequest.cct_rsa_ephemeral_dh: - case CertificateRequest.cct_dss_ephemeral_dh: - default: - typeName = null; - break; + // Fixed DH/ECDH client authentication not supported + // + // case CertificateRequest.cct_rsa_fixed_dh: + // case CertificateRequest.cct_dss_fixed_dh: + // case CertificateRequest.cct_rsa_fixed_ecdh: + // case CertificateRequest.cct_ecdsa_fixed_ecdh: + // + // Any other values (currently not used in TLS) + // + // case CertificateRequest.cct_rsa_ephemeral_dh: + // case CertificateRequest.cct_dss_ephemeral_dh: + default: + typeName = null; + break; } if ((typeName != null) && (!keytypesTmp.contains(typeName))) { @@ -813,18 +816,6 @@ X509Certificate[] certs = km.getCertificateChain(alias); if ((certs != null) && (certs.length != 0)) { PublicKey publicKey = certs[0].getPublicKey(); - // for EC, make sure we use a supported named curve - if (publicKey instanceof ECPublicKey) { - ECParameterSpec params = - ((ECPublicKey)publicKey).getParams(); - int index = - SupportedEllipticCurvesExtension.getCurveIndex( - params); - if (!SupportedEllipticCurvesExtension.isSupported( - index)) { - publicKey = null; - } - } if (publicKey != null) { m1 = new CertificateMsg(certs); signingKey = km.getPrivateKey(alias); @@ -1385,6 +1376,17 @@ sslContext.getSecureRandom(), maxProtocolVersion, sessionId, cipherSuites); + // add elliptic curves and point format extensions + if (cipherSuites.containsEC()) { + SupportedEllipticCurvesExtension ece = + SupportedEllipticCurvesExtension.createExtension(algorithmConstraints); + if (ece != null) { + clientHelloMessage.extensions.add(ece); + clientHelloMessage.extensions.add( + SupportedEllipticPointFormatsExtension.DEFAULT); + } + } + // add signature_algorithm extension if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) { // we will always send the signature_algorithm extension
--- a/src/share/classes/sun/security/ssl/ECDHCrypt.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/ECDHCrypt.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,10 +56,11 @@ } // Called by ServerHandshaker for ephemeral ECDH - ECDHCrypt(String curveName, SecureRandom random) { + ECDHCrypt(int curveId, SecureRandom random) { try { KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("EC"); - ECGenParameterSpec params = new ECGenParameterSpec(curveName); + ECGenParameterSpec params = + SupportedEllipticCurvesExtension.getECGenParamSpec(curveId); kpg.initialize(params, random); KeyPair kp = kpg.generateKeyPair(); privateKey = kp.getPrivate();
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java Mon Sep 19 11:21:02 2016 -0700 @@ -230,11 +230,6 @@ this.sessionId = sessionId; this.cipherSuites = cipherSuites; - if (cipherSuites.containsEC()) { - extensions.add(SupportedEllipticCurvesExtension.DEFAULT); - extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT); - } - clnt_random = new RandomCookie(generator); compression_methods = NULL_COMPRESSION; }
--- a/src/share/classes/sun/security/ssl/Handshaker.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/Handshaker.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -636,13 +636,41 @@ ArrayList<CipherSuite> suites = new ArrayList<>(); if (!(activeProtocols.collection().isEmpty()) && activeProtocols.min.v != ProtocolVersion.NONE.v) { + boolean checkedCurves = false; + boolean hasCurves = false; for (CipherSuite suite : enabledCipherSuites.collection()) { if (suite.obsoleted > activeProtocols.min.v && suite.supported <= activeProtocols.max.v) { if (algorithmConstraints.permits( EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) { - suites.add(suite); + boolean available = true; + if (suite.keyExchange.isEC) { + if (!checkedCurves) { + hasCurves = SupportedEllipticCurvesExtension + .hasActiveCurves(algorithmConstraints); + checkedCurves = true; + + if (!hasCurves && debug != null && + Debug.isOn("verbose")) { + System.out.println( + "No available elliptic curves"); + } + } + + available = hasCurves; + + if (!available && debug != null && + Debug.isOn("verbose")) { + System.out.println( + "No active elliptic curves, ignore " + + suite); + } + } + + if (available) { + suites.add(suite); + } } } else if (debug != null && Debug.isOn("verbose")) { if (suite.obsoleted <= activeProtocols.min.v) { @@ -679,18 +707,10 @@ ProtocolList getActiveProtocols() { if (activeProtocols == null) { boolean enabledSSL20Hello = false; + boolean checkedCurves = false; + boolean hasCurves = false; ArrayList<ProtocolVersion> protocols = new ArrayList<>(4); for (ProtocolVersion protocol : enabledProtocols.collection()) { - if (!algorithmConstraints.permits( - EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), - protocol.name, null)) { - if (debug != null && Debug.isOn("verbose")) { - System.out.println( - "Ignoring disabled protocol: " + protocol); - } - - continue; - } // Need not to check the SSL20Hello protocol. if (protocol.v == ProtocolVersion.SSL20Hello.v) { enabledSSL20Hello = true; @@ -714,9 +734,36 @@ if (algorithmConstraints.permits( EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) { - protocols.add(protocol); - found = true; - break; + + boolean available = true; + if (suite.keyExchange.isEC) { + if (!checkedCurves) { + hasCurves = SupportedEllipticCurvesExtension + .hasActiveCurves(algorithmConstraints); + checkedCurves = true; + + if (!hasCurves && debug != null && + Debug.isOn("verbose")) { + System.out.println( + "No activated elliptic curves"); + } + } + + available = hasCurves; + + if (!available && debug != null && + Debug.isOn("verbose")) { + System.out.println( + "No active elliptic curves, ignore " + + suite + " for " + protocol); + } + } + + if (available) { + protocols.add(protocol); + found = true; + break; + } } else if (debug != null && Debug.isOn("verbose")) { System.out.println( "Ignoring disabled cipher suite: " + suite +
--- a/src/share/classes/sun/security/ssl/JsseJce.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/JsseJce.java Mon Sep 19 11:21:02 2016 -0700 @@ -290,6 +290,15 @@ } } + static AlgorithmParameters getAlgorithmParameters(String algorithm) + throws NoSuchAlgorithmException { + if (cryptoProvider == null) { + return AlgorithmParameters.getInstance(algorithm); + } else { + return AlgorithmParameters.getInstance(algorithm, cryptoProvider); + } + } + static SecureRandom getSecureRandom() throws KeyManagementException { if (cryptoProvider == null) { return new SecureRandom(); @@ -409,6 +418,7 @@ JsseJce.getKeyAgreement("ECDH"); JsseJce.getKeyFactory("EC"); JsseJce.getKeyPairGenerator("EC"); + JsseJce.getAlgorithmParameters("EC"); } catch (Exception e) { mediator = false; }
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java Mon Sep 19 11:21:02 2016 -0700 @@ -92,7 +92,8 @@ // we remember it for the RSA premaster secret version check private ProtocolVersion clientRequestedVersion; - private SupportedEllipticCurvesExtension supportedCurves; + // client supported elliptic curves + private SupportedEllipticCurvesExtension requestedCurves; // the preferable signature algorithm used by ServerKeyExchange message SignatureAndHashAlgorithm preferableSignatureAlgorithm; @@ -682,7 +683,7 @@ throw new SSLException("Client did not resume a session"); } - supportedCurves = (SupportedEllipticCurvesExtension) + requestedCurves = (SupportedEllipticCurvesExtension) mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES); // We only need to handle the "signature_algorithm" extension @@ -1412,26 +1413,15 @@ // If we cannot continue because we do not support any of the curves that // the client requested, return false. Otherwise (all is well), return true. private boolean setupEphemeralECDHKeys() { - int index = -1; - if (supportedCurves != null) { - // if the client sent the supported curves extension, pick the - // first one that we support; - for (int curveId : supportedCurves.curveIds()) { - if (SupportedEllipticCurvesExtension.isSupported(curveId)) { - index = curveId; - break; - } - } - if (index < 0) { - // no match found, cannot use this ciphersuite - return false; - } - } else { - // pick our preference - index = SupportedEllipticCurvesExtension.DEFAULT.curveIds()[0]; + int index = (requestedCurves != null) ? + requestedCurves.getPreferredCurve(algorithmConstraints) : + SupportedEllipticCurvesExtension.getActiveCurves(algorithmConstraints); + if (index < 0) { + // no match found, cannot use this ciphersuite + return false; } - String oid = SupportedEllipticCurvesExtension.getCurveOid(index); - ecdh = new ECDHCrypt(oid, sslContext.getSecureRandom()); + + ecdh = new ECDHCrypt(index, sslContext.getSecureRandom()); return true; } @@ -1480,11 +1470,9 @@ return false; } ECParameterSpec params = ((ECPublicKey)publicKey).getParams(); - int index = SupportedEllipticCurvesExtension.getCurveIndex(params); - if (SupportedEllipticCurvesExtension.isSupported(index) == false) { - return false; - } - if ((supportedCurves != null) && !supportedCurves.contains(index)) { + int id = SupportedEllipticCurvesExtension.getCurveIndex(params); + if ((id <= 0) || !SupportedEllipticCurvesExtension.isSupported(id) || + ((requestedCurves != null) && !requestedCurves.contains(id))) { return false; } }
--- a/src/share/classes/sun/security/ssl/SupportedEllipticCurvesExtension.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/ssl/SupportedEllipticCurvesExtension.java Mon Sep 19 11:21:02 2016 -0700 @@ -27,39 +27,195 @@ import java.io.IOException; import java.security.spec.ECParameterSpec; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.InvalidParameterSpecException; +import java.security.AlgorithmParameters; +import java.security.AlgorithmConstraints; +import java.security.CryptoPrimitive; +import java.security.AccessController; +import java.util.EnumSet; import java.util.HashMap; import java.util.Map; +import java.util.ArrayList; +import javax.net.ssl.SSLProtocolException; -import javax.net.ssl.SSLProtocolException; +import sun.security.action.GetPropertyAction; final class SupportedEllipticCurvesExtension extends HelloExtension { - // the extension value to send in the ClientHello message - static final SupportedEllipticCurvesExtension DEFAULT; + private static final int ARBITRARY_PRIME = 0xff01; + private static final int ARBITRARY_CHAR2 = 0xff02; + + // speed up the searching + private static final Map<String, Integer> oidToIdMap = new HashMap<>(); + private static final Map<Integer, String> idToOidMap = new HashMap<>(); + + // speed up the parameters construction + private static final Map<Integer, + AlgorithmParameters> idToParams = new HashMap<>(); + + // the supported elliptic curves + private static final int[] supportedCurveIds; + + // the curves of the extension + private final int[] curveIds; + + // See sun.security.util.CurveDB for the OIDs + private static enum NamedEllipticCurve { + T163_K1(1, "sect163k1", "1.3.132.0.1", true), // NIST K-163 + T163_R1(2, "sect163r1", "1.3.132.0.2", false), + T163_R2(3, "sect163r2", "1.3.132.0.15", true), // NIST B-163 + T193_R1(4, "sect193r1", "1.3.132.0.24", false), + T193_R2(5, "sect193r2", "1.3.132.0.25", false), + T233_K1(6, "sect233k1", "1.3.132.0.26", true), // NIST K-233 + T233_R1(7, "sect233r1", "1.3.132.0.27", true), // NIST B-233 + T239_K1(8, "sect239k1", "1.3.132.0.3", false), + T283_K1(9, "sect283k1", "1.3.132.0.16", true), // NIST K-283 + T283_R1(10, "sect283r1", "1.3.132.0.17", true), // NIST B-283 + T409_K1(11, "sect409k1", "1.3.132.0.36", true), // NIST K-409 + T409_R1(12, "sect409r1", "1.3.132.0.37", true), // NIST B-409 + T571_K1(13, "sect571k1", "1.3.132.0.38", true), // NIST K-571 + T571_R1(14, "sect571r1", "1.3.132.0.39", true), // NIST B-571 - private static final boolean fips; + P160_K1(15, "secp160k1", "1.3.132.0.9", false), + P160_R1(16, "secp160r1", "1.3.132.0.8", false), + P160_R2(17, "secp160r2", "1.3.132.0.30", false), + P192_K1(18, "secp192k1", "1.3.132.0.31", false), + P192_R1(19, "secp192r1", "1.2.840.10045.3.1.1", true), // NIST P-192 + P224_K1(20, "secp224k1", "1.3.132.0.32", false), + P224_R1(21, "secp224r1", "1.3.132.0.33", true), // NIST P-224 + P256_K1(22, "secp256k1", "1.3.132.0.10", false), + P256_R1(23, "secp256r1", "1.2.840.10045.3.1.7", true), // NIST P-256 + P384_R1(24, "secp384r1", "1.3.132.0.34", true), // NIST P-384 + P521_R1(25, "secp521r1", "1.3.132.0.35", true); // NIST P-521 + + int id; + String name; + String oid; + boolean isFips; + + NamedEllipticCurve(int id, String name, String oid, boolean isFips) { + this.id = id; + this.name = name; + this.oid = oid; + this.isFips = isFips; + + if (oidToIdMap.put(oid, id) != null || + idToOidMap.put(id, oid) != null) { + + throw new RuntimeException( + "Duplicate named elliptic curve definition: " + name); + } + } + + static NamedEllipticCurve getCurve(String name, boolean requireFips) { + for (NamedEllipticCurve curve : NamedEllipticCurve.values()) { + if (curve.name.equals(name) && (!requireFips || curve.isFips)) { + return curve; + } + } + + return null; + } + } static { - int[] ids; - fips = SunJSSE.isFIPS(); - if (fips == false) { - ids = new int[] { - // NIST curves first - // prefer NIST P-256, rest in order of increasing key length - 23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14, - // non-NIST curves - 15, 16, 17, 2, 18, 4, 5, 20, 8, 22, - }; + boolean requireFips = SunJSSE.isFIPS(); + + // hack code to initialize NamedEllipticCurve + NamedEllipticCurve nec = + NamedEllipticCurve.getCurve("secp256r1", false); + + // The value of the System Property defines a list of enabled named + // curves in preference order, separated with comma. For example: + // + // jdk.tls.namedGroups="secp521r1, secp256r1, secp384r1" + // + // If the System Property is not defined or the value is empty, the + // default curves and preferences will be used. + String property = AccessController.doPrivileged( + new GetPropertyAction("jdk.tls.namedGroups")); + if (property != null && property.length() != 0) { + // remove double quote marks from beginning/end of the property + if (property.length() > 1 && property.charAt(0) == '"' && + property.charAt(property.length() - 1) == '"') { + property = property.substring(1, property.length() - 1); + } + } + + ArrayList<Integer> idList; + if (property != null && property.length() != 0) { // customized curves + String[] curves = property.split(","); + idList = new ArrayList<>(curves.length); + for (String curve : curves) { + curve = curve.trim(); + if (!curve.isEmpty()) { + NamedEllipticCurve namedCurve = + NamedEllipticCurve.getCurve(curve, requireFips); + if (namedCurve != null) { + if (isAvailableCurve(namedCurve.id)) { + idList.add(namedCurve.id); + } + } // ignore unknown curves + } + } + } else { // default curves + int[] ids; + if (requireFips) { + ids = new int[] { + // only NIST curves in FIPS mode + 23, 24, 25, 9, 10, 11, 12, 13, 14, + }; + } else { + ids = new int[] { + // NIST curves first + 23, 24, 25, 9, 10, 11, 12, 13, 14, + // non-NIST curves + 22, + }; + } + + idList = new ArrayList<>(ids.length); + for (int curveId : ids) { + if (isAvailableCurve(curveId)) { + idList.add(curveId); + } + } + } + + if (idList.isEmpty()) { + throw new IllegalArgumentException( + "System property jdk.tls.namedGroups(" + property + ") " + + "contains no supported elliptic curves"); } else { - ids = new int[] { - // same as above, but allow only NIST curves in FIPS mode - 23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14, - }; + supportedCurveIds = new int[idList.size()]; + int i = 0; + for (Integer id : idList) { + supportedCurveIds[i++] = id; + } } - DEFAULT = new SupportedEllipticCurvesExtension(ids); } - private final int[] curveIds; + // check whether the curve is supported by the underlying providers + private static boolean isAvailableCurve(int curveId) { + String oid = idToOidMap.get(curveId); + if (oid != null) { + AlgorithmParameters params = null; + try { + params = JsseJce.getAlgorithmParameters("EC"); + params.init(new ECGenParameterSpec(oid)); + } catch (Exception e) { + return false; + } + + // cache the parameters + idToParams.put(curveId, params); + + return true; + } + + return false; + } private SupportedEllipticCurvesExtension(int[] curveIds) { super(ExtensionType.EXT_ELLIPTIC_CURVES); @@ -73,12 +229,67 @@ if (((len & 1) != 0) || (k + 2 != len)) { throw new SSLProtocolException("Invalid " + type + " extension"); } + + // Note: unknown curves will be ignored later. curveIds = new int[k >> 1]; for (int i = 0; i < curveIds.length; i++) { curveIds[i] = s.getInt16(); } } + // get the preferred active curve + static int getActiveCurves(AlgorithmConstraints constraints) { + return getPreferredCurve(supportedCurveIds, constraints); + } + + static boolean hasActiveCurves(AlgorithmConstraints constraints) { + return getActiveCurves(constraints) >= 0; + } + + static SupportedEllipticCurvesExtension createExtension( + AlgorithmConstraints constraints) { + + ArrayList<Integer> idList = new ArrayList<>(supportedCurveIds.length); + for (int curveId : supportedCurveIds) { + if (constraints.permits( + EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), + "EC", idToParams.get(curveId))) { + idList.add(curveId); + } + } + + if (!idList.isEmpty()) { + int[] ids = new int[idList.size()]; + int i = 0; + for (Integer id : idList) { + ids[i++] = id; + } + + return new SupportedEllipticCurvesExtension(ids); + } + + return null; + } + + // get the preferred activated curve + int getPreferredCurve(AlgorithmConstraints constraints) { + return getPreferredCurve(curveIds, constraints); + } + + // get a preferred activated curve + private static int getPreferredCurve(int[] curves, + AlgorithmConstraints constraints) { + for (int curveId : curves) { + if (constraints.permits( + EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), + "EC", idToParams.get(curveId))) { + return curveId; + } + } + + return -1; + } + boolean contains(int index) { for (int curveId : curveIds) { if (index == curveId) { @@ -88,12 +299,6 @@ return false; } - // Return a reference to the internal curveIds array. - // The caller must NOT modify the contents. - int[] curveIds() { - return curveIds; - } - @Override int length() { return 6 + (curveIds.length << 1); @@ -121,18 +326,9 @@ } else { sb.append(", "); } - // first check if it is a known named curve, then try other cases. - String oid = getCurveOid(curveId); - if (oid != null) { - ECParameterSpec spec = JsseJce.getECParameterSpec(oid); - // this toString() output will look nice for the current - // implementation of the ECParameterSpec class in the Sun - // provider, but may not look good for other implementations. - if (spec != null) { - sb.append(spec.toString().split(" ")[0]); - } else { - sb.append(oid); - } + String curveName = getCurveName(curveId); + if (curveName != null) { + sb.append(curveName); } else if (curveId == ARBITRARY_PRIME) { sb.append("arbitrary_explicit_prime_curves"); } else if (curveId == ARBITRARY_CHAR2) { @@ -145,16 +341,15 @@ return sb.toString(); } - // Test whether we support the curve with the given index. + // Test whether the given curve is supported. static boolean isSupported(int index) { - if ((index <= 0) || (index >= NAMED_CURVE_OID_TABLE.length)) { - return false; + for (int curveId : supportedCurveIds) { + if (index == curveId) { + return true; + } } - if (fips == false) { - // in non-FIPS mode, we support all valid indices - return true; - } - return DEFAULT.contains(index); + + return false; } static int getCurveIndex(ECParameterSpec params) { @@ -162,57 +357,32 @@ if (oid == null) { return -1; } - Integer n = curveIndices.get(oid); + Integer n = oidToIdMap.get(oid); return (n == null) ? -1 : n; } static String getCurveOid(int index) { - if ((index > 0) && (index < NAMED_CURVE_OID_TABLE.length)) { - return NAMED_CURVE_OID_TABLE[index]; - } - return null; + return idToOidMap.get(index); } - private final static int ARBITRARY_PRIME = 0xff01; - private final static int ARBITRARY_CHAR2 = 0xff02; - - // See sun.security.ec.NamedCurve for the OIDs - private final static String[] NAMED_CURVE_OID_TABLE = new String[] { - null, // (0) unused - "1.3.132.0.1", // (1) sect163k1, NIST K-163 - "1.3.132.0.2", // (2) sect163r1 - "1.3.132.0.15", // (3) sect163r2, NIST B-163 - "1.3.132.0.24", // (4) sect193r1 - "1.3.132.0.25", // (5) sect193r2 - "1.3.132.0.26", // (6) sect233k1, NIST K-233 - "1.3.132.0.27", // (7) sect233r1, NIST B-233 - "1.3.132.0.3", // (8) sect239k1 - "1.3.132.0.16", // (9) sect283k1, NIST K-283 - "1.3.132.0.17", // (10) sect283r1, NIST B-283 - "1.3.132.0.36", // (11) sect409k1, NIST K-409 - "1.3.132.0.37", // (12) sect409r1, NIST B-409 - "1.3.132.0.38", // (13) sect571k1, NIST K-571 - "1.3.132.0.39", // (14) sect571r1, NIST B-571 - "1.3.132.0.9", // (15) secp160k1 - "1.3.132.0.8", // (16) secp160r1 - "1.3.132.0.30", // (17) secp160r2 - "1.3.132.0.31", // (18) secp192k1 - "1.2.840.10045.3.1.1", // (19) secp192r1, NIST P-192 - "1.3.132.0.32", // (20) secp224k1 - "1.3.132.0.33", // (21) secp224r1, NIST P-224 - "1.3.132.0.10", // (22) secp256k1 - "1.2.840.10045.3.1.7", // (23) secp256r1, NIST P-256 - "1.3.132.0.34", // (24) secp384r1, NIST P-384 - "1.3.132.0.35", // (25) secp521r1, NIST P-521 - }; - - private final static Map<String,Integer> curveIndices; - - static { - curveIndices = new HashMap<String,Integer>(); - for (int i = 1; i < NAMED_CURVE_OID_TABLE.length; i++) { - curveIndices.put(NAMED_CURVE_OID_TABLE[i], i); + static ECGenParameterSpec getECGenParamSpec(int index) { + AlgorithmParameters params = idToParams.get(index); + try { + return params.getParameterSpec(ECGenParameterSpec.class); + } catch (InvalidParameterSpecException ipse) { + // should be unlikely + String curveOid = getCurveOid(index); + return new ECGenParameterSpec(curveOid); } } + private static String getCurveName(int index) { + for (NamedEllipticCurve namedCurve : NamedEllipticCurve.values()) { + if (namedCurve.id == index) { + return namedCurve.name; + } + } + + return null; + } }
--- a/src/share/classes/sun/security/tools/jarsigner/Main.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/tools/jarsigner/Main.java Mon Sep 19 11:21:02 2016 -0700 @@ -603,6 +603,7 @@ } Manifest man = jf.getManifest(); + boolean hasSignature = false; // The map to record display info, only used when -verbose provided // key: signer info string @@ -618,6 +619,10 @@ while (e.hasMoreElements()) { JarEntry je = e.nextElement(); String name = je.getName(); + + hasSignature = hasSignature + || SignatureFileVerifier.isBlockOrSF(name); + CodeSigner[] signers = je.getCodeSigners(); boolean isSigned = (signers != null); anySigned |= isSigned; @@ -757,8 +762,11 @@ System.out.println(rb.getString("no.manifest.")); if (!anySigned) { - System.out.println(rb.getString( - "jar.is.unsigned.signatures.missing.or.not.parsable.")); + if (hasSignature) { + System.out.println(rb.getString("jar.treated.unsigned")); + } else { + System.out.println(rb.getString("jar.is.unsigned")); + } } else { boolean warningAppeared = false; boolean errorAppeared = false;
--- a/src/share/classes/sun/security/tools/jarsigner/Resources.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/tools/jarsigner/Resources.java Mon Sep 19 11:21:02 2016 -0700 @@ -135,8 +135,10 @@ {"no.manifest.", "no manifest."}, {".Signature.related.entries.","(Signature related entries)"}, {".Unsigned.entries.", "(Unsigned entries)"}, - {"jar.is.unsigned.signatures.missing.or.not.parsable.", - "jar is unsigned. (signatures missing or not parsable)"}, + {"jar.is.unsigned", + "jar is unsigned."}, + {"jar.treated.unsigned", + "Signature not parsable or verifiable. The jar will be treated as unsigned. The jar may have been signed with a weak algorithm that is now disabled. For more information, rerun jarsigner with debug enabled (-J-Djava.security.debug=jar)."}, {"jar.signed.", "jar signed."}, {"jar.signed.with.signer.errors.", "jar signed, with signer errors."}, {"jar.verified.", "jar verified."},
--- a/src/share/classes/sun/security/util/AbstractAlgorithmConstraints.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/util/AbstractAlgorithmConstraints.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import java.security.AlgorithmConstraints; import java.security.PrivilegedAction; import java.security.Security; -import java.util.Map; import java.util.Set; /** @@ -45,8 +44,7 @@ } // Get algorithm constraints from the specified security property. - private static void loadAlgorithmsMap(Map<String, String[]> algorithmsMap, - String propertyName) { + static String[] getAlgorithms(String propertyName) { String property = AccessController.doPrivileged( new PrivilegedAction<String>() { @Override @@ -72,18 +70,7 @@ if (algorithmsInProperty == null) { algorithmsInProperty = new String[0]; } - algorithmsMap.put(propertyName, algorithmsInProperty); - } - - static String[] getAlgorithms(Map<String, String[]> algorithmsMap, - String propertyName) { - synchronized (algorithmsMap) { - if (!algorithmsMap.containsKey(propertyName)) { - loadAlgorithmsMap(algorithmsMap, propertyName); - } - - return algorithmsMap.get(propertyName); - } + return algorithmsInProperty; } static boolean checkAlgorithm(String[] algorithms, String algorithm,
--- a/src/share/classes/sun/security/util/AlgorithmDecomposer.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/util/AlgorithmDecomposer.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,19 +38,7 @@ private static final Pattern pattern = Pattern.compile("with|and", Pattern.CASE_INSENSITIVE); - /** - * Decompose the standard algorithm name into sub-elements. - * <p> - * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA" - * so that we can check the "SHA1" and "RSA" algorithm constraints - * separately. - * <p> - * Please override the method if need to support more name pattern. - */ - public Set<String> decompose(String algorithm) { - if (algorithm == null || algorithm.length() == 0) { - return new HashSet<>(); - } + private static Set<String> decomposeImpl(String algorithm) { // algorithm/mode/padding String[] transTockens = transPattern.split(algorithm); @@ -76,6 +64,24 @@ elements.add(token); } } + return elements; + } + + /** + * Decompose the standard algorithm name into sub-elements. + * <p> + * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA" + * so that we can check the "SHA1" and "RSA" algorithm constraints + * separately. + * <p> + * Please override the method if need to support more name pattern. + */ + public Set<String> decompose(String algorithm) { + if (algorithm == null || algorithm.length() == 0) { + return new HashSet<>(); + } + + Set<String> elements = decomposeImpl(algorithm); // In Java standard algorithm name specification, for different // purpose, the SHA-1 and SHA-2 algorithm names are different. For @@ -127,4 +133,40 @@ return elements; } + private static void hasLoop(Set<String> elements, String find, String replace) { + if (elements.contains(find)) { + if (!elements.contains(replace)) { + elements.add(replace); } + elements.remove(find); + } + } + + /* + * This decomposes a standard name into sub-elements with a consistent + * message digest algorithm name to avoid overly complicated checking. + */ + public static Set<String> decomposeOneHash(String algorithm) { + if (algorithm == null || algorithm.length() == 0) { + return new HashSet<>(); + } + + Set<String> elements = decomposeImpl(algorithm); + + hasLoop(elements, "SHA-1", "SHA1"); + hasLoop(elements, "SHA-224", "SHA224"); + hasLoop(elements, "SHA-256", "SHA256"); + hasLoop(elements, "SHA-384", "SHA384"); + hasLoop(elements, "SHA-512", "SHA512"); + + return elements; + } + + /* + * The provided message digest algorithm name will return a consistent + * naming scheme. + */ + public static String hashName(String algorithm) { + return algorithm.replace("-", ""); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/security/util/AnchorCertificates.java Mon Sep 19 11:21:02 2016 -0700 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.util; + +import java.io.File; +import java.io.FileInputStream; +import java.security.AccessController; +import java.security.KeyStore; +import java.security.PrivilegedAction; +import java.security.cert.X509Certificate; +import java.util.Enumeration; +import java.util.HashSet; + +import sun.security.x509.X509CertImpl; + +/** + * The purpose of this class is to determine the trust anchor certificates is in + * the cacerts file. This is used for PKIX CertPath checking. + */ +public class AnchorCertificates { + + private static final Debug debug = Debug.getInstance("certpath"); + private static final String HASH = "SHA-256"; + private static HashSet<String> certs; + + static { + AccessController.doPrivileged(new PrivilegedAction<Void>() { + @Override + public Void run() { + File f = new File(System.getProperty("java.home"), + "lib/security/cacerts"); + KeyStore cacerts; + try { + cacerts = KeyStore.getInstance("JKS"); + try (FileInputStream fis = new FileInputStream(f)) { + cacerts.load(fis, "changeit".toCharArray()); + certs = new HashSet<>(); + Enumeration<String> list = cacerts.aliases(); + String alias; + while (list.hasMoreElements()) { + alias = list.nextElement(); + // Check if this cert is labeled a trust anchor. + if (alias.contains(" [jdk")) { + X509Certificate cert = (X509Certificate) cacerts + .getCertificate(alias); + certs.add(X509CertImpl.getFingerprint(HASH, cert)); + } + } + } + } catch (Exception e) { + if (debug != null) { + debug.println("Error parsing cacerts"); + } + e.printStackTrace(); + } + return null; + } + }); + } + + /** + * Checks if a certificate is a trust anchor. + * + * @param cert the certificate to check + * @return true if the certificate is trusted. + */ + public static boolean contains(X509Certificate cert) { + String key = X509CertImpl.getFingerprint(HASH, cert); + boolean result = certs.contains(key); + if (result && debug != null) { + debug.println("AnchorCertificate.contains: matched " + + cert.getSubjectDN()); + } + return result; + } + + private AnchorCertificates() {} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/security/util/CertConstraintParameters.java Mon Sep 19 11:21:02 2016 -0700 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.util; + +import java.security.cert.X509Certificate; + +/** + * This class is a wrapper for keeping state and passing objects between PKIX, + * AlgorithmChecker, and DisabledAlgorithmConstraints. + */ +public class CertConstraintParameters { + // A certificate being passed to check against constraints. + private final X509Certificate cert; + + // This is true if the trust anchor in the certificate chain matches a cert + // in AnchorCertificates + private final boolean trustedMatch; + + public CertConstraintParameters(X509Certificate c, boolean match) { + cert = c; + trustedMatch = match; + } + + public CertConstraintParameters(X509Certificate c) { + this(c, false); + } + + // Returns if the trust anchor has a match if anchor checking is enabled. + public boolean isTrustedMatch() { + return trustedMatch; + } + + public X509Certificate getCertificate() { + return cert; + } +}
--- a/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,12 +28,14 @@ import java.security.CryptoPrimitive; import java.security.AlgorithmParameters; import java.security.Key; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorException.BasicReason; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.HashSet; import java.util.Locale; +import java.util.Map; 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; @@ -44,6 +46,7 @@ * for the syntax of the disabled algorithm string. */ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { + private static final Debug debug = Debug.getInstance("certpath"); // the known security property, jdk.certpath.disabledAlgorithms public final static String PROPERTY_CERTPATH_DISABLED_ALGS = @@ -53,17 +56,12 @@ public final static String PROPERTY_TLS_DISABLED_ALGS = "jdk.tls.disabledAlgorithms"; - private final static Map<String, String[]> disabledAlgorithmsMap = - new HashMap<>(); - private final static Map<String, KeySizeConstraints> keySizeConstraintsMap = - new HashMap<>(); - // the known security property, jdk.jar.disabledAlgorithms public static final String PROPERTY_JAR_DISABLED_ALGS = "jdk.jar.disabledAlgorithms"; private final String[] disabledAlgorithms; - private final KeySizeConstraints keySizeConstraints; + private final Constraints algorithmConstraints; /** * Initialize algorithm constraints with the specified security property. @@ -86,11 +84,14 @@ public DisabledAlgorithmConstraints(String propertyName, AlgorithmDecomposer decomposer) { super(decomposer); - disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName); - keySizeConstraints = getKeySizeConstraints(disabledAlgorithms, - propertyName); + disabledAlgorithms = getAlgorithms(propertyName); + algorithmConstraints = new Constraints(disabledAlgorithms); } + /* + * This only checks if the algorithm has been completely disabled. If + * there are keysize or other limit, this method allow the algorithm. + */ @Override final public boolean permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters) { @@ -103,11 +104,19 @@ return checkAlgorithm(disabledAlgorithms, algorithm, decomposer); } + /* + * Checks if the key algorithm has been disabled or constraints have been + * placed on the key. + */ @Override final public boolean permits(Set<CryptoPrimitive> primitives, Key key) { return checkConstraints(primitives, "", key, null); } + /* + * Checks if the key algorithm has been disabled or if constraints have + * been placed on the key. + */ @Override final public boolean permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters) { @@ -119,7 +128,39 @@ return checkConstraints(primitives, algorithm, key, parameters); } - // Check algorithm constraints + /* + * Check if a x509Certificate object is permitted. Check if all + * algorithms are allowed, certificate constraints, and the + * public key against key constraints. + * + * Uses new style permit() which throws exceptions. + */ + public final void permits(Set<CryptoPrimitive> primitives, + CertConstraintParameters cp) throws CertPathValidatorException { + checkConstraints(primitives, cp); + } + + /* + * Check if Certificate object is within the constraints. + * Uses new style permit() which throws exceptions. + */ + public final void permits(Set<CryptoPrimitive> primitives, + X509Certificate cert) throws CertPathValidatorException { + checkConstraints(primitives, new CertConstraintParameters(cert)); + } + + // Check if a string is contained inside the property + public boolean checkProperty(String param) { + param = param.toLowerCase(Locale.ENGLISH); + for (String block : disabledAlgorithms) { + if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) { + return true; + } + } + return false; + } + + // Check algorithm constraints with key and algorithm private boolean checkConstraints(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters) { @@ -128,7 +169,7 @@ throw new IllegalArgumentException("The key cannot be null"); } - // check the target algorithm + // check the signature algorithm if (algorithm != null && algorithm.length() != 0) { if (!permits(primitives, algorithm, parameters)) { return false; @@ -141,97 +182,203 @@ } // check the key constraints - if (keySizeConstraints.disables(key)) { - return false; - } - - return true; + return algorithmConstraints.permits(key); } - private static KeySizeConstraints getKeySizeConstraints( - String[] disabledAlgorithms, String propertyName) { - synchronized (keySizeConstraintsMap) { - if(!keySizeConstraintsMap.containsKey(propertyName)) { - // map the key constraints - KeySizeConstraints keySizeConstraints = - new KeySizeConstraints(disabledAlgorithms); - keySizeConstraintsMap.put(propertyName, keySizeConstraints); - } + /* + * Check algorithm constraints with Certificate + * Uses new style permit() which throws exceptions. + */ + private void checkConstraints(Set<CryptoPrimitive> primitives, + CertConstraintParameters cp) throws CertPathValidatorException { + + X509Certificate cert = cp.getCertificate(); + String algorithm = cert.getSigAlgName(); - return keySizeConstraintsMap.get(propertyName); + // Check signature algorithm is not disabled + if (!permits(primitives, algorithm, null)) { + throw new CertPathValidatorException( + "Algorithm constraints check failed on disabled "+ + "signature algorithm: " + algorithm, + null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } + + // Check key algorithm is not disabled + if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) { + throw new CertPathValidatorException( + "Algorithm constraints check failed on disabled "+ + "public key algorithm: " + algorithm, + null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); + } + + // Check the certificate and key constraints + algorithmConstraints.permits(cp); + } /** - * key constraints + * Key and Certificate Constraints + * + * The complete disabling of an algorithm is not handled by Constraints or + * Constraint classes. That is addressed with + * permit(Set<CryptoPrimitive>, String, AlgorithmParameters) + * + * When passing a Key to permit(), the boolean return values follow the + * same as the interface class AlgorithmConstraints.permit(). This is to + * maintain compatibility: + * 'true' means the operation is allowed. + * 'false' means it failed the constraints and is disallowed. + * + * When passing CertConstraintParameters through permit(), an exception + * will be thrown on a failure to better identify why the operation was + * disallowed. */ - private static class KeySizeConstraints { - private static final Pattern pattern = Pattern.compile( - "(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)"); - private Map<String, Set<KeySizeConstraint>> constraintsMap = - Collections.synchronizedMap( - new HashMap<String, Set<KeySizeConstraint>>()); + private static class Constraints { + private Map<String, Set<Constraint>> constraintsMap = new HashMap<>(); + private static final Pattern keySizePattern = Pattern.compile( + "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)"); - public KeySizeConstraints(String[] restrictions) { - for (String restriction : restrictions) { - if (restriction == null || restriction.isEmpty()) { + public Constraints(String[] constraintArray) { + for (String constraintEntry : constraintArray) { + if (constraintEntry == null || constraintEntry.isEmpty()) { continue; } - Matcher matcher = pattern.matcher(restriction); - if (matcher.matches()) { - String algorithm = matcher.group(1); + constraintEntry = constraintEntry.trim(); + if (debug != null) { + debug.println("Constraints: " + constraintEntry); + } - KeySizeConstraint.Operator operator = - KeySizeConstraint.Operator.of(matcher.group(2)); - int length = Integer.parseInt(matcher.group(3)); + // Check if constraint is a complete disabling of an + // algorithm or has conditions. + String algorithm; + String policy; + int space = constraintEntry.indexOf(' '); + if (space > 0) { + algorithm = AlgorithmDecomposer.hashName( + constraintEntry.substring(0, space). + toUpperCase(Locale.ENGLISH)); + policy = constraintEntry.substring(space + 1); + } else { + constraintsMap.computeIfAbsent( + constraintEntry.toUpperCase(Locale.ENGLISH), + k -> new HashSet<>()); + continue; + } - algorithm = algorithm.toLowerCase(Locale.ENGLISH); + // Convert constraint conditions into Constraint classes + Constraint c, lastConstraint = null; + // Allow only one jdkCA entry per constraint entry + boolean jdkCALimit = false; + + for (String entry : policy.split("&")) { + entry = entry.trim(); - synchronized (constraintsMap) { - if (!constraintsMap.containsKey(algorithm)) { - constraintsMap.put(algorithm, - new HashSet<KeySizeConstraint>()); + Matcher matcher = keySizePattern.matcher(entry); + if (matcher.matches()) { + if (debug != null) { + debug.println("Constraints set to keySize: " + + entry); } + c = new KeySizeConstraint(algorithm, + KeySizeConstraint.Operator.of(matcher.group(1)), + Integer.parseInt(matcher.group(2))); - Set<KeySizeConstraint> constraintSet = - constraintsMap.get(algorithm); - KeySizeConstraint constraint = - new KeySizeConstraint(operator, length); - constraintSet.add(constraint); + } else if (entry.equalsIgnoreCase("jdkCA")) { + if (debug != null) { + debug.println("Constraints set to jdkCA."); + } + if (jdkCALimit) { + throw new IllegalArgumentException("Only one " + + "jdkCA entry allowed in property. " + + "Constraint: " + constraintEntry); + } + c = new jdkCAConstraint(algorithm); + jdkCALimit = true; + } else { + throw new IllegalArgumentException("Error in security" + + " property. Constraint unknown: " + entry); } + + // Link multiple conditions for a single constraint + // into a linked list. + if (lastConstraint == null) { + if (!constraintsMap.containsKey(algorithm)) { + constraintsMap.putIfAbsent(algorithm, + new HashSet<>()); + } + constraintsMap.get(algorithm).add(c); + } else { + lastConstraint.nextConstraint = c; + } + lastConstraint = c; } } } - // 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<KeySizeConstraint> constraintSet = - constraintsMap.get(algorithm); - for (KeySizeConstraint constraint : constraintSet) { - if (constraint.disables(key)) { - return true; - } + // Get applicable constraints based off the signature algorithm + private Set<Constraint> getConstraints(String algorithm) { + return constraintsMap.get(algorithm); + } + + // Check if KeySizeConstraints permit the specified key + public boolean permits(Key key) { + Set<Constraint> set = getConstraints(key.getAlgorithm()); + if (set == null) { + return true; + } + for (Constraint constraint : set) { + if (!constraint.permits(key)) { + if (debug != null) { + debug.println("keySizeConstraint: failed key " + + "constraint check " + KeyUtil.getKeySize(key)); } + return false; + } + } + return true; + } + + // Check if constraints permit this cert. + public void permits(CertConstraintParameters cp) + throws CertPathValidatorException { + X509Certificate cert = cp.getCertificate(); + + if (debug != null) { + debug.println("Constraints.permits(): " + cert.getSigAlgName()); + } + + // Get all signature algorithms to check for constraints + Set<String> algorithms = + AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName()); + if (algorithms == null || algorithms.isEmpty()) { + return; + } + + // Attempt to add the public key algorithm to the set + algorithms.add(cert.getPublicKey().getAlgorithm()); + + // Check all applicable constraints + for (String algorithm : algorithms) { + Set<Constraint> set = getConstraints(algorithm); + if (set == null) { + continue; + } + for (Constraint constraint : set) { + constraint.permits(cp); } } - - return false; } - } + } - /** - * Key size constraint. - * - * e.g. "keysize <= 1024" - */ - private static class KeySizeConstraint { + // Abstract class for algorithm constraint checking + private abstract static class Constraint { + String algorithm; + Constraint nextConstraint = null; + // operator - static enum Operator { + enum Operator { EQ, // "==" NE, // "!=" LT, // "<" @@ -255,16 +402,77 @@ return GE; } - throw new IllegalArgumentException( - s + " is not a legal Operator"); + throw new IllegalArgumentException("Error in security " + + "property. " + s + " is not a legal Operator"); } } + /** + * Check if an algorithm constraint permit this key to be used. + * @param key Public key + * @return true if constraints do not match + */ + public boolean permits(Key key) { + return true; + } + + /** + * Check if an algorithm constraint is permit this certificate to + * be used. + * @param cp CertificateParameter containing certificate and state info + * @return true if constraints do not match + */ + public abstract void permits(CertConstraintParameters cp) + throws CertPathValidatorException; + } + + /* + * This class contains constraints dealing with the certificate chain + * of the certificate. + */ + private static class jdkCAConstraint extends Constraint { + jdkCAConstraint(String algo) { + algorithm = algo; + } + + /* + * Check if each constraint fails and check if there is a linked + * constraint Any permitted constraint will exit the linked list + * to allow the operation. + */ + public void permits(CertConstraintParameters cp) + throws CertPathValidatorException { + if (debug != null) { + debug.println("jdkCAConstraints.permits(): " + algorithm); + } + + // Return false if the chain has a trust anchor in cacerts + if (cp.isTrustedMatch()) { + if (nextConstraint != null) { + nextConstraint.permits(cp); + return; + } + throw new CertPathValidatorException( + "Algorithm constraints check failed on certificate " + + "anchor limits", + null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); + } + } + } + + + /* + * This class contains constraints dealing with the key size + * support limits per algorithm. e.g. "keySize <= 1024" + */ + private static class KeySizeConstraint extends Constraint { + private int minSize; // the minimal available key size private int maxSize; // the maximal available key size private int prohibitedSize = -1; // unavailable key sizes - public KeySizeConstraint(Operator operator, int length) { + public KeySizeConstraint(String algo, Operator operator, int length) { + algorithm = algo; switch (operator) { case EQ: // an unavailable key size this.minSize = 0; @@ -298,21 +506,59 @@ } } - // Does this key constraint disable the specified key? - public boolean disables(Key key) { - int size = KeyUtil.getKeySize(key); + /* + * If we are passed a certificate, extract the public key and use it. + * + * Check if each constraint fails and check if there is a linked + * constraint Any permitted constraint will exit the linked list + * to allow the operation. + */ + public void permits(CertConstraintParameters cp) + throws CertPathValidatorException { + if (!permitsImpl(cp.getCertificate().getPublicKey())) { + if (nextConstraint != null) { + nextConstraint.permits(cp); + return; + } + throw new CertPathValidatorException( + "Algorithm constraints check failed on keysize limits", + null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); + } + } + + // Check if key constraint disable the specified key + // Uses old style permit() + public boolean permits(Key key) { + // If we recursively find a constraint that permits us to use + // this key, return true and skip any other constraint checks. + if (nextConstraint != null && nextConstraint.permits(key)) { + return true; + } + if (debug != null) { + debug.println("KeySizeConstraints.permits(): " + algorithm); + } + + return permitsImpl(key); + } + + private boolean permitsImpl(Key key) { + // Verify this constraint is for this public key algorithm + if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) { + return true; + } + + int size = KeyUtil.getKeySize(key); if (size == 0) { - return true; // we don't allow any key of size 0. + return false; // we don't allow any key of size 0. } else if (size > 0) { - return ((size < minSize) || (size > maxSize) || + return !((size < minSize) || (size > maxSize) || (prohibitedSize == size)); } // Otherwise, the key size is not accessible. Conservatively, // please don't disable such keys. - return false; + return true; + } } } -} -
--- a/src/share/classes/sun/security/util/LegacyAlgorithmConstraints.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/util/LegacyAlgorithmConstraints.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ import java.security.AlgorithmParameters; import java.security.CryptoPrimitive; import java.security.Key; -import java.util.HashMap; -import java.util.Map; import java.util.Set; import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms; @@ -42,15 +40,12 @@ public final static String PROPERTY_TLS_LEGACY_ALGS = "jdk.tls.legacyAlgorithms"; - private final static Map<String, String[]> legacyAlgorithmsMap = - new HashMap<>(); - private final String[] legacyAlgorithms; public LegacyAlgorithmConstraints(String propertyName, AlgorithmDecomposer decomposer) { super(decomposer); - legacyAlgorithms = getAlgorithms(legacyAlgorithmsMap, propertyName); + legacyAlgorithms = getAlgorithms(propertyName); } @Override
--- a/src/share/classes/sun/security/x509/X509CertImpl.java Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/classes/sun/security/x509/X509CertImpl.java Mon Sep 19 11:21:02 2016 -0700 @@ -1932,18 +1932,19 @@ public String getFingerprint(String algorithm) { return fingerprints.computeIfAbsent(algorithm, - x -> getCertificateFingerPrint(x)); + x -> getFingerprint(x, this)); } /** * Gets the requested finger print of the certificate. The result * only contains 0-9 and A-F. No small case, no colon. */ - private String getCertificateFingerPrint(String mdAlg) { + public static String getFingerprint(String algorithm, + X509Certificate cert) { String fingerPrint = ""; try { - byte[] encCertInfo = getEncoded(); - MessageDigest md = MessageDigest.getInstance(mdAlg); + byte[] encCertInfo = cert.getEncoded(); + MessageDigest md = MessageDigest.getInstance(algorithm); byte[] digest = md.digest(encCertInfo); StringBuffer buf = new StringBuffer(); for (int i = 0; i < digest.length; i++) {
--- a/src/share/lib/security/java.security-aix Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/lib/security/java.security-aix Mon Sep 19 11:21:02 2016 -0700 @@ -429,13 +429,13 @@ # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint, CertConstraint # # KeySizeConstraint: # keySize Operator DecimalInteger @@ -452,6 +452,9 @@ # DecimalDigit: one of # 1 2 3 4 5 6 7 8 9 0 # +# CertConstraint +# jdkCA +# # 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 @@ -474,6 +477,29 @@ # be disabled. Note that the "KeySizeConstraint" only makes sense to key # algorithms. # +# "CertConstraint" specifies additional constraints for +# certificates that contain algorithms that are restricted: +# +# "jdkCA" prohibits the specified algorithm only if the algorithm is used +# in a certificate chain that terminates at a marked trust anchor in the +# lib/security/cacerts keystore. All other chains are not affected. +# If the jdkCA constraint is not set, then all chains using the +# specified algorithm are restricted. jdkCA may only be used once in +# a DisabledAlgorithm expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following "SHA1 jdkCA" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. # @@ -482,7 +508,7 @@ # # jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ - DSA keySize < 1024 + DSA keySize < 1024, EC keySize < 224 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing @@ -505,12 +531,13 @@ # 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. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -524,7 +551,7 @@ # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -554,7 +581,7 @@ # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -567,7 +594,8 @@ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
--- a/src/share/lib/security/java.security-linux Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/lib/security/java.security-linux Mon Sep 19 11:21:02 2016 -0700 @@ -429,13 +429,13 @@ # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint, CertConstraint # # KeySizeConstraint: # keySize Operator DecimalInteger @@ -452,6 +452,9 @@ # DecimalDigit: one of # 1 2 3 4 5 6 7 8 9 0 # +# CertConstraint +# jdkCA +# # 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 @@ -474,6 +477,29 @@ # be disabled. Note that the "KeySizeConstraint" only makes sense to key # algorithms. # +# "CertConstraint" specifies additional constraints for +# certificates that contain algorithms that are restricted: +# +# "jdkCA" prohibits the specified algorithm only if the algorithm is used +# in a certificate chain that terminates at a marked trust anchor in the +# lib/security/cacerts keystore. All other chains are not affected. +# If the jdkCA constraint is not set, then all chains using the +# specified algorithm are restricted. jdkCA may only be used once in +# a DisabledAlgorithm expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. # @@ -482,7 +508,7 @@ # # jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ - DSA keySize < 1024 + DSA keySize < 1024, EC keySize < 224 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing @@ -505,12 +531,13 @@ # 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. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -524,7 +551,7 @@ # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -554,7 +581,7 @@ # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -567,7 +594,8 @@ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
--- a/src/share/lib/security/java.security-macosx Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/lib/security/java.security-macosx Mon Sep 19 11:21:02 2016 -0700 @@ -432,13 +432,13 @@ # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint, CertConstraint # # KeySizeConstraint: # keySize Operator DecimalInteger @@ -455,6 +455,9 @@ # DecimalDigit: one of # 1 2 3 4 5 6 7 8 9 0 # +# CertConstraint +# jdkCA +# # 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 @@ -477,6 +480,29 @@ # be disabled. Note that the "KeySizeConstraint" only makes sense to key # algorithms. # +# "CertConstraint" specifies additional constraints for +# certificates that contain algorithms that are restricted: +# +# "jdkCA" prohibits the specified algorithm only if the algorithm is used +# in a certificate chain that terminates at a marked trust anchor in the +# lib/security/cacerts keystore. All other chains are not affected. +# If the jdkCA constraint is not set, then all chains using the +# specified algorithm are restricted. jdkCA may only be used once in +# a DisabledAlgorithm expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. # @@ -485,7 +511,7 @@ # # jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ - DSA keySize < 1024 + DSA keySize < 1024, EC keySize < 224 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing @@ -508,12 +534,13 @@ # 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. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -527,7 +554,7 @@ # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -557,7 +584,7 @@ # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -570,7 +597,8 @@ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
--- a/src/share/lib/security/java.security-solaris Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/lib/security/java.security-solaris Mon Sep 19 11:21:02 2016 -0700 @@ -431,13 +431,13 @@ # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint, CertConstraint # # KeySizeConstraint: # keySize Operator DecimalInteger @@ -454,6 +454,9 @@ # DecimalDigit: one of # 1 2 3 4 5 6 7 8 9 0 # +# CertConstraint +# jdkCA +# # 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 @@ -476,6 +479,29 @@ # be disabled. Note that the "KeySizeConstraint" only makes sense to key # algorithms. # +# "CertConstraint" specifies additional constraints for +# certificates that contain algorithms that are restricted: +# +# "jdkCA" prohibits the specified algorithm only if the algorithm is used +# in a certificate chain that terminates at a marked trust anchor in the +# lib/security/cacerts keystore. All other chains are not affected. +# If the jdkCA constraint is not set, then all chains using the +# specified algorithm are restricted. jdkCA may only be used once in +# a DisabledAlgorithm expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. # @@ -484,7 +510,7 @@ # # jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ - DSA keySize < 1024 + DSA keySize < 1024, EC keySize < 224 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing @@ -507,12 +533,13 @@ # 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. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -526,7 +553,7 @@ # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -556,7 +583,7 @@ # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -569,7 +596,8 @@ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
--- a/src/share/lib/security/java.security-windows Thu Sep 08 15:00:00 2016 -0700 +++ b/src/share/lib/security/java.security-windows Mon Sep 19 11:21:02 2016 -0700 @@ -432,13 +432,13 @@ # " DisabledAlgorithm { , DisabledAlgorithm } " # # DisabledAlgorithm: -# AlgorithmName [Constraint] +# AlgorithmName [Constraint] { '&' Constraint } # # AlgorithmName: # (see below) # # Constraint: -# KeySizeConstraint +# KeySizeConstraint, CertConstraint # # KeySizeConstraint: # keySize Operator DecimalInteger @@ -455,6 +455,9 @@ # DecimalDigit: one of # 1 2 3 4 5 6 7 8 9 0 # +# CertConstraint +# jdkCA +# # 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 @@ -477,6 +480,29 @@ # be disabled. Note that the "KeySizeConstraint" only makes sense to key # algorithms. # +# "CertConstraint" specifies additional constraints for +# certificates that contain algorithms that are restricted: +# +# "jdkCA" prohibits the specified algorithm only if the algorithm is used +# in a certificate chain that terminates at a marked trust anchor in the +# lib/security/cacerts keystore. All other chains are not affected. +# If the jdkCA constraint is not set, then all chains using the +# specified algorithm are restricted. jdkCA may only be used once in +# a DisabledAlgorithm expression. +# Example: To apply this constraint to SHA-1 certificates, include +# the following: "SHA1 jdkCA" +# +# When an algorithm must satisfy more than one constraint, it must be +# delimited by an ampersand '&'. For example, to restrict certificates in a +# chain that terminate at a distribution provided trust anchor and contain +# RSA keys that are less than or equal to 1024 bits, add the following +# constraint: "RSA keySize <= 1024 & jdkCA". +# +# All DisabledAlgorithms expressions are processed in the order defined in the +# property. This requires lower keysize constraints to be specified +# before larger keysize constraints of the same algorithm. For example: +# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048". +# # Note: This property is currently used by Oracle's PKIX implementation. It # is not guaranteed to be examined and used by other implementations. # @@ -485,7 +511,7 @@ # # jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ - DSA keySize < 1024 + DSA keySize < 1024, EC keySize < 224 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing @@ -508,12 +534,13 @@ # 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. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 +jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \ + EC keySize < 224 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -527,7 +554,7 @@ # During SSL/TLS security parameters negotiation, legacy algorithms will # not be negotiated unless there are no other candidates. # -# The syntax of the disabled algorithm string is described as this Java +# The syntax of the legacy algorithms string is described as this Java # BNF-style: # LegacyAlgorithms: # " LegacyAlgorithm { , LegacyAlgorithm } " @@ -557,7 +584,7 @@ # See SSL/TLS specifications and "Java Cryptography Architecture Standard # Algorithm Name Documentation" for information about the algorithm names. # -# Note: This property is currently used by Oracle's JSSE implementation. +# Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # There is no guarantee the property will continue to exist or be of the # same syntax in future releases. @@ -570,7 +597,8 @@ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \ DH_anon, ECDH_anon, \ - RC4_128, RC4_40, DES_CBC, DES40_CBC + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC # The pre-defined default finite field Diffie-Hellman ephemeral (DHE) # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
--- a/src/solaris/native/java/net/SocketOutputStream.c Thu Sep 08 15:00:00 2016 -0700 +++ b/src/solaris/native/java/net/SocketOutputStream.c Mon Sep 19 11:21:02 2016 -0700 @@ -103,31 +103,35 @@ int llen = chunkLen; (*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP); - while(llen > 0) { - int n = NET_Send(fd, bufP + loff, llen, 0); - if (n > 0) { - llen -= n; - loff += n; - continue; + if ((*env)->ExceptionCheck(env)) { + break; + } else { + while(llen > 0) { + int n = NET_Send(fd, bufP + loff, llen, 0); + if (n > 0) { + llen -= n; + loff += n; + continue; + } + if (n == JVM_IO_INTR) { + JNU_ThrowByName(env, "java/io/InterruptedIOException", 0); + } else { + if (errno == ECONNRESET) { + JNU_ThrowByName(env, "sun/net/ConnectionResetException", + "Connection reset"); + } else { + NET_ThrowByNameWithLastError(env, "java/net/SocketException", + "Write failed"); + } + } + if (bufP != BUF) { + free(bufP); + } + return; } - if (n == JVM_IO_INTR) { - JNU_ThrowByName(env, "java/io/InterruptedIOException", 0); - } else { - if (errno == ECONNRESET) { - JNU_ThrowByName(env, "sun/net/ConnectionResetException", - "Connection reset"); - } else { - NET_ThrowByNameWithLastError(env, "java/net/SocketException", - "Write failed"); - } - } - if (bufP != BUF) { - free(bufP); - } - return; + len -= chunkLen; + off += chunkLen; } - len -= chunkLen; - off += chunkLen; } if (bufP != BUF) {
--- a/src/windows/native/java/net/SocketOutputStream.c Thu Sep 08 15:00:00 2016 -0700 +++ b/src/windows/native/java/net/SocketOutputStream.c Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,66 +100,69 @@ int retry = 0; (*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP); - - while(llen > 0) { - int n = send(fd, bufP + loff, llen, 0); - if (n > 0) { - llen -= n; - loff += n; - continue; - } - - /* - * Due to a bug in Windows Sockets (observed on NT and Windows - * 2000) it may be necessary to retry the send. The issue is that - * on blocking sockets send/WSASend is supposed to block if there - * is insufficient buffer space available. If there are a large - * number of threads blocked on write due to congestion then it's - * possile to hit the NT/2000 bug whereby send returns WSAENOBUFS. - * The workaround we use is to retry the send. If we have a - * large buffer to send (>2k) then we retry with a maximum of - * 2k buffer. If we hit the issue with <=2k buffer then we backoff - * for 1 second and retry again. We repeat this up to a reasonable - * limit before bailing out and throwing an exception. In load - * conditions we've observed that the send will succeed after 2-3 - * attempts but this depends on network buffers associated with - * other sockets draining. - */ - if (WSAGetLastError() == WSAENOBUFS) { - if (llen > MAX_BUFFER_LEN) { - buflen = MAX_BUFFER_LEN; - chunkLen = MAX_BUFFER_LEN; - llen = MAX_BUFFER_LEN; + if ((*env)->ExceptionCheck(env)) { + break; + } else { + while(llen > 0) { + int n = send(fd, bufP + loff, llen, 0); + if (n > 0) { + llen -= n; + loff += n; continue; } - if (retry >= 30) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", - "No buffer space available - exhausted attempts to queue buffer"); - if (bufP != BUF) { - free(bufP); - } - return; - } - Sleep(1000); - retry++; - continue; - } - /* - * Send failed - can be caused by close or write error. - */ - if (WSAGetLastError() == WSAENOTSOCK) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); - } else { - NET_ThrowCurrent(env, "socket write error"); + /* + * Due to a bug in Windows Sockets (observed on NT and Windows + * 2000) it may be necessary to retry the send. The issue is that + * on blocking sockets send/WSASend is supposed to block if there + * is insufficient buffer space available. If there are a large + * number of threads blocked on write due to congestion then it's + * possile to hit the NT/2000 bug whereby send returns WSAENOBUFS. + * The workaround we use is to retry the send. If we have a + * large buffer to send (>2k) then we retry with a maximum of + * 2k buffer. If we hit the issue with <=2k buffer then we backoff + * for 1 second and retry again. We repeat this up to a reasonable + * limit before bailing out and throwing an exception. In load + * conditions we've observed that the send will succeed after 2-3 + * attempts but this depends on network buffers associated with + * other sockets draining. + */ + if (WSAGetLastError() == WSAENOBUFS) { + if (llen > MAX_BUFFER_LEN) { + buflen = MAX_BUFFER_LEN; + chunkLen = MAX_BUFFER_LEN; + llen = MAX_BUFFER_LEN; + continue; + } + if (retry >= 30) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "No buffer space available - exhausted attempts to queue buffer"); + if (bufP != BUF) { + free(bufP); + } + return; + } + Sleep(1000); + retry++; + continue; + } + + /* + * Send failed - can be caused by close or write error. + */ + if (WSAGetLastError() == WSAENOTSOCK) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); + } else { + NET_ThrowCurrent(env, "socket write error"); + } + if (bufP != BUF) { + free(bufP); + } + return; } - if (bufP != BUF) { - free(bufP); - } - return; + len -= chunkLen; + off += chunkLen; } - len -= chunkLen; - off += chunkLen; } if (bufP != BUF) {
--- a/test/javax/net/ssl/ciphersuites/DisabledAlgorithms.java Thu Sep 08 15:00:00 2016 -0700 +++ b/test/javax/net/ssl/ciphersuites/DisabledAlgorithms.java Mon Sep 19 11:21:02 2016 -0700 @@ -41,7 +41,8 @@ * @bug 8076221 * @summary Check if weak cipher suites are disabled * @run main/othervm DisabledAlgorithms default - * @run main/othervm DisabledAlgorithms empty + * @run main/othervm -Djdk.tls.namedGroups="secp256r1,secp192r1" + * DisabledAlgorithms empty */ public class DisabledAlgorithms { @@ -97,6 +98,11 @@ System.out.println("jdk.tls.disabledAlgorithms = " + Security.getProperty("jdk.tls.disabledAlgorithms")); + // some of the certs in our test are weak; disable + Security.setProperty("jdk.certpath.disabledAlgorithms", ""); + System.out.println("jdk.certpath.disabledAlgorithms = " + + Security.getProperty("jdk.cerpath.disabledAlgorithms")); + // check if RC4 cipher suites can be used // if jdk.tls.disabledAlgorithms is empty checkSuccess(rc4_ciphersuites); @@ -224,6 +230,7 @@ socket.getSession().invalidate(); } catch (SSLHandshakeException e) { System.out.println("Server: run: " + e); + e.printStackTrace(); sslError = true; stopped = true; } catch (IOException e) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/net/ssl/ciphersuites/ECCurvesconstraints.java Mon Sep 19 11:21:02 2016 -0700 @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 8148516 + * @summary Improve the default strength of EC in JDK + * @run main/othervm ECCurvesconstraints PKIX + * @run main/othervm ECCurvesconstraints SunX509 + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import javax.net.ssl.*; +import java.security.Security; +import java.security.KeyStore; +import java.security.KeyFactory; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.*; +import java.security.interfaces.*; +import java.util.Base64; + + +public class ECCurvesconstraints { + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = false; + + /* + * Where do we find the keystores? + */ + // Certificates and key used in the test. + // + // EC curve: secp224k1 + static String trustedCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBCzCBugIEVz2lcjAKBggqhkjOPQQDAjAaMRgwFgYDVQQDDA93d3cuZXhhbXBs\n" + + "ZS5vcmcwHhcNMTYwNTE5MTEzNzM5WhcNMTcwNTE5MTEzNzM5WjAaMRgwFgYDVQQD\n" + + "DA93d3cuZXhhbXBsZS5vcmcwTjAQBgcqhkjOPQIBBgUrgQQAIAM6AAT68uovMZ8f\n" + + "KARn5NOjvieJaq6h8zHYkM9w5DuN0kkOo4KBhke06EkQj0nvQQcSvppTV6RoDLY4\n" + + "djAKBggqhkjOPQQDAgNAADA9AhwMNIujM0R0llpPH6d89d1S3VRGH/78ovc+zw51\n" + + "Ah0AuZ1YlQkUbrJIzkuPSICxz5UfCWPe+7w4as+wiA==\n" + + "-----END CERTIFICATE-----"; + + // Private key in the format of PKCS#8 + static String targetPrivateKey = + "MIGCAgEAMBAGByqGSM49AgEGBSuBBAAgBGswaQIBAQQdAPbckc86mgW/zexB1Ajq\n" + + "38HntWOjdxL6XSoiAsWgBwYFK4EEACChPAM6AAT68uovMZ8fKARn5NOjvieJaq6h\n" + + "8zHYkM9w5DuN0kkOo4KBhke06EkQj0nvQQcSvppTV6RoDLY4dg=="; + + static String[] serverCerts = {trustedCertStr}; + static String[] serverKeys = {targetPrivateKey}; + static String[] clientCerts = {trustedCertStr}; + static String[] clientKeys = {targetPrivateKey}; + + static char passphrase[] = "passphrase".toCharArray(); + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + SSLContext context = generateSSLContext(false); + SSLServerSocketFactory sslssf = context.getServerSocketFactory(); + SSLServerSocket sslServerSocket = + (SSLServerSocket)sslssf.createServerSocket(serverPort); + serverPort = sslServerSocket.getLocalPort(); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept(); + try { + sslSocket.setSoTimeout(5000); + sslSocket.setSoLinger(true, 5); + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslIS.read(); + sslOS.write('A'); + sslOS.flush(); + + throw new Exception("EC curve secp224k1 should be disabled"); + } catch (SSLHandshakeException she) { + // expected exception: no cipher suites in common + System.out.println("Expected exception: " + she); + } finally { + sslSocket.close(); + sslServerSocket.close(); + } + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + SSLContext context = generateSSLContext(true); + SSLSocketFactory sslsf = context.getSocketFactory(); + + SSLSocket sslSocket = + (SSLSocket)sslsf.createSocket("localhost", serverPort); + + try { + sslSocket.setSoTimeout(5000); + sslSocket.setSoLinger(true, 5); + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslOS.write('B'); + sslOS.flush(); + sslIS.read(); + + throw new Exception("EC curve secp224k1 should be disabled"); + } catch (SSLHandshakeException she) { + // expected exception: Received fatal alert + System.out.println("Expected exception: " + she); + } finally { + sslSocket.close(); + } + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + private static String tmAlgorithm; // trust manager + + private static void parseArguments(String[] args) { + tmAlgorithm = args[0]; + } + + private static SSLContext generateSSLContext(boolean isClient) + throws Exception { + + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + // create a key store + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + + // import the trused cert + ByteArrayInputStream is = + new ByteArrayInputStream(trustedCertStr.getBytes()); + Certificate trusedCert = cf.generateCertificate(is); + is.close(); + + ks.setCertificateEntry("Export Signer", trusedCert); + + String[] certStrs = null; + String[] keyStrs = null; + if (isClient) { + certStrs = clientCerts; + keyStrs = clientKeys; + } else { + certStrs = serverCerts; + keyStrs = serverKeys; + } + + for (int i = 0; i < certStrs.length; i++) { + // generate the private key. + String keySpecStr = keyStrs[i]; + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder().decode(keySpecStr)); + KeyFactory kf = KeyFactory.getInstance("EC"); + ECPrivateKey priKey = + (ECPrivateKey)kf.generatePrivate(priKeySpec); + + // generate certificate chain + String keyCertStr = certStrs[i]; + is = new ByteArrayInputStream(keyCertStr.getBytes()); + Certificate keyCert = cf.generateCertificate(is); + is.close(); + + Certificate[] chain = new Certificate[2]; + chain[0] = keyCert; + chain[1] = trusedCert; + + // import the key entry. + ks.setKeyEntry("key-entry-" + i, priKey, passphrase, chain); + } + + // create SSL context + TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); + tmf.init(ks); + + SSLContext ctx = SSLContext.getInstance("TLS"); + KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, passphrase); + + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + ks = null; + + return ctx; + } + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + + /* + * Get the customized arguments. + */ + parseArguments(args); + + /* + * Start the tests. + */ + new ECCurvesconstraints(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + ECCurvesconstraints() throws Exception { + try { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + } catch (Exception e) { + // swallow for now. Show later + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + serverThread.join(); + } else { + clientThread.join(); + } + + /* + * When we get here, the test is pretty much over. + * Which side threw the error? + */ + Exception local; + Exception remote; + String whichRemote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + whichRemote = "server"; + } else { + remote = clientException; + local = serverException; + whichRemote = "client"; + } + + /* + * If both failed, return the curthread's exception, but also + * print the remote side Exception + */ + if ((local != null) && (remote != null)) { + System.out.println(whichRemote + " also threw:"); + remote.printStackTrace(); + System.out.println(); + throw local; + } + + if (remote != null) { + throw remote; + } + + if (local != null) { + throw local; + } + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died, because of " + e); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + try { + doServerSide(); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died, because of " + e); + clientException = e; + } + } + }; + clientThread.start(); + } else { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + } +}
--- a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java Thu Sep 08 15:00:00 2016 -0700 +++ b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java Mon Sep 19 11:21:02 2016 -0700 @@ -90,13 +90,14 @@ * @throws RuntimeException * If the string was not found */ - public void shouldContain(String expectedString) { + public OutputAnalyzer shouldContain(String expectedString) { if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) { reportDiagnosticSummary(); throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n"); } + return this; } /** @@ -107,12 +108,13 @@ * @throws RuntimeException * If the string was not found */ - public void stdoutShouldContain(String expectedString) { + public OutputAnalyzer stdoutShouldContain(String expectedString) { if (!stdout.contains(expectedString)) { reportDiagnosticSummary(); throw new RuntimeException("'" + expectedString + "' missing from stdout \n"); } + return this; } /** @@ -123,24 +125,25 @@ * @throws RuntimeException * If the string was not found */ - public void stderrShouldContain(String expectedString) { + public OutputAnalyzer stderrShouldContain(String expectedString) { if (!stderr.contains(expectedString)) { reportDiagnosticSummary(); throw new RuntimeException("'" + expectedString + "' missing from stderr \n"); } + return this; } /** * Verify that the stdout and stderr contents of output buffer does not * contain the string * - * @param expectedString + * @param notExpectedString * String that the buffer should not contain * @throws RuntimeException * If the string was found */ - public void shouldNotContain(String notExpectedString) { + public OutputAnalyzer shouldNotContain(String notExpectedString) { if (stdout.contains(notExpectedString)) { reportDiagnosticSummary(); throw new RuntimeException("'" + notExpectedString @@ -151,23 +154,25 @@ throw new RuntimeException("'" + notExpectedString + "' found in stderr \n"); } + return this; } /** * Verify that the stdout contents of output buffer does not contain the * string * - * @param expectedString + * @param notExpectedString * String that the buffer should not contain * @throws RuntimeException * If the string was found */ - public void stdoutShouldNotContain(String notExpectedString) { + public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) { if (stdout.contains(notExpectedString)) { reportDiagnosticSummary(); throw new RuntimeException("'" + notExpectedString + "' found in stdout \n"); } + return this; } /** @@ -195,7 +200,7 @@ * @throws RuntimeException * If the pattern was not found */ - public void shouldMatch(String pattern) { + public OutputAnalyzer shouldMatch(String pattern) { Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE) .matcher(stdout); Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE) @@ -205,6 +210,7 @@ throw new RuntimeException("'" + pattern + "' missing from stdout/stderr \n"); } + return this; } /** @@ -214,7 +220,7 @@ * @throws RuntimeException * If the pattern was not found */ - public void stdoutShouldMatch(String pattern) { + public OutputAnalyzer stdoutShouldMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( stdout); if (!matcher.find()) { @@ -222,6 +228,7 @@ throw new RuntimeException("'" + pattern + "' missing from stdout \n"); } + return this; } /** @@ -231,7 +238,7 @@ * @throws RuntimeException * If the pattern was not found */ - public void stderrShouldMatch(String pattern) { + public OutputAnalyzer stderrShouldMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( stderr); if (!matcher.find()) { @@ -239,6 +246,7 @@ throw new RuntimeException("'" + pattern + "' missing from stderr \n"); } + return this; } /** @@ -249,7 +257,7 @@ * @throws RuntimeException * If the pattern was found */ - public void shouldNotMatch(String pattern) { + public OutputAnalyzer shouldNotMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( stdout); if (matcher.find()) { @@ -263,6 +271,7 @@ throw new RuntimeException("'" + pattern + "' found in stderr: '" + matcher.group() + "' \n"); } + return this; } /** @@ -273,13 +282,14 @@ * @throws RuntimeException * If the pattern was found */ - public void stdoutShouldNotMatch(String pattern) { + public OutputAnalyzer stdoutShouldNotMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( stdout); if (matcher.find()) { reportDiagnosticSummary(); throw new RuntimeException("'" + pattern + "' found in stdout \n"); } + return this; } /** @@ -290,13 +300,14 @@ * @throws RuntimeException * If the pattern was found */ - public void stderrShouldNotMatch(String pattern) { + public OutputAnalyzer stderrShouldNotMatch(String pattern) { Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( stderr); if (matcher.find()) { reportDiagnosticSummary(); throw new RuntimeException("'" + pattern + "' found in stderr \n"); } + return this; } /** @@ -344,12 +355,13 @@ * If the exit value from the process did not match the expected * value */ - public void shouldHaveExitValue(int expectedExitValue) { + public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) { if (getExitValue() != expectedExitValue) { reportDiagnosticSummary(); throw new RuntimeException("Expected to get exit value of [" + expectedExitValue + "]\n"); } + return this; } /** @@ -357,11 +369,12 @@ * - standard input produced by the process under test - standard output - * exit code Note: the command line is printed by the ProcessTools */ - private void reportDiagnosticSummary() { + private OutputAnalyzer reportDiagnosticSummary() { String msg = " stdout: [" + stdout + "];\n" + " stderr: [" + stderr + "]\n" + " exitValue = " + getExitValue() + "\n"; System.err.println(msg); + return this; } /**
--- a/test/sun/security/ec/TestEC.java Thu Sep 08 15:00:00 2016 -0700 +++ b/test/sun/security/ec/TestEC.java Mon Sep 19 11:21:02 2016 -0700 @@ -35,7 +35,7 @@ * @library ../pkcs11/sslecc * @library ../../../java/security/testlibrary * @compile -XDignore.symbol.file TestEC.java - * @run main/othervm TestEC + * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC */ import java.security.NoSuchProviderException;
--- a/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java Thu Sep 08 15:00:00 2016 -0700 +++ b/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java Mon Sep 19 11:21:02 2016 -0700 @@ -33,7 +33,8 @@ * @author Andreas Sterbenz * @library .. * @library ../../../../java/security/testlibrary - * @run main/othervm ClientJSSEServerJSSE + * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" + * ClientJSSEServerJSSE */ import java.security.*;
--- a/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java Thu Sep 08 15:00:00 2016 -0700 +++ b/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java Mon Sep 19 11:21:02 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ * @bug 7188657 * @summary There should be a way to reorder the JSSE ciphers * @run main/othervm UseCipherSuitesOrder - * TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA */ import java.io.*;
--- a/test/sun/security/ssl/sanity/interop/ClientJSSEServerJSSE.java Thu Sep 08 15:00:00 2016 -0700 +++ b/test/sun/security/ssl/sanity/interop/ClientJSSEServerJSSE.java Mon Sep 19 11:21:02 2016 -0700 @@ -26,7 +26,8 @@ * @bug 4496785 * @summary Verify that all ciphersuites work in all configurations * @author Andreas Sterbenz - * @run main/othervm/timeout=300 ClientJSSEServerJSSE + * @run main/othervm/timeout=300 -Djdk.tls.namedGroups="secp256r1,secp192r1" + * ClientJSSEServerJSSE */ import java.security.Security;
--- a/test/sun/security/tools/jarsigner/warnings/Test.java Thu Sep 08 15:00:00 2016 -0700 +++ b/test/sun/security/tools/jarsigner/warnings/Test.java Mon Sep 19 11:21:02 2016 -0700 @@ -22,6 +22,11 @@ */ import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * Base class. @@ -175,4 +180,21 @@ } analyzer.shouldContain(JAR_SIGNED); } + + protected OutputAnalyzer keytool(String... cmd) throws Throwable { + return tool(KEYTOOL, cmd); + } + + protected OutputAnalyzer jarsigner(String... cmd) throws Throwable { + return tool(JARSIGNER, cmd); + } + + private OutputAnalyzer tool(String tool, String... args) throws Throwable { + List<String> cmd = new ArrayList<>(); + cmd.add(tool); + cmd.add("-J-Duser.language=en"); + cmd.add("-J-Duser.country=US"); + cmd.addAll(Arrays.asList(args)); + return ProcessTools.executeCommand(cmd.toArray(new String[cmd.size()])); + } }