Skip to content

Commit d730183

Browse files
committed
Incorporate OpenJDK jdk-9.0.4+11 changes, which includes new support for RFC 7627 Extended Master Secret Extension so this commit takes out my code that was supporting Extended Master Secret
1 parent 2701485 commit d730183

File tree

7 files changed

+501
-447
lines changed

7 files changed

+501
-447
lines changed

src/main/java/sun/security/ssl/ClientHandshaker.java

Lines changed: 156 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -148,6 +148,10 @@ final class ClientHandshaker extends Handshaker {
148148
private static final boolean enableMFLExtension =
149149
Debug.getBooleanProperty("jsse.enableMFLExtension", false);
150150

151+
// To switch off the supported_groups extension for DHE cipher suite.
152+
private static final boolean enableFFDHE =
153+
Debug.getBooleanProperty("jsse.enableFFDHE", true);
154+
151155
// Whether an ALPN extension was sent in the ClientHello
152156
private boolean alpnActive = false;
153157

@@ -613,11 +617,6 @@ private void serverHello(ServerHello mesg) throws IOException {
613617

614618
// -- token binding etc. changes begin --
615619
setConnectionRandoms();
616-
617-
HelloExtension emsx = mesg.extensions.get(ExtensionType.EXT_EXTENDED_MASTER_SECRET);
618-
if (emsx != null) {
619-
isExtendedMasterSecretExtension = true;
620-
}
621620
// -- token binding etc. changes end --
622621

623622
if (isNegotiable(mesg.cipherSuite) == false) {
@@ -637,22 +636,6 @@ private void serverHello(ServerHello mesg) throws IOException {
637636
// NOTREACHED
638637
}
639638

640-
// -- token binding etc. changes begin --
641-
TokenBindingExtension tbx = (TokenBindingExtension) mesg.extensions.get(ExtensionType.EXT_TOKEN_BINDING);
642-
if (tbx != null) {
643-
byte[] requestedKeyParamsList = getConnectionSupportedTokenBindingKeyParams();
644-
645-
try {
646-
byte serverChosenKeyParams = tbx.processServerHello(isExtendedMasterSecretExtension,
647-
secureRenegotiation, requestedKeyParamsList);
648-
setConnectionNegotiatedTokenBindingKeyParams(serverChosenKeyParams);
649-
}
650-
catch (SSLHandshakeException e) {
651-
fatalSE(Alerts.alert_unsupported_extension, e.getMessage(), e);
652-
}
653-
}
654-
// -- token binding etc. changes end --
655-
656639
// so far so good, let's look at the session
657640
if (session != null) {
658641
// we tried to resume, let's see what the server decided
@@ -676,16 +659,18 @@ private void serverHello(ServerHello mesg) throws IOException {
676659

677660
// validate subject identity
678661
ClientKeyExchangeService p =
679-
ClientKeyExchangeService.find(sessionSuite.keyExchange.name);
662+
ClientKeyExchangeService.find(
663+
sessionSuite.keyExchange.name);
680664
if (p != null) {
681665
Principal localPrincipal = session.getLocalPrincipal();
682666

683667
if (p.isRelated(true, getAccSE(), localPrincipal)) {
684668
if (debug != null && Debug.isOn("session"))
685669
System.out.println("Subject identity is same");
686670
} else {
687-
throw new SSLProtocolException("Server resumed" +
688-
" session with wrong subject identity or no subject");
671+
throw new SSLProtocolException(
672+
"Server resumed session with " +
673+
"wrong subject identity or no subject");
689674
}
690675
}
691676

@@ -728,6 +713,70 @@ private void serverHello(ServerHello mesg) throws IOException {
728713
} // Otherwise, using the value negotiated during the original
729714
// session initiation
730715

716+
// check the "extended_master_secret" extension
717+
ExtendedMasterSecretExtension extendedMasterSecretExt =
718+
(ExtendedMasterSecretExtension)mesg.extensions.get(
719+
ExtensionType.EXT_EXTENDED_MASTER_SECRET);
720+
if (extendedMasterSecretExt != null) {
721+
// Is it the expected server extension?
722+
if (!useExtendedMasterSecret ||
723+
!mesgVersion.useTLS10PlusSpec() || !requestedToUseEMS) {
724+
fatalSE(Alerts.alert_unsupported_extension,
725+
"Server sent the extended_master_secret " +
726+
"extension improperly");
727+
}
728+
729+
// For abbreviated handshake, if the original session did not use
730+
// the "extended_master_secret" extension but the new ServerHello
731+
// contains the extension, the client MUST abort the handshake.
732+
if (resumingSession && (session != null) &&
733+
!session.getUseExtendedMasterSecret()) {
734+
fatalSE(Alerts.alert_unsupported_extension,
735+
"Server sent an unexpected extended_master_secret " +
736+
"extension on session resumption");
737+
}
738+
} else {
739+
if (useExtendedMasterSecret && !allowLegacyMasterSecret) {
740+
// For full handshake, if a client receives a ServerHello
741+
// without the extension, it SHOULD abort the handshake if
742+
// it does not wish to interoperate with legacy servers.
743+
fatalSE(Alerts.alert_handshake_failure,
744+
"Extended Master Secret extension is required");
745+
}
746+
747+
if (resumingSession && (session != null)) {
748+
if (session.getUseExtendedMasterSecret()) {
749+
// For abbreviated handshake, if the original session used
750+
// the "extended_master_secret" extension but the new
751+
// ServerHello does not contain the extension, the client
752+
// MUST abort the handshake.
753+
fatalSE(Alerts.alert_handshake_failure,
754+
"Missing Extended Master Secret extension " +
755+
"on session resumption");
756+
} else if (useExtendedMasterSecret && !allowLegacyResumption) {
757+
// Unlikely, abbreviated handshake should be discarded.
758+
fatalSE(Alerts.alert_handshake_failure,
759+
"Extended Master Secret extension is required");
760+
}
761+
}
762+
}
763+
764+
// -- token binding etc. changes begin --
765+
TokenBindingExtension tbx = (TokenBindingExtension) mesg.extensions.get(ExtensionType.EXT_TOKEN_BINDING);
766+
if (tbx != null) {
767+
byte[] requestedKeyParamsList = getConnectionSupportedTokenBindingKeyParams();
768+
769+
try {
770+
byte serverChosenKeyParams = tbx.processServerHello(extendedMasterSecretExt != null,
771+
secureRenegotiation, requestedKeyParamsList);
772+
setConnectionNegotiatedTokenBindingKeyParams(serverChosenKeyParams);
773+
}
774+
catch (SSLHandshakeException e) {
775+
fatalSE(Alerts.alert_unsupported_extension, e.getMessage(), e);
776+
}
777+
}
778+
// -- token binding etc. changes end --
779+
731780
// check the ALPN extension
732781
ALPNExtension serverHelloALPN =
733782
(ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN);
@@ -792,17 +841,19 @@ private void serverHello(ServerHello mesg) throws IOException {
792841
fatalSE(Alerts.alert_unexpected_message, "Server set " +
793842
type + " extension when not requested by client");
794843
}
795-
} else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
844+
} else if ((type != ExtensionType.EXT_SUPPORTED_GROUPS)
796845
&& (type != ExtensionType.EXT_EC_POINT_FORMATS)
797846
&& (type != ExtensionType.EXT_SERVER_NAME)
798847
&& (type != ExtensionType.EXT_ALPN)
799848
&& (type != ExtensionType.EXT_RENEGOTIATION_INFO)
849+
&& (type != ExtensionType.EXT_STATUS_REQUEST)
850+
&& (type != ExtensionType.EXT_STATUS_REQUEST_V2)
800851
// -- token binding etc. changes begin --
801852
&& (type != ExtensionType.EXT_TOKEN_BINDING)
802-
&& (type != ExtensionType.EXT_EXTENDED_MASTER_SECRET)
803853
// -- token binding etc. changes end --
804-
&& (type != ExtensionType.EXT_STATUS_REQUEST)
805-
&& (type != ExtensionType.EXT_STATUS_REQUEST_V2)) {
854+
&& (type != ExtensionType.EXT_EXTENDED_MASTER_SECRET)) {
855+
// Note: Better to check client requested extensions rather
856+
// than all supported extensions.
806857
fatalSE(Alerts.alert_unsupported_extension,
807858
"Server sent an unsupported extension: " + type);
808859
}
@@ -811,7 +862,8 @@ private void serverHello(ServerHello mesg) throws IOException {
811862
// Create a new session, we need to do the full handshake
812863
session = new SSLSessionImpl(protocolVersion, cipherSuite,
813864
getLocalSupportedSignAlgs(),
814-
mesg.sessionId, getHostSE(), getPortSE());
865+
mesg.sessionId, getHostSE(), getPortSE(),
866+
(extendedMasterSecretExt != null));
815867
session.setRequestedServerNames(requestedServerNames);
816868
session.setNegotiatedMaxFragSize(requestedMFLength);
817869
session.setMaximumPacketSize(maximumPacketSize);
@@ -852,6 +904,17 @@ private void serverKeyExchange(RSA_ServerKeyExchange mesg)
852904
* our own D-H algorithm object so we can defer key calculations
853905
* until after we've sent the client key exchange message (which
854906
* gives client and server some useful parallelism).
907+
*
908+
* Note per section 3 of RFC 7919, if the server is not compatible with
909+
* FFDHE specification, the client MAY decide to continue the connection
910+
* if the selected DHE group is acceptable under local policy, or it MAY
911+
* decide to terminate the connection with a fatal insufficient_security
912+
* (71) alert. The algorithm constraints mechanism is JDK local policy
913+
* used for additional DHE parameters checking. So this implementation
914+
* does not check the server compatibility and just pass to the local
915+
* algorithm constraints checking. The client will continue the
916+
* connection if the server selected DHE group is acceptable by the
917+
* specified algorithm constraints.
855918
*/
856919
private void serverKeyExchange(DH_ServerKeyExchange mesg)
857920
throws IOException {
@@ -1442,6 +1505,44 @@ HandshakeMessage getKickstartMessage() throws SSLException {
14421505
session = null;
14431506
}
14441507

1508+
if ((session != null) && useExtendedMasterSecret) {
1509+
boolean isTLS10Plus = sessionVersion.useTLS10PlusSpec();
1510+
if (isTLS10Plus && !session.getUseExtendedMasterSecret()) {
1511+
if (!allowLegacyResumption) {
1512+
// perform full handshake instead
1513+
//
1514+
// The client SHOULD NOT offer an abbreviated handshake
1515+
// to resume a session that does not use an extended
1516+
// master secret. Instead, it SHOULD offer a full
1517+
// handshake.
1518+
session = null;
1519+
}
1520+
}
1521+
1522+
if ((session != null) && !allowUnsafeServerCertChange) {
1523+
// It is fine to move on with abbreviate handshake if
1524+
// endpoint identification is enabled.
1525+
String identityAlg = getEndpointIdentificationAlgorithmSE();
1526+
if ((identityAlg == null || identityAlg.length() == 0)) {
1527+
if (isTLS10Plus) {
1528+
if (!session.getUseExtendedMasterSecret()) {
1529+
// perform full handshake instead
1530+
session = null;
1531+
} // Otherwise, use extended master secret.
1532+
} else {
1533+
// The extended master secret extension does not
1534+
// apply to SSL 3.0. Perform a full handshake
1535+
// instead.
1536+
//
1537+
// Note that the useExtendedMasterSecret is
1538+
// extended to protect SSL 3.0 connections,
1539+
// by discarding abbreviate handshake.
1540+
session = null;
1541+
}
1542+
}
1543+
}
1544+
}
1545+
14451546
if (session != null) {
14461547
if (debug != null) {
14471548
if (Debug.isOn("handshake") || Debug.isOn("session")) {
@@ -1524,14 +1625,17 @@ HandshakeMessage getKickstartMessage() throws SSLException {
15241625
sslContext.getSecureRandom(), maxProtocolVersion,
15251626
sessionId, cipherSuites, isDTLS);
15261627

1527-
// add elliptic curves and point format extensions
1528-
if (cipherSuites.containsEC()) {
1529-
EllipticCurvesExtension ece =
1530-
EllipticCurvesExtension.createExtension(algorithmConstraints);
1531-
if (ece != null) {
1532-
clientHelloMessage.extensions.add(ece);
1628+
// Add named groups extension for ECDHE and FFDHE if necessary.
1629+
SupportedGroupsExtension sge =
1630+
SupportedGroupsExtension.createExtension(
1631+
algorithmConstraints,
1632+
cipherSuites, enableFFDHE);
1633+
if (sge != null) {
1634+
clientHelloMessage.extensions.add(sge);
1635+
// Add elliptic point format extensions
1636+
if (cipherSuites.contains(NamedGroupType.NAMED_GROUP_ECDHE)) {
15331637
clientHelloMessage.extensions.add(
1534-
EllipticPointFormatsExtension.DEFAULT);
1638+
EllipticPointFormatsExtension.DEFAULT);
15351639
}
15361640
}
15371641

@@ -1548,6 +1652,14 @@ HandshakeMessage getKickstartMessage() throws SSLException {
15481652
clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
15491653
}
15501654

1655+
// add Extended Master Secret extension
1656+
if (useExtendedMasterSecret && maxProtocolVersion.useTLS10PlusSpec()) {
1657+
if ((session == null) || session.getUseExtendedMasterSecret()) {
1658+
clientHelloMessage.addExtendedMasterSecretExtension();
1659+
requestedToUseEMS = true;
1660+
}
1661+
}
1662+
15511663
// add server_name extension
15521664
if (enableSNIExtension) {
15531665
if (session != null) {
@@ -1626,8 +1738,7 @@ HandshakeMessage getKickstartMessage() throws SSLException {
16261738
// -- token binding etc. changes begin --
16271739
byte[] supportedTokenBindingKeyParams = getConnectionSupportedTokenBindingKeyParams();
16281740

1629-
if (supportedTokenBindingKeyParams != null && supportedTokenBindingKeyParams.length > 0) {
1630-
clientHelloMessage.extensions.add(new ExtendedMasterSecretExtension());
1741+
if (supportedTokenBindingKeyParams != null && supportedTokenBindingKeyParams.length > 0 && requestedToUseEMS) {
16311742
clientHelloMessage.extensions.add(new TokenBindingExtension(1, 0, supportedTokenBindingKeyParams));
16321743
}
16331744
// -- token binding etc. changes end --
@@ -1672,10 +1783,14 @@ private void serverCertificate(CertificateMsg mesg) throws IOException {
16721783
// Allow server certificate change in client side during renegotiation
16731784
// after a session-resumption abbreviated initial handshake?
16741785
//
1675-
// DO NOT need to check allowUnsafeServerCertChange here. We only
1786+
// DO NOT need to check allowUnsafeServerCertChange here. We only
16761787
// reserve server certificates when allowUnsafeServerCertChange is
16771788
// flase.
1678-
if (reservedServerCerts != null) {
1789+
//
1790+
// Allow server certificate change if it is negotiated to use the
1791+
// extended master secret.
1792+
if ((reservedServerCerts != null) &&
1793+
!session.getUseExtendedMasterSecret()) {
16791794
// It is not necessary to check the certificate update if endpoint
16801795
// identification is enabled.
16811796
String identityAlg = getEndpointIdentificationAlgorithmSE();

src/main/java/sun/security/ssl/ExtendedMasterSecretExtension.java

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)