Skip to content
This repository has been archived by the owner on Oct 25, 2018. It is now read-only.

Fix for grizzly-npn support for JDK8u161/JDK8u162 #5

Merged
merged 1 commit into from
Feb 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 129 additions & 24 deletions bootstrap/src/main/java/sun/security/ssl/ClientHandshaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -655,15 +655,66 @@ public Subject run() throws Exception {
} else {
// we wanted to resume, but the server refused
//
// Invalidate the session in case of reusing next time.
session.invalidate();
// Invalidate the session for initial handshake in case
// of reusing next time.
if (isInitialHandshake) {
session.invalidate();
}
session = null;
if (!enableNewSession) {
throw new SSLException("New session creation is disabled");
}
}
}

// 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.v >= ProtocolVersion.TLS10.v) || !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");
}
}
}

if (resumingSession && session != null) {
setHandshakeSessionSE(session);
// Reserve the handshake state if this is a session-resumption
Expand All @@ -687,8 +738,9 @@ public Subject run() throws Exception {
// BEGIN GRIZZLY NPN
// Include NPN as a supported extension.
&& (type != ExtensionType.EXT_NEXT_PROTOCOL_NEGOTIATION)
&& (type != ExtensionType.EXT_APPLICATION_LEVEL_PROTOCOL_NEGOTIATION)) {
&& (type != ExtensionType.EXT_APPLICATION_LEVEL_PROTOCOL_NEGOTIATION)
// END GRIZZLY NPN
&& (type != ExtensionType.EXT_EXTENDED_MASTER_SECRET)){
fatalSE(Alerts.alert_unsupported_extension,
"Server sent an unsupported extension: " + type);
}
Expand Down Expand Up @@ -721,7 +773,8 @@ public Subject run() throws Exception {
// Create a new session, we need to do the full handshake
session = new SSLSessionImpl(protocolVersion, cipherSuite,
getLocalSupportedSignAlgs(),
mesg.sessionId, getHostSE(), getPortSE());
mesg.sessionId, getHostSE(), getPortSE(),
(extendedMasterSecretExt != null));
session.setRequestedServerNames(requestedServerNames);
setHandshakeSessionSE(session);
if (debug != null && Debug.isOn("handshake")) {
Expand Down Expand Up @@ -839,13 +892,16 @@ private void serverHelloDone(ServerHelloDone mesg) throws IOException {
break;

// Fixed DH/ECDH client authentication not supported
case CertificateRequest.cct_rsa_fixed_dh:
case CertificateRequest.cct_dss_fixed_dh:
case CertificateRequest.cct_rsa_fixed_ecdh:
case CertificateRequest.cct_ecdsa_fixed_ecdh:
// Any other values (currently not used in TLS)
case CertificateRequest.cct_rsa_ephemeral_dh:
case CertificateRequest.cct_dss_ephemeral_dh:
//
// case CertificateRequest.cct_rsa_fixed_dh:
// case CertificateRequest.cct_dss_fixed_dh:
// case CertificateRequest.cct_rsa_fixed_ecdh:
// case CertificateRequest.cct_ecdsa_fixed_ecdh:
//
// Any other values (currently not used in TLS)
//
// case CertificateRequest.cct_rsa_ephemeral_dh:
// case CertificateRequest.cct_dss_ephemeral_dh:
default:
typeName = null;
break;
Expand Down Expand Up @@ -876,18 +932,6 @@ private void serverHelloDone(ServerHelloDone mesg) throws IOException {
X509Certificate[] certs = km.getCertificateChain(alias);
if ((certs != null) && (certs.length != 0)) {
PublicKey publicKey = certs[0].getPublicKey();
// for EC, make sure we use a supported named curve
if (publicKey instanceof ECPublicKey) {
ECParameterSpec params =
((ECPublicKey)publicKey).getParams();
int index =
SupportedEllipticCurvesExtension.getCurveIndex(
params);
if (!SupportedEllipticCurvesExtension.isSupported(
index)) {
publicKey = null;
}
}
if (publicKey != null) {
m1 = new CertificateMsg(certs);
signingKey = km.getPrivateKey(alias);
Expand Down Expand Up @@ -1366,6 +1410,44 @@ HandshakeMessage getKickstartMessage() throws SSLException {
session = null;
}

if ((session != null) && useExtendedMasterSecret) {
boolean isTLS10Plus = sessionVersion.v >= ProtocolVersion.TLS10.v;
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 (debug != null) {
if (Debug.isOn("handshake") || Debug.isOn("session")) {
Expand Down Expand Up @@ -1448,6 +1530,17 @@ HandshakeMessage getKickstartMessage() throws SSLException {
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);
clientHelloMessage.extensions.add(
EllipticPointFormatsExtension.DEFAULT);
}
}

// add signature_algorithm extension
if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) {
// we will always send the signature_algorithm extension
Expand All @@ -1461,6 +1554,14 @@ HandshakeMessage getKickstartMessage() throws SSLException {
clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
}

// add Extended Master Secret extension
if (useExtendedMasterSecret && (maxProtocolVersion.v >= ProtocolVersion.TLS10.v)) {
if ((session == null) || session.getUseExtendedMasterSecret()) {
clientHelloMessage.addExtendedMasterSecretExtension();
requestedToUseEMS = true;
}
}

// add server_name extension
if (enableSNIExtension) {
if (session != null) {
Expand Down Expand Up @@ -1536,7 +1637,11 @@ private void serverCertificate(CertificateMsg mesg) throws IOException {
// DO NOT need to check allowUnsafeServerCertChange here. We only
// reserve server certificates when allowUnsafeServerCertChange is
// 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
// identification is enabled.
String identityAlg = getEndpointIdentificationAlgorithmSE();
Expand Down
6 changes: 5 additions & 1 deletion bootstrap/src/main/java/sun/security/ssl/ExtensionType.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public String toString() {
return name;
}

static List<ExtensionType> knownExtensions = new ArrayList<ExtensionType>(9);
static List<ExtensionType> knownExtensions = new ArrayList<ExtensionType>(14);

static ExtensionType get(int id) {
for (ExtensionType ext : knownExtensions) {
Expand Down Expand Up @@ -111,6 +111,10 @@ private static ExtensionType e(int id, String name) {
final static ExtensionType EXT_SIGNATURE_ALGORITHMS =
e(0x000D, "signature_algorithms"); // IANA registry value: 13

// 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
final static ExtensionType EXT_RENEGOTIATION_INFO =
e(0xff01, "renegotiation_info"); // IANA registry value: 65281
Expand Down
14 changes: 8 additions & 6 deletions bootstrap/src/main/java/sun/security/ssl/HandshakeMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,10 @@ void addAlpnExtension(final SSLEngineImpl sslEngine) {
}
// END GRIZZLY NPN

void addExtendedMasterSecretExtension() {
extensions.add(new ExtendedMasterSecretExtension());
}

@Override
int messageType() { return ht_client_hello; }

Expand Down Expand Up @@ -1175,7 +1179,7 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
ECParameterSpec params = publicKey.getParams();
ECPoint point = publicKey.getW();
pointBytes = JsseJce.encodePoint(point, params.getCurve());
curveId = SupportedEllipticCurvesExtension.getCurveIndex(params);
curveId = EllipticCurvesExtension.getCurveIndex(params);

if (privateKey == null) {
// ECDH_anon
Expand All @@ -1189,7 +1193,7 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
} else {
sig = getSignature(privateKey.getAlgorithm());
}
sig.initSign(privateKey); // where is the SecureRandom?
sig.initSign(privateKey, sr);

updateSignature(sig, clntNonce, svrNonce);
signatureBytes = sig.sign();
Expand All @@ -1213,13 +1217,11 @@ class ECDH_ServerKeyExchange extends ServerKeyExchange {
// the supported curves during the exchange of the Hello messages.
if (curveType == CURVE_NAMED_CURVE) {
curveId = input.getInt16();
if (SupportedEllipticCurvesExtension.isSupported(curveId)
== false) {
if (!EllipticCurvesExtension.isSupported(curveId)) {
throw new SSLHandshakeException(
"Unsupported curveId: " + curveId);
}
String curveOid =
SupportedEllipticCurvesExtension.getCurveOid(curveId);
String curveOid = EllipticCurvesExtension.getCurveOid(curveId);
if (curveOid == null) {
throw new SSLHandshakeException(
"Unknown named curve: " + curveId);
Expand Down
Loading