src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
Print this page
8144566 Custom HostnameVerifier disables SNI extension
*** 207,216 ****
--- 207,222 ----
List<SNIServerName> serverNames =
Collections.<SNIServerName>emptyList();
Collection<SNIMatcher> sniMatchers =
Collections.<SNIMatcher>emptyList();
+ // Is the serverNames set to empty with SSLParameters.setServerNames()?
+ private boolean noSniExtension = false;
+
+ // Is the sniMatchers set to empty with SSLParameters.setSNIMatchers()?
+ private boolean noSniMatcher = false;
+
// Configured application protocol values
String[] applicationProtocols = new String[0];
// Negotiated application protocol value.
//
*** 640,649 ****
--- 646,660 ----
throw new SocketException(
"Cannot handle non-Inet socket addresses.");
}
super.connect(endpoint, timeout);
+
+ if (host == null || host.length() == 0) {
+ useImplicitHost(false);
+ }
+
doneConnect();
}
/**
* Initialize the handshaker and socket streams.
*** 2096,2152 ****
synchronized void setVersion(ProtocolVersion protocolVersion) {
this.protocolVersion = protocolVersion;
outputRecord.setVersion(protocolVersion);
}
synchronized String getHost() {
// Note that the host may be null or empty for localhost.
if (host == null || host.length() == 0) {
! if (!trustNameService) {
! // If the local name service is not trustworthy, reverse host
! // name resolution should not be performed for endpoint
! // identification. Use the application original specified
! // hostname or IP address instead.
! host = getOriginalHostname(getInetAddress());
! } else {
! host = getInetAddress().getHostName();
}
- }
return host;
}
/*
! * Get the original application specified hostname.
*/
! private static String getOriginalHostname(InetAddress inetAddress) {
! /*
! * Get the original hostname via jdk.internal.misc.SharedSecrets.
! */
! JavaNetInetAddressAccess jna = SharedSecrets.getJavaNetInetAddressAccess();
String originalHostname = jna.getOriginalHostName(inetAddress);
! /*
! * If no application specified hostname, use the IP address.
! */
! if (originalHostname == null || originalHostname.length() == 0) {
! originalHostname = inetAddress.getHostAddress();
}
! return originalHostname;
}
// ONLY used by HttpsClient to setup the URI specified hostname
//
// Please NOTE that this method MUST be called before calling to
// SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter
// may override SNIHostName in the customized server name indication.
public synchronized void setHost(String host) {
this.host = host;
this.serverNames =
Utilities.addToSNIServerNameList(this.serverNames, this.host);
}
/**
* Gets an input stream to read from the peer on the other side.
* Data read from this stream was always integrity protected in
* transit, and will usually have been confidentiality protected.
--- 2107,2188 ----
synchronized void setVersion(ProtocolVersion protocolVersion) {
this.protocolVersion = protocolVersion;
outputRecord.setVersion(protocolVersion);
}
+ //
+ // ONLY used by ClientHandshaker for the server hostname during handshaking
+ //
synchronized String getHost() {
// Note that the host may be null or empty for localhost.
if (host == null || host.length() == 0) {
! useImplicitHost(true);
}
return host;
}
/*
! * Try to set and use the implicit specified hostname
*/
! private synchronized void useImplicitHost(boolean noSniUpdate) {
!
! // Note: If the local name service is not trustworthy, reverse
! // host name resolution should not be performed for endpoint
! // identification. Use the application original specified
! // hostname or IP address instead.
!
! // Get the original hostname via jdk.internal.misc.SharedSecrets
! InetAddress inetAddress = getInetAddress();
! if (inetAddress == null) { // not connected
! return;
! }
!
! JavaNetInetAddressAccess jna =
! SharedSecrets.getJavaNetInetAddressAccess();
String originalHostname = jna.getOriginalHostName(inetAddress);
+ if ((originalHostname != null) &&
+ (originalHostname.length() != 0)) {
! host = originalHostname;
! if (!noSniUpdate && serverNames.isEmpty() && !noSniExtension) {
! serverNames =
! Utilities.addToSNIServerNameList(serverNames, host);
!
! if (!roleIsServer &&
! (handshaker != null) && !handshaker.started()) {
! handshaker.setSNIServerNames(serverNames);
}
+ }
! return;
}
+ // No explicitly specified hostname, no server name indication.
+ if (!trustNameService) {
+ // The local name service is not trustworthy, use IP address.
+ host = inetAddress.getHostAddress();
+ } else {
+ // Use the underlying reverse host name resolution service.
+ host = getInetAddress().getHostName();
+ }
+ }
+
// ONLY used by HttpsClient to setup the URI specified hostname
//
// Please NOTE that this method MUST be called before calling to
// SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter
// may override SNIHostName in the customized server name indication.
public synchronized void setHost(String host) {
this.host = host;
this.serverNames =
Utilities.addToSNIServerNameList(this.serverNames, this.host);
+
+ if (!roleIsServer && (handshaker != null) && !handshaker.started()) {
+ handshaker.setSNIServerNames(serverNames);
}
+ }
/**
* Gets an input stream to read from the peer on the other side.
* Data read from this stream was always integrity protected in
* transit, and will usually have been confidentiality protected.
*** 2531,2542 ****
--- 2567,2591 ----
SSLParameters params = super.getSSLParameters();
// the super implementation does not handle the following parameters
params.setEndpointIdentificationAlgorithm(identificationProtocol);
params.setAlgorithmConstraints(algorithmConstraints);
+
+ if (sniMatchers.isEmpty() && !noSniMatcher) {
+ // 'null' indicates none has been set
+ params.setSNIMatchers(null);
+ } else {
params.setSNIMatchers(sniMatchers);
+ }
+
+ if (serverNames.isEmpty() && !noSniExtension) {
+ // 'null' indicates none has been set
+ params.setServerNames(null);
+ } else {
params.setServerNames(serverNames);
+ }
+
params.setUseCipherSuitesOrder(preferLocalCipherSuites);
params.setMaximumPacketSize(maximumPacketSize);
params.setApplicationProtocols(applicationProtocols);
// DTLS handshake retransmissions parameter does not apply here.
*** 2566,2580 ****
--- 2615,2631 ----
maximumPacketSize = outputRecord.getMaxPacketSize();
}
List<SNIServerName> sniNames = params.getServerNames();
if (sniNames != null) {
+ noSniExtension = sniNames.isEmpty();
serverNames = sniNames;
}
Collection<SNIMatcher> matchers = params.getSNIMatchers();
if (matchers != null) {
+ noSniMatcher = matchers.isEmpty();
sniMatchers = matchers;
}
applicationProtocols = params.getApplicationProtocols();