提交 e5003f8f 编写于 作者: A asaha

Merge

/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -155,11 +155,12 @@ class SocketInputStream extends FileInputStream ...@@ -155,11 +155,12 @@ class SocketInputStream extends FileInputStream
} }
// bounds check // bounds check
if (length <= 0 || off < 0 || off + length > b.length) { if (length <= 0 || off < 0 || length > b.length - off) {
if (length == 0) { if (length == 0) {
return 0; return 0;
} }
throw new ArrayIndexOutOfBoundsException(); throw new ArrayIndexOutOfBoundsException("length == " + length
+ " off == " + off + " buffer length == " + b.length);
} }
boolean gotReset = false; boolean gotReset = false;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -97,11 +97,13 @@ class SocketOutputStream extends FileOutputStream ...@@ -97,11 +97,13 @@ class SocketOutputStream extends FileOutputStream
*/ */
private void socketWrite(byte b[], int off, int len) throws IOException { 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) { if (len == 0) {
return; return;
} }
throw new ArrayIndexOutOfBoundsException(); throw new ArrayIndexOutOfBoundsException("len == " + len
+ " off == " + off + " buffer length == " + b.length);
} }
FileDescriptor fd = impl.acquireFD(); FileDescriptor fd = impl.acquireFD();
......
...@@ -55,6 +55,7 @@ import sun.security.util.DerInputStream; ...@@ -55,6 +55,7 @@ import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream; import sun.security.util.DerOutputStream;
import sun.security.util.DerValue; import sun.security.util.DerValue;
import sun.security.util.DisabledAlgorithmConstraints; import sun.security.util.DisabledAlgorithmConstraints;
import sun.security.util.KeyUtil;
import sun.security.util.ObjectIdentifier; import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId; import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name; import sun.security.x509.X500Name;
...@@ -399,7 +400,9 @@ public class SignerInfo implements DerEncoder { ...@@ -399,7 +400,9 @@ public class SignerInfo implements DerEncoder {
// check if the public key is restricted // check if the public key is restricted
if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
throw new SignatureException("Public key check failed. " + throw new SignatureException("Public key check failed. " +
"Disabled algorithm used: " + key.getAlgorithm()); "Disabled key used: " +
KeyUtil.getKeySize(key) + " bit " +
key.getAlgorithm());
} }
if (cert.hasUnsupportedCriticalExtension()) { if (cert.hasUnsupportedCriticalExtension()) {
......
/* /*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,12 +31,10 @@ import java.util.Collection; ...@@ -31,12 +31,10 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509CRL; import java.security.cert.X509CRL;
...@@ -48,10 +46,13 @@ import java.security.cert.CertificateException; ...@@ -48,10 +46,13 @@ import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.PKIXReason; import java.security.cert.PKIXReason;
import java.io.IOException; import java.security.interfaces.DSAParams;
import java.security.interfaces.*; import java.security.interfaces.DSAPublicKey;
import java.security.spec.*; import java.security.spec.DSAPublicKeySpec;
import sun.security.util.AnchorCertificates;
import sun.security.util.CertConstraintParameters;
import sun.security.util.Debug;
import sun.security.util.DisabledAlgorithmConstraints; import sun.security.util.DisabledAlgorithmConstraints;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CRLImpl; import sun.security.x509.X509CRLImpl;
...@@ -69,6 +70,7 @@ import sun.security.x509.AlgorithmId; ...@@ -69,6 +70,7 @@ import sun.security.x509.AlgorithmId;
* @see PKIXParameters * @see PKIXParameters
*/ */
final public class AlgorithmChecker extends PKIXCertPathChecker { final public class AlgorithmChecker extends PKIXCertPathChecker {
private static final Debug debug = Debug.getInstance("certpath");
private final AlgorithmConstraints constraints; private final AlgorithmConstraints constraints;
private final PublicKey trustedPubKey; private final PublicKey trustedPubKey;
...@@ -88,6 +90,14 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -88,6 +90,14 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
certPathDefaultConstraints = new DisabledAlgorithmConstraints( certPathDefaultConstraints = new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
// If there is no "cacerts" keyword, then disable anchor checking
private static final boolean publicCALimits =
certPathDefaultConstraints.checkProperty("jdkCA");
// If anchor checking enabled, this will be true if the trust anchor
// has a match in the cacerts file
private boolean trustedMatch = false;
/** /**
* Create a new <code>AlgorithmChecker</code> with the algorithm * Create a new <code>AlgorithmChecker</code> with the algorithm
* constraints specified in security property * constraints specified in security property
...@@ -136,6 +146,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -136,6 +146,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
if (anchor.getTrustedCert() != null) { if (anchor.getTrustedCert() != null) {
this.trustedPubKey = anchor.getTrustedCert().getPublicKey(); this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
// Check for anchor certificate restrictions
trustedMatch = checkFingerprint(anchor.getTrustedCert());
if (trustedMatch && debug != null) {
debug.println("trustedMatch = true");
}
} else { } else {
this.trustedPubKey = anchor.getCAPublicKey(); this.trustedPubKey = anchor.getCAPublicKey();
} }
...@@ -144,6 +159,19 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -144,6 +159,19 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
this.constraints = constraints; this.constraints = constraints;
} }
// Check this 'cert' for restrictions in the AnchorCertificates
// trusted certificates list
private static boolean checkFingerprint(X509Certificate cert) {
if (!publicCALimits) {
return false;
}
if (debug != null) {
debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName());
}
return AnchorCertificates.contains(cert);
}
@Override @Override
public void init(boolean forward) throws CertPathValidatorException { public void init(boolean forward) throws CertPathValidatorException {
// Note that this class does not support forward mode. // Note that this class does not support forward mode.
...@@ -181,36 +209,8 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -181,36 +209,8 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
return; return;
} }
X509CertImpl x509Cert = null;
try {
x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
PublicKey currPubKey = x509Cert.getPublicKey();
String currSigAlg = x509Cert.getSigAlgName();
AlgorithmId algorithmId = null;
try {
algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
// Check the current signature algorithm
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
// check the key usage and key size // check the key usage and key size
boolean[] keyUsage = x509Cert.getKeyUsage(); boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage();
if (keyUsage != null && keyUsage.length < 9) { if (keyUsage != null && keyUsage.length < 9) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"incorrect KeyUsage extension", "incorrect KeyUsage extension",
...@@ -248,28 +248,68 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -248,28 +248,68 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
if (primitives.isEmpty()) { if (primitives.isEmpty()) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"incorrect KeyUsage extension", "incorrect KeyUsage extension bits",
null, null, -1, PKIXReason.INVALID_KEY_USAGE); null, null, -1, PKIXReason.INVALID_KEY_USAGE);
} }
} }
PublicKey currPubKey = cert.getPublicKey();
// Check against DisabledAlgorithmConstraints certpath constraints.
// permits() will throw exception on failure.
certPathDefaultConstraints.permits(primitives,
new CertConstraintParameters((X509Certificate)cert,
trustedMatch));
// new CertConstraintParameters(x509Cert, trustedMatch));
// If there is no previous key, set one and exit
if (prevPubKey == null) {
prevPubKey = currPubKey;
return;
}
X509CertImpl x509Cert;
AlgorithmId algorithmId;
try {
x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
String currSigAlg = x509Cert.getSigAlgName();
// If 'constraints' is not of DisabledAlgorithmConstraints, check all
// everything individually
if (!(constraints instanceof DisabledAlgorithmConstraints)) {
// Check the current signature algorithm
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on signature " +
"algorithm: " + currSigAlg, null, null, -1,
BasicReason.ALGORITHM_CONSTRAINED);
}
if (!constraints.permits(primitives, currPubKey)) { if (!constraints.permits(primitives, currPubKey)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"algorithm constraints check failed", "Algorithm constraints check failed on keysize: " +
sun.security.util.KeyUtil.getKeySize(currPubKey),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
}
// Check with previous cert for signature algorithm and public key // Check with previous cert for signature algorithm and public key
if (prevPubKey != null) { if (prevPubKey != null) {
if (currSigAlg != null) {
if (!constraints.permits( if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET, SIGNATURE_PRIMITIVE_SET,
currSigAlg, prevPubKey, currSigAlgParams)) { currSigAlg, prevPubKey, currSigAlgParams)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"Algorithm constraints check failed: " + currSigAlg, "Algorithm constraints check failed on " +
"signature algorithm: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
}
// Inherit key parameters from previous key // Inherit key parameters from previous key
if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) { if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
...@@ -282,7 +322,7 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -282,7 +322,7 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
DSAParams params = ((DSAPublicKey)prevPubKey).getParams(); DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
if (params == null) { if (params == null) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"Key parameters missing"); "Key parameters missing from public key.");
} }
try { try {
...@@ -330,6 +370,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -330,6 +370,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
// Don't bother to change the trustedPubKey. // Don't bother to change the trustedPubKey.
if (anchor.getTrustedCert() != null) { if (anchor.getTrustedCert() != null) {
prevPubKey = anchor.getTrustedCert().getPublicKey(); prevPubKey = anchor.getTrustedCert().getPublicKey();
// Check for anchor certificate restrictions
trustedMatch = checkFingerprint(anchor.getTrustedCert());
if (trustedMatch && debug != null) {
debug.println("trustedMatch = true");
}
} else { } else {
prevPubKey = anchor.getCAPublicKey(); prevPubKey = anchor.getCAPublicKey();
} }
...@@ -370,7 +415,8 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -370,7 +415,8 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
if (!certPathDefaultConstraints.permits( if (!certPathDefaultConstraints.permits(
SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) { SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"algorithm check failed: " + sigAlgName + " is disabled", "Algorithm constraints check failed on signature algorithm: " +
sigAlgName + " is disabled",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
} }
......
...@@ -131,8 +131,8 @@ class PKIXMasterCertPathValidator { ...@@ -131,8 +131,8 @@ class PKIXMasterCertPathValidator {
} catch (CertPathValidatorException cpve) { } catch (CertPathValidatorException cpve) {
throw new CertPathValidatorException(cpve.getMessage(), throw new CertPathValidatorException(cpve.getMessage(),
cpve.getCause(), cpOriginal, cpSize - (i + 1), (cpve.getCause() != null) ? cpve.getCause() : cpve,
cpve.getReason()); cpOriginal, cpSize - (i + 1), cpve.getReason());
} }
} }
......
/* /*
* Copyright (c) 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -326,36 +326,38 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -326,36 +326,38 @@ final class CipherSuite implements Comparable<CipherSuite> {
static enum KeyExchange { static enum KeyExchange {
// key exchange algorithms // key exchange algorithms
K_NULL ("NULL", false), K_NULL ("NULL", false, false),
K_RSA ("RSA", true), K_RSA ("RSA", true, false),
K_RSA_EXPORT ("RSA_EXPORT", true), K_RSA_EXPORT ("RSA_EXPORT", true, false),
K_DH_RSA ("DH_RSA", false), K_DH_RSA ("DH_RSA", false, false),
K_DH_DSS ("DH_DSS", false), K_DH_DSS ("DH_DSS", false, false),
K_DHE_DSS ("DHE_DSS", true), K_DHE_DSS ("DHE_DSS", true, false),
K_DHE_RSA ("DHE_RSA", true), K_DHE_RSA ("DHE_RSA", true, false),
K_DH_ANON ("DH_anon", true), K_DH_ANON ("DH_anon", true, false),
K_ECDH_ECDSA ("ECDH_ECDSA", ALLOW_ECC), K_ECDH_ECDSA ("ECDH_ECDSA", ALLOW_ECC, true),
K_ECDH_RSA ("ECDH_RSA", ALLOW_ECC), K_ECDH_RSA ("ECDH_RSA", ALLOW_ECC, true),
K_ECDHE_ECDSA("ECDHE_ECDSA", ALLOW_ECC), K_ECDHE_ECDSA("ECDHE_ECDSA", ALLOW_ECC, true),
K_ECDHE_RSA ("ECDHE_RSA", ALLOW_ECC), K_ECDHE_RSA ("ECDHE_RSA", ALLOW_ECC, true),
K_ECDH_ANON ("ECDH_anon", ALLOW_ECC), K_ECDH_ANON ("ECDH_anon", ALLOW_ECC, true),
// Kerberos cipher suites // Kerberos cipher suites
K_KRB5 ("KRB5", true), K_KRB5 ("KRB5", true, false),
K_KRB5_EXPORT("KRB5_EXPORT", true), K_KRB5_EXPORT("KRB5_EXPORT", true, false),
// renegotiation protection request signaling cipher suite // 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 // name of the key exchange algorithm, e.g. DHE_DSS
final String name; final String name;
final boolean allowed; final boolean allowed;
final boolean isEC;
private final boolean alwaysAvailable; private final boolean alwaysAvailable;
KeyExchange(String name, boolean allowed) { KeyExchange(String name, boolean allowed, boolean isEC) {
this.name = name; this.name = name;
this.allowed = allowed; this.allowed = allowed;
this.isEC = isEC;
this.alwaysAvailable = allowed && this.alwaysAvailable = allowed &&
(!name.startsWith("EC")) && (!name.startsWith("KRB")); (!name.startsWith("EC")) && (!name.startsWith("KRB"));
} }
...@@ -365,7 +367,7 @@ final class CipherSuite implements Comparable<CipherSuite> { ...@@ -365,7 +367,7 @@ final class CipherSuite implements Comparable<CipherSuite> {
return true; return true;
} }
if (name.startsWith("EC")) { if (isEC) {
return (allowed && JsseJce.isEcAvailable()); return (allowed && JsseJce.isEcAvailable());
} else if (name.startsWith("KRB")) { } else if (name.startsWith("KRB")) {
return (allowed && JsseJce.isKerberosAvailable()); return (allowed && JsseJce.isKerberosAvailable());
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -112,20 +112,15 @@ final class CipherSuiteList { ...@@ -112,20 +112,15 @@ final class CipherSuiteList {
boolean containsEC() { boolean containsEC() {
if (containsEC == null) { if (containsEC == null) {
for (CipherSuite c : cipherSuites) { for (CipherSuite c : cipherSuites) {
switch (c.keyExchange) { if (c.keyExchange.isEC) {
case K_ECDH_ECDSA:
case K_ECDH_RSA:
case K_ECDHE_ECDSA:
case K_ECDHE_RSA:
case K_ECDH_ANON:
containsEC = true; containsEC = true;
return true; return true;
default:
break;
} }
} }
containsEC = false; containsEC = false;
} }
return containsEC; return containsEC;
} }
......
...@@ -776,13 +776,16 @@ final class ClientHandshaker extends Handshaker { ...@@ -776,13 +776,16 @@ final class ClientHandshaker extends Handshaker {
break; break;
// Fixed DH/ECDH client authentication not supported // Fixed DH/ECDH client authentication not supported
case CertificateRequest.cct_rsa_fixed_dh: //
case CertificateRequest.cct_dss_fixed_dh: // case CertificateRequest.cct_rsa_fixed_dh:
case CertificateRequest.cct_rsa_fixed_ecdh: // case CertificateRequest.cct_dss_fixed_dh:
case CertificateRequest.cct_ecdsa_fixed_ecdh: // case CertificateRequest.cct_rsa_fixed_ecdh:
// case CertificateRequest.cct_ecdsa_fixed_ecdh:
//
// Any other values (currently not used in TLS) // Any other values (currently not used in TLS)
case CertificateRequest.cct_rsa_ephemeral_dh: //
case CertificateRequest.cct_dss_ephemeral_dh: // case CertificateRequest.cct_rsa_ephemeral_dh:
// case CertificateRequest.cct_dss_ephemeral_dh:
default: default:
typeName = null; typeName = null;
break; break;
...@@ -813,18 +816,6 @@ final class ClientHandshaker extends Handshaker { ...@@ -813,18 +816,6 @@ final class ClientHandshaker extends Handshaker {
X509Certificate[] certs = km.getCertificateChain(alias); X509Certificate[] certs = km.getCertificateChain(alias);
if ((certs != null) && (certs.length != 0)) { if ((certs != null) && (certs.length != 0)) {
PublicKey publicKey = certs[0].getPublicKey(); 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) { if (publicKey != null) {
m1 = new CertificateMsg(certs); m1 = new CertificateMsg(certs);
signingKey = km.getPrivateKey(alias); signingKey = km.getPrivateKey(alias);
...@@ -1385,6 +1376,17 @@ final class ClientHandshaker extends Handshaker { ...@@ -1385,6 +1376,17 @@ final class ClientHandshaker extends Handshaker {
sslContext.getSecureRandom(), maxProtocolVersion, sslContext.getSecureRandom(), maxProtocolVersion,
sessionId, cipherSuites); 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 // add signature_algorithm extension
if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) { if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) {
// we will always send the signature_algorithm extension // we will always send the signature_algorithm extension
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -56,10 +56,11 @@ final class ECDHCrypt { ...@@ -56,10 +56,11 @@ final class ECDHCrypt {
} }
// Called by ServerHandshaker for ephemeral ECDH // Called by ServerHandshaker for ephemeral ECDH
ECDHCrypt(String curveName, SecureRandom random) { ECDHCrypt(int curveId, SecureRandom random) {
try { try {
KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("EC"); KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("EC");
ECGenParameterSpec params = new ECGenParameterSpec(curveName); ECGenParameterSpec params =
SupportedEllipticCurvesExtension.getECGenParamSpec(curveId);
kpg.initialize(params, random); kpg.initialize(params, random);
KeyPair kp = kpg.generateKeyPair(); KeyPair kp = kpg.generateKeyPair();
privateKey = kp.getPrivate(); privateKey = kp.getPrivate();
......
...@@ -230,11 +230,6 @@ static final class ClientHello extends HandshakeMessage { ...@@ -230,11 +230,6 @@ static final class ClientHello extends HandshakeMessage {
this.sessionId = sessionId; this.sessionId = sessionId;
this.cipherSuites = cipherSuites; this.cipherSuites = cipherSuites;
if (cipherSuites.containsEC()) {
extensions.add(SupportedEllipticCurvesExtension.DEFAULT);
extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT);
}
clnt_random = new RandomCookie(generator); clnt_random = new RandomCookie(generator);
compression_methods = NULL_COMPRESSION; compression_methods = NULL_COMPRESSION;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -636,14 +636,42 @@ abstract class Handshaker { ...@@ -636,14 +636,42 @@ abstract class Handshaker {
ArrayList<CipherSuite> suites = new ArrayList<>(); ArrayList<CipherSuite> suites = new ArrayList<>();
if (!(activeProtocols.collection().isEmpty()) && if (!(activeProtocols.collection().isEmpty()) &&
activeProtocols.min.v != ProtocolVersion.NONE.v) { activeProtocols.min.v != ProtocolVersion.NONE.v) {
boolean checkedCurves = false;
boolean hasCurves = false;
for (CipherSuite suite : enabledCipherSuites.collection()) { for (CipherSuite suite : enabledCipherSuites.collection()) {
if (suite.obsoleted > activeProtocols.min.v && if (suite.obsoleted > activeProtocols.min.v &&
suite.supported <= activeProtocols.max.v) { suite.supported <= activeProtocols.max.v) {
if (algorithmConstraints.permits( if (algorithmConstraints.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
suite.name, null)) { suite.name, null)) {
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); suites.add(suite);
} }
}
} else if (debug != null && Debug.isOn("verbose")) { } else if (debug != null && Debug.isOn("verbose")) {
if (suite.obsoleted <= activeProtocols.min.v) { if (suite.obsoleted <= activeProtocols.min.v) {
System.out.println( System.out.println(
...@@ -679,18 +707,10 @@ abstract class Handshaker { ...@@ -679,18 +707,10 @@ abstract class Handshaker {
ProtocolList getActiveProtocols() { ProtocolList getActiveProtocols() {
if (activeProtocols == null) { if (activeProtocols == null) {
boolean enabledSSL20Hello = false; boolean enabledSSL20Hello = false;
boolean checkedCurves = false;
boolean hasCurves = false;
ArrayList<ProtocolVersion> protocols = new ArrayList<>(4); ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
for (ProtocolVersion protocol : enabledProtocols.collection()) { 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. // Need not to check the SSL20Hello protocol.
if (protocol.v == ProtocolVersion.SSL20Hello.v) { if (protocol.v == ProtocolVersion.SSL20Hello.v) {
enabledSSL20Hello = true; enabledSSL20Hello = true;
...@@ -714,9 +734,36 @@ abstract class Handshaker { ...@@ -714,9 +734,36 @@ abstract class Handshaker {
if (algorithmConstraints.permits( if (algorithmConstraints.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
suite.name, null)) { suite.name, null)) {
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); protocols.add(protocol);
found = true; found = true;
break; break;
}
} else if (debug != null && Debug.isOn("verbose")) { } else if (debug != null && Debug.isOn("verbose")) {
System.out.println( System.out.println(
"Ignoring disabled cipher suite: " + suite + "Ignoring disabled cipher suite: " + suite +
......
...@@ -290,6 +290,15 @@ final class JsseJce { ...@@ -290,6 +290,15 @@ final class JsseJce {
} }
} }
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 { static SecureRandom getSecureRandom() throws KeyManagementException {
if (cryptoProvider == null) { if (cryptoProvider == null) {
return new SecureRandom(); return new SecureRandom();
...@@ -409,6 +418,7 @@ final class JsseJce { ...@@ -409,6 +418,7 @@ final class JsseJce {
JsseJce.getKeyAgreement("ECDH"); JsseJce.getKeyAgreement("ECDH");
JsseJce.getKeyFactory("EC"); JsseJce.getKeyFactory("EC");
JsseJce.getKeyPairGenerator("EC"); JsseJce.getKeyPairGenerator("EC");
JsseJce.getAlgorithmParameters("EC");
} catch (Exception e) { } catch (Exception e) {
mediator = false; mediator = false;
} }
......
...@@ -92,7 +92,8 @@ final class ServerHandshaker extends Handshaker { ...@@ -92,7 +92,8 @@ final class ServerHandshaker extends Handshaker {
// we remember it for the RSA premaster secret version check // we remember it for the RSA premaster secret version check
private ProtocolVersion clientRequestedVersion; private ProtocolVersion clientRequestedVersion;
private SupportedEllipticCurvesExtension supportedCurves; // client supported elliptic curves
private SupportedEllipticCurvesExtension requestedCurves;
// the preferable signature algorithm used by ServerKeyExchange message // the preferable signature algorithm used by ServerKeyExchange message
SignatureAndHashAlgorithm preferableSignatureAlgorithm; SignatureAndHashAlgorithm preferableSignatureAlgorithm;
...@@ -682,7 +683,7 @@ final class ServerHandshaker extends Handshaker { ...@@ -682,7 +683,7 @@ final class ServerHandshaker extends Handshaker {
throw new SSLException("Client did not resume a session"); throw new SSLException("Client did not resume a session");
} }
supportedCurves = (SupportedEllipticCurvesExtension) requestedCurves = (SupportedEllipticCurvesExtension)
mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES); mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
// We only need to handle the "signature_algorithm" extension // We only need to handle the "signature_algorithm" extension
...@@ -1412,26 +1413,15 @@ final class ServerHandshaker extends Handshaker { ...@@ -1412,26 +1413,15 @@ final class ServerHandshaker extends Handshaker {
// If we cannot continue because we do not support any of the curves that // 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. // the client requested, return false. Otherwise (all is well), return true.
private boolean setupEphemeralECDHKeys() { private boolean setupEphemeralECDHKeys() {
int index = -1; int index = (requestedCurves != null) ?
if (supportedCurves != null) { requestedCurves.getPreferredCurve(algorithmConstraints) :
// if the client sent the supported curves extension, pick the SupportedEllipticCurvesExtension.getActiveCurves(algorithmConstraints);
// first one that we support;
for (int curveId : supportedCurves.curveIds()) {
if (SupportedEllipticCurvesExtension.isSupported(curveId)) {
index = curveId;
break;
}
}
if (index < 0) { if (index < 0) {
// no match found, cannot use this ciphersuite // no match found, cannot use this ciphersuite
return false; return false;
} }
} else {
// pick our preference ecdh = new ECDHCrypt(index, sslContext.getSecureRandom());
index = SupportedEllipticCurvesExtension.DEFAULT.curveIds()[0];
}
String oid = SupportedEllipticCurvesExtension.getCurveOid(index);
ecdh = new ECDHCrypt(oid, sslContext.getSecureRandom());
return true; return true;
} }
...@@ -1480,11 +1470,9 @@ final class ServerHandshaker extends Handshaker { ...@@ -1480,11 +1470,9 @@ final class ServerHandshaker extends Handshaker {
return false; return false;
} }
ECParameterSpec params = ((ECPublicKey)publicKey).getParams(); ECParameterSpec params = ((ECPublicKey)publicKey).getParams();
int index = SupportedEllipticCurvesExtension.getCurveIndex(params); int id = SupportedEllipticCurvesExtension.getCurveIndex(params);
if (SupportedEllipticCurvesExtension.isSupported(index) == false) { if ((id <= 0) || !SupportedEllipticCurvesExtension.isSupported(id) ||
return false; ((requestedCurves != null) && !requestedCurves.contains(id))) {
}
if ((supportedCurves != null) && !supportedCurves.contains(index)) {
return false; return false;
} }
} }
......
...@@ -27,39 +27,195 @@ package sun.security.ssl; ...@@ -27,39 +27,195 @@ package sun.security.ssl;
import java.io.IOException; import java.io.IOException;
import java.security.spec.ECParameterSpec; 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.HashMap;
import java.util.Map; 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 { final class SupportedEllipticCurvesExtension extends HelloExtension {
// the extension value to send in the ClientHello message private static final int ARBITRARY_PRIME = 0xff01;
static final SupportedEllipticCurvesExtension DEFAULT; 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
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) {
private static final boolean fips; 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 { static {
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; int[] ids;
fips = SunJSSE.isFIPS(); if (requireFips) {
if (fips == false) {
ids = new int[] { ids = new int[] {
// NIST curves first // only NIST curves in FIPS mode
// prefer NIST P-256, rest in order of increasing key length 23, 24, 25, 9, 10, 11, 12, 13, 14,
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,
}; };
} else { } else {
ids = new int[] { ids = new int[] {
// same as above, but allow only NIST curves in FIPS mode // NIST curves first
23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14, 23, 24, 25, 9, 10, 11, 12, 13, 14,
// non-NIST curves
22,
}; };
} }
DEFAULT = new SupportedEllipticCurvesExtension(ids);
idList = new ArrayList<>(ids.length);
for (int curveId : ids) {
if (isAvailableCurve(curveId)) {
idList.add(curveId);
}
}
} }
private final int[] curveIds; if (idList.isEmpty()) {
throw new IllegalArgumentException(
"System property jdk.tls.namedGroups(" + property + ") " +
"contains no supported elliptic curves");
} else {
supportedCurveIds = new int[idList.size()];
int i = 0;
for (Integer id : idList) {
supportedCurveIds[i++] = id;
}
}
}
// 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) { private SupportedEllipticCurvesExtension(int[] curveIds) {
super(ExtensionType.EXT_ELLIPTIC_CURVES); super(ExtensionType.EXT_ELLIPTIC_CURVES);
...@@ -73,12 +229,67 @@ final class SupportedEllipticCurvesExtension extends HelloExtension { ...@@ -73,12 +229,67 @@ final class SupportedEllipticCurvesExtension extends HelloExtension {
if (((len & 1) != 0) || (k + 2 != len)) { if (((len & 1) != 0) || (k + 2 != len)) {
throw new SSLProtocolException("Invalid " + type + " extension"); throw new SSLProtocolException("Invalid " + type + " extension");
} }
// Note: unknown curves will be ignored later.
curveIds = new int[k >> 1]; curveIds = new int[k >> 1];
for (int i = 0; i < curveIds.length; i++) { for (int i = 0; i < curveIds.length; i++) {
curveIds[i] = s.getInt16(); 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) { boolean contains(int index) {
for (int curveId : curveIds) { for (int curveId : curveIds) {
if (index == curveId) { if (index == curveId) {
...@@ -88,12 +299,6 @@ final class SupportedEllipticCurvesExtension extends HelloExtension { ...@@ -88,12 +299,6 @@ final class SupportedEllipticCurvesExtension extends HelloExtension {
return false; return false;
} }
// Return a reference to the internal curveIds array.
// The caller must NOT modify the contents.
int[] curveIds() {
return curveIds;
}
@Override @Override
int length() { int length() {
return 6 + (curveIds.length << 1); return 6 + (curveIds.length << 1);
...@@ -121,18 +326,9 @@ final class SupportedEllipticCurvesExtension extends HelloExtension { ...@@ -121,18 +326,9 @@ final class SupportedEllipticCurvesExtension extends HelloExtension {
} else { } else {
sb.append(", "); sb.append(", ");
} }
// first check if it is a known named curve, then try other cases. String curveName = getCurveName(curveId);
String oid = getCurveOid(curveId); if (curveName != null) {
if (oid != null) { sb.append(curveName);
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);
}
} else if (curveId == ARBITRARY_PRIME) { } else if (curveId == ARBITRARY_PRIME) {
sb.append("arbitrary_explicit_prime_curves"); sb.append("arbitrary_explicit_prime_curves");
} else if (curveId == ARBITRARY_CHAR2) { } else if (curveId == ARBITRARY_CHAR2) {
...@@ -145,16 +341,15 @@ final class SupportedEllipticCurvesExtension extends HelloExtension { ...@@ -145,16 +341,15 @@ final class SupportedEllipticCurvesExtension extends HelloExtension {
return sb.toString(); 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) { static boolean isSupported(int index) {
if ((index <= 0) || (index >= NAMED_CURVE_OID_TABLE.length)) { for (int curveId : supportedCurveIds) {
return false; if (index == curveId) {
}
if (fips == false) {
// in non-FIPS mode, we support all valid indices
return true; return true;
} }
return DEFAULT.contains(index); }
return false;
} }
static int getCurveIndex(ECParameterSpec params) { static int getCurveIndex(ECParameterSpec params) {
...@@ -162,57 +357,32 @@ final class SupportedEllipticCurvesExtension extends HelloExtension { ...@@ -162,57 +357,32 @@ final class SupportedEllipticCurvesExtension extends HelloExtension {
if (oid == null) { if (oid == null) {
return -1; return -1;
} }
Integer n = curveIndices.get(oid); Integer n = oidToIdMap.get(oid);
return (n == null) ? -1 : n; return (n == null) ? -1 : n;
} }
static String getCurveOid(int index) { static String getCurveOid(int index) {
if ((index > 0) && (index < NAMED_CURVE_OID_TABLE.length)) { return idToOidMap.get(index);
return NAMED_CURVE_OID_TABLE[index];
} }
return null;
}
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 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);
}
}
static { private static String getCurveName(int index) {
curveIndices = new HashMap<String,Integer>(); for (NamedEllipticCurve namedCurve : NamedEllipticCurve.values()) {
for (int i = 1; i < NAMED_CURVE_OID_TABLE.length; i++) { if (namedCurve.id == index) {
curveIndices.put(NAMED_CURVE_OID_TABLE[i], i); return namedCurve.name;
} }
} }
return null;
}
} }
...@@ -603,6 +603,7 @@ public class Main { ...@@ -603,6 +603,7 @@ public class Main {
} }
Manifest man = jf.getManifest(); Manifest man = jf.getManifest();
boolean hasSignature = false;
// The map to record display info, only used when -verbose provided // The map to record display info, only used when -verbose provided
// key: signer info string // key: signer info string
...@@ -618,6 +619,10 @@ public class Main { ...@@ -618,6 +619,10 @@ public class Main {
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
JarEntry je = e.nextElement(); JarEntry je = e.nextElement();
String name = je.getName(); String name = je.getName();
hasSignature = hasSignature
|| SignatureFileVerifier.isBlockOrSF(name);
CodeSigner[] signers = je.getCodeSigners(); CodeSigner[] signers = je.getCodeSigners();
boolean isSigned = (signers != null); boolean isSigned = (signers != null);
anySigned |= isSigned; anySigned |= isSigned;
...@@ -757,8 +762,11 @@ public class Main { ...@@ -757,8 +762,11 @@ public class Main {
System.out.println(rb.getString("no.manifest.")); System.out.println(rb.getString("no.manifest."));
if (!anySigned) { if (!anySigned) {
System.out.println(rb.getString( if (hasSignature) {
"jar.is.unsigned.signatures.missing.or.not.parsable.")); System.out.println(rb.getString("jar.treated.unsigned"));
} else {
System.out.println(rb.getString("jar.is.unsigned"));
}
} else { } else {
boolean warningAppeared = false; boolean warningAppeared = false;
boolean errorAppeared = false; boolean errorAppeared = false;
......
...@@ -135,8 +135,10 @@ public class Resources extends java.util.ListResourceBundle { ...@@ -135,8 +135,10 @@ public class Resources extends java.util.ListResourceBundle {
{"no.manifest.", "no manifest."}, {"no.manifest.", "no manifest."},
{".Signature.related.entries.","(Signature related entries)"}, {".Signature.related.entries.","(Signature related entries)"},
{".Unsigned.entries.", "(Unsigned entries)"}, {".Unsigned.entries.", "(Unsigned entries)"},
{"jar.is.unsigned.signatures.missing.or.not.parsable.", {"jar.is.unsigned",
"jar is unsigned. (signatures missing or not parsable)"}, "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.", "jar signed."},
{"jar.signed.with.signer.errors.", "jar signed, with signer errors."}, {"jar.signed.with.signer.errors.", "jar signed, with signer errors."},
{"jar.verified.", "jar verified."}, {"jar.verified.", "jar verified."},
......
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,7 +29,6 @@ import java.security.AccessController; ...@@ -29,7 +29,6 @@ import java.security.AccessController;
import java.security.AlgorithmConstraints; import java.security.AlgorithmConstraints;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.Security; import java.security.Security;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
...@@ -45,8 +44,7 @@ public abstract class AbstractAlgorithmConstraints ...@@ -45,8 +44,7 @@ public abstract class AbstractAlgorithmConstraints
} }
// Get algorithm constraints from the specified security property. // Get algorithm constraints from the specified security property.
private static void loadAlgorithmsMap(Map<String, String[]> algorithmsMap, static String[] getAlgorithms(String propertyName) {
String propertyName) {
String property = AccessController.doPrivileged( String property = AccessController.doPrivileged(
new PrivilegedAction<String>() { new PrivilegedAction<String>() {
@Override @Override
...@@ -72,18 +70,7 @@ public abstract class AbstractAlgorithmConstraints ...@@ -72,18 +70,7 @@ public abstract class AbstractAlgorithmConstraints
if (algorithmsInProperty == null) { if (algorithmsInProperty == null) {
algorithmsInProperty = new String[0]; algorithmsInProperty = new String[0];
} }
algorithmsMap.put(propertyName, algorithmsInProperty); return algorithmsInProperty;
}
static String[] getAlgorithms(Map<String, String[]> algorithmsMap,
String propertyName) {
synchronized (algorithmsMap) {
if (!algorithmsMap.containsKey(propertyName)) {
loadAlgorithmsMap(algorithmsMap, propertyName);
}
return algorithmsMap.get(propertyName);
}
} }
static boolean checkAlgorithm(String[] algorithms, String algorithm, static boolean checkAlgorithm(String[] algorithms, String algorithm,
......
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -38,19 +38,7 @@ public class AlgorithmDecomposer { ...@@ -38,19 +38,7 @@ public class AlgorithmDecomposer {
private static final Pattern pattern = private static final Pattern pattern =
Pattern.compile("with|and", Pattern.CASE_INSENSITIVE); Pattern.compile("with|and", Pattern.CASE_INSENSITIVE);
/** private static Set<String> decomposeImpl(String algorithm) {
* Decompose the standard algorithm name into sub-elements.
* <p>
* For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
* so that we can check the "SHA1" and "RSA" algorithm constraints
* separately.
* <p>
* Please override the method if need to support more name pattern.
*/
public Set<String> decompose(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
// algorithm/mode/padding // algorithm/mode/padding
String[] transTockens = transPattern.split(algorithm); String[] transTockens = transPattern.split(algorithm);
...@@ -76,6 +64,24 @@ public class AlgorithmDecomposer { ...@@ -76,6 +64,24 @@ public class AlgorithmDecomposer {
elements.add(token); elements.add(token);
} }
} }
return elements;
}
/**
* Decompose the standard algorithm name into sub-elements.
* <p>
* For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
* so that we can check the "SHA1" and "RSA" algorithm constraints
* separately.
* <p>
* Please override the method if need to support more name pattern.
*/
public Set<String> decompose(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
Set<String> elements = decomposeImpl(algorithm);
// In Java standard algorithm name specification, for different // In Java standard algorithm name specification, for different
// purpose, the SHA-1 and SHA-2 algorithm names are different. For // purpose, the SHA-1 and SHA-2 algorithm names are different. For
...@@ -127,4 +133,40 @@ public class AlgorithmDecomposer { ...@@ -127,4 +133,40 @@ public class AlgorithmDecomposer {
return elements; return elements;
} }
private static void hasLoop(Set<String> elements, String find, String replace) {
if (elements.contains(find)) {
if (!elements.contains(replace)) {
elements.add(replace);
}
elements.remove(find);
}
}
/*
* This decomposes a standard name into sub-elements with a consistent
* message digest algorithm name to avoid overly complicated checking.
*/
public static Set<String> decomposeOneHash(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
Set<String> elements = decomposeImpl(algorithm);
hasLoop(elements, "SHA-1", "SHA1");
hasLoop(elements, "SHA-224", "SHA224");
hasLoop(elements, "SHA-256", "SHA256");
hasLoop(elements, "SHA-384", "SHA384");
hasLoop(elements, "SHA-512", "SHA512");
return elements;
}
/*
* The provided message digest algorithm name will return a consistent
* naming scheme.
*/
public static String hashName(String algorithm) {
return algorithm.replace("-", "");
}
} }
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.io.File;
import java.io.FileInputStream;
import java.security.AccessController;
import java.security.KeyStore;
import java.security.PrivilegedAction;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashSet;
import sun.security.x509.X509CertImpl;
/**
* The purpose of this class is to determine the trust anchor certificates is in
* the cacerts file. This is used for PKIX CertPath checking.
*/
public class AnchorCertificates {
private static final Debug debug = Debug.getInstance("certpath");
private static final String HASH = "SHA-256";
private static HashSet<String> certs;
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
File f = new File(System.getProperty("java.home"),
"lib/security/cacerts");
KeyStore cacerts;
try {
cacerts = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream(f)) {
cacerts.load(fis, "changeit".toCharArray());
certs = new HashSet<>();
Enumeration<String> list = cacerts.aliases();
String alias;
while (list.hasMoreElements()) {
alias = list.nextElement();
// Check if this cert is labeled a trust anchor.
if (alias.contains(" [jdk")) {
X509Certificate cert = (X509Certificate) cacerts
.getCertificate(alias);
certs.add(X509CertImpl.getFingerprint(HASH, cert));
}
}
}
} catch (Exception e) {
if (debug != null) {
debug.println("Error parsing cacerts");
}
e.printStackTrace();
}
return null;
}
});
}
/**
* Checks if a certificate is a trust anchor.
*
* @param cert the certificate to check
* @return true if the certificate is trusted.
*/
public static boolean contains(X509Certificate cert) {
String key = X509CertImpl.getFingerprint(HASH, cert);
boolean result = certs.contains(key);
if (result && debug != null) {
debug.println("AnchorCertificate.contains: matched " +
cert.getSubjectDN());
}
return result;
}
private AnchorCertificates() {}
}
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.security.cert.X509Certificate;
/**
* This class is a wrapper for keeping state and passing objects between PKIX,
* AlgorithmChecker, and DisabledAlgorithmConstraints.
*/
public class CertConstraintParameters {
// A certificate being passed to check against constraints.
private final X509Certificate cert;
// This is true if the trust anchor in the certificate chain matches a cert
// in AnchorCertificates
private final boolean trustedMatch;
public CertConstraintParameters(X509Certificate c, boolean match) {
cert = c;
trustedMatch = match;
}
public CertConstraintParameters(X509Certificate c) {
this(c, false);
}
// Returns if the trust anchor has a match if anchor checking is enabled.
public boolean isTrustedMatch() {
return trustedMatch;
}
public X509Certificate getCertificate() {
return cert;
}
}
/* /*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,12 +28,14 @@ package sun.security.util; ...@@ -28,12 +28,14 @@ package sun.security.util;
import java.security.CryptoPrimitive; import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.Key; import java.security.Key;
import java.util.Locale; import java.security.cert.CertPathValidatorException;
import java.util.Set; import java.security.cert.CertPathValidatorException.BasicReason;
import java.util.Collections; import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.Matcher; import java.util.regex.Matcher;
...@@ -44,6 +46,7 @@ import java.util.regex.Matcher; ...@@ -44,6 +46,7 @@ import java.util.regex.Matcher;
* for the syntax of the disabled algorithm string. * for the syntax of the disabled algorithm string.
*/ */
public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
private static final Debug debug = Debug.getInstance("certpath");
// the known security property, jdk.certpath.disabledAlgorithms // the known security property, jdk.certpath.disabledAlgorithms
public final static String PROPERTY_CERTPATH_DISABLED_ALGS = public final static String PROPERTY_CERTPATH_DISABLED_ALGS =
...@@ -53,17 +56,12 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -53,17 +56,12 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
public final static String PROPERTY_TLS_DISABLED_ALGS = public final static String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms"; "jdk.tls.disabledAlgorithms";
private final static Map<String, String[]> disabledAlgorithmsMap =
new HashMap<>();
private final static Map<String, KeySizeConstraints> keySizeConstraintsMap =
new HashMap<>();
// the known security property, jdk.jar.disabledAlgorithms // the known security property, jdk.jar.disabledAlgorithms
public static final String PROPERTY_JAR_DISABLED_ALGS = public static final String PROPERTY_JAR_DISABLED_ALGS =
"jdk.jar.disabledAlgorithms"; "jdk.jar.disabledAlgorithms";
private final String[] disabledAlgorithms; private final String[] disabledAlgorithms;
private final KeySizeConstraints keySizeConstraints; private final Constraints algorithmConstraints;
/** /**
* Initialize algorithm constraints with the specified security property. * Initialize algorithm constraints with the specified security property.
...@@ -86,11 +84,14 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -86,11 +84,14 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
public DisabledAlgorithmConstraints(String propertyName, public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) { AlgorithmDecomposer decomposer) {
super(decomposer); super(decomposer);
disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName); disabledAlgorithms = getAlgorithms(propertyName);
keySizeConstraints = getKeySizeConstraints(disabledAlgorithms, algorithmConstraints = new Constraints(disabledAlgorithms);
propertyName);
} }
/*
* This only checks if the algorithm has been completely disabled. If
* there are keysize or other limit, this method allow the algorithm.
*/
@Override @Override
final public boolean permits(Set<CryptoPrimitive> primitives, final public boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters) { String algorithm, AlgorithmParameters parameters) {
...@@ -103,11 +104,19 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -103,11 +104,19 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return checkAlgorithm(disabledAlgorithms, algorithm, decomposer); return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
} }
/*
* Checks if the key algorithm has been disabled or constraints have been
* placed on the key.
*/
@Override @Override
final public boolean permits(Set<CryptoPrimitive> primitives, Key key) { final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
return checkConstraints(primitives, "", key, null); return checkConstraints(primitives, "", key, null);
} }
/*
* Checks if the key algorithm has been disabled or if constraints have
* been placed on the key.
*/
@Override @Override
final public boolean permits(Set<CryptoPrimitive> primitives, final public boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) { String algorithm, Key key, AlgorithmParameters parameters) {
...@@ -119,7 +128,39 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -119,7 +128,39 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return checkConstraints(primitives, algorithm, key, parameters); return checkConstraints(primitives, algorithm, key, parameters);
} }
// Check algorithm constraints /*
* Check if a x509Certificate object is permitted. Check if all
* algorithms are allowed, certificate constraints, and the
* public key against key constraints.
*
* Uses new style permit() which throws exceptions.
*/
public final void permits(Set<CryptoPrimitive> primitives,
CertConstraintParameters cp) throws CertPathValidatorException {
checkConstraints(primitives, cp);
}
/*
* Check if Certificate object is within the constraints.
* Uses new style permit() which throws exceptions.
*/
public final void permits(Set<CryptoPrimitive> primitives,
X509Certificate cert) throws CertPathValidatorException {
checkConstraints(primitives, new CertConstraintParameters(cert));
}
// Check if a string is contained inside the property
public boolean checkProperty(String param) {
param = param.toLowerCase(Locale.ENGLISH);
for (String block : disabledAlgorithms) {
if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
return true;
}
}
return false;
}
// Check algorithm constraints with key and algorithm
private boolean checkConstraints(Set<CryptoPrimitive> primitives, private boolean checkConstraints(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) { String algorithm, Key key, AlgorithmParameters parameters) {
...@@ -128,7 +169,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -128,7 +169,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
throw new IllegalArgumentException("The key cannot be null"); throw new IllegalArgumentException("The key cannot be null");
} }
// check the target algorithm // check the signature algorithm
if (algorithm != null && algorithm.length() != 0) { if (algorithm != null && algorithm.length() != 0) {
if (!permits(primitives, algorithm, parameters)) { if (!permits(primitives, algorithm, parameters)) {
return false; return false;
...@@ -141,97 +182,203 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -141,97 +182,203 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
// check the key constraints // check the key constraints
if (keySizeConstraints.disables(key)) { return algorithmConstraints.permits(key);
return false;
} }
return true; /*
} * Check algorithm constraints with Certificate
* Uses new style permit() which throws exceptions.
*/
private void checkConstraints(Set<CryptoPrimitive> primitives,
CertConstraintParameters cp) throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
String algorithm = cert.getSigAlgName();
private static KeySizeConstraints getKeySizeConstraints( // Check signature algorithm is not disabled
String[] disabledAlgorithms, String propertyName) { if (!permits(primitives, algorithm, null)) {
synchronized (keySizeConstraintsMap) { throw new CertPathValidatorException(
if(!keySizeConstraintsMap.containsKey(propertyName)) { "Algorithm constraints check failed on disabled "+
// map the key constraints "signature algorithm: " + algorithm,
KeySizeConstraints keySizeConstraints = null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
new KeySizeConstraints(disabledAlgorithms);
keySizeConstraintsMap.put(propertyName, keySizeConstraints);
} }
return keySizeConstraintsMap.get(propertyName); // Check key algorithm is not disabled
if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on disabled "+
"public key algorithm: " + algorithm,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
// Check the certificate and key constraints
algorithmConstraints.permits(cp);
} }
/** /**
* key constraints * Key and Certificate Constraints
*
* The complete disabling of an algorithm is not handled by Constraints or
* Constraint classes. That is addressed with
* permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
*
* When passing a Key to permit(), the boolean return values follow the
* same as the interface class AlgorithmConstraints.permit(). This is to
* maintain compatibility:
* 'true' means the operation is allowed.
* 'false' means it failed the constraints and is disallowed.
*
* When passing CertConstraintParameters through permit(), an exception
* will be thrown on a failure to better identify why the operation was
* disallowed.
*/ */
private static class KeySizeConstraints {
private static final Pattern pattern = Pattern.compile(
"(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
private Map<String, Set<KeySizeConstraint>> constraintsMap = private static class Constraints {
Collections.synchronizedMap( private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
new HashMap<String, Set<KeySizeConstraint>>()); private static final Pattern keySizePattern = Pattern.compile(
"keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
public KeySizeConstraints(String[] restrictions) { public Constraints(String[] constraintArray) {
for (String restriction : restrictions) { for (String constraintEntry : constraintArray) {
if (restriction == null || restriction.isEmpty()) { if (constraintEntry == null || constraintEntry.isEmpty()) {
continue; continue;
} }
Matcher matcher = pattern.matcher(restriction); constraintEntry = constraintEntry.trim();
if (matcher.matches()) { if (debug != null) {
String algorithm = matcher.group(1); debug.println("Constraints: " + constraintEntry);
}
// Check if constraint is a complete disabling of an
// algorithm or has conditions.
String algorithm;
String policy;
int space = constraintEntry.indexOf(' ');
if (space > 0) {
algorithm = AlgorithmDecomposer.hashName(
constraintEntry.substring(0, space).
toUpperCase(Locale.ENGLISH));
policy = constraintEntry.substring(space + 1);
} else {
constraintsMap.computeIfAbsent(
constraintEntry.toUpperCase(Locale.ENGLISH),
k -> new HashSet<>());
continue;
}
KeySizeConstraint.Operator operator = // Convert constraint conditions into Constraint classes
KeySizeConstraint.Operator.of(matcher.group(2)); Constraint c, lastConstraint = null;
int length = Integer.parseInt(matcher.group(3)); // Allow only one jdkCA entry per constraint entry
boolean jdkCALimit = false;
algorithm = algorithm.toLowerCase(Locale.ENGLISH); for (String entry : policy.split("&")) {
entry = entry.trim();
synchronized (constraintsMap) { Matcher matcher = keySizePattern.matcher(entry);
if (!constraintsMap.containsKey(algorithm)) { if (matcher.matches()) {
constraintsMap.put(algorithm, if (debug != null) {
new HashSet<KeySizeConstraint>()); debug.println("Constraints set to keySize: " +
entry);
} }
c = new KeySizeConstraint(algorithm,
KeySizeConstraint.Operator.of(matcher.group(1)),
Integer.parseInt(matcher.group(2)));
Set<KeySizeConstraint> constraintSet = } else if (entry.equalsIgnoreCase("jdkCA")) {
constraintsMap.get(algorithm); if (debug != null) {
KeySizeConstraint constraint = debug.println("Constraints set to jdkCA.");
new KeySizeConstraint(operator, length); }
constraintSet.add(constraint); if (jdkCALimit) {
throw new IllegalArgumentException("Only one " +
"jdkCA entry allowed in property. " +
"Constraint: " + constraintEntry);
} }
c = new jdkCAConstraint(algorithm);
jdkCALimit = true;
} else {
throw new IllegalArgumentException("Error in security" +
" property. Constraint unknown: " + entry);
}
// Link multiple conditions for a single constraint
// into a linked list.
if (lastConstraint == null) {
if (!constraintsMap.containsKey(algorithm)) {
constraintsMap.putIfAbsent(algorithm,
new HashSet<>());
} }
constraintsMap.get(algorithm).add(c);
} else {
lastConstraint.nextConstraint = c;
} }
lastConstraint = c;
}
}
}
// Get applicable constraints based off the signature algorithm
private Set<Constraint> getConstraints(String algorithm) {
return constraintsMap.get(algorithm);
} }
// Does this KeySizeConstraints disable the specified key? // Check if KeySizeConstraints permit the specified key
public boolean disables(Key key) { public boolean permits(Key key) {
String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH); Set<Constraint> set = getConstraints(key.getAlgorithm());
synchronized (constraintsMap) { if (set == null) {
if (constraintsMap.containsKey(algorithm)) {
Set<KeySizeConstraint> constraintSet =
constraintsMap.get(algorithm);
for (KeySizeConstraint constraint : constraintSet) {
if (constraint.disables(key)) {
return true; return true;
} }
for (Constraint constraint : set) {
if (!constraint.permits(key)) {
if (debug != null) {
debug.println("keySizeConstraint: failed key " +
"constraint check " + KeyUtil.getKeySize(key));
}
return false;
} }
} }
return true;
} }
return false; // Check if constraints permit this cert.
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
if (debug != null) {
debug.println("Constraints.permits(): " + cert.getSigAlgName());
} }
// Get all signature algorithms to check for constraints
Set<String> algorithms =
AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
if (algorithms == null || algorithms.isEmpty()) {
return;
} }
/** // Attempt to add the public key algorithm to the set
* Key size constraint. algorithms.add(cert.getPublicKey().getAlgorithm());
*
* e.g. "keysize <= 1024" // Check all applicable constraints
*/ for (String algorithm : algorithms) {
private static class KeySizeConstraint { Set<Constraint> set = getConstraints(algorithm);
if (set == null) {
continue;
}
for (Constraint constraint : set) {
constraint.permits(cp);
}
}
}
}
// Abstract class for algorithm constraint checking
private abstract static class Constraint {
String algorithm;
Constraint nextConstraint = null;
// operator // operator
static enum Operator { enum Operator {
EQ, // "==" EQ, // "=="
NE, // "!=" NE, // "!="
LT, // "<" LT, // "<"
...@@ -255,16 +402,77 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -255,16 +402,77 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return GE; return GE;
} }
throw new IllegalArgumentException( throw new IllegalArgumentException("Error in security " +
s + " is not a legal Operator"); "property. " + s + " is not a legal Operator");
}
}
/**
* Check if an algorithm constraint permit this key to be used.
* @param key Public key
* @return true if constraints do not match
*/
public boolean permits(Key key) {
return true;
}
/**
* Check if an algorithm constraint is permit this certificate to
* be used.
* @param cp CertificateParameter containing certificate and state info
* @return true if constraints do not match
*/
public abstract void permits(CertConstraintParameters cp)
throws CertPathValidatorException;
}
/*
* This class contains constraints dealing with the certificate chain
* of the certificate.
*/
private static class jdkCAConstraint extends Constraint {
jdkCAConstraint(String algo) {
algorithm = algo;
}
/*
* Check if each constraint fails and check if there is a linked
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
if (debug != null) {
debug.println("jdkCAConstraints.permits(): " + algorithm);
}
// Return false if the chain has a trust anchor in cacerts
if (cp.isTrustedMatch()) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
"anchor limits",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
} }
}
/*
* This class contains constraints dealing with the key size
* support limits per algorithm. e.g. "keySize <= 1024"
*/
private static class KeySizeConstraint extends Constraint {
private int minSize; // the minimal available key size private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes private int prohibitedSize = -1; // unavailable key sizes
public KeySizeConstraint(Operator operator, int length) { public KeySizeConstraint(String algo, Operator operator, int length) {
algorithm = algo;
switch (operator) { switch (operator) {
case EQ: // an unavailable key size case EQ: // an unavailable key size
this.minSize = 0; this.minSize = 0;
...@@ -298,21 +506,59 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -298,21 +506,59 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
} }
// Does this key constraint disable the specified key? /*
public boolean disables(Key key) { * If we are passed a certificate, extract the public key and use it.
int size = KeyUtil.getKeySize(key); *
* Check if each constraint fails and check if there is a linked
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
if (!permitsImpl(cp.getCertificate().getPublicKey())) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on keysize limits",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
// Check if key constraint disable the specified key
// Uses old style permit()
public boolean permits(Key key) {
// If we recursively find a constraint that permits us to use
// this key, return true and skip any other constraint checks.
if (nextConstraint != null && nextConstraint.permits(key)) {
return true;
}
if (debug != null) {
debug.println("KeySizeConstraints.permits(): " + algorithm);
}
return permitsImpl(key);
}
private boolean permitsImpl(Key key) {
// Verify this constraint is for this public key algorithm
if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
return true;
}
int size = KeyUtil.getKeySize(key);
if (size == 0) { if (size == 0) {
return true; // we don't allow any key of size 0. return false; // we don't allow any key of size 0.
} else if (size > 0) { } else if (size > 0) {
return ((size < minSize) || (size > maxSize) || return !((size < minSize) || (size > maxSize) ||
(prohibitedSize == size)); (prohibitedSize == size));
} // Otherwise, the key size is not accessible. Conservatively, } // Otherwise, the key size is not accessible. Conservatively,
// please don't disable such keys. // please don't disable such keys.
return false; return true;
}
} }
} }
}
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,8 +28,6 @@ package sun.security.util; ...@@ -28,8 +28,6 @@ package sun.security.util;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.CryptoPrimitive; import java.security.CryptoPrimitive;
import java.security.Key; import java.security.Key;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms; import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms;
...@@ -42,15 +40,12 @@ public class LegacyAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -42,15 +40,12 @@ public class LegacyAlgorithmConstraints extends AbstractAlgorithmConstraints {
public final static String PROPERTY_TLS_LEGACY_ALGS = public final static String PROPERTY_TLS_LEGACY_ALGS =
"jdk.tls.legacyAlgorithms"; "jdk.tls.legacyAlgorithms";
private final static Map<String, String[]> legacyAlgorithmsMap =
new HashMap<>();
private final String[] legacyAlgorithms; private final String[] legacyAlgorithms;
public LegacyAlgorithmConstraints(String propertyName, public LegacyAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) { AlgorithmDecomposer decomposer) {
super(decomposer); super(decomposer);
legacyAlgorithms = getAlgorithms(legacyAlgorithmsMap, propertyName); legacyAlgorithms = getAlgorithms(propertyName);
} }
@Override @Override
......
...@@ -1932,18 +1932,19 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { ...@@ -1932,18 +1932,19 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
public String getFingerprint(String algorithm) { public String getFingerprint(String algorithm) {
return fingerprints.computeIfAbsent(algorithm, return fingerprints.computeIfAbsent(algorithm,
x -> getCertificateFingerPrint(x)); x -> getFingerprint(x, this));
} }
/** /**
* Gets the requested finger print of the certificate. The result * Gets the requested finger print of the certificate. The result
* only contains 0-9 and A-F. No small case, no colon. * only contains 0-9 and A-F. No small case, no colon.
*/ */
private String getCertificateFingerPrint(String mdAlg) { public static String getFingerprint(String algorithm,
X509Certificate cert) {
String fingerPrint = ""; String fingerPrint = "";
try { try {
byte[] encCertInfo = getEncoded(); byte[] encCertInfo = cert.getEncoded();
MessageDigest md = MessageDigest.getInstance(mdAlg); MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] digest = md.digest(encCertInfo); byte[] digest = md.digest(encCertInfo);
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
for (int i = 0; i < digest.length; i++) { for (int i = 0; i < digest.length; i++) {
......
...@@ -429,13 +429,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -429,13 +429,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -452,6 +452,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -452,6 +452,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -474,6 +477,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -474,6 +477,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
...@@ -482,7 +508,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -482,7 +508,7 @@ krb5.kdc.bad.policy = tryLast
# #
# #
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ 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 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS) processing # (SSL/TLS) processing
...@@ -505,12 +531,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -505,12 +531,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# See the specification of "jdk.certpath.disabledAlgorithms" for the # See the specification of "jdk.certpath.disabledAlgorithms" for the
# syntax of the disabled algorithm string. # 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. # It is not guaranteed to be examined and used by other implementations.
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 # 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) # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation. # processing in JSSE implementation.
...@@ -524,7 +551,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -524,7 +551,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# During SSL/TLS security parameters negotiation, legacy algorithms will # During SSL/TLS security parameters negotiation, legacy algorithms will
# not be negotiated unless there are no other candidates. # 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: # BNF-style:
# LegacyAlgorithms: # LegacyAlgorithms:
# " LegacyAlgorithm { , LegacyAlgorithm } " # " LegacyAlgorithm { , LegacyAlgorithm } "
...@@ -554,7 +581,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -554,7 +581,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# See SSL/TLS specifications and "Java Cryptography Architecture Standard # See SSL/TLS specifications and "Java Cryptography Architecture Standard
# Algorithm Name Documentation" for information about the algorithm names. # 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. # 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 # There is no guarantee the property will continue to exist or be of the
# same syntax in future releases. # same syntax in future releases.
...@@ -567,7 +594,8 @@ jdk.tls.legacyAlgorithms= \ ...@@ -567,7 +594,8 @@ jdk.tls.legacyAlgorithms= \
DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \
DH_RSA_EXPORT, RSA_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \
DH_anon, ECDH_anon, \ 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) # The pre-defined default finite field Diffie-Hellman ephemeral (DHE)
# parameters for Transport Layer Security (SSL/TLS/DTLS) processing. # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
......
...@@ -429,13 +429,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -429,13 +429,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -452,6 +452,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -452,6 +452,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -474,6 +477,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -474,6 +477,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
...@@ -482,7 +508,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -482,7 +508,7 @@ krb5.kdc.bad.policy = tryLast
# #
# #
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ 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 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS) processing # (SSL/TLS) processing
...@@ -505,12 +531,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -505,12 +531,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# See the specification of "jdk.certpath.disabledAlgorithms" for the # See the specification of "jdk.certpath.disabledAlgorithms" for the
# syntax of the disabled algorithm string. # 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. # It is not guaranteed to be examined and used by other implementations.
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 # 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) # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation. # processing in JSSE implementation.
...@@ -524,7 +551,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -524,7 +551,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# During SSL/TLS security parameters negotiation, legacy algorithms will # During SSL/TLS security parameters negotiation, legacy algorithms will
# not be negotiated unless there are no other candidates. # 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: # BNF-style:
# LegacyAlgorithms: # LegacyAlgorithms:
# " LegacyAlgorithm { , LegacyAlgorithm } " # " LegacyAlgorithm { , LegacyAlgorithm } "
...@@ -554,7 +581,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -554,7 +581,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# See SSL/TLS specifications and "Java Cryptography Architecture Standard # See SSL/TLS specifications and "Java Cryptography Architecture Standard
# Algorithm Name Documentation" for information about the algorithm names. # 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. # 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 # There is no guarantee the property will continue to exist or be of the
# same syntax in future releases. # same syntax in future releases.
...@@ -567,7 +594,8 @@ jdk.tls.legacyAlgorithms= \ ...@@ -567,7 +594,8 @@ jdk.tls.legacyAlgorithms= \
DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \
DH_RSA_EXPORT, RSA_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \
DH_anon, ECDH_anon, \ 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) # The pre-defined default finite field Diffie-Hellman ephemeral (DHE)
# parameters for Transport Layer Security (SSL/TLS/DTLS) processing. # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
......
...@@ -432,13 +432,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -432,13 +432,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -455,6 +455,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -455,6 +455,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -477,6 +480,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -477,6 +480,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
...@@ -485,7 +511,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -485,7 +511,7 @@ krb5.kdc.bad.policy = tryLast
# #
# #
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ 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 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS) processing # (SSL/TLS) processing
...@@ -508,12 +534,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -508,12 +534,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# See the specification of "jdk.certpath.disabledAlgorithms" for the # See the specification of "jdk.certpath.disabledAlgorithms" for the
# syntax of the disabled algorithm string. # 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. # It is not guaranteed to be examined and used by other implementations.
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 # 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) # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation. # processing in JSSE implementation.
...@@ -527,7 +554,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -527,7 +554,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# During SSL/TLS security parameters negotiation, legacy algorithms will # During SSL/TLS security parameters negotiation, legacy algorithms will
# not be negotiated unless there are no other candidates. # 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: # BNF-style:
# LegacyAlgorithms: # LegacyAlgorithms:
# " LegacyAlgorithm { , LegacyAlgorithm } " # " LegacyAlgorithm { , LegacyAlgorithm } "
...@@ -557,7 +584,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -557,7 +584,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# See SSL/TLS specifications and "Java Cryptography Architecture Standard # See SSL/TLS specifications and "Java Cryptography Architecture Standard
# Algorithm Name Documentation" for information about the algorithm names. # 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. # 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 # There is no guarantee the property will continue to exist or be of the
# same syntax in future releases. # same syntax in future releases.
...@@ -570,7 +597,8 @@ jdk.tls.legacyAlgorithms= \ ...@@ -570,7 +597,8 @@ jdk.tls.legacyAlgorithms= \
DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \
DH_RSA_EXPORT, RSA_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \
DH_anon, ECDH_anon, \ 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) # The pre-defined default finite field Diffie-Hellman ephemeral (DHE)
# parameters for Transport Layer Security (SSL/TLS/DTLS) processing. # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
......
...@@ -431,13 +431,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -431,13 +431,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -454,6 +454,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -454,6 +454,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -476,6 +479,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -476,6 +479,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
...@@ -484,7 +510,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -484,7 +510,7 @@ krb5.kdc.bad.policy = tryLast
# #
# #
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ 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 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS) processing # (SSL/TLS) processing
...@@ -507,12 +533,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -507,12 +533,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# See the specification of "jdk.certpath.disabledAlgorithms" for the # See the specification of "jdk.certpath.disabledAlgorithms" for the
# syntax of the disabled algorithm string. # 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. # It is not guaranteed to be examined and used by other implementations.
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 # 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) # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation. # processing in JSSE implementation.
...@@ -526,7 +553,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -526,7 +553,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# During SSL/TLS security parameters negotiation, legacy algorithms will # During SSL/TLS security parameters negotiation, legacy algorithms will
# not be negotiated unless there are no other candidates. # 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: # BNF-style:
# LegacyAlgorithms: # LegacyAlgorithms:
# " LegacyAlgorithm { , LegacyAlgorithm } " # " LegacyAlgorithm { , LegacyAlgorithm } "
...@@ -556,7 +583,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -556,7 +583,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# See SSL/TLS specifications and "Java Cryptography Architecture Standard # See SSL/TLS specifications and "Java Cryptography Architecture Standard
# Algorithm Name Documentation" for information about the algorithm names. # 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. # 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 # There is no guarantee the property will continue to exist or be of the
# same syntax in future releases. # same syntax in future releases.
...@@ -569,7 +596,8 @@ jdk.tls.legacyAlgorithms= \ ...@@ -569,7 +596,8 @@ jdk.tls.legacyAlgorithms= \
DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \
DH_RSA_EXPORT, RSA_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \
DH_anon, ECDH_anon, \ 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) # The pre-defined default finite field Diffie-Hellman ephemeral (DHE)
# parameters for Transport Layer Security (SSL/TLS/DTLS) processing. # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
......
...@@ -432,13 +432,13 @@ krb5.kdc.bad.policy = tryLast ...@@ -432,13 +432,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
...@@ -455,6 +455,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -455,6 +455,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
...@@ -477,6 +480,29 @@ krb5.kdc.bad.policy = tryLast ...@@ -477,6 +480,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
# "jdkCA" prohibits the specified algorithm only if the algorithm is used
# in a certificate chain that terminates at a marked trust anchor in the
# lib/security/cacerts keystore. All other chains are not affected.
# If the jdkCA constraint is not set, then all chains using the
# specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
# Example: To apply this constraint to SHA-1 certificates, include
# the following: "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #
...@@ -485,7 +511,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -485,7 +511,7 @@ krb5.kdc.bad.policy = tryLast
# #
# #
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ 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 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS) processing # (SSL/TLS) processing
...@@ -508,12 +534,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -508,12 +534,13 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# See the specification of "jdk.certpath.disabledAlgorithms" for the # See the specification of "jdk.certpath.disabledAlgorithms" for the
# syntax of the disabled algorithm string. # 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. # It is not guaranteed to be examined and used by other implementations.
# #
# Example: # Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 # 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) # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation. # processing in JSSE implementation.
...@@ -527,7 +554,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -527,7 +554,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# During SSL/TLS security parameters negotiation, legacy algorithms will # During SSL/TLS security parameters negotiation, legacy algorithms will
# not be negotiated unless there are no other candidates. # 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: # BNF-style:
# LegacyAlgorithms: # LegacyAlgorithms:
# " LegacyAlgorithm { , LegacyAlgorithm } " # " LegacyAlgorithm { , LegacyAlgorithm } "
...@@ -557,7 +584,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768 ...@@ -557,7 +584,7 @@ jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
# See SSL/TLS specifications and "Java Cryptography Architecture Standard # See SSL/TLS specifications and "Java Cryptography Architecture Standard
# Algorithm Name Documentation" for information about the algorithm names. # 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. # 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 # There is no guarantee the property will continue to exist or be of the
# same syntax in future releases. # same syntax in future releases.
...@@ -570,7 +597,8 @@ jdk.tls.legacyAlgorithms= \ ...@@ -570,7 +597,8 @@ jdk.tls.legacyAlgorithms= \
DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \ DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \
DH_RSA_EXPORT, RSA_EXPORT, \ DH_RSA_EXPORT, RSA_EXPORT, \
DH_anon, ECDH_anon, \ 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) # The pre-defined default finite field Diffie-Hellman ephemeral (DHE)
# parameters for Transport Layer Security (SSL/TLS/DTLS) processing. # parameters for Transport Layer Security (SSL/TLS/DTLS) processing.
......
...@@ -103,6 +103,9 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this, ...@@ -103,6 +103,9 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
int llen = chunkLen; int llen = chunkLen;
(*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP); (*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);
if ((*env)->ExceptionCheck(env)) {
break;
} else {
while(llen > 0) { while(llen > 0) {
int n = NET_Send(fd, bufP + loff, llen, 0); int n = NET_Send(fd, bufP + loff, llen, 0);
if (n > 0) { if (n > 0) {
...@@ -129,6 +132,7 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this, ...@@ -129,6 +132,7 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
len -= chunkLen; len -= chunkLen;
off += chunkLen; off += chunkLen;
} }
}
if (bufP != BUF) { if (bufP != BUF) {
free(bufP); free(bufP);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -100,7 +100,9 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this, ...@@ -100,7 +100,9 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
int retry = 0; int retry = 0;
(*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP); (*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);
if ((*env)->ExceptionCheck(env)) {
break;
} else {
while(llen > 0) { while(llen > 0) {
int n = send(fd, bufP + loff, llen, 0); int n = send(fd, bufP + loff, llen, 0);
if (n > 0) { if (n > 0) {
...@@ -161,6 +163,7 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this, ...@@ -161,6 +163,7 @@ Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
len -= chunkLen; len -= chunkLen;
off += chunkLen; off += chunkLen;
} }
}
if (bufP != BUF) { if (bufP != BUF) {
free(bufP); free(bufP);
......
...@@ -41,7 +41,8 @@ import javax.net.ssl.SSLSocketFactory; ...@@ -41,7 +41,8 @@ import javax.net.ssl.SSLSocketFactory;
* @bug 8076221 * @bug 8076221
* @summary Check if weak cipher suites are disabled * @summary Check if weak cipher suites are disabled
* @run main/othervm DisabledAlgorithms default * @run main/othervm DisabledAlgorithms default
* @run main/othervm DisabledAlgorithms empty * @run main/othervm -Djdk.tls.namedGroups="secp256r1,secp192r1"
* DisabledAlgorithms empty
*/ */
public class DisabledAlgorithms { public class DisabledAlgorithms {
...@@ -97,6 +98,11 @@ public class DisabledAlgorithms { ...@@ -97,6 +98,11 @@ public class DisabledAlgorithms {
System.out.println("jdk.tls.disabledAlgorithms = " System.out.println("jdk.tls.disabledAlgorithms = "
+ Security.getProperty("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 // check if RC4 cipher suites can be used
// if jdk.tls.disabledAlgorithms is empty // if jdk.tls.disabledAlgorithms is empty
checkSuccess(rc4_ciphersuites); checkSuccess(rc4_ciphersuites);
...@@ -224,6 +230,7 @@ public class DisabledAlgorithms { ...@@ -224,6 +230,7 @@ public class DisabledAlgorithms {
socket.getSession().invalidate(); socket.getSession().invalidate();
} catch (SSLHandshakeException e) { } catch (SSLHandshakeException e) {
System.out.println("Server: run: " + e); System.out.println("Server: run: " + e);
e.printStackTrace();
sslError = true; sslError = true;
stopped = true; stopped = true;
} catch (IOException e) { } catch (IOException e) {
......
/*
* 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;
}
}
}
}
...@@ -90,13 +90,14 @@ public final class OutputAnalyzer { ...@@ -90,13 +90,14 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the string was not found * If the string was not found
*/ */
public void shouldContain(String expectedString) { public OutputAnalyzer shouldContain(String expectedString) {
if (!stdout.contains(expectedString) if (!stdout.contains(expectedString)
&& !stderr.contains(expectedString)) { && !stderr.contains(expectedString)) {
reportDiagnosticSummary(); reportDiagnosticSummary();
throw new RuntimeException("'" + expectedString throw new RuntimeException("'" + expectedString
+ "' missing from stdout/stderr \n"); + "' missing from stdout/stderr \n");
} }
return this;
} }
/** /**
...@@ -107,12 +108,13 @@ public final class OutputAnalyzer { ...@@ -107,12 +108,13 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the string was not found * If the string was not found
*/ */
public void stdoutShouldContain(String expectedString) { public OutputAnalyzer stdoutShouldContain(String expectedString) {
if (!stdout.contains(expectedString)) { if (!stdout.contains(expectedString)) {
reportDiagnosticSummary(); reportDiagnosticSummary();
throw new RuntimeException("'" + expectedString throw new RuntimeException("'" + expectedString
+ "' missing from stdout \n"); + "' missing from stdout \n");
} }
return this;
} }
/** /**
...@@ -123,24 +125,25 @@ public final class OutputAnalyzer { ...@@ -123,24 +125,25 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the string was not found * If the string was not found
*/ */
public void stderrShouldContain(String expectedString) { public OutputAnalyzer stderrShouldContain(String expectedString) {
if (!stderr.contains(expectedString)) { if (!stderr.contains(expectedString)) {
reportDiagnosticSummary(); reportDiagnosticSummary();
throw new RuntimeException("'" + expectedString throw new RuntimeException("'" + expectedString
+ "' missing from stderr \n"); + "' missing from stderr \n");
} }
return this;
} }
/** /**
* Verify that the stdout and stderr contents of output buffer does not * Verify that the stdout and stderr contents of output buffer does not
* contain the string * contain the string
* *
* @param expectedString * @param notExpectedString
* String that the buffer should not contain * String that the buffer should not contain
* @throws RuntimeException * @throws RuntimeException
* If the string was found * If the string was found
*/ */
public void shouldNotContain(String notExpectedString) { public OutputAnalyzer shouldNotContain(String notExpectedString) {
if (stdout.contains(notExpectedString)) { if (stdout.contains(notExpectedString)) {
reportDiagnosticSummary(); reportDiagnosticSummary();
throw new RuntimeException("'" + notExpectedString throw new RuntimeException("'" + notExpectedString
...@@ -151,23 +154,25 @@ public final class OutputAnalyzer { ...@@ -151,23 +154,25 @@ public final class OutputAnalyzer {
throw new RuntimeException("'" + notExpectedString throw new RuntimeException("'" + notExpectedString
+ "' found in stderr \n"); + "' found in stderr \n");
} }
return this;
} }
/** /**
* Verify that the stdout contents of output buffer does not contain the * Verify that the stdout contents of output buffer does not contain the
* string * string
* *
* @param expectedString * @param notExpectedString
* String that the buffer should not contain * String that the buffer should not contain
* @throws RuntimeException * @throws RuntimeException
* If the string was found * If the string was found
*/ */
public void stdoutShouldNotContain(String notExpectedString) { public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) {
if (stdout.contains(notExpectedString)) { if (stdout.contains(notExpectedString)) {
reportDiagnosticSummary(); reportDiagnosticSummary();
throw new RuntimeException("'" + notExpectedString throw new RuntimeException("'" + notExpectedString
+ "' found in stdout \n"); + "' found in stdout \n");
} }
return this;
} }
/** /**
...@@ -195,7 +200,7 @@ public final class OutputAnalyzer { ...@@ -195,7 +200,7 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the pattern was not found * If the pattern was not found
*/ */
public void shouldMatch(String pattern) { public OutputAnalyzer shouldMatch(String pattern) {
Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE) Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
.matcher(stdout); .matcher(stdout);
Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE) Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
...@@ -205,6 +210,7 @@ public final class OutputAnalyzer { ...@@ -205,6 +210,7 @@ public final class OutputAnalyzer {
throw new RuntimeException("'" + pattern throw new RuntimeException("'" + pattern
+ "' missing from stdout/stderr \n"); + "' missing from stdout/stderr \n");
} }
return this;
} }
/** /**
...@@ -214,7 +220,7 @@ public final class OutputAnalyzer { ...@@ -214,7 +220,7 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the pattern was not found * If the pattern was not found
*/ */
public void stdoutShouldMatch(String pattern) { public OutputAnalyzer stdoutShouldMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
stdout); stdout);
if (!matcher.find()) { if (!matcher.find()) {
...@@ -222,6 +228,7 @@ public final class OutputAnalyzer { ...@@ -222,6 +228,7 @@ public final class OutputAnalyzer {
throw new RuntimeException("'" + pattern throw new RuntimeException("'" + pattern
+ "' missing from stdout \n"); + "' missing from stdout \n");
} }
return this;
} }
/** /**
...@@ -231,7 +238,7 @@ public final class OutputAnalyzer { ...@@ -231,7 +238,7 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the pattern was not found * If the pattern was not found
*/ */
public void stderrShouldMatch(String pattern) { public OutputAnalyzer stderrShouldMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
stderr); stderr);
if (!matcher.find()) { if (!matcher.find()) {
...@@ -239,6 +246,7 @@ public final class OutputAnalyzer { ...@@ -239,6 +246,7 @@ public final class OutputAnalyzer {
throw new RuntimeException("'" + pattern throw new RuntimeException("'" + pattern
+ "' missing from stderr \n"); + "' missing from stderr \n");
} }
return this;
} }
/** /**
...@@ -249,7 +257,7 @@ public final class OutputAnalyzer { ...@@ -249,7 +257,7 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the pattern was found * If the pattern was found
*/ */
public void shouldNotMatch(String pattern) { public OutputAnalyzer shouldNotMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
stdout); stdout);
if (matcher.find()) { if (matcher.find()) {
...@@ -263,6 +271,7 @@ public final class OutputAnalyzer { ...@@ -263,6 +271,7 @@ public final class OutputAnalyzer {
throw new RuntimeException("'" + pattern + "' found in stderr: '" throw new RuntimeException("'" + pattern + "' found in stderr: '"
+ matcher.group() + "' \n"); + matcher.group() + "' \n");
} }
return this;
} }
/** /**
...@@ -273,13 +282,14 @@ public final class OutputAnalyzer { ...@@ -273,13 +282,14 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the pattern was found * If the pattern was found
*/ */
public void stdoutShouldNotMatch(String pattern) { public OutputAnalyzer stdoutShouldNotMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
stdout); stdout);
if (matcher.find()) { if (matcher.find()) {
reportDiagnosticSummary(); reportDiagnosticSummary();
throw new RuntimeException("'" + pattern + "' found in stdout \n"); throw new RuntimeException("'" + pattern + "' found in stdout \n");
} }
return this;
} }
/** /**
...@@ -290,13 +300,14 @@ public final class OutputAnalyzer { ...@@ -290,13 +300,14 @@ public final class OutputAnalyzer {
* @throws RuntimeException * @throws RuntimeException
* If the pattern was found * If the pattern was found
*/ */
public void stderrShouldNotMatch(String pattern) { public OutputAnalyzer stderrShouldNotMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher( Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
stderr); stderr);
if (matcher.find()) { if (matcher.find()) {
reportDiagnosticSummary(); reportDiagnosticSummary();
throw new RuntimeException("'" + pattern + "' found in stderr \n"); throw new RuntimeException("'" + pattern + "' found in stderr \n");
} }
return this;
} }
/** /**
...@@ -344,12 +355,13 @@ public final class OutputAnalyzer { ...@@ -344,12 +355,13 @@ public final class OutputAnalyzer {
* If the exit value from the process did not match the expected * If the exit value from the process did not match the expected
* value * value
*/ */
public void shouldHaveExitValue(int expectedExitValue) { public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) {
if (getExitValue() != expectedExitValue) { if (getExitValue() != expectedExitValue) {
reportDiagnosticSummary(); reportDiagnosticSummary();
throw new RuntimeException("Expected to get exit value of [" throw new RuntimeException("Expected to get exit value of ["
+ expectedExitValue + "]\n"); + expectedExitValue + "]\n");
} }
return this;
} }
/** /**
...@@ -357,11 +369,12 @@ public final class OutputAnalyzer { ...@@ -357,11 +369,12 @@ public final class OutputAnalyzer {
* - standard input produced by the process under test - standard output - * - standard input produced by the process under test - standard output -
* exit code Note: the command line is printed by the ProcessTools * exit code Note: the command line is printed by the ProcessTools
*/ */
private void reportDiagnosticSummary() { private OutputAnalyzer reportDiagnosticSummary() {
String msg = " stdout: [" + stdout + "];\n" + " stderr: [" + stderr String msg = " stdout: [" + stdout + "];\n" + " stderr: [" + stderr
+ "]\n" + " exitValue = " + getExitValue() + "\n"; + "]\n" + " exitValue = " + getExitValue() + "\n";
System.err.println(msg); System.err.println(msg);
return this;
} }
/** /**
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
* @library ../pkcs11/sslecc * @library ../pkcs11/sslecc
* @library ../../../java/security/testlibrary * @library ../../../java/security/testlibrary
* @compile -XDignore.symbol.file TestEC.java * @compile -XDignore.symbol.file TestEC.java
* @run main/othervm TestEC * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
*/ */
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
......
...@@ -33,7 +33,8 @@ ...@@ -33,7 +33,8 @@
* @author Andreas Sterbenz * @author Andreas Sterbenz
* @library .. * @library ..
* @library ../../../../java/security/testlibrary * @library ../../../../java/security/testlibrary
* @run main/othervm ClientJSSEServerJSSE * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1"
* ClientJSSEServerJSSE
*/ */
import java.security.*; import java.security.*;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* @bug 7188657 * @bug 7188657
* @summary There should be a way to reorder the JSSE ciphers * @summary There should be a way to reorder the JSSE ciphers
* @run main/othervm UseCipherSuitesOrder * @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.*; import java.io.*;
......
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
* @bug 4496785 * @bug 4496785
* @summary Verify that all ciphersuites work in all configurations * @summary Verify that all ciphersuites work in all configurations
* @author Andreas Sterbenz * @author Andreas Sterbenz
* @run main/othervm/timeout=300 ClientJSSEServerJSSE * @run main/othervm/timeout=300 -Djdk.tls.namedGroups="secp256r1,secp192r1"
* ClientJSSEServerJSSE
*/ */
import java.security.Security; import java.security.Security;
......
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
*/ */
import jdk.testlibrary.OutputAnalyzer; import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.ProcessTools;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
* Base class. * Base class.
...@@ -175,4 +180,21 @@ public abstract class Test { ...@@ -175,4 +180,21 @@ public abstract class Test {
} }
analyzer.shouldContain(JAR_SIGNED); 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()]));
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册