8148421: Transport Layer Security (TLS) Session Hash and Extended Master Secret Extension
Co-authored-by: Martin Balao <mbalao@redhat.com> Reviewed-by: jnimeh, ahgross, rhalade, wetmore
This commit is contained in:
parent
f29e21abb1
commit
82bf0799c6
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2017, 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
|
||||||
@ -769,6 +769,8 @@ public final class SunJCE extends Provider {
|
|||||||
"com.sun.crypto.provider.TlsMasterSecretGenerator");
|
"com.sun.crypto.provider.TlsMasterSecretGenerator");
|
||||||
put("Alg.Alias.KeyGenerator.SunTls12MasterSecret",
|
put("Alg.Alias.KeyGenerator.SunTls12MasterSecret",
|
||||||
"SunTlsMasterSecret");
|
"SunTlsMasterSecret");
|
||||||
|
put("Alg.Alias.KeyGenerator.SunTlsExtendedMasterSecret",
|
||||||
|
"SunTlsMasterSecret");
|
||||||
|
|
||||||
put("KeyGenerator.SunTlsKeyMaterial",
|
put("KeyGenerator.SunTlsKeyMaterial",
|
||||||
"com.sun.crypto.provider.TlsKeyMaterialGenerator");
|
"com.sun.crypto.provider.TlsKeyMaterialGenerator");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2017, 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
|
||||||
@ -102,21 +102,32 @@ public final class TlsMasterSecretGenerator extends KeyGeneratorSpi {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] master;
|
byte[] master;
|
||||||
byte[] clientRandom = spec.getClientRandom();
|
|
||||||
byte[] serverRandom = spec.getServerRandom();
|
|
||||||
|
|
||||||
if (protocolVersion >= 0x0301) {
|
if (protocolVersion >= 0x0301) {
|
||||||
byte[] seed = concat(clientRandom, serverRandom);
|
byte[] label;
|
||||||
|
byte[] seed;
|
||||||
|
byte[] extendedMasterSecretSessionHash =
|
||||||
|
spec.getExtendedMasterSecretSessionHash();
|
||||||
|
if (extendedMasterSecretSessionHash.length != 0) {
|
||||||
|
label = LABEL_EXTENDED_MASTER_SECRET;
|
||||||
|
seed = extendedMasterSecretSessionHash;
|
||||||
|
} else {
|
||||||
|
byte[] clientRandom = spec.getClientRandom();
|
||||||
|
byte[] serverRandom = spec.getServerRandom();
|
||||||
|
label = LABEL_MASTER_SECRET;
|
||||||
|
seed = concat(clientRandom, serverRandom);
|
||||||
|
}
|
||||||
master = ((protocolVersion >= 0x0303) ?
|
master = ((protocolVersion >= 0x0303) ?
|
||||||
doTLS12PRF(premaster, LABEL_MASTER_SECRET, seed, 48,
|
doTLS12PRF(premaster, label, seed, 48,
|
||||||
spec.getPRFHashAlg(), spec.getPRFHashLength(),
|
spec.getPRFHashAlg(), spec.getPRFHashLength(),
|
||||||
spec.getPRFBlockSize()) :
|
spec.getPRFBlockSize()) :
|
||||||
doTLS10PRF(premaster, LABEL_MASTER_SECRET, seed, 48));
|
doTLS10PRF(premaster, label, seed, 48));
|
||||||
} else {
|
} else {
|
||||||
master = new byte[48];
|
master = new byte[48];
|
||||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||||
MessageDigest sha = MessageDigest.getInstance("SHA");
|
MessageDigest sha = MessageDigest.getInstance("SHA");
|
||||||
|
|
||||||
|
byte[] clientRandom = spec.getClientRandom();
|
||||||
|
byte[] serverRandom = spec.getServerRandom();
|
||||||
byte[] tmp = new byte[20];
|
byte[] tmp = new byte[20];
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
sha.update(SSL3_CONST[i]);
|
sha.update(SSL3_CONST[i]);
|
||||||
@ -175,5 +186,5 @@ public final class TlsMasterSecretGenerator extends KeyGeneratorSpi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2017, 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
|
||||||
@ -55,6 +55,11 @@ abstract class TlsPrfGenerator extends KeyGeneratorSpi {
|
|||||||
static final byte[] LABEL_MASTER_SECRET = // "master secret"
|
static final byte[] LABEL_MASTER_SECRET = // "master secret"
|
||||||
{ 109, 97, 115, 116, 101, 114, 32, 115, 101, 99, 114, 101, 116 };
|
{ 109, 97, 115, 116, 101, 114, 32, 115, 101, 99, 114, 101, 116 };
|
||||||
|
|
||||||
|
static final byte[] LABEL_EXTENDED_MASTER_SECRET =
|
||||||
|
// "extended master secret"
|
||||||
|
{ 101, 120, 116, 101, 110, 100, 101, 100, 32, 109, 97, 115, 116,
|
||||||
|
101, 114, 32, 115, 101, 99, 114, 101, 116 };
|
||||||
|
|
||||||
static final byte[] LABEL_KEY_EXPANSION = // "key expansion"
|
static final byte[] LABEL_KEY_EXPANSION = // "key expansion"
|
||||||
{ 107, 101, 121, 32, 101, 120, 112, 97, 110, 115, 105, 111, 110 };
|
{ 107, 101, 121, 32, 101, 120, 112, 97, 110, 115, 105, 111, 110 };
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2017, 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
|
||||||
@ -48,6 +48,7 @@ public class TlsMasterSecretParameterSpec implements AlgorithmParameterSpec {
|
|||||||
private final SecretKey premasterSecret;
|
private final SecretKey premasterSecret;
|
||||||
private final int majorVersion, minorVersion;
|
private final int majorVersion, minorVersion;
|
||||||
private final byte[] clientRandom, serverRandom;
|
private final byte[] clientRandom, serverRandom;
|
||||||
|
private final byte[] extendedMasterSecretSessionHash;
|
||||||
private final String prfHashAlg;
|
private final String prfHashAlg;
|
||||||
private final int prfHashLength;
|
private final int prfHashLength;
|
||||||
private final int prfBlockSize;
|
private final int prfBlockSize;
|
||||||
@ -80,6 +81,50 @@ public class TlsMasterSecretParameterSpec implements AlgorithmParameterSpec {
|
|||||||
int majorVersion, int minorVersion,
|
int majorVersion, int minorVersion,
|
||||||
byte[] clientRandom, byte[] serverRandom,
|
byte[] clientRandom, byte[] serverRandom,
|
||||||
String prfHashAlg, int prfHashLength, int prfBlockSize) {
|
String prfHashAlg, int prfHashLength, int prfBlockSize) {
|
||||||
|
this(premasterSecret, majorVersion, minorVersion,
|
||||||
|
clientRandom, serverRandom,
|
||||||
|
new byte[0],
|
||||||
|
prfHashAlg, prfHashLength, prfBlockSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new TlsMasterSecretParameterSpec.
|
||||||
|
*
|
||||||
|
* <p>The <code>getAlgorithm()</code> method of <code>premasterSecret</code>
|
||||||
|
* should return <code>"TlsRsaPremasterSecret"</code> if the key exchange
|
||||||
|
* algorithm was RSA and <code>"TlsPremasterSecret"</code> otherwise.
|
||||||
|
*
|
||||||
|
* @param premasterSecret the premaster secret
|
||||||
|
* @param majorVersion the major number of the protocol version
|
||||||
|
* @param minorVersion the minor number of the protocol version
|
||||||
|
* @param extendedMasterSecretSessionHash the session hash for
|
||||||
|
* Extended Master Secret
|
||||||
|
* @param prfHashAlg the name of the TLS PRF hash algorithm to use.
|
||||||
|
* Used only for TLS 1.2+. TLS1.1 and earlier use a fixed PRF.
|
||||||
|
* @param prfHashLength the output length of the TLS PRF hash algorithm.
|
||||||
|
* Used only for TLS 1.2+.
|
||||||
|
* @param prfBlockSize the input block size of the TLS PRF hash algorithm.
|
||||||
|
* Used only for TLS 1.2+.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if premasterSecret is null
|
||||||
|
* @throws IllegalArgumentException if minorVersion or majorVersion are
|
||||||
|
* negative or larger than 255
|
||||||
|
*/
|
||||||
|
public TlsMasterSecretParameterSpec(SecretKey premasterSecret,
|
||||||
|
int majorVersion, int minorVersion,
|
||||||
|
byte[] extendedMasterSecretSessionHash,
|
||||||
|
String prfHashAlg, int prfHashLength, int prfBlockSize) {
|
||||||
|
this(premasterSecret, majorVersion, minorVersion,
|
||||||
|
new byte[0], new byte[0],
|
||||||
|
extendedMasterSecretSessionHash,
|
||||||
|
prfHashAlg, prfHashLength, prfBlockSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TlsMasterSecretParameterSpec(SecretKey premasterSecret,
|
||||||
|
int majorVersion, int minorVersion,
|
||||||
|
byte[] clientRandom, byte[] serverRandom,
|
||||||
|
byte[] extendedMasterSecretSessionHash,
|
||||||
|
String prfHashAlg, int prfHashLength, int prfBlockSize) {
|
||||||
if (premasterSecret == null) {
|
if (premasterSecret == null) {
|
||||||
throw new NullPointerException("premasterSecret must not be null");
|
throw new NullPointerException("premasterSecret must not be null");
|
||||||
}
|
}
|
||||||
@ -88,6 +133,9 @@ public class TlsMasterSecretParameterSpec implements AlgorithmParameterSpec {
|
|||||||
this.minorVersion = checkVersion(minorVersion);
|
this.minorVersion = checkVersion(minorVersion);
|
||||||
this.clientRandom = clientRandom.clone();
|
this.clientRandom = clientRandom.clone();
|
||||||
this.serverRandom = serverRandom.clone();
|
this.serverRandom = serverRandom.clone();
|
||||||
|
this.extendedMasterSecretSessionHash =
|
||||||
|
(extendedMasterSecretSessionHash != null ?
|
||||||
|
extendedMasterSecretSessionHash.clone() : new byte[0]);
|
||||||
this.prfHashAlg = prfHashAlg;
|
this.prfHashAlg = prfHashAlg;
|
||||||
this.prfHashLength = prfHashLength;
|
this.prfHashLength = prfHashLength;
|
||||||
this.prfBlockSize = prfBlockSize;
|
this.prfBlockSize = prfBlockSize;
|
||||||
@ -146,6 +194,17 @@ public class TlsMasterSecretParameterSpec implements AlgorithmParameterSpec {
|
|||||||
return serverRandom.clone();
|
return serverRandom.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a copy of the Extended Master Secret session hash.
|
||||||
|
*
|
||||||
|
* @return a copy of the Extended Master Secret session hash, or an empty
|
||||||
|
* array if no extended master secret session hash was provided
|
||||||
|
* at instantiation time
|
||||||
|
*/
|
||||||
|
public byte[] getExtendedMasterSecretSessionHash() {
|
||||||
|
return extendedMasterSecretSessionHash.clone();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the PRF hash algorithm to use in the PRF calculation.
|
* Obtains the PRF hash algorithm to use in the PRF calculation.
|
||||||
*
|
*
|
||||||
|
@ -655,7 +655,8 @@ final class ClientHandshaker extends Handshaker {
|
|||||||
|
|
||||||
// validate subject identity
|
// validate subject identity
|
||||||
ClientKeyExchangeService p =
|
ClientKeyExchangeService p =
|
||||||
ClientKeyExchangeService.find(sessionSuite.keyExchange.name);
|
ClientKeyExchangeService.find(
|
||||||
|
sessionSuite.keyExchange.name);
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
Principal localPrincipal = session.getLocalPrincipal();
|
Principal localPrincipal = session.getLocalPrincipal();
|
||||||
|
|
||||||
@ -663,8 +664,9 @@ final class ClientHandshaker extends Handshaker {
|
|||||||
if (debug != null && Debug.isOn("session"))
|
if (debug != null && Debug.isOn("session"))
|
||||||
System.out.println("Subject identity is same");
|
System.out.println("Subject identity is same");
|
||||||
} else {
|
} else {
|
||||||
throw new SSLProtocolException("Server resumed" +
|
throw new SSLProtocolException(
|
||||||
" session with wrong subject identity or no subject");
|
"Server resumed session with " +
|
||||||
|
"wrong subject identity or no subject");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,6 +709,54 @@ final class ClientHandshaker extends Handshaker {
|
|||||||
} // Otherwise, using the value negotiated during the original
|
} // Otherwise, using the value negotiated during the original
|
||||||
// session initiation
|
// session initiation
|
||||||
|
|
||||||
|
// check the "extended_master_secret" extension
|
||||||
|
ExtendedMasterSecretExtension extendedMasterSecretExt =
|
||||||
|
(ExtendedMasterSecretExtension)mesg.extensions.get(
|
||||||
|
ExtensionType.EXT_EXTENDED_MASTER_SECRET);
|
||||||
|
if (extendedMasterSecretExt != null) {
|
||||||
|
// Is it the expected server extension?
|
||||||
|
if (!useExtendedMasterSecret ||
|
||||||
|
!mesgVersion.useTLS10PlusSpec() || !requestedToUseEMS) {
|
||||||
|
fatalSE(Alerts.alert_unsupported_extension,
|
||||||
|
"Server sent the extended_master_secret " +
|
||||||
|
"extension improperly");
|
||||||
|
}
|
||||||
|
|
||||||
|
// For abbreviated handshake, if the original session did not use
|
||||||
|
// the "extended_master_secret" extension but the new ServerHello
|
||||||
|
// contains the extension, the client MUST abort the handshake.
|
||||||
|
if (resumingSession && (session != null) &&
|
||||||
|
!session.getUseExtendedMasterSecret()) {
|
||||||
|
fatalSE(Alerts.alert_unsupported_extension,
|
||||||
|
"Server sent an unexpected extended_master_secret " +
|
||||||
|
"extension on session resumption");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (useExtendedMasterSecret && !allowLegacyMasterSecret) {
|
||||||
|
// For full handshake, if a client receives a ServerHello
|
||||||
|
// without the extension, it SHOULD abort the handshake if
|
||||||
|
// it does not wish to interoperate with legacy servers.
|
||||||
|
fatalSE(Alerts.alert_handshake_failure,
|
||||||
|
"Extended Master Secret extension is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resumingSession && (session != null)) {
|
||||||
|
if (session.getUseExtendedMasterSecret()) {
|
||||||
|
// For abbreviated handshake, if the original session used
|
||||||
|
// the "extended_master_secret" extension but the new
|
||||||
|
// ServerHello does not contain the extension, the client
|
||||||
|
// MUST abort the handshake.
|
||||||
|
fatalSE(Alerts.alert_handshake_failure,
|
||||||
|
"Missing Extended Master Secret extension " +
|
||||||
|
"on session resumption");
|
||||||
|
} else if (useExtendedMasterSecret && !allowLegacyResumption) {
|
||||||
|
// Unlikely, abbreviated handshake should be discarded.
|
||||||
|
fatalSE(Alerts.alert_handshake_failure,
|
||||||
|
"Extended Master Secret extension is required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check the ALPN extension
|
// check the ALPN extension
|
||||||
ALPNExtension serverHelloALPN =
|
ALPNExtension serverHelloALPN =
|
||||||
(ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN);
|
(ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN);
|
||||||
@ -777,7 +827,8 @@ final class ClientHandshaker extends Handshaker {
|
|||||||
&& (type != ExtensionType.EXT_ALPN)
|
&& (type != ExtensionType.EXT_ALPN)
|
||||||
&& (type != ExtensionType.EXT_RENEGOTIATION_INFO)
|
&& (type != ExtensionType.EXT_RENEGOTIATION_INFO)
|
||||||
&& (type != ExtensionType.EXT_STATUS_REQUEST)
|
&& (type != ExtensionType.EXT_STATUS_REQUEST)
|
||||||
&& (type != ExtensionType.EXT_STATUS_REQUEST_V2)) {
|
&& (type != ExtensionType.EXT_STATUS_REQUEST_V2)
|
||||||
|
&& (type != ExtensionType.EXT_EXTENDED_MASTER_SECRET)) {
|
||||||
// Note: Better to check client requested extensions rather
|
// Note: Better to check client requested extensions rather
|
||||||
// than all supported extensions.
|
// than all supported extensions.
|
||||||
fatalSE(Alerts.alert_unsupported_extension,
|
fatalSE(Alerts.alert_unsupported_extension,
|
||||||
@ -788,7 +839,8 @@ final class ClientHandshaker extends Handshaker {
|
|||||||
// Create a new session, we need to do the full handshake
|
// Create a new session, we need to do the full handshake
|
||||||
session = new SSLSessionImpl(protocolVersion, cipherSuite,
|
session = new SSLSessionImpl(protocolVersion, cipherSuite,
|
||||||
getLocalSupportedSignAlgs(),
|
getLocalSupportedSignAlgs(),
|
||||||
mesg.sessionId, getHostSE(), getPortSE());
|
mesg.sessionId, getHostSE(), getPortSE(),
|
||||||
|
(extendedMasterSecretExt != null));
|
||||||
session.setRequestedServerNames(requestedServerNames);
|
session.setRequestedServerNames(requestedServerNames);
|
||||||
session.setNegotiatedMaxFragSize(requestedMFLength);
|
session.setNegotiatedMaxFragSize(requestedMFLength);
|
||||||
session.setMaximumPacketSize(maximumPacketSize);
|
session.setMaximumPacketSize(maximumPacketSize);
|
||||||
@ -1430,6 +1482,44 @@ final class ClientHandshaker extends Handshaker {
|
|||||||
session = null;
|
session = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((session != null) && useExtendedMasterSecret) {
|
||||||
|
boolean isTLS10Plus = sessionVersion.useTLS10PlusSpec();
|
||||||
|
if (isTLS10Plus && !session.getUseExtendedMasterSecret()) {
|
||||||
|
if (!allowLegacyResumption) {
|
||||||
|
// perform full handshake instead
|
||||||
|
//
|
||||||
|
// The client SHOULD NOT offer an abbreviated handshake
|
||||||
|
// to resume a session that does not use an extended
|
||||||
|
// master secret. Instead, it SHOULD offer a full
|
||||||
|
// handshake.
|
||||||
|
session = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((session != null) && !allowUnsafeServerCertChange) {
|
||||||
|
// It is fine to move on with abbreviate handshake if
|
||||||
|
// endpoint identification is enabled.
|
||||||
|
String identityAlg = getEndpointIdentificationAlgorithmSE();
|
||||||
|
if ((identityAlg == null || identityAlg.length() == 0)) {
|
||||||
|
if (isTLS10Plus) {
|
||||||
|
if (!session.getUseExtendedMasterSecret()) {
|
||||||
|
// perform full handshake instead
|
||||||
|
session = null;
|
||||||
|
} // Otherwise, use extended master secret.
|
||||||
|
} else {
|
||||||
|
// The extended master secret extension does not
|
||||||
|
// apply to SSL 3.0. Perform a full handshake
|
||||||
|
// instead.
|
||||||
|
//
|
||||||
|
// Note that the useExtendedMasterSecret is
|
||||||
|
// extended to protect SSL 3.0 connections,
|
||||||
|
// by discarding abbreviate handshake.
|
||||||
|
session = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
if (debug != null) {
|
if (debug != null) {
|
||||||
if (Debug.isOn("handshake") || Debug.isOn("session")) {
|
if (Debug.isOn("handshake") || Debug.isOn("session")) {
|
||||||
@ -1539,6 +1629,14 @@ final class ClientHandshaker extends Handshaker {
|
|||||||
clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
|
clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add Extended Master Secret extension
|
||||||
|
if (useExtendedMasterSecret && maxProtocolVersion.useTLS10PlusSpec()) {
|
||||||
|
if ((session == null) || session.getUseExtendedMasterSecret()) {
|
||||||
|
clientHelloMessage.addExtendedMasterSecretExtension();
|
||||||
|
requestedToUseEMS = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add server_name extension
|
// add server_name extension
|
||||||
if (enableSNIExtension) {
|
if (enableSNIExtension) {
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
@ -1647,10 +1745,14 @@ final class ClientHandshaker extends Handshaker {
|
|||||||
// Allow server certificate change in client side during renegotiation
|
// Allow server certificate change in client side during renegotiation
|
||||||
// after a session-resumption abbreviated initial handshake?
|
// after a session-resumption abbreviated initial handshake?
|
||||||
//
|
//
|
||||||
// DO NOT need to check allowUnsafeServerCertChange here. We only
|
// DO NOT need to check allowUnsafeServerCertChange here. We only
|
||||||
// reserve server certificates when allowUnsafeServerCertChange is
|
// reserve server certificates when allowUnsafeServerCertChange is
|
||||||
// flase.
|
// flase.
|
||||||
if (reservedServerCerts != null) {
|
//
|
||||||
|
// Allow server certificate change if it is negotiated to use the
|
||||||
|
// extended master secret.
|
||||||
|
if ((reservedServerCerts != null) &&
|
||||||
|
!session.getUseExtendedMasterSecret()) {
|
||||||
// It is not necessary to check the certificate update if endpoint
|
// It is not necessary to check the certificate update if endpoint
|
||||||
// identification is enabled.
|
// identification is enabled.
|
||||||
String identityAlg = getEndpointIdentificationAlgorithmSE();
|
String identityAlg = getEndpointIdentificationAlgorithmSE();
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.security.ssl;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.net.ssl.SSLProtocolException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended Master Secret TLS extension (TLS 1.0+). This extension
|
||||||
|
* defines how to calculate the TLS connection master secret and
|
||||||
|
* mitigates some types of man-in-the-middle attacks.
|
||||||
|
*
|
||||||
|
* See further information in
|
||||||
|
* <a href="https://tools.ietf.org/html/rfc7627">RFC 7627</a>.
|
||||||
|
*
|
||||||
|
* @author Martin Balao (mbalao@redhat.com)
|
||||||
|
*/
|
||||||
|
final class ExtendedMasterSecretExtension extends HelloExtension {
|
||||||
|
ExtendedMasterSecretExtension() {
|
||||||
|
super(ExtensionType.EXT_EXTENDED_MASTER_SECRET);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedMasterSecretExtension(HandshakeInStream s,
|
||||||
|
int len) throws IOException {
|
||||||
|
super(ExtensionType.EXT_EXTENDED_MASTER_SECRET);
|
||||||
|
|
||||||
|
if (len != 0) {
|
||||||
|
throw new SSLProtocolException("Invalid " + type + " extension");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int length() {
|
||||||
|
return 4; // 4: extension type and length fields
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void send(HandshakeOutStream s) throws IOException {
|
||||||
|
s.putInt16(type.id); // ExtensionType extension_type;
|
||||||
|
s.putInt16(0); // extension_data length
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Extension " + type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -43,7 +43,7 @@ final class ExtensionType {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<ExtensionType> knownExtensions = new ArrayList<>(15);
|
static List<ExtensionType> knownExtensions = new ArrayList<>(16);
|
||||||
|
|
||||||
static ExtensionType get(int id) {
|
static ExtensionType get(int id) {
|
||||||
for (ExtensionType ext : knownExtensions) {
|
for (ExtensionType ext : knownExtensions) {
|
||||||
@ -105,6 +105,10 @@ final class ExtensionType {
|
|||||||
static final ExtensionType EXT_STATUS_REQUEST_V2 =
|
static final ExtensionType EXT_STATUS_REQUEST_V2 =
|
||||||
e(0x0011, "status_request_v2"); // IANA registry value: 17
|
e(0x0011, "status_request_v2"); // IANA registry value: 17
|
||||||
|
|
||||||
|
// extensions defined in RFC 7627
|
||||||
|
static final ExtensionType EXT_EXTENDED_MASTER_SECRET =
|
||||||
|
e(0x0017, "extended_master_secret"); // IANA registry value: 23
|
||||||
|
|
||||||
// extensions defined in RFC 5746
|
// extensions defined in RFC 5746
|
||||||
static final ExtensionType EXT_RENEGOTIATION_INFO =
|
static final ExtensionType EXT_RENEGOTIATION_INFO =
|
||||||
e(0xff01, "renegotiation_info"); // IANA registry value: 65281
|
e(0xff01, "renegotiation_info"); // IANA registry value: 65281
|
||||||
|
@ -389,6 +389,10 @@ static final class ClientHello extends HandshakeMessage {
|
|||||||
extensions.add(signatureAlgorithm);
|
extensions.add(signatureAlgorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addExtendedMasterSecretExtension() {
|
||||||
|
extensions.add(new ExtendedMasterSecretExtension());
|
||||||
|
}
|
||||||
|
|
||||||
void addMFLExtension(int maximumPacketSize) {
|
void addMFLExtension(int maximumPacketSize) {
|
||||||
HelloExtension maxFragmentLength =
|
HelloExtension maxFragmentLength =
|
||||||
new MaxFragmentLengthExtension(maximumPacketSize);
|
new MaxFragmentLengthExtension(maximumPacketSize);
|
||||||
@ -1441,7 +1445,7 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
|
|||||||
} else {
|
} else {
|
||||||
sig = getSignature(privateKey.getAlgorithm());
|
sig = getSignature(privateKey.getAlgorithm());
|
||||||
}
|
}
|
||||||
sig.initSign(privateKey); // where is the SecureRandom?
|
sig.initSign(privateKey, sr);
|
||||||
|
|
||||||
updateSignature(sig, clntNonce, svrNonce);
|
updateSignature(sig, clntNonce, svrNonce);
|
||||||
signatureBytes = sig.sign();
|
signatureBytes = sig.sign();
|
||||||
|
@ -30,12 +30,6 @@ import java.io.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.AlgorithmConstraints;
|
|
||||||
import java.security.AccessControlContext;
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
|
||||||
import java.security.PrivilegedActionException;
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import javax.crypto.*;
|
import javax.crypto.*;
|
||||||
@ -225,6 +219,20 @@ abstract class Handshaker {
|
|||||||
Debug.getBooleanProperty(
|
Debug.getBooleanProperty(
|
||||||
"jdk.tls.rejectClientInitiatedRenegotiation", false);
|
"jdk.tls.rejectClientInitiatedRenegotiation", false);
|
||||||
|
|
||||||
|
// To switch off the extended_master_secret extension.
|
||||||
|
static final boolean useExtendedMasterSecret;
|
||||||
|
|
||||||
|
// Allow session resumption without Extended Master Secret extension.
|
||||||
|
static final boolean allowLegacyResumption =
|
||||||
|
Debug.getBooleanProperty("jdk.tls.allowLegacyResumption", true);
|
||||||
|
|
||||||
|
// Allow full handshake without Extended Master Secret extension.
|
||||||
|
static final boolean allowLegacyMasterSecret =
|
||||||
|
Debug.getBooleanProperty("jdk.tls.allowLegacyMasterSecret", true);
|
||||||
|
|
||||||
|
// Is it requested to use extended master secret extension?
|
||||||
|
boolean requestedToUseEMS = false;
|
||||||
|
|
||||||
// need to dispose the object when it is invalidated
|
// need to dispose the object when it is invalidated
|
||||||
boolean invalidated;
|
boolean invalidated;
|
||||||
|
|
||||||
@ -233,6 +241,24 @@ abstract class Handshaker {
|
|||||||
*/
|
*/
|
||||||
final boolean isDTLS;
|
final boolean isDTLS;
|
||||||
|
|
||||||
|
// Is the extended_master_secret extension supported?
|
||||||
|
static {
|
||||||
|
boolean supportExtendedMasterSecret = true;
|
||||||
|
try {
|
||||||
|
KeyGenerator kg =
|
||||||
|
JsseJce.getKeyGenerator("SunTlsExtendedMasterSecret");
|
||||||
|
} catch (NoSuchAlgorithmException nae) {
|
||||||
|
supportExtendedMasterSecret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportExtendedMasterSecret) {
|
||||||
|
useExtendedMasterSecret = Debug.getBooleanProperty(
|
||||||
|
"jdk.tls.useExtendedMasterSecret", true);
|
||||||
|
} else {
|
||||||
|
useExtendedMasterSecret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Handshaker(SSLSocketImpl c, SSLContextImpl context,
|
Handshaker(SSLSocketImpl c, SSLContextImpl context,
|
||||||
ProtocolList enabledProtocols, boolean needCertVerify,
|
ProtocolList enabledProtocols, boolean needCertVerify,
|
||||||
boolean isClient, ProtocolVersion activeProtocolVersion,
|
boolean isClient, ProtocolVersion activeProtocolVersion,
|
||||||
@ -243,7 +269,7 @@ abstract class Handshaker {
|
|||||||
init(context, enabledProtocols, needCertVerify, isClient,
|
init(context, enabledProtocols, needCertVerify, isClient,
|
||||||
activeProtocolVersion, isInitialHandshake, secureRenegotiation,
|
activeProtocolVersion, isInitialHandshake, secureRenegotiation,
|
||||||
clientVerifyData, serverVerifyData);
|
clientVerifyData, serverVerifyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handshaker(SSLEngineImpl engine, SSLContextImpl context,
|
Handshaker(SSLEngineImpl engine, SSLContextImpl context,
|
||||||
ProtocolList enabledProtocols, boolean needCertVerify,
|
ProtocolList enabledProtocols, boolean needCertVerify,
|
||||||
@ -1226,6 +1252,7 @@ abstract class Handshaker {
|
|||||||
* SHA1 hashes are of (different) constant strings, the pre-master
|
* SHA1 hashes are of (different) constant strings, the pre-master
|
||||||
* secret, and the nonces provided by the client and the server.
|
* secret, and the nonces provided by the client and the server.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
|
private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
|
||||||
ProtocolVersion requestedVersion) {
|
ProtocolVersion requestedVersion) {
|
||||||
|
|
||||||
@ -1276,11 +1303,37 @@ abstract class Handshaker {
|
|||||||
int prfHashLength = prf.getPRFHashLength();
|
int prfHashLength = prf.getPRFHashLength();
|
||||||
int prfBlockSize = prf.getPRFBlockSize();
|
int prfBlockSize = prf.getPRFBlockSize();
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
TlsMasterSecretParameterSpec spec;
|
||||||
TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec(
|
if (session.getUseExtendedMasterSecret()) {
|
||||||
preMasterSecret, (majorVersion & 0xFF), (minorVersion & 0xFF),
|
// reset to use the extended master secret algorithm
|
||||||
clnt_random.random_bytes, svr_random.random_bytes,
|
masterAlg = "SunTlsExtendedMasterSecret";
|
||||||
prfHashAlg, prfHashLength, prfBlockSize);
|
|
||||||
|
byte[] sessionHash = null;
|
||||||
|
if (protocolVersion.useTLS12PlusSpec()) {
|
||||||
|
sessionHash = handshakeHash.getFinishedHash();
|
||||||
|
} else {
|
||||||
|
// TLS 1.0/1.1, DTLS 1.0
|
||||||
|
sessionHash = new byte[36];
|
||||||
|
try {
|
||||||
|
handshakeHash.getMD5Clone().digest(sessionHash, 0, 16);
|
||||||
|
handshakeHash.getSHAClone().digest(sessionHash, 16, 20);
|
||||||
|
} catch (DigestException de) {
|
||||||
|
throw new ProviderException(de);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spec = new TlsMasterSecretParameterSpec(
|
||||||
|
preMasterSecret,
|
||||||
|
(majorVersion & 0xFF), (minorVersion & 0xFF),
|
||||||
|
sessionHash,
|
||||||
|
prfHashAlg, prfHashLength, prfBlockSize);
|
||||||
|
} else {
|
||||||
|
spec = new TlsMasterSecretParameterSpec(
|
||||||
|
preMasterSecret,
|
||||||
|
(majorVersion & 0xFF), (minorVersion & 0xFF),
|
||||||
|
clnt_random.random_bytes, svr_random.random_bytes,
|
||||||
|
prfHashAlg, prfHashLength, prfBlockSize);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
|
KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
|
||||||
|
@ -93,6 +93,8 @@ final class HelloExtensions {
|
|||||||
extension = new CertStatusReqExtension(s, extlen);
|
extension = new CertStatusReqExtension(s, extlen);
|
||||||
} else if (extType == ExtensionType.EXT_STATUS_REQUEST_V2) {
|
} else if (extType == ExtensionType.EXT_STATUS_REQUEST_V2) {
|
||||||
extension = new CertStatusReqListV2Extension(s, extlen);
|
extension = new CertStatusReqListV2Extension(s, extlen);
|
||||||
|
} else if (extType == ExtensionType.EXT_EXTENDED_MASTER_SECRET) {
|
||||||
|
extension = new ExtendedMasterSecretExtension(s, extlen);
|
||||||
} else {
|
} else {
|
||||||
extension = new UnknownExtension(s, extlen, extType);
|
extension = new UnknownExtension(s, extlen, extType);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* 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.
|
* 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
|
||||||
@ -91,6 +91,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
|||||||
private byte compressionMethod;
|
private byte compressionMethod;
|
||||||
private CipherSuite cipherSuite;
|
private CipherSuite cipherSuite;
|
||||||
private SecretKey masterSecret;
|
private SecretKey masterSecret;
|
||||||
|
private final boolean useExtendedMasterSecret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Information not part of the SSLv3 protocol spec, but used
|
* Information not part of the SSLv3 protocol spec, but used
|
||||||
@ -148,7 +149,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
|||||||
*/
|
*/
|
||||||
private SSLSessionImpl() {
|
private SSLSessionImpl() {
|
||||||
this(ProtocolVersion.NONE, CipherSuite.C_NULL, null,
|
this(ProtocolVersion.NONE, CipherSuite.C_NULL, null,
|
||||||
new SessionId(false, null), null, -1);
|
new SessionId(false, null), null, -1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -158,9 +159,11 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
|||||||
*/
|
*/
|
||||||
SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
|
SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
|
||||||
Collection<SignatureAndHashAlgorithm> algorithms,
|
Collection<SignatureAndHashAlgorithm> algorithms,
|
||||||
SecureRandom generator, String host, int port) {
|
SecureRandom generator, String host, int port,
|
||||||
|
boolean useExtendedMasterSecret) {
|
||||||
this(protocolVersion, cipherSuite, algorithms,
|
this(protocolVersion, cipherSuite, algorithms,
|
||||||
new SessionId(defaultRejoinable, generator), host, port);
|
new SessionId(defaultRejoinable, generator), host, port,
|
||||||
|
useExtendedMasterSecret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -168,7 +171,8 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
|||||||
*/
|
*/
|
||||||
SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
|
SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
|
||||||
Collection<SignatureAndHashAlgorithm> algorithms,
|
Collection<SignatureAndHashAlgorithm> algorithms,
|
||||||
SessionId id, String host, int port) {
|
SessionId id, String host, int port,
|
||||||
|
boolean useExtendedMasterSecret) {
|
||||||
this.protocolVersion = protocolVersion;
|
this.protocolVersion = protocolVersion;
|
||||||
sessionId = id;
|
sessionId = id;
|
||||||
peerCerts = null;
|
peerCerts = null;
|
||||||
@ -182,6 +186,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
|||||||
SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
|
SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
|
||||||
negotiatedMaxFragLen = -1;
|
negotiatedMaxFragLen = -1;
|
||||||
statusResponses = null;
|
statusResponses = null;
|
||||||
|
this.useExtendedMasterSecret = useExtendedMasterSecret;
|
||||||
|
|
||||||
if (debug != null && Debug.isOn("session")) {
|
if (debug != null && Debug.isOn("session")) {
|
||||||
System.out.println("%% Initialized: " + this);
|
System.out.println("%% Initialized: " + this);
|
||||||
@ -203,6 +208,10 @@ final class SSLSessionImpl extends ExtendedSSLSession {
|
|||||||
return masterSecret;
|
return masterSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean getUseExtendedMasterSecret() {
|
||||||
|
return useExtendedMasterSecret;
|
||||||
|
}
|
||||||
|
|
||||||
void setPeerCertificates(X509Certificate[] peer) {
|
void setPeerCertificates(X509Certificate[] peer) {
|
||||||
if (peerCerts == null) {
|
if (peerCerts == null) {
|
||||||
peerCerts = peer;
|
peerCerts = peer;
|
||||||
|
@ -529,6 +529,27 @@ final class ServerHandshaker extends Handshaker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check out the "extended_master_secret" extension
|
||||||
|
if (useExtendedMasterSecret) {
|
||||||
|
ExtendedMasterSecretExtension extendedMasterSecretExtension =
|
||||||
|
(ExtendedMasterSecretExtension)mesg.extensions.get(
|
||||||
|
ExtensionType.EXT_EXTENDED_MASTER_SECRET);
|
||||||
|
if (extendedMasterSecretExtension != null) {
|
||||||
|
requestedToUseEMS = true;
|
||||||
|
} else if (mesg.protocolVersion.useTLS10PlusSpec()) {
|
||||||
|
if (!allowLegacyMasterSecret) {
|
||||||
|
// For full handshake, if the server receives a ClientHello
|
||||||
|
// without the extension, it SHOULD abort the handshake if
|
||||||
|
// it does not wish to interoperate with legacy clients.
|
||||||
|
//
|
||||||
|
// As if extended master extension is required for full
|
||||||
|
// handshake, it MUST be used in abbreviated handshake too.
|
||||||
|
fatalSE(Alerts.alert_handshake_failure,
|
||||||
|
"Extended Master Secret extension is required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check the ALPN extension
|
// check the ALPN extension
|
||||||
ALPNExtension clientHelloALPN = (ALPNExtension)
|
ALPNExtension clientHelloALPN = (ALPNExtension)
|
||||||
mesg.extensions.get(ExtensionType.EXT_ALPN);
|
mesg.extensions.get(ExtensionType.EXT_ALPN);
|
||||||
@ -592,11 +613,45 @@ final class ServerHandshaker extends Handshaker {
|
|||||||
if (resumingSession) {
|
if (resumingSession) {
|
||||||
ProtocolVersion oldVersion = previous.getProtocolVersion();
|
ProtocolVersion oldVersion = previous.getProtocolVersion();
|
||||||
// cannot resume session with different version
|
// cannot resume session with different version
|
||||||
if (oldVersion != protocolVersion) {
|
if (oldVersion != mesg.protocolVersion) {
|
||||||
resumingSession = false;
|
resumingSession = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resumingSession && useExtendedMasterSecret) {
|
||||||
|
if (requestedToUseEMS &&
|
||||||
|
!previous.getUseExtendedMasterSecret()) {
|
||||||
|
// For abbreviated handshake request, If the original
|
||||||
|
// session did not use the "extended_master_secret"
|
||||||
|
// extension but the new ClientHello contains the
|
||||||
|
// extension, then the server MUST NOT perform the
|
||||||
|
// abbreviated handshake. Instead, it SHOULD continue
|
||||||
|
// with a full handshake.
|
||||||
|
resumingSession = false;
|
||||||
|
} else if (!requestedToUseEMS &&
|
||||||
|
previous.getUseExtendedMasterSecret()) {
|
||||||
|
// For abbreviated handshake request, if the original
|
||||||
|
// session used the "extended_master_secret" extension
|
||||||
|
// but the new ClientHello does not contain it, the
|
||||||
|
// server MUST abort the abbreviated handshake.
|
||||||
|
fatalSE(Alerts.alert_handshake_failure,
|
||||||
|
"Missing Extended Master Secret extension " +
|
||||||
|
"on session resumption");
|
||||||
|
} else if (!requestedToUseEMS &&
|
||||||
|
!previous.getUseExtendedMasterSecret()) {
|
||||||
|
// For abbreviated handshake request, if neither the
|
||||||
|
// original session nor the new ClientHello uses the
|
||||||
|
// extension, the server SHOULD abort the handshake.
|
||||||
|
if (!allowLegacyResumption) {
|
||||||
|
fatalSE(Alerts.alert_handshake_failure,
|
||||||
|
"Missing Extended Master Secret extension " +
|
||||||
|
"on session resumption");
|
||||||
|
} else { // Otherwise, continue with a full handshake.
|
||||||
|
resumingSession = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cannot resume session with different server name indication
|
// cannot resume session with different server name indication
|
||||||
if (resumingSession) {
|
if (resumingSession) {
|
||||||
List<SNIServerName> oldServerNames =
|
List<SNIServerName> oldServerNames =
|
||||||
@ -630,7 +685,7 @@ final class ServerHandshaker extends Handshaker {
|
|||||||
if (resumingSession) {
|
if (resumingSession) {
|
||||||
CipherSuite suite = previous.getSuite();
|
CipherSuite suite = previous.getSuite();
|
||||||
ClientKeyExchangeService p =
|
ClientKeyExchangeService p =
|
||||||
ClientKeyExchangeService.find(suite.keyExchange.name);
|
ClientKeyExchangeService.find(suite.keyExchange.name);
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
Principal localPrincipal = previous.getLocalPrincipal();
|
Principal localPrincipal = previous.getLocalPrincipal();
|
||||||
|
|
||||||
@ -784,7 +839,9 @@ final class ServerHandshaker extends Handshaker {
|
|||||||
session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL,
|
session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL,
|
||||||
getLocalSupportedSignAlgs(),
|
getLocalSupportedSignAlgs(),
|
||||||
sslContext.getSecureRandom(),
|
sslContext.getSecureRandom(),
|
||||||
getHostAddressSE(), getPortSE());
|
getHostAddressSE(), getPortSE(),
|
||||||
|
(requestedToUseEMS &&
|
||||||
|
protocolVersion.useTLS10PlusSpec()));
|
||||||
|
|
||||||
if (protocolVersion.useTLS12PlusSpec()) {
|
if (protocolVersion.useTLS12PlusSpec()) {
|
||||||
if (peerSupportedSignAlgs != null) {
|
if (peerSupportedSignAlgs != null) {
|
||||||
@ -886,6 +943,10 @@ final class ServerHandshaker extends Handshaker {
|
|||||||
m1.extensions.add(maxFragLenExt);
|
m1.extensions.add(maxFragLenExt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session.getUseExtendedMasterSecret()) {
|
||||||
|
m1.extensions.add(new ExtendedMasterSecretExtension());
|
||||||
|
}
|
||||||
|
|
||||||
StaplingParameters staplingParams = processStapling(mesg);
|
StaplingParameters staplingParams = processStapling(mesg);
|
||||||
if (staplingParams != null) {
|
if (staplingParams != null) {
|
||||||
// We now can safely assert status_request[_v2] in our
|
// We now can safely assert status_request[_v2] in our
|
||||||
@ -963,7 +1024,8 @@ final class ServerHandshaker extends Handshaker {
|
|||||||
* defined in the protocol spec are explicitly stated to require
|
* defined in the protocol spec are explicitly stated to require
|
||||||
* using RSA certificates.
|
* using RSA certificates.
|
||||||
*/
|
*/
|
||||||
if (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) {
|
if (ClientKeyExchangeService.find(
|
||||||
|
cipherSuite.keyExchange.name) != null) {
|
||||||
// No external key exchange provider needs a cert now.
|
// No external key exchange provider needs a cert now.
|
||||||
} else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
|
} else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
|
||||||
if (certs == null) {
|
if (certs == null) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2017, 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
|
||||||
@ -44,6 +44,7 @@ public class NoMacInitialClientHello extends DTLSOverDatagram {
|
|||||||
boolean needInvalidRecords = true;
|
boolean needInvalidRecords = true;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.setProperty("jdk.tls.useExtendedMasterSecret", "false");
|
||||||
NoMacInitialClientHello testCase = new NoMacInitialClientHello();
|
NoMacInitialClientHello testCase = new NoMacInitialClientHello();
|
||||||
testCase.runTest(testCase);
|
testCase.runTest(testCase);
|
||||||
}
|
}
|
||||||
|
@ -31,45 +31,45 @@
|
|||||||
* @bug 6956398
|
* @bug 6956398
|
||||||
* @summary make ephemeral DH key match the length of the certificate key
|
* @summary make ephemeral DH key match the length of the certificate key
|
||||||
* @run main/othervm
|
* @run main/othervm
|
||||||
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1639 267
|
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1643 267
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
|
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1259 75
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=matched
|
* -Djdk.tls.ephemeralDHKeySize=matched
|
||||||
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
|
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1259 75
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=legacy
|
* -Djdk.tls.ephemeralDHKeySize=legacy
|
||||||
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
|
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1259 75
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=1024
|
* -Djdk.tls.ephemeralDHKeySize=1024
|
||||||
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75
|
* DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1259 75
|
||||||
*
|
*
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* DHEKeySizing SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA true 229 75
|
* DHEKeySizing SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA true 233 75
|
||||||
*
|
*
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1383 139
|
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1387 139
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=legacy
|
* -Djdk.tls.ephemeralDHKeySize=legacy
|
||||||
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1319 107
|
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1323 107
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=matched
|
* -Djdk.tls.ephemeralDHKeySize=matched
|
||||||
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1639 267
|
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1643 267
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=1024
|
* -Djdk.tls.ephemeralDHKeySize=1024
|
||||||
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1383 139
|
* DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1387 139
|
||||||
*
|
*
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
|
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 361 139
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=legacy
|
* -Djdk.tls.ephemeralDHKeySize=legacy
|
||||||
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 293 107
|
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 297 107
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=matched
|
* -Djdk.tls.ephemeralDHKeySize=matched
|
||||||
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
|
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 361 139
|
||||||
* @run main/othervm -Djsse.enableFFDHE=false
|
* @run main/othervm -Djsse.enableFFDHE=false
|
||||||
* -Djdk.tls.ephemeralDHKeySize=1024
|
* -Djdk.tls.ephemeralDHKeySize=1024
|
||||||
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139
|
* DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 361 139
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -101,10 +101,10 @@
|
|||||||
* Here is a summary of the record length in the test case.
|
* Here is a summary of the record length in the test case.
|
||||||
*
|
*
|
||||||
* | ServerHello Series | ClientKeyExchange | ServerHello Anon
|
* | ServerHello Series | ClientKeyExchange | ServerHello Anon
|
||||||
* 512-bit | 1255 bytes | 75 bytes | 229 bytes
|
* 512-bit | 1259 bytes | 75 bytes | 233 bytes
|
||||||
* 768-bit | 1319 bytes | 107 bytes | 293 bytes
|
* 768-bit | 1323 bytes | 107 bytes | 297 bytes
|
||||||
* 1024-bit | 1383 bytes | 139 bytes | 357 bytes
|
* 1024-bit | 1387 bytes | 139 bytes | 361 bytes
|
||||||
* 2048-bit | 1639 bytes | 267 bytes | 357 bytes
|
* 2048-bit | 1643 bytes | 267 bytes | 361 bytes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import javax.net.ssl.*;
|
import javax.net.ssl.*;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -38,6 +38,6 @@ public class OptimalListSize {
|
|||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
OptimalCapacity.ofArrayList(
|
OptimalCapacity.ofArrayList(
|
||||||
Class.forName("sun.security.ssl.ExtensionType"),
|
Class.forName("sun.security.ssl.ExtensionType"),
|
||||||
"knownExtensions", 15);
|
"knownExtensions", 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user