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();