Skip to content

Commit

Permalink
Fix for grizzly-npn support for JDK8u161/JDK8u162
Browse files Browse the repository at this point in the history
  • Loading branch information
anajosep committed Feb 26, 2018
1 parent b46c70c commit d084264
Show file tree
Hide file tree
Showing 6 changed files with 361 additions and 75 deletions.
153 changes: 129 additions & 24 deletions bootstrap/src/main/java/sun/security/ssl/ClientHandshaker.java
Expand Up @@ -631,15 +631,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 @@ -663,8 +714,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 @@ -697,7 +749,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 @@ -815,13 +868,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 @@ -852,18 +908,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 @@ -1342,6 +1386,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 @@ -1424,6 +1506,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 @@ -1437,6 +1530,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 @@ -1512,7 +1613,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
Expand Up @@ -34,7 +34,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 @@ -87,6 +87,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
Expand Up @@ -415,6 +415,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 @@ -1151,7 +1155,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 @@ -1165,7 +1169,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 @@ -1189,13 +1193,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

0 comments on commit d084264

Please sign in to comment.