提交 fdb1d842 编写于 作者: I igerasim

8140436: Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for TLS

Reviewed-by: valeriep, jnimeh, apetcher
上级 6a158108
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, 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
......@@ -42,6 +42,7 @@ import static sun.security.ssl.CipherSuite.KeyExchange.*;
import static sun.security.ssl.CipherSuite.PRF.*;
import static sun.security.ssl.CipherSuite.CipherType.*;
import static sun.security.ssl.JsseJce.*;
import static sun.security.ssl.NamedGroupType.*;
/**
* An SSL/TLS CipherSuite. Constants for the standard key exchange, cipher,
......@@ -326,38 +327,38 @@ final class CipherSuite implements Comparable<CipherSuite> {
static enum KeyExchange {
// key exchange algorithms
K_NULL ("NULL", false, false),
K_RSA ("RSA", true, false),
K_RSA_EXPORT ("RSA_EXPORT", true, false),
K_DH_RSA ("DH_RSA", false, false),
K_DH_DSS ("DH_DSS", false, false),
K_DHE_DSS ("DHE_DSS", true, false),
K_DHE_RSA ("DHE_RSA", true, false),
K_DH_ANON ("DH_anon", true, false),
K_ECDH_ECDSA ("ECDH_ECDSA", ALLOW_ECC, true),
K_ECDH_RSA ("ECDH_RSA", ALLOW_ECC, true),
K_ECDHE_ECDSA("ECDHE_ECDSA", ALLOW_ECC, true),
K_ECDHE_RSA ("ECDHE_RSA", ALLOW_ECC, true),
K_ECDH_ANON ("ECDH_anon", ALLOW_ECC, true),
K_NULL ("NULL", false, NAMED_GROUP_NONE),
K_RSA ("RSA", true, NAMED_GROUP_NONE),
K_RSA_EXPORT ("RSA_EXPORT", true, NAMED_GROUP_NONE),
K_DH_RSA ("DH_RSA", false, NAMED_GROUP_NONE),
K_DH_DSS ("DH_DSS", false, NAMED_GROUP_NONE),
K_DHE_DSS ("DHE_DSS", true, NAMED_GROUP_FFDHE),
K_DHE_RSA ("DHE_RSA", true, NAMED_GROUP_FFDHE),
K_DH_ANON ("DH_anon", true, NAMED_GROUP_FFDHE),
K_ECDH_ECDSA ("ECDH_ECDSA", ALLOW_ECC, NAMED_GROUP_ECDHE),
K_ECDH_RSA ("ECDH_RSA", ALLOW_ECC, NAMED_GROUP_ECDHE),
K_ECDHE_ECDSA("ECDHE_ECDSA", ALLOW_ECC, NAMED_GROUP_ECDHE),
K_ECDHE_RSA ("ECDHE_RSA", ALLOW_ECC, NAMED_GROUP_ECDHE),
K_ECDH_ANON ("ECDH_anon", ALLOW_ECC, NAMED_GROUP_ECDHE),
// Kerberos cipher suites
K_KRB5 ("KRB5", true, false),
K_KRB5_EXPORT("KRB5_EXPORT", true, false),
K_KRB5 ("KRB5", true, NAMED_GROUP_NONE),
K_KRB5_EXPORT("KRB5_EXPORT", true, NAMED_GROUP_NONE),
// renegotiation protection request signaling cipher suite
K_SCSV ("SCSV", true, false);
K_SCSV ("SCSV", true, NAMED_GROUP_NONE);
// name of the key exchange algorithm, e.g. DHE_DSS
final String name;
final boolean allowed;
final boolean isEC;
final NamedGroupType groupType;
private final boolean alwaysAvailable;
KeyExchange(String name, boolean allowed, boolean isEC) {
KeyExchange(String name, boolean allowed, NamedGroupType groupType) {
this.name = name;
this.allowed = allowed;
this.isEC = isEC;
this.groupType = groupType;
this.alwaysAvailable = allowed &&
(!name.startsWith("EC")) && (!name.startsWith("KRB"));
}
......@@ -367,7 +368,7 @@ final class CipherSuite implements Comparable<CipherSuite> {
return true;
}
if (isEC) {
if (groupType == NAMED_GROUP_ECDHE) {
return (allowed && JsseJce.isEcAvailable());
} else if (name.startsWith("KRB")) {
return (allowed && JsseJce.isKerberosAvailable());
......
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, 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
......@@ -30,6 +30,7 @@ import java.io.*;
import java.util.*;
import javax.net.ssl.SSLException;
import static sun.security.ssl.NamedGroupType.*;
/**
* A list of CipherSuites. Also maintains the lists of supported and
......@@ -42,15 +43,16 @@ final class CipherSuiteList {
private final Collection<CipherSuite> cipherSuites;
private String[] suiteNames;
// flag indicating whether this list contains any ECC ciphersuites.
// null if not yet checked.
private volatile Boolean containsEC;
private final EnumSet<NamedGroupType> groupsTypes =
EnumSet.noneOf(NamedGroupType.class);
// for use by buildAvailableCache() and
// Handshaker.getKickstartMessage() only
CipherSuiteList(Collection<CipherSuite> cipherSuites) {
this.cipherSuites = cipherSuites;
for (CipherSuite suite : cipherSuites) {
updateGroupTypes(suite);
}
}
/**
......@@ -59,6 +61,7 @@ final class CipherSuiteList {
CipherSuiteList(CipherSuite suite) {
cipherSuites = new ArrayList<CipherSuite>(1);
cipherSuites.add(suite);
updateGroupTypes(suite);
}
/**
......@@ -82,6 +85,7 @@ final class CipherSuiteList {
+ suiteName + " with currently installed providers");
}
cipherSuites.add(suite);
updateGroupTypes(suite);
}
}
......@@ -97,7 +101,20 @@ final class CipherSuiteList {
}
cipherSuites = new ArrayList<CipherSuite>(bytes.length >> 1);
for (int i = 0; i < bytes.length; i += 2) {
cipherSuites.add(CipherSuite.valueOf(bytes[i], bytes[i+1]));
CipherSuite suite = CipherSuite.valueOf(bytes[i], bytes[i+1]);
cipherSuites.add(suite);
updateGroupTypes(suite);
}
}
// Please don't use this method except constructors.
private void updateGroupTypes(CipherSuite cipherSuite) {
if (cipherSuite.keyExchange != null && (!cipherSuite.exportable)) {
NamedGroupType groupType = cipherSuite.keyExchange.groupType;
if ((groupType != NAMED_GROUP_NONE) &&
(!groupsTypes.contains(groupType))) {
groupsTypes.add(groupType);
}
}
}
......@@ -108,20 +125,9 @@ final class CipherSuiteList {
return cipherSuites.contains(suite);
}
// Return whether this list contains any ECC ciphersuites
boolean containsEC() {
if (containsEC == null) {
for (CipherSuite c : cipherSuites) {
if (c.keyExchange.isEC) {
containsEC = true;
return true;
}
}
containsEC = false;
}
return containsEC;
// Return whether this list contains cipher suites of a named group type.
boolean contains(NamedGroupType groupType) {
return groupsTypes.contains(groupType);
}
/**
......
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
......@@ -141,6 +141,10 @@ final class ClientHandshaker extends Handshaker {
private final static boolean allowUnsafeServerCertChange =
Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
// To switch off the supported_groups extension for DHE cipher suite.
private static final boolean enableFFDHE =
Debug.getBooleanProperty("jsse.enableFFDHE", true);
private List<SNIServerName> requestedServerNames =
Collections.<SNIServerName>emptyList();
......@@ -649,10 +653,12 @@ final class ClientHandshaker extends Handshaker {
ExtensionType type = ext.type;
if (type == ExtensionType.EXT_SERVER_NAME) {
serverNamesAccepted = true;
} else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
} else if ((type != ExtensionType.EXT_SUPPORTED_GROUPS)
&& (type != ExtensionType.EXT_EC_POINT_FORMATS)
&& (type != ExtensionType.EXT_SERVER_NAME)
&& (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
// Note: Better to check client requested extensions rather
// than all supported extensions.
fatalSE(Alerts.alert_unsupported_extension,
"Server sent an unsupported extension: " + type);
}
......@@ -701,6 +707,17 @@ final class ClientHandshaker extends Handshaker {
* our own D-H algorithm object so we can defer key calculations
* until after we've sent the client key exchange message (which
* gives client and server some useful parallelism).
*
* Note per section 3 of RFC 7919, if the server is not compatible with
* FFDHE specification, the client MAY decide to continue the connection
* if the selected DHE group is acceptable under local policy, or it MAY
* decide to terminate the connection with a fatal insufficient_security
* (71) alert. The algorithm constraints mechanism is JDK local policy
* used for additional DHE parameters checking. So this implementation
* does not check the server compatibility and just pass to the local
* algorithm constraints checking. The client will continue the
* connection if the server selected DHE group is acceptable by the
* specified algorithm constraints.
*/
private void serverKeyExchange(DH_ServerKeyExchange mesg)
throws IOException {
......@@ -1379,14 +1396,17 @@ final class ClientHandshaker extends Handshaker {
sslContext.getSecureRandom(), maxProtocolVersion,
sessionId, cipherSuites);
// add elliptic curves and point format extensions
if (cipherSuites.containsEC()) {
EllipticCurvesExtension ece =
EllipticCurvesExtension.createExtension(algorithmConstraints);
if (ece != null) {
clientHelloMessage.extensions.add(ece);
// Add named groups extension for ECDHE and FFDHE if necessary.
SupportedGroupsExtension sge =
SupportedGroupsExtension.createExtension(
algorithmConstraints,
cipherSuites, enableFFDHE);
if (sge != null) {
clientHelloMessage.extensions.add(sge);
// Add elliptic point format extensions
if (cipherSuites.contains(NamedGroupType.NAMED_GROUP_ECDHE)) {
clientHelloMessage.extensions.add(
EllipticPointFormatsExtension.DEFAULT);
EllipticPointFormatsExtension.DEFAULT);
}
}
......
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
......@@ -26,14 +26,8 @@
package sun.security.ssl;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.math.BigInteger;
import java.security.*;
import java.io.IOException;
import javax.net.ssl.SSLHandshakeException;
import javax.crypto.SecretKey;
import javax.crypto.KeyAgreement;
......@@ -101,7 +95,7 @@ final class DHCrypt {
*/
DHCrypt(int keyLength, SecureRandom random) {
this(keyLength,
ParametersHolder.definedParams.get(keyLength), random);
PredefinedDHParameterSpecs.definedParams.get(keyLength), random);
}
/**
......@@ -115,6 +109,14 @@ final class DHCrypt {
new DHParameterSpec(modulus, base), random);
}
/**
* Generate a Diffie-Hellman keypair using the named group.
*/
DHCrypt(NamedGroup namedGroup, SecureRandom random) {
this(-1, // The length (-1) is not used in the implementation.
SupportedGroupsExtension.getDHParameterSpec(namedGroup), random);
}
/**
* Generate a Diffie-Hellman keypair using the specified size and
* parameters.
......@@ -272,141 +274,4 @@ final class DHCrypt {
return null;
}
// lazy initialization holder class idiom for static default parameters
//
// See Effective Java Second Edition: Item 71.
private static class ParametersHolder {
private final static boolean debugIsOn =
(Debug.getInstance("ssl") != null) && Debug.isOn("sslctx");
//
// Default DH ephemeral parameters
//
private static final BigInteger g2 = BigInteger.valueOf(2);
private static final BigInteger p512 = new BigInteger( // generated
"D87780E15FF50B4ABBE89870188B049406B5BEA98AB23A02" +
"41D88EA75B7755E669C08093D3F0CA7FC3A5A25CF067DCB9" +
"A43DD89D1D90921C6328884461E0B6D3", 16);
private static final BigInteger p768 = new BigInteger( // RFC 2409
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
"E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p1024 = new BigInteger( // RFC 2409
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" +
"FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p2048 = new BigInteger( // TLS FEDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" +
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" +
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" +
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" +
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" +
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" +
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" +
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" +
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" +
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" +
"886B423861285C97FFFFFFFFFFFFFFFF", 16);
private static final BigInteger[] supportedPrimes = {
p512, p768, p1024, p2048};
// a measure of the uncertainty that prime modulus p is not a prime
//
// see BigInteger.isProbablePrime(int certainty)
private final static int PRIME_CERTAINTY = 120;
// the known security property, jdk.tls.server.defaultDHEParameters
private final static String PROPERTY_NAME =
"jdk.tls.server.defaultDHEParameters";
private static final Pattern spacesPattern = Pattern.compile("\\s+");
private final static Pattern syntaxPattern = Pattern.compile(
"(\\{[0-9A-Fa-f]+,[0-9A-Fa-f]+\\})" +
"(,\\{[0-9A-Fa-f]+,[0-9A-Fa-f]+\\})*");
private static final Pattern paramsPattern = Pattern.compile(
"\\{([0-9A-Fa-f]+),([0-9A-Fa-f]+)\\}");
// cache of predefined default DH ephemeral parameters
private final static Map<Integer,DHParameterSpec> definedParams;
static {
String property = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
return Security.getProperty(PROPERTY_NAME);
}
});
if (property != null && !property.isEmpty()) {
// remove double quote marks from beginning/end of the property
if (property.length() >= 2 && property.charAt(0) == '"' &&
property.charAt(property.length() - 1) == '"') {
property = property.substring(1, property.length() - 1);
}
property = property.trim();
}
if (property != null && !property.isEmpty()) {
Matcher spacesMatcher = spacesPattern.matcher(property);
property = spacesMatcher.replaceAll("");
if (debugIsOn) {
System.out.println("The Security Property " +
PROPERTY_NAME + ": " + property);
}
}
Map<Integer,DHParameterSpec> defaultParams = new HashMap<>();
if (property != null && !property.isEmpty()) {
Matcher syntaxMatcher = syntaxPattern.matcher(property);
if (syntaxMatcher.matches()) {
Matcher paramsFinder = paramsPattern.matcher(property);
while(paramsFinder.find()) {
String primeModulus = paramsFinder.group(1);
BigInteger p = new BigInteger(primeModulus, 16);
if (!p.isProbablePrime(PRIME_CERTAINTY)) {
if (debugIsOn) {
System.out.println(
"Prime modulus p in Security Property, " +
PROPERTY_NAME + ", is not a prime: " +
primeModulus);
}
continue;
}
String baseGenerator = paramsFinder.group(2);
BigInteger g = new BigInteger(baseGenerator, 16);
DHParameterSpec spec = new DHParameterSpec(p, g);
int primeLen = p.bitLength();
defaultParams.put(primeLen, spec);
}
} else if (debugIsOn) {
System.out.println("Invalid Security Property, " +
PROPERTY_NAME + ", definition");
}
}
for (BigInteger p : supportedPrimes) {
int primeLen = p.bitLength();
defaultParams.putIfAbsent(primeLen, new DHParameterSpec(p, g2));
}
definedParams =
Collections.<Integer,DHParameterSpec>unmodifiableMap(
defaultParams);
}
}
}
/*
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -56,17 +56,17 @@ final class ECDHCrypt {
}
// Called by ServerHandshaker for ephemeral ECDH
ECDHCrypt(int curveId, SecureRandom random) {
ECDHCrypt(NamedGroup namedGroup, SecureRandom random) {
try {
KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("EC");
ECGenParameterSpec params =
EllipticCurvesExtension.getECGenParamSpec(curveId);
SupportedGroupsExtension.getECGenParamSpec(namedGroup);
kpg.initialize(params, random);
KeyPair kp = kpg.generateKeyPair();
privateKey = kp.getPrivate();
publicKey = (ECPublicKey)kp.getPublic();
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate DH keypair", e);
throw new RuntimeException("Could not generate ECDH keypair", e);
}
}
......@@ -79,7 +79,7 @@ final class ECDHCrypt {
privateKey = kp.getPrivate();
publicKey = (ECPublicKey)kp.getPublic();
} catch (GeneralSecurityException e) {
throw new RuntimeException("Could not generate DH keypair", e);
throw new RuntimeException("Could not generate ECDH keypair", e);
}
}
......
/*
* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2017, 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
......@@ -43,7 +43,7 @@ final class ExtensionType {
return name;
}
static List<ExtensionType> knownExtensions = new ArrayList<ExtensionType>(9);
static List<ExtensionType> knownExtensions = new ArrayList<>(13);
static ExtensionType get(int id) {
for (ExtensionType ext : knownExtensions) {
......@@ -61,42 +61,42 @@ final class ExtensionType {
}
// extensions defined in RFC 3546
final static ExtensionType EXT_SERVER_NAME =
static final ExtensionType EXT_SERVER_NAME =
e(0x0000, "server_name"); // IANA registry value: 0
final static ExtensionType EXT_MAX_FRAGMENT_LENGTH =
static final ExtensionType EXT_MAX_FRAGMENT_LENGTH =
e(0x0001, "max_fragment_length"); // IANA registry value: 1
final static ExtensionType EXT_CLIENT_CERTIFICATE_URL =
static final ExtensionType EXT_CLIENT_CERTIFICATE_URL =
e(0x0002, "client_certificate_url"); // IANA registry value: 2
final static ExtensionType EXT_TRUSTED_CA_KEYS =
static final ExtensionType EXT_TRUSTED_CA_KEYS =
e(0x0003, "trusted_ca_keys"); // IANA registry value: 3
final static ExtensionType EXT_TRUNCATED_HMAC =
static final ExtensionType EXT_TRUNCATED_HMAC =
e(0x0004, "truncated_hmac"); // IANA registry value: 4
final static ExtensionType EXT_STATUS_REQUEST =
static final ExtensionType EXT_STATUS_REQUEST =
e(0x0005, "status_request"); // IANA registry value: 5
// extensions defined in RFC 4681
final static ExtensionType EXT_USER_MAPPING =
static final ExtensionType EXT_USER_MAPPING =
e(0x0006, "user_mapping"); // IANA registry value: 6
// extensions defined in RFC 5081
final static ExtensionType EXT_CERT_TYPE =
static final ExtensionType EXT_CERT_TYPE =
e(0x0009, "cert_type"); // IANA registry value: 9
// extensions defined in RFC 4492 (ECC)
final static ExtensionType EXT_ELLIPTIC_CURVES =
e(0x000A, "elliptic_curves"); // IANA registry value: 10
final static ExtensionType EXT_EC_POINT_FORMATS =
// extensions defined in RFC 4492 (ECC) and RFC 7919 (FFDHE)
static final ExtensionType EXT_SUPPORTED_GROUPS =
e(0x000A, "supported_groups"); // IANA registry value: 10
static final ExtensionType EXT_EC_POINT_FORMATS =
e(0x000B, "ec_point_formats"); // IANA registry value: 11
// extensions defined in RFC 5054
final static ExtensionType EXT_SRP =
static final ExtensionType EXT_SRP =
e(0x000C, "srp"); // IANA registry value: 12
// extensions defined in RFC 5246
final static ExtensionType EXT_SIGNATURE_ALGORITHMS =
static final ExtensionType EXT_SIGNATURE_ALGORITHMS =
e(0x000D, "signature_algorithms"); // IANA registry value: 13
// extensions defined in RFC 5746
final static ExtensionType EXT_RENEGOTIATION_INFO =
static final ExtensionType EXT_RENEGOTIATION_INFO =
e(0xff01, "renegotiation_info"); // IANA registry value: 65281
}
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
......@@ -982,8 +982,9 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
private final static int CURVE_EXPLICIT_CHAR2 = 2;
private final static int CURVE_NAMED_CURVE = 3;
// id of the curve we are using
private int curveId;
// id of the named group we are using
private int groupId;
// encoded public point
private byte[] pointBytes;
......@@ -1002,7 +1003,8 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
ECDH_ServerKeyExchange(ECDHCrypt obj, PrivateKey privateKey,
byte[] clntNonce, byte[] svrNonce, SecureRandom sr,
SignatureAndHashAlgorithm signAlgorithm,
ProtocolVersion protocolVersion) throws GeneralSecurityException {
ProtocolVersion protocolVersion)
throws SSLHandshakeException, GeneralSecurityException {
this.protocolVersion = protocolVersion;
......@@ -1010,7 +1012,14 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
ECParameterSpec params = publicKey.getParams();
ECPoint point = publicKey.getW();
pointBytes = JsseJce.encodePoint(point, params.getCurve());
curveId = EllipticCurvesExtension.getCurveIndex(params);
NamedGroup namedGroup = NamedGroup.valueOf(params);
if ((namedGroup == null) || (namedGroup.oid == null) ){
// unlikely
throw new SSLHandshakeException(
"Unnamed EC parameter spec: " + params);
}
groupId = namedGroup.id;
if (privateKey == null) {
// ECDH_anon
......@@ -1047,20 +1056,27 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
// These parsing errors should never occur as we negotiated
// the supported curves during the exchange of the Hello messages.
if (curveType == CURVE_NAMED_CURVE) {
curveId = input.getInt16();
if (!EllipticCurvesExtension.isSupported(curveId)) {
groupId = input.getInt16();
NamedGroup namedGroup = NamedGroup.valueOf(groupId);
if (namedGroup == null) {
throw new SSLHandshakeException(
"Unsupported curveId: " + curveId);
"Unknown named group ID: " + groupId);
}
String curveOid = EllipticCurvesExtension.getCurveOid(curveId);
if (curveOid == null) {
if (!SupportedGroupsExtension.supports(namedGroup)) {
throw new SSLHandshakeException(
"Unknown named curve: " + curveId);
"Unsupported named group: " + namedGroup);
}
parameters = JsseJce.getECParameterSpec(curveOid);
if (namedGroup.oid == null) {
throw new SSLHandshakeException(
"Unknown named EC curve: " + namedGroup);
}
parameters = JsseJce.getECParameterSpec(namedGroup.oid);
if (parameters == null) {
throw new SSLHandshakeException(
"Unsupported curve: " + curveOid);
"No supported EC parameter for named group: " + namedGroup);
}
} else {
throw new SSLHandshakeException(
......@@ -1143,8 +1159,8 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
sig.update(svrNonce);
sig.update((byte)CURVE_NAMED_CURVE);
sig.update((byte)(curveId >> 8));
sig.update((byte)curveId);
sig.update((byte)(groupId >> 8));
sig.update((byte)groupId);
sig.update((byte)pointBytes.length);
sig.update(pointBytes);
}
......@@ -1165,7 +1181,7 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
@Override
void send(HandshakeOutStream s) throws IOException {
s.putInt8(CURVE_NAMED_CURVE);
s.putInt16(curveId);
s.putInt16(groupId);
s.putBytes8(pointBytes);
if (signatureBytes != null) {
......
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
......@@ -50,6 +50,7 @@ import sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.PRF.*;
import static sun.security.ssl.CipherSuite.CipherType.*;
import static sun.security.ssl.NamedGroupType.*;
/**
* Handshaker ... processes handshake records from an SSL V3.0
......@@ -636,41 +637,14 @@ abstract class Handshaker {
ArrayList<CipherSuite> suites = new ArrayList<>();
if (!(activeProtocols.collection().isEmpty()) &&
activeProtocols.min.v != ProtocolVersion.NONE.v) {
boolean checkedCurves = false;
boolean hasCurves = false;
Map<NamedGroupType, Boolean> cachedStatus =
new EnumMap<>(NamedGroupType.class);
for (CipherSuite suite : enabledCipherSuites.collection()) {
if (suite.obsoleted > activeProtocols.min.v &&
suite.supported <= activeProtocols.max.v) {
if (algorithmConstraints.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
suite.name, null)) {
boolean available = true;
if (suite.keyExchange.isEC) {
if (!checkedCurves) {
hasCurves = EllipticCurvesExtension
.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);
}
if (suite.isAvailable() &&
(suite.obsoleted > activeProtocols.min.v &&
suite.supported <= activeProtocols.max.v)) {
if (isActivatable(suite, cachedStatus)) {
suites.add(suite);
}
} else if (debug != null && Debug.isOn("verbose")) {
if (suite.obsoleted <= activeProtocols.min.v) {
......@@ -728,46 +702,15 @@ abstract class Handshaker {
continue;
}
boolean found = false;
Map<NamedGroupType, Boolean> cachedStatus =
new EnumMap<>(NamedGroupType.class);
for (CipherSuite suite : enabledCipherSuites.collection()) {
if (suite.isAvailable() && suite.obsoleted > protocol.v &&
suite.supported <= protocol.v) {
if (algorithmConstraints.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
suite.name, null)) {
boolean available = true;
if (suite.keyExchange.isEC) {
if (!checkedCurves) {
hasCurves = EllipticCurvesExtension
.hasActiveCurves(algorithmConstraints);
checkedCurves = true;
if (!hasCurves && debug != null &&
Debug.isOn("verbose")) {
System.out.println(
"No activated elliptic curves");
}
}
available = hasCurves;
if (!available && debug != null &&
Debug.isOn("verbose")) {
System.out.println(
"No active elliptic curves, ignore " +
suite + " for " + protocol);
}
}
if (available) {
protocols.add(protocol);
found = true;
break;
}
} else if (debug != null && Debug.isOn("verbose")) {
System.out.println(
"Ignoring disabled cipher suite: " + suite +
" for " + protocol);
if (isActivatable(suite, cachedStatus)) {
protocols.add(protocol);
found = true;
break;
}
} else if (debug != null && Debug.isOn("verbose")) {
System.out.println(
......@@ -775,6 +718,7 @@ abstract class Handshaker {
" for " + protocol);
}
}
if (!found && (debug != null) && Debug.isOn("handshake")) {
System.out.println(
"No available cipher suite for " + protocol);
......@@ -791,6 +735,43 @@ abstract class Handshaker {
return activeProtocols;
}
private boolean isActivatable(CipherSuite suite,
Map<NamedGroupType, Boolean> cachedStatus) {
if (algorithmConstraints.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) {
boolean available = true;
NamedGroupType groupType = suite.keyExchange.groupType;
if (groupType != NAMED_GROUP_NONE) {
Boolean checkedStatus = cachedStatus.get(groupType);
if (checkedStatus == null) {
available = SupportedGroupsExtension.isActivatable(
algorithmConstraints, groupType);
cachedStatus.put(groupType, available);
if (!available && debug != null && Debug.isOn("verbose")) {
System.out.println("No activated named group");
}
} else {
available = checkedStatus.booleanValue();
}
if (!available && debug != null && Debug.isOn("verbose")) {
System.out.println(
"No active named group, ignore " + suite);
}
return available;
} else {
return true;
}
} else if (debug != null && Debug.isOn("verbose")) {
System.out.println("Ignoring disabled cipher suite: " + suite);
}
return false;
}
/**
* As long as handshaking has not activated, we can
* change whether session creations are allowed.
......
/*
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2017, 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
......@@ -49,7 +49,7 @@ import javax.net.ssl.*;
* explicitly support.
* . ServerNameExtension: the server_name extension.
* . SignatureAlgorithmsExtension: the signature_algorithms extension.
* . EllipticCurvesExtension: the ECC supported curves extension.
* . SupportedGroupsExtension: the supported groups extension.
* . EllipticPointFormatsExtension: the ECC supported point formats
* (compressed/uncompressed) extension.
*
......@@ -78,8 +78,8 @@ final class HelloExtensions {
extension = new ServerNameExtension(s, extlen);
} else if (extType == ExtensionType.EXT_SIGNATURE_ALGORITHMS) {
extension = new SignatureAlgorithmsExtension(s, extlen);
} else if (extType == ExtensionType.EXT_ELLIPTIC_CURVES) {
extension = new EllipticCurvesExtension(s, extlen);
} else if (extType == ExtensionType.EXT_SUPPORTED_GROUPS) {
extension = new SupportedGroupsExtension(s, extlen);
} else if (extType == ExtensionType.EXT_EC_POINT_FORMATS) {
extension = new EllipticPointFormatsExtension(s, extlen);
} else if (extType == ExtensionType.EXT_RENEGOTIATION_INFO) {
......
/*
* Copyright (c) 2017, 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.ssl;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECGenParameterSpec;
import static sun.security.ssl.NamedGroupType.*;
enum NamedGroup {
// Elliptic Curves (RFC 4492)
//
// See sun.security.util.CurveDB for the OIDs
// NIST K-163
SECT163_K1(1, NAMED_GROUP_ECDHE, "sect163k1", "1.3.132.0.1", true),
SECT163_R1(2, NAMED_GROUP_ECDHE, "sect163r1", "1.3.132.0.2", false),
// NIST B-163
SECT163_R2(3, NAMED_GROUP_ECDHE, "sect163r2", "1.3.132.0.15", true),
SECT193_R1(4, NAMED_GROUP_ECDHE, "sect193r1", "1.3.132.0.24", false),
SECT193_R2(5, NAMED_GROUP_ECDHE, "sect193r2", "1.3.132.0.25", false),
// NIST K-233
SECT233_K1(6, NAMED_GROUP_ECDHE, "sect233k1", "1.3.132.0.26", true),
// NIST B-233
SECT233_R1(7, NAMED_GROUP_ECDHE, "sect233r1", "1.3.132.0.27", true),
SECT239_K1(8, NAMED_GROUP_ECDHE, "sect239k1", "1.3.132.0.3", false),
// NIST K-283
SECT283_K1(9, NAMED_GROUP_ECDHE, "sect283k1", "1.3.132.0.16", true),
// NIST B-283
SECT283_R1(10, NAMED_GROUP_ECDHE, "sect283r1", "1.3.132.0.17", true),
// NIST K-409
SECT409_K1(11, NAMED_GROUP_ECDHE, "sect409k1", "1.3.132.0.36", true),
// NIST B-409
SECT409_R1(12, NAMED_GROUP_ECDHE, "sect409r1", "1.3.132.0.37", true),
// NIST K-571
SECT571_K1(13, NAMED_GROUP_ECDHE, "sect571k1", "1.3.132.0.38", true),
// NIST B-571
SECT571_R1(14, NAMED_GROUP_ECDHE, "sect571r1", "1.3.132.0.39", true),
SECP160_K1(15, NAMED_GROUP_ECDHE, "secp160k1", "1.3.132.0.9", false),
SECP160_R1(16, NAMED_GROUP_ECDHE, "secp160r1", "1.3.132.0.8", false),
SECP160_R2(17, NAMED_GROUP_ECDHE, "secp160r2", "1.3.132.0.30", false),
SECP192_K1(18, NAMED_GROUP_ECDHE, "secp192k1", "1.3.132.0.31", false),
// NIST P-192
SECP192_R1(19, NAMED_GROUP_ECDHE, "secp192r1", "1.2.840.10045.3.1.1", true),
SECP224_K1(20, NAMED_GROUP_ECDHE, "secp224k1", "1.3.132.0.32", false),
// NIST P-224
SECP224_R1(21, NAMED_GROUP_ECDHE, "secp224r1", "1.3.132.0.33", true),
SECP256_K1(22, NAMED_GROUP_ECDHE, "secp256k1", "1.3.132.0.10", false),
// NIST P-256
SECP256_R1(23, NAMED_GROUP_ECDHE, "secp256r1", "1.2.840.10045.3.1.7", true),
// NIST P-384
SECP384_R1(24, NAMED_GROUP_ECDHE, "secp384r1", "1.3.132.0.34", true),
// NIST P-521
SECP521_R1(25, NAMED_GROUP_ECDHE, "secp521r1", "1.3.132.0.35", true),
// Finite Field Diffie-Hellman Ephemeral Parameters (RFC 7919)
FFDHE_2048(256, NAMED_GROUP_FFDHE, "ffdhe2048", true),
FFDHE_3072(257, NAMED_GROUP_FFDHE, "ffdhe3072", true),
FFDHE_4096(258, NAMED_GROUP_FFDHE, "ffdhe4096", true),
FFDHE_6144(259, NAMED_GROUP_FFDHE, "ffdhe6144", true),
FFDHE_8192(260, NAMED_GROUP_FFDHE, "ffdhe8192", true);
int id;
NamedGroupType type;
String name;
String oid;
String algorithm;
boolean isFips;
// Constructor used for Elliptic Curve Groups (ECDHE)
NamedGroup(int id, NamedGroupType type,
String name, String oid, boolean isFips) {
this.id = id;
this.type = type;
this.name = name;
this.oid = oid;
this.algorithm = "EC";
this.isFips = isFips;
}
// Constructor used for Finite Field Diffie-Hellman Groups (FFDHE)
NamedGroup(int id, NamedGroupType type, String name, boolean isFips) {
this.id = id;
this.type = type;
this.name = name;
this.oid = null;
this.algorithm = "DiffieHellman";
this.isFips = isFips;
}
static NamedGroup valueOf(int id) {
for (NamedGroup group : NamedGroup.values()) {
if (group.id == id) {
return group;
}
}
return null;
}
static NamedGroup nameOf(String name) {
for (NamedGroup group : NamedGroup.values()) {
if (group.name.equals(name)) {
return group;
}
}
return null;
}
static NamedGroup valueOf(ECParameterSpec params) {
String oid = JsseJce.getNamedCurveOid(params);
if ((oid != null) && (!oid.isEmpty())) {
for (NamedGroup group : NamedGroup.values()) {
if (oid.equals(group.oid)) {
return group;
}
}
}
return null;
}
@Override
public String toString() {
return this.name;
}
}
/*
* Copyright (c) 2017, 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.ssl;
enum NamedGroupType {
NAMED_GROUP_ECDHE, // Elliptic Curve Groups (ECDHE)
NAMED_GROUP_FFDHE, // Finite Field Groups (DHE)
NAMED_GROUP_NONE // No predefined named group
}
/*
* Copyright (c) 2017, 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.ssl;
import java.security.*;
import java.math.BigInteger;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import javax.crypto.spec.DHParameterSpec;
/**
* Predefined default DH ephemeral parameters.
*/
final class PredefinedDHParameterSpecs {
private final static boolean debugIsOn =
(Debug.getInstance("ssl") != null) && Debug.isOn("sslctx");
//
// Default DH ephemeral parameters
//
private static final BigInteger p512 = new BigInteger( // generated
"D87780E15FF50B4ABBE89870188B049406B5BEA98AB23A02" +
"41D88EA75B7755E669C08093D3F0CA7FC3A5A25CF067DCB9" +
"A43DD89D1D90921C6328884461E0B6D3", 16);
private static final BigInteger p768 = new BigInteger( // RFC 2409
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
"E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p1024 = new BigInteger( // RFC 2409
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" +
"FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p1536 = new BigInteger( // RFC 3526
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
"670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p2048 = new BigInteger( // TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" +
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" +
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" +
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" +
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" +
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" +
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" +
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" +
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" +
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" +
"886B423861285C97FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p3072 = new BigInteger( // TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" +
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" +
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" +
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" +
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" +
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" +
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" +
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" +
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" +
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" +
"886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" +
"61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" +
"AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" +
"64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" +
"ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" +
"3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p4096 = new BigInteger( // TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" +
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" +
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" +
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" +
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" +
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" +
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" +
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" +
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" +
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" +
"886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" +
"61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" +
"AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" +
"64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" +
"ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" +
"3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" +
"7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" +
"87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" +
"A907600A918130C46DC778F971AD0038092999A333CB8B7A" +
"1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" +
"8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6A" +
"FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p6144 = new BigInteger( // TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" +
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" +
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" +
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" +
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" +
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" +
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" +
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" +
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" +
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" +
"886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" +
"61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" +
"AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" +
"64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" +
"ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" +
"3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" +
"7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" +
"87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" +
"A907600A918130C46DC778F971AD0038092999A333CB8B7A" +
"1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" +
"8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" +
"0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" +
"3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" +
"CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" +
"A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" +
"0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" +
"763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" +
"B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" +
"D72B03746AE77F5E62292C311562A846505DC82DB854338A" +
"E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" +
"5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" +
"A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF", 16);
private static final BigInteger p8192 = new BigInteger( // TLS FFDHE
"FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" +
"D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" +
"7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" +
"2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" +
"984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" +
"30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" +
"B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" +
"0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" +
"9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" +
"3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" +
"886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" +
"61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" +
"AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" +
"64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" +
"ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" +
"3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" +
"7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" +
"87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" +
"A907600A918130C46DC778F971AD0038092999A333CB8B7A" +
"1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" +
"8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" +
"0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" +
"3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" +
"CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" +
"A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" +
"0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" +
"763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" +
"B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" +
"D72B03746AE77F5E62292C311562A846505DC82DB854338A" +
"E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" +
"5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" +
"A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C838" +
"1E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E" +
"0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665" +
"CB2C0F1CC01BD70229388839D2AF05E454504AC78B758282" +
"2846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022" +
"BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C" +
"51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9" +
"D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA457" +
"1EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30" +
"FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D" +
"97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88C" +
"D68C8BB7C5C6424CFFFFFFFFFFFFFFFF", 16);
private static final BigInteger[] supportedPrimes = {
p512, p768, p1024, p1536, p2048, p3072, p4096, p6144, p8192};
private static final BigInteger[] ffdhePrimes = {
p2048, p3072, p4096, p6144, p8192};
// a measure of the uncertainty that prime modulus p is not a prime
//
// see BigInteger.isProbablePrime(int certainty)
private final static int PRIME_CERTAINTY = 120;
// the known security property, jdk.tls.server.defaultDHEParameters
private final static String PROPERTY_NAME =
"jdk.tls.server.defaultDHEParameters";
private static final Pattern spacesPattern = Pattern.compile("\\s+");
private final static Pattern syntaxPattern = Pattern.compile(
"(\\{[0-9A-Fa-f]+,[0-9A-Fa-f]+\\})" +
"(,\\{[0-9A-Fa-f]+,[0-9A-Fa-f]+\\})*");
private static final Pattern paramsPattern = Pattern.compile(
"\\{([0-9A-Fa-f]+),([0-9A-Fa-f]+)\\}");
// cache of predefined default DH ephemeral parameters
final static Map<Integer, DHParameterSpec> definedParams;
// cache of Finite Field DH Ephemeral parameters (RFC 7919/FFDHE)
final static Map<Integer, DHParameterSpec> ffdheParams;
static {
String property = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
return Security.getProperty(PROPERTY_NAME);
}
});
if (property != null && !property.isEmpty()) {
// remove double quote marks from beginning/end of the property
if (property.length() >= 2 && property.charAt(0) == '"' &&
property.charAt(property.length() - 1) == '"') {
property = property.substring(1, property.length() - 1);
}
property = property.trim();
}
if (property != null && !property.isEmpty()) {
Matcher spacesMatcher = spacesPattern.matcher(property);
property = spacesMatcher.replaceAll("");
if (debugIsOn) {
System.out.println("The Security Property " +
PROPERTY_NAME + ": " + property);
}
}
Map<Integer,DHParameterSpec> defaultParams = new HashMap<>();
if (property != null && !property.isEmpty()) {
Matcher syntaxMatcher = syntaxPattern.matcher(property);
if (syntaxMatcher.matches()) {
Matcher paramsFinder = paramsPattern.matcher(property);
while(paramsFinder.find()) {
String primeModulus = paramsFinder.group(1);
BigInteger p = new BigInteger(primeModulus, 16);
if (!p.isProbablePrime(PRIME_CERTAINTY)) {
if (debugIsOn) {
System.out.println(
"Prime modulus p in Security Property, " +
PROPERTY_NAME + ", is not a prime: " +
primeModulus);
}
continue;
}
String baseGenerator = paramsFinder.group(2);
BigInteger g = new BigInteger(baseGenerator, 16);
DHParameterSpec spec = new DHParameterSpec(p, g);
int primeLen = p.bitLength();
defaultParams.put(primeLen, spec);
}
} else if (debugIsOn) {
System.out.println("Invalid Security Property, " +
PROPERTY_NAME + ", definition");
}
}
Map<Integer,DHParameterSpec> tempFFDHEs = new HashMap<>();
for (BigInteger p : ffdhePrimes) {
int primeLen = p.bitLength();
DHParameterSpec dhps = new DHParameterSpec(p, BigInteger.valueOf(2));
tempFFDHEs.put(primeLen, dhps);
defaultParams.putIfAbsent(primeLen, dhps);
}
for (BigInteger p : supportedPrimes) {
int primeLen = p.bitLength();
if (defaultParams.get(primeLen) == null) {
defaultParams.put(primeLen,
new DHParameterSpec(p, BigInteger.valueOf(2)));
}
}
ffdheParams =
Collections.<Integer,DHParameterSpec>unmodifiableMap(tempFFDHEs);
definedParams =
Collections.<Integer,DHParameterSpec>unmodifiableMap(defaultParams);
}
}
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
......@@ -93,7 +93,7 @@ final class ServerHandshaker extends Handshaker {
private ProtocolVersion clientRequestedVersion;
// client supported elliptic curves
private EllipticCurvesExtension requestedCurves;
private SupportedGroupsExtension requestedGroups;
// the preferable signature algorithm used by ServerKeyExchange message
SignatureAndHashAlgorithm preferableSignatureAlgorithm;
......@@ -683,8 +683,8 @@ final class ServerHandshaker extends Handshaker {
throw new SSLException("Client did not resume a session");
}
requestedCurves = (EllipticCurvesExtension)
mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
requestedGroups = (SupportedGroupsExtension)
mesg.extensions.get(ExtensionType.EXT_SUPPORTED_GROUPS);
// We only need to handle the "signature_algorithm" extension
// for full handshakes and TLS 1.2 or later.
......@@ -1158,6 +1158,8 @@ final class ServerHandshaker extends Handshaker {
}
}
// The named group used for ECDHE and FFDHE.
NamedGroup namedGroup = null;
switch (keyExchange) {
case K_RSA:
// need RSA certs for authentication
......@@ -1183,6 +1185,37 @@ final class ServerHandshaker extends Handshaker {
}
break;
case K_DHE_RSA:
// Is ephemeral DH cipher suite usable for the connection?
//
// [RFC 7919] If a compatible TLS server receives a Supported
// Groups extension from a client that includes any FFDHE group
// (i.e., any codepoint between 256 and 511, inclusive, even if
// unknown to the server), and if none of the client-proposed
// FFDHE groups are known and acceptable to the server, then
// the server MUST NOT select an FFDHE cipher suite. In this
// case, the server SHOULD select an acceptable non-FFDHE cipher
// suite from the client's offered list. If the extension is
// present with FFDHE groups, none of the client's offered
// groups are acceptable by the server, and none of the client's
// proposed non-FFDHE cipher suites are acceptable to the server,
// the server MUST end the connection with a fatal TLS alert
// of type insufficient_security(71).
//
// Note: For compatibility, if an application is customized to
// use legacy sizes (512 bits for exportable cipher suites and
// 768 bits for others), or the cipher suite is exportable, the
// FFDHE extension will not be used.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) &&
(requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(
algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
......@@ -1203,9 +1236,20 @@ final class ServerHandshaker extends Handshaker {
}
}
setupEphemeralDHKeys(suite.exportable, privateKey);
setupEphemeralDHKeys(namedGroup, suite.exportable, privateKey);
break;
case K_ECDHE_RSA:
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ?
requestedGroups.getPreferredGroup(
algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) :
SupportedGroupsExtension.getPreferredECGroup(
algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
......@@ -1226,11 +1270,23 @@ final class ServerHandshaker extends Handshaker {
}
}
if (setupEphemeralECDHKeys() == false) {
return false;
}
setupEphemeralECDHKeys(namedGroup);
break;
case K_DHE_DSS:
// Is ephemeral DH cipher suite usable for the connection?
//
// See comment in K_DHE_RSA case.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) &&
(requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(
algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm =
......@@ -1251,9 +1307,20 @@ final class ServerHandshaker extends Handshaker {
return false;
}
setupEphemeralDHKeys(suite.exportable, privateKey);
setupEphemeralDHKeys(namedGroup, suite.exportable, privateKey);
break;
case K_ECDHE_ECDSA:
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ?
requestedGroups.getPreferredGroup(
algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) :
SupportedGroupsExtension.getPreferredECGroup(
algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm =
......@@ -1273,9 +1340,8 @@ final class ServerHandshaker extends Handshaker {
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
if (setupEphemeralECDHKeys() == false) {
return false;
}
setupEphemeralECDHKeys(namedGroup);
break;
case K_ECDH_RSA:
// need EC cert
......@@ -1299,14 +1365,36 @@ final class ServerHandshaker extends Handshaker {
}
break;
case K_DH_ANON:
// Is ephemeral DH cipher suite usable for the connection?
//
// See comment in K_DHE_RSA case.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) &&
(requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(
algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// no certs needed for anonymous
setupEphemeralDHKeys(suite.exportable, null);
setupEphemeralDHKeys(namedGroup, suite.exportable, null);
break;
case K_ECDH_ANON:
// no certs needed for anonymous
if (setupEphemeralECDHKeys() == false) {
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ?
requestedGroups.getPreferredGroup(
algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) :
SupportedGroupsExtension.getPreferredECGroup(
algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// no certs needed for anonymous
setupEphemeralECDHKeys(namedGroup);
break;
default:
// internal error, unknown key exchange
......@@ -1350,7 +1438,15 @@ final class ServerHandshaker extends Handshaker {
* Acquire some "ephemeral" Diffie-Hellman keys for this handshake.
* We don't reuse these, for improved forward secrecy.
*/
private void setupEphemeralDHKeys(boolean export, Key key) {
private void setupEphemeralDHKeys(
NamedGroup namedGroup, boolean export, Key key) {
// Are the client and server willing to negotiate FFDHE groups?
if ((!useLegacyEphemeralDHKeys) && (!export) && (namedGroup != null)) {
dh = new DHCrypt(namedGroup, sslContext.getSecureRandom());
return;
} // Otherwise, the client is not compatible with FFDHE extension.
/*
* 768 bits ephemeral DH private keys were used to be used in
* ServerKeyExchange except that exportable ciphers max out at 512
......@@ -1416,20 +1512,11 @@ final class ServerHandshaker extends Handshaker {
dh = new DHCrypt(keySize, sslContext.getSecureRandom());
}
// Setup the ephemeral ECDH parameters.
// If we cannot continue because we do not support any of the curves that
// the client requested, return false. Otherwise (all is well), return true.
private boolean setupEphemeralECDHKeys() {
int index = (requestedCurves != null) ?
requestedCurves.getPreferredCurve(algorithmConstraints) :
EllipticCurvesExtension.getActiveCurves(algorithmConstraints);
if (index < 0) {
// no match found, cannot use this ciphersuite
return false;
}
ecdh = new ECDHCrypt(index, sslContext.getSecureRandom());
return true;
/**
* Setup the ephemeral ECDH parameters.
*/
private void setupEphemeralECDHKeys(NamedGroup namedGroup) {
ecdh = new ECDHCrypt(namedGroup, sslContext.getSecureRandom());
}
private void setupStaticECDHKeys() {
......@@ -1477,9 +1564,11 @@ final class ServerHandshaker extends Handshaker {
return false;
}
ECParameterSpec params = ((ECPublicKey)publicKey).getParams();
int id = EllipticCurvesExtension.getCurveIndex(params);
if ((id <= 0) || !EllipticCurvesExtension.isSupported(id) ||
((requestedCurves != null) && !requestedCurves.contains(id))) {
NamedGroup namedGroup = NamedGroup.valueOf(params);
if ((namedGroup == null) ||
(!SupportedGroupsExtension.supports(namedGroup)) ||
((requestedGroups != null) &&
!requestedGroups.contains(namedGroup.id))) {
return false;
}
}
......
此差异已折叠。
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -31,33 +31,44 @@
* @bug 6956398
* @summary make ephemeral DH key match the length of the certificate key
* @run main/othervm
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1639 267
* @run main/othervm -Djsse.enableFFDHE=false
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=matched
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=legacy
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=1024
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
*
* @run main/othervm
* @run main/othervm -Djsse.enableFFDHE=false
* DHEKeySizing SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA true 229 75
*
* @run main/othervm
* @run main/othervm -Djsse.enableFFDHE=false
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1383 139
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=legacy
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1319 107
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=matched
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1639 267
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=1024
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1383 139
*
* @run main/othervm
* @run main/othervm -Djsse.enableFFDHE=false
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=legacy
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 293 107
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=matched
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
* @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
* @run main/othervm -Djsse.enableFFDHE=false
* -Djdk.tls.ephemeralDHKeySize=1024
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
*/
......
/*
* Copyright (c) 2017, 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.
*
* 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 8140436
* @modules jdk.crypto.ec
* @library /javax/net/ssl/templates
* @summary Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for TLS
* @run main/othervm UseStrongDHSizes 2048
*/
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Security;
import javax.net.ssl.SSLSocket;
public class UseStrongDHSizes extends SSLSocketTemplate {
/*
* Run the test case.
*/
public static void main(String[] args) throws Exception {
// reset the security property to make sure that the algorithms
// and keys used in this test are not disabled unexpectedly.
String constraint = "DH keySize < " + Integer.valueOf(args[0]);
Security.setProperty("jdk.tls.disabledAlgorithms", constraint);
Security.setProperty("jdk.certpath.disabledAlgorithms", "");
(new UseStrongDHSizes()).run();
}
@Override
protected void runServerApplication(SSLSocket socket) throws Exception {
String ciphers[] = {
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"};
socket.setEnabledCipherSuites(ciphers);
socket.setWantClientAuth(true);
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();
sslIS.read();
sslOS.write(85);
sslOS.flush();
}
@Override
protected void runClientApplication(SSLSocket socket) throws Exception {
String ciphers[] = {
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"};
socket.setEnabledCipherSuites(ciphers);
socket.setUseClientMode(true);
InputStream sslIS = socket.getInputStream();
OutputStream sslOS = socket.getOutputStream();
sslOS.write(280);
sslOS.flush();
sslIS.read();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册