src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java

Print this page
8144566 Custom HostnameVerifier disables SNI extension


 192     private boolean             enableSessionCreation = true;
 193     private String              host;
 194     private boolean             autoClose = true;
 195     private AccessControlContext acc;
 196 
 197     // The cipher suites enabled for use on this connection.
 198     private CipherSuiteList     enabledCipherSuites;
 199 
 200     // The endpoint identification protocol
 201     private String              identificationProtocol = null;
 202 
 203     // The cryptographic algorithm constraints
 204     private AlgorithmConstraints    algorithmConstraints = null;
 205 
 206     // The server name indication and matchers
 207     List<SNIServerName>         serverNames =
 208                                     Collections.<SNIServerName>emptyList();
 209     Collection<SNIMatcher>      sniMatchers =
 210                                     Collections.<SNIMatcher>emptyList();
 211 






 212     // Configured application protocol values
 213     String[] applicationProtocols = new String[0];
 214 
 215     // Negotiated application protocol value.
 216     //
 217     // The value under negotiation will be obtained from handshaker.
 218     String applicationProtocol = null;
 219 
 220     /*
 221      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 222      * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
 223      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 224      *
 225      * There are several locks here.
 226      *
 227      * The primary lock is the per-instance lock used by
 228      * synchronized(this) and the synchronized methods.  It controls all
 229      * access to things such as the connection state and variables which
 230      * affect handshaking.  If we are inside a synchronized method, we
 231      * can access the state directly, otherwise, we must use the


 625      *
 626      * @param   endpoint the <code>SocketAddress</code>
 627      * @param   timeout  the timeout value to be used, 0 is no timeout
 628      * @throws  IOException if an error occurs during the connection
 629      * @throws  SocketTimeoutException if timeout expires before connecting
 630      */
 631     @Override
 632     public void connect(SocketAddress endpoint, int timeout)
 633             throws IOException {
 634 
 635         if (isLayered()) {
 636             throw new SocketException("Already connected");
 637         }
 638 
 639         if (!(endpoint instanceof InetSocketAddress)) {
 640             throw new SocketException(
 641                                   "Cannot handle non-Inet socket addresses.");
 642         }
 643 
 644         super.connect(endpoint, timeout);





 645         doneConnect();
 646     }
 647 
 648     /**
 649      * Initialize the handshaker and socket streams.
 650      *
 651      * Called by connect, the layered constructor, and SSLServerSocket.
 652      */
 653     void doneConnect() throws IOException {
 654         /*
 655          * Save the input and output streams.  May be done only after
 656          * java.net actually connects using the socket "self", else
 657          * we get some pretty bizarre failure modes.
 658          */
 659         sockInput = super.getInputStream();
 660         sockOutput = super.getOutputStream();
 661 
 662         inputRecord.setDeliverStream(sockOutput);
 663         outputRecord.setDeliverStream(sockOutput);
 664 


2081         CipherBox writeCipher;
2082         try {
2083             writeCipher = handshaker.newWriteCipher();
2084             writeAuthenticator = handshaker.newWriteAuthenticator();
2085         } catch (GeneralSecurityException e) {
2086             // "can't happen"
2087             throw new SSLException("Algorithm missing:  ", e);
2088         }
2089         outputRecord.changeWriteCiphers(writeAuthenticator, writeCipher);
2090     }
2091 
2092     /*
2093      * Updates the SSL version associated with this connection.
2094      * Called from Handshaker once it has determined the negotiated version.
2095      */
2096     synchronized void setVersion(ProtocolVersion protocolVersion) {
2097         this.protocolVersion = protocolVersion;
2098         outputRecord.setVersion(protocolVersion);
2099     }
2100 



2101     synchronized String getHost() {
2102         // Note that the host may be null or empty for localhost.
2103         if (host == null || host.length() == 0) {
2104             if (!trustNameService) {
2105                 // If the local name service is not trustworthy, reverse host
2106                 // name resolution should not be performed for endpoint
2107                 // identification.  Use the application original specified
2108                 // hostname or IP address instead.
2109                 host = getOriginalHostname(getInetAddress());
2110             } else {
2111                 host = getInetAddress().getHostName();
2112             }
2113         }
2114 
2115         return host;
2116     }
2117 
2118     /*
2119      * Get the original application specified hostname.
2120      */
2121     private static String getOriginalHostname(InetAddress inetAddress) {
2122         /*
2123          * Get the original hostname via jdk.internal.misc.SharedSecrets.
2124          */
2125         JavaNetInetAddressAccess jna = SharedSecrets.getJavaNetInetAddressAccess();










2126         String originalHostname = jna.getOriginalHostName(inetAddress);


2127 
2128         /*
2129          * If no application specified hostname, use the IP address.
2130          */
2131         if (originalHostname == null || originalHostname.length() == 0) {
2132             originalHostname = inetAddress.getHostAddress();



2133         }

2134 
2135         return originalHostname;
2136     }
2137 










2138     // ONLY used by HttpsClient to setup the URI specified hostname
2139     //
2140     // Please NOTE that this method MUST be called before calling to
2141     // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter
2142     // may override SNIHostName in the customized server name indication.
2143     public synchronized void setHost(String host) {
2144         this.host = host;
2145         this.serverNames =
2146             Utilities.addToSNIServerNameList(this.serverNames, this.host);



2147     }

2148 
2149     /**
2150      * Gets an input stream to read from the peer on the other side.
2151      * Data read from this stream was always integrity protected in
2152      * transit, and will usually have been confidentiality protected.
2153      */
2154     @Override
2155     public synchronized InputStream getInputStream() throws IOException {
2156         if (isClosed()) {
2157             throw new SocketException("Socket is closed");
2158         }
2159 
2160         /*
2161          * Can't call isConnected() here, because the Handshakers
2162          * do some initialization before we actually connect.
2163          */
2164         if (connectionState == cs_START) {
2165             throw new SocketException("Socket is not connected");
2166         }
2167 


2516             throw new IllegalArgumentException("no listeners");
2517         }
2518         if (handshakeListeners.remove(listener) == null) {
2519             throw new IllegalArgumentException("listener not registered");
2520         }
2521         if (handshakeListeners.isEmpty()) {
2522             handshakeListeners = null;
2523         }
2524     }
2525 
2526     /**
2527      * Returns the SSLParameters in effect for this SSLSocket.
2528      */
2529     @Override
2530     public synchronized SSLParameters getSSLParameters() {
2531         SSLParameters params = super.getSSLParameters();
2532 
2533         // the super implementation does not handle the following parameters
2534         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2535         params.setAlgorithmConstraints(algorithmConstraints);





2536         params.setSNIMatchers(sniMatchers);






2537         params.setServerNames(serverNames);


2538         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
2539         params.setMaximumPacketSize(maximumPacketSize);
2540         params.setApplicationProtocols(applicationProtocols);
2541 
2542         // DTLS handshake retransmissions parameter does not apply here.
2543 
2544         return params;
2545     }
2546 
2547     /**
2548      * Applies SSLParameters to this socket.
2549      */
2550     @Override
2551     public synchronized void setSSLParameters(SSLParameters params) {
2552         super.setSSLParameters(params);
2553 
2554         // the super implementation does not handle the following parameters
2555         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2556         algorithmConstraints = params.getAlgorithmConstraints();
2557         preferLocalCipherSuites = params.getUseCipherSuitesOrder();
2558         maximumPacketSize = params.getMaximumPacketSize();
2559 
2560         // DTLS handshake retransmissions parameter does not apply here.
2561 
2562         if (maximumPacketSize != 0) {
2563             outputRecord.changePacketSize(maximumPacketSize);
2564         } else {
2565             // use the implicit maximum packet size.
2566             maximumPacketSize = outputRecord.getMaxPacketSize();
2567         }
2568 
2569         List<SNIServerName> sniNames = params.getServerNames();
2570         if (sniNames != null) {

2571             serverNames = sniNames;
2572         }
2573 
2574         Collection<SNIMatcher> matchers = params.getSNIMatchers();
2575         if (matchers != null) {

2576             sniMatchers = matchers;
2577         }
2578 
2579         applicationProtocols = params.getApplicationProtocols();
2580 
2581         if ((handshaker != null) && !handshaker.started()) {
2582             handshaker.setIdentificationProtocol(identificationProtocol);
2583             handshaker.setAlgorithmConstraints(algorithmConstraints);
2584             handshaker.setMaximumPacketSize(maximumPacketSize);
2585             handshaker.setApplicationProtocols(applicationProtocols);
2586             if (roleIsServer) {
2587                 handshaker.setSNIMatchers(sniMatchers);
2588                 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
2589             } else {
2590                 handshaker.setSNIServerNames(serverNames);
2591             }
2592         }
2593     }
2594 
2595     @Override




 192     private boolean             enableSessionCreation = true;
 193     private String              host;
 194     private boolean             autoClose = true;
 195     private AccessControlContext acc;
 196 
 197     // The cipher suites enabled for use on this connection.
 198     private CipherSuiteList     enabledCipherSuites;
 199 
 200     // The endpoint identification protocol
 201     private String              identificationProtocol = null;
 202 
 203     // The cryptographic algorithm constraints
 204     private AlgorithmConstraints    algorithmConstraints = null;
 205 
 206     // The server name indication and matchers
 207     List<SNIServerName>         serverNames =
 208                                     Collections.<SNIServerName>emptyList();
 209     Collection<SNIMatcher>      sniMatchers =
 210                                     Collections.<SNIMatcher>emptyList();
 211 
 212     // Is the serverNames set to empty with SSLParameters.setServerNames()?
 213     private boolean             noSniExtension = false;
 214 
 215     // Is the sniMatchers set to empty with SSLParameters.setSNIMatchers()?
 216     private boolean             noSniMatcher = false;
 217 
 218     // Configured application protocol values
 219     String[] applicationProtocols = new String[0];
 220 
 221     // Negotiated application protocol value.
 222     //
 223     // The value under negotiation will be obtained from handshaker.
 224     String applicationProtocol = null;
 225 
 226     /*
 227      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 228      * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
 229      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
 230      *
 231      * There are several locks here.
 232      *
 233      * The primary lock is the per-instance lock used by
 234      * synchronized(this) and the synchronized methods.  It controls all
 235      * access to things such as the connection state and variables which
 236      * affect handshaking.  If we are inside a synchronized method, we
 237      * can access the state directly, otherwise, we must use the


 631      *
 632      * @param   endpoint the <code>SocketAddress</code>
 633      * @param   timeout  the timeout value to be used, 0 is no timeout
 634      * @throws  IOException if an error occurs during the connection
 635      * @throws  SocketTimeoutException if timeout expires before connecting
 636      */
 637     @Override
 638     public void connect(SocketAddress endpoint, int timeout)
 639             throws IOException {
 640 
 641         if (isLayered()) {
 642             throw new SocketException("Already connected");
 643         }
 644 
 645         if (!(endpoint instanceof InetSocketAddress)) {
 646             throw new SocketException(
 647                                   "Cannot handle non-Inet socket addresses.");
 648         }
 649 
 650         super.connect(endpoint, timeout);
 651 
 652         if (host == null || host.length() == 0) {
 653             useImplicitHost(false);
 654         }
 655 
 656         doneConnect();
 657     }
 658 
 659     /**
 660      * Initialize the handshaker and socket streams.
 661      *
 662      * Called by connect, the layered constructor, and SSLServerSocket.
 663      */
 664     void doneConnect() throws IOException {
 665         /*
 666          * Save the input and output streams.  May be done only after
 667          * java.net actually connects using the socket "self", else
 668          * we get some pretty bizarre failure modes.
 669          */
 670         sockInput = super.getInputStream();
 671         sockOutput = super.getOutputStream();
 672 
 673         inputRecord.setDeliverStream(sockOutput);
 674         outputRecord.setDeliverStream(sockOutput);
 675 


2092         CipherBox writeCipher;
2093         try {
2094             writeCipher = handshaker.newWriteCipher();
2095             writeAuthenticator = handshaker.newWriteAuthenticator();
2096         } catch (GeneralSecurityException e) {
2097             // "can't happen"
2098             throw new SSLException("Algorithm missing:  ", e);
2099         }
2100         outputRecord.changeWriteCiphers(writeAuthenticator, writeCipher);
2101     }
2102 
2103     /*
2104      * Updates the SSL version associated with this connection.
2105      * Called from Handshaker once it has determined the negotiated version.
2106      */
2107     synchronized void setVersion(ProtocolVersion protocolVersion) {
2108         this.protocolVersion = protocolVersion;
2109         outputRecord.setVersion(protocolVersion);
2110     }
2111 
2112     //
2113     // ONLY used by ClientHandshaker for the server hostname during handshaking
2114     //
2115     synchronized String getHost() {
2116         // Note that the host may be null or empty for localhost.
2117         if (host == null || host.length() == 0) {
2118             useImplicitHost(true);







2119         }

2120 
2121         return host;
2122     }
2123 
2124     /*
2125      * Try to set and use the implicit specified hostname
2126      */
2127     private synchronized void useImplicitHost(boolean noSniUpdate) {
2128 
2129         // Note: If the local name service is not trustworthy, reverse
2130         // host name resolution should not be performed for endpoint
2131         // identification.  Use the application original specified
2132         // hostname or IP address instead.
2133 
2134         // Get the original hostname via jdk.internal.misc.SharedSecrets
2135         InetAddress inetAddress = getInetAddress();
2136         if (inetAddress == null) {      // not connected
2137             return;
2138         }
2139 
2140         JavaNetInetAddressAccess jna =
2141                 SharedSecrets.getJavaNetInetAddressAccess();
2142         String originalHostname = jna.getOriginalHostName(inetAddress);
2143         if ((originalHostname != null) &&
2144                 (originalHostname.length() != 0)) {
2145 
2146             host = originalHostname;
2147             if (!noSniUpdate && serverNames.isEmpty() && !noSniExtension) {
2148                 serverNames =
2149                         Utilities.addToSNIServerNameList(serverNames, host);
2150 
2151                 if (!roleIsServer &&
2152                         (handshaker != null) && !handshaker.started()) {
2153                     handshaker.setSNIServerNames(serverNames);
2154                 }
2155             }
2156 
2157             return;
2158         }
2159 
2160         // No explicitly specified hostname, no server name indication.
2161         if (!trustNameService) {
2162             // The local name service is not trustworthy, use IP address.
2163             host = inetAddress.getHostAddress();
2164         } else {
2165             // Use the underlying reverse host name resolution service.
2166             host = getInetAddress().getHostName();
2167         }
2168     }
2169 
2170     // ONLY used by HttpsClient to setup the URI specified hostname
2171     //
2172     // Please NOTE that this method MUST be called before calling to
2173     // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter
2174     // may override SNIHostName in the customized server name indication.
2175     public synchronized void setHost(String host) {
2176         this.host = host;
2177         this.serverNames =
2178             Utilities.addToSNIServerNameList(this.serverNames, this.host);
2179 
2180         if (!roleIsServer && (handshaker != null) && !handshaker.started()) {
2181             handshaker.setSNIServerNames(serverNames);
2182         }
2183     }
2184 
2185     /**
2186      * Gets an input stream to read from the peer on the other side.
2187      * Data read from this stream was always integrity protected in
2188      * transit, and will usually have been confidentiality protected.
2189      */
2190     @Override
2191     public synchronized InputStream getInputStream() throws IOException {
2192         if (isClosed()) {
2193             throw new SocketException("Socket is closed");
2194         }
2195 
2196         /*
2197          * Can't call isConnected() here, because the Handshakers
2198          * do some initialization before we actually connect.
2199          */
2200         if (connectionState == cs_START) {
2201             throw new SocketException("Socket is not connected");
2202         }
2203 


2552             throw new IllegalArgumentException("no listeners");
2553         }
2554         if (handshakeListeners.remove(listener) == null) {
2555             throw new IllegalArgumentException("listener not registered");
2556         }
2557         if (handshakeListeners.isEmpty()) {
2558             handshakeListeners = null;
2559         }
2560     }
2561 
2562     /**
2563      * Returns the SSLParameters in effect for this SSLSocket.
2564      */
2565     @Override
2566     public synchronized SSLParameters getSSLParameters() {
2567         SSLParameters params = super.getSSLParameters();
2568 
2569         // the super implementation does not handle the following parameters
2570         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2571         params.setAlgorithmConstraints(algorithmConstraints);
2572 
2573         if (sniMatchers.isEmpty() && !noSniMatcher) {
2574             // 'null' indicates none has been set
2575             params.setSNIMatchers(null);
2576         } else {
2577             params.setSNIMatchers(sniMatchers);
2578         }
2579 
2580         if (serverNames.isEmpty() && !noSniExtension) {
2581             // 'null' indicates none has been set
2582             params.setServerNames(null);
2583         } else {
2584             params.setServerNames(serverNames);
2585         }
2586 
2587         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
2588         params.setMaximumPacketSize(maximumPacketSize);
2589         params.setApplicationProtocols(applicationProtocols);
2590 
2591         // DTLS handshake retransmissions parameter does not apply here.
2592 
2593         return params;
2594     }
2595 
2596     /**
2597      * Applies SSLParameters to this socket.
2598      */
2599     @Override
2600     public synchronized void setSSLParameters(SSLParameters params) {
2601         super.setSSLParameters(params);
2602 
2603         // the super implementation does not handle the following parameters
2604         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2605         algorithmConstraints = params.getAlgorithmConstraints();
2606         preferLocalCipherSuites = params.getUseCipherSuitesOrder();
2607         maximumPacketSize = params.getMaximumPacketSize();
2608 
2609         // DTLS handshake retransmissions parameter does not apply here.
2610 
2611         if (maximumPacketSize != 0) {
2612             outputRecord.changePacketSize(maximumPacketSize);
2613         } else {
2614             // use the implicit maximum packet size.
2615             maximumPacketSize = outputRecord.getMaxPacketSize();
2616         }
2617 
2618         List<SNIServerName> sniNames = params.getServerNames();
2619         if (sniNames != null) {
2620             noSniExtension = sniNames.isEmpty();
2621             serverNames = sniNames;
2622         }
2623 
2624         Collection<SNIMatcher> matchers = params.getSNIMatchers();
2625         if (matchers != null) {
2626             noSniMatcher = matchers.isEmpty();
2627             sniMatchers = matchers;
2628         }
2629 
2630         applicationProtocols = params.getApplicationProtocols();
2631 
2632         if ((handshaker != null) && !handshaker.started()) {
2633             handshaker.setIdentificationProtocol(identificationProtocol);
2634             handshaker.setAlgorithmConstraints(algorithmConstraints);
2635             handshaker.setMaximumPacketSize(maximumPacketSize);
2636             handshaker.setApplicationProtocols(applicationProtocols);
2637             if (roleIsServer) {
2638                 handshaker.setSNIMatchers(sniMatchers);
2639                 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
2640             } else {
2641                 handshaker.setSNIServerNames(serverNames);
2642             }
2643         }
2644     }
2645 
2646     @Override