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
|