提交 aea2268c 编写于 作者: C coffeys

8148516: Improve the default strength of EC in JDK

Reviewed-by: xuelei
上级 72c4152a
/* /*
* 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;
}
} }
...@@ -508,7 +508,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -508,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
...@@ -536,7 +536,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -536,7 +536,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# #
# 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.
......
...@@ -508,7 +508,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -508,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
...@@ -536,7 +536,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -536,7 +536,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# #
# 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.
......
...@@ -511,7 +511,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -511,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
...@@ -539,7 +539,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -539,7 +539,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# #
# 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.
......
...@@ -510,7 +510,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -510,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
...@@ -538,7 +538,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -538,7 +538,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# #
# 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.
......
...@@ -511,7 +511,7 @@ krb5.kdc.bad.policy = tryLast ...@@ -511,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
...@@ -539,7 +539,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ ...@@ -539,7 +539,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
# #
# 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.
......
...@@ -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;
}
}
}
}
...@@ -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.*;
......
...@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册