author | redestad |
Thu, 13 Dec 2018 15:31:05 +0100 | |
changeset 53018 | 8bf9268df0e2 |
parent 52474 | 13266dac5fdb |
child 57968 | 8595871a5446 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
52474
13266dac5fdb
8212261: Add SSLSession accessors to HttpsURLConnection and SecureCacheResponse
xuelei
parents:
50768
diff
changeset
|
2 |
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
||
27 |
package sun.net.www.protocol.https; |
|
28 |
||
29 |
import java.io.IOException; |
|
30 |
import java.io.UnsupportedEncodingException; |
|
31 |
import java.io.PrintStream; |
|
32 |
import java.io.BufferedOutputStream; |
|
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
33 |
import java.net.InetAddress; |
2 | 34 |
import java.net.Socket; |
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
35 |
import java.net.SocketException; |
2 | 36 |
import java.net.URL; |
37 |
import java.net.UnknownHostException; |
|
38 |
import java.net.InetSocketAddress; |
|
39 |
import java.net.Proxy; |
|
40 |
import java.security.Principal; |
|
41 |
import java.security.cert.*; |
|
42351
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
42 |
import java.util.Objects; |
2 | 43 |
import java.util.StringTokenizer; |
44 |
import java.util.Vector; |
|
45 |
||
46 |
import javax.security.auth.x500.X500Principal; |
|
47 |
||
48 |
import javax.net.ssl.*; |
|
49 |
import sun.net.www.http.HttpClient; |
|
42351
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
50 |
import sun.net.www.protocol.http.AuthenticatorKeys; |
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
51 |
import sun.net.www.protocol.http.HttpURLConnection; |
2 | 52 |
import sun.security.action.*; |
53 |
||
54 |
import sun.security.util.HostnameChecker; |
|
55 |
import sun.security.ssl.SSLSocketImpl; |
|
56 |
||
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
57 |
import sun.util.logging.PlatformLogger; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
58 |
import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
59 |
|
2 | 60 |
|
61 |
/** |
|
62 |
* This class provides HTTPS client URL support, building on the standard |
|
63 |
* "sun.net.www" HTTP protocol handler. HTTPS is the same protocol as HTTP, |
|
64 |
* but differs in the transport layer which it uses: <UL> |
|
65 |
* |
|
66 |
* <LI>There's a <em>Secure Sockets Layer</em> between TCP |
|
67 |
* and the HTTP protocol code. |
|
68 |
* |
|
69 |
* <LI>It uses a different default TCP port. |
|
70 |
* |
|
71 |
* <LI>It doesn't use application level proxies, which can see and |
|
72 |
* manipulate HTTP user level data, compromising privacy. It uses |
|
73 |
* low level tunneling instead, which hides HTTP protocol and data |
|
74 |
* from all third parties. (Traffic analysis is still possible). |
|
75 |
* |
|
76 |
* <LI>It does basic server authentication, to protect |
|
77 |
* against "URL spoofing" attacks. This involves deciding |
|
78 |
* whether the X.509 certificate chain identifying the server |
|
79 |
* is trusted, and verifying that the name of the server is |
|
80 |
* found in the certificate. (The application may enable an |
|
81 |
* anonymous SSL cipher suite, and such checks are not done |
|
82 |
* for anonymous ciphers.) |
|
83 |
* |
|
84 |
* <LI>It exposes key SSL session attributes, specifically the |
|
85 |
* cipher suite in use and the server's X509 certificates, to |
|
86 |
* application software which knows about this protocol handler. |
|
87 |
* |
|
88 |
* </UL> |
|
89 |
* |
|
90 |
* <P> System properties used include: <UL> |
|
91 |
* |
|
92 |
* <LI><em>https.proxyHost</em> ... the host supporting SSL |
|
93 |
* tunneling using the conventional CONNECT syntax |
|
94 |
* |
|
95 |
* <LI><em>https.proxyPort</em> ... port to use on proxyHost |
|
96 |
* |
|
97 |
* <LI><em>https.cipherSuites</em> ... comma separated list of |
|
98 |
* SSL cipher suite names to enable. |
|
99 |
* |
|
100 |
* <LI><em>http.nonProxyHosts</em> ... |
|
101 |
* |
|
102 |
* </UL> |
|
103 |
* |
|
104 |
* @author David Brownell |
|
105 |
* @author Bill Foote |
|
106 |
*/ |
|
107 |
||
108 |
// final for export control reasons (access to APIs); remove with care |
|
109 |
final class HttpsClient extends HttpClient |
|
110 |
implements HandshakeCompletedListener |
|
111 |
{ |
|
112 |
// STATIC STATE and ACCESSORS THERETO |
|
113 |
||
114 |
// HTTPS uses a different default port number than HTTP. |
|
115 |
private static final int httpsPortNumber = 443; |
|
116 |
||
7043 | 117 |
// default HostnameVerifier class canonical name |
118 |
private static final String defaultHVCanonicalName = |
|
119 |
"javax.net.ssl.HttpsURLConnection.DefaultHostnameVerifier"; |
|
120 |
||
2 | 121 |
/** Returns the default HTTPS port (443) */ |
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
122 |
@Override |
2 | 123 |
protected int getDefaultPort() { return httpsPortNumber; } |
124 |
||
125 |
private HostnameVerifier hv; |
|
126 |
private SSLSocketFactory sslSocketFactory; |
|
127 |
||
128 |
// HttpClient.proxyDisabled will always be false, because we don't |
|
129 |
// use an application-level HTTP proxy. We might tunnel through |
|
130 |
// our http proxy, though. |
|
131 |
||
132 |
||
133 |
// INSTANCE DATA |
|
134 |
||
135 |
// last negotiated SSL session |
|
136 |
private SSLSession session; |
|
137 |
||
138 |
private String [] getCipherSuites() { |
|
139 |
// |
|
140 |
// If ciphers are assigned, sort them into an array. |
|
141 |
// |
|
142 |
String ciphers []; |
|
37593
824750ada3d6
8154231: Simplify access to System properties from JDK code
redestad
parents:
29615
diff
changeset
|
143 |
String cipherString = |
37781
71ed5645f17c
8155775: Re-examine naming of privileged methods to access System properties
redestad
parents:
37593
diff
changeset
|
144 |
GetPropertyAction.privilegedGetProperty("https.cipherSuites"); |
2 | 145 |
|
53018
8bf9268df0e2
8215281: Use String.isEmpty() when applicable in java.base
redestad
parents:
52474
diff
changeset
|
146 |
if (cipherString == null || cipherString.isEmpty()) { |
2 | 147 |
ciphers = null; |
148 |
} else { |
|
149 |
StringTokenizer tokenizer; |
|
150 |
Vector<String> v = new Vector<String>(); |
|
151 |
||
152 |
tokenizer = new StringTokenizer(cipherString, ","); |
|
153 |
while (tokenizer.hasMoreTokens()) |
|
154 |
v.addElement(tokenizer.nextToken()); |
|
155 |
ciphers = new String [v.size()]; |
|
156 |
for (int i = 0; i < ciphers.length; i++) |
|
157 |
ciphers [i] = v.elementAt(i); |
|
158 |
} |
|
159 |
return ciphers; |
|
160 |
} |
|
161 |
||
162 |
private String [] getProtocols() { |
|
163 |
// |
|
164 |
// If protocols are assigned, sort them into an array. |
|
165 |
// |
|
166 |
String protocols []; |
|
37593
824750ada3d6
8154231: Simplify access to System properties from JDK code
redestad
parents:
29615
diff
changeset
|
167 |
String protocolString = |
37781
71ed5645f17c
8155775: Re-examine naming of privileged methods to access System properties
redestad
parents:
37593
diff
changeset
|
168 |
GetPropertyAction.privilegedGetProperty("https.protocols"); |
2 | 169 |
|
53018
8bf9268df0e2
8215281: Use String.isEmpty() when applicable in java.base
redestad
parents:
52474
diff
changeset
|
170 |
if (protocolString == null || protocolString.isEmpty()) { |
2 | 171 |
protocols = null; |
172 |
} else { |
|
173 |
StringTokenizer tokenizer; |
|
174 |
Vector<String> v = new Vector<String>(); |
|
175 |
||
176 |
tokenizer = new StringTokenizer(protocolString, ","); |
|
177 |
while (tokenizer.hasMoreTokens()) |
|
178 |
v.addElement(tokenizer.nextToken()); |
|
179 |
protocols = new String [v.size()]; |
|
180 |
for (int i = 0; i < protocols.length; i++) { |
|
181 |
protocols [i] = v.elementAt(i); |
|
182 |
} |
|
183 |
} |
|
184 |
return protocols; |
|
185 |
} |
|
186 |
||
187 |
private String getUserAgent() { |
|
37781
71ed5645f17c
8155775: Re-examine naming of privileged methods to access System properties
redestad
parents:
37593
diff
changeset
|
188 |
String userAgent = |
71ed5645f17c
8155775: Re-examine naming of privileged methods to access System properties
redestad
parents:
37593
diff
changeset
|
189 |
GetPropertyAction.privilegedGetProperty("https.agent"); |
53018
8bf9268df0e2
8215281: Use String.isEmpty() when applicable in java.base
redestad
parents:
52474
diff
changeset
|
190 |
if (userAgent == null || userAgent.isEmpty()) { |
2 | 191 |
userAgent = "JSSE"; |
192 |
} |
|
193 |
return userAgent; |
|
194 |
} |
|
195 |
||
196 |
// CONSTRUCTOR, FACTORY |
|
197 |
||
198 |
||
199 |
/** |
|
200 |
* Create an HTTPS client URL. Traffic will be tunneled through any |
|
201 |
* intermediate nodes rather than proxied, so that confidentiality |
|
202 |
* of data exchanged can be preserved. However, note that all the |
|
203 |
* anonymous SSL flavors are subject to "person-in-the-middle" |
|
204 |
* attacks against confidentiality. If you enable use of those |
|
205 |
* flavors, you may be giving up the protection you get through |
|
206 |
* SSL tunneling. |
|
207 |
* |
|
208 |
* Use New to get new HttpsClient. This constructor is meant to be |
|
209 |
* used only by New method. New properly checks for URL spoofing. |
|
210 |
* |
|
211 |
* @param URL https URL with which a connection must be established |
|
212 |
*/ |
|
213 |
private HttpsClient(SSLSocketFactory sf, URL url) |
|
214 |
throws IOException |
|
215 |
{ |
|
216 |
// HttpClient-level proxying is always disabled, |
|
217 |
// because we override doConnect to do tunneling instead. |
|
218 |
this(sf, url, (String)null, -1); |
|
219 |
} |
|
220 |
||
221 |
/** |
|
222 |
* Create an HTTPS client URL. Traffic will be tunneled through |
|
223 |
* the specified proxy server. |
|
224 |
*/ |
|
225 |
HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort) |
|
226 |
throws IOException { |
|
227 |
this(sf, url, proxyHost, proxyPort, -1); |
|
228 |
} |
|
229 |
||
230 |
/** |
|
231 |
* Create an HTTPS client URL. Traffic will be tunneled through |
|
232 |
* the specified proxy server, with a connect timeout |
|
233 |
*/ |
|
234 |
HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort, |
|
235 |
int connectTimeout) |
|
236 |
throws IOException { |
|
237 |
this(sf, url, |
|
238 |
(proxyHost == null? null: |
|
28568
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
239 |
HttpClient.newHttpProxy(proxyHost, proxyPort, "https")), |
2 | 240 |
connectTimeout); |
241 |
} |
|
242 |
||
243 |
/** |
|
244 |
* Same as previous constructor except using a Proxy |
|
245 |
*/ |
|
246 |
HttpsClient(SSLSocketFactory sf, URL url, Proxy proxy, |
|
247 |
int connectTimeout) |
|
248 |
throws IOException { |
|
28568
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
249 |
PlatformLogger logger = HttpURLConnection.getHttpLogger(); |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
250 |
if (logger.isLoggable(PlatformLogger.Level.FINEST)) { |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
251 |
logger.finest("Creating new HttpsClient with url:" + url + " and proxy:" + proxy + |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
252 |
" with connect timeout:" + connectTimeout); |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
253 |
} |
2 | 254 |
this.proxy = proxy; |
255 |
setSSLSocketFactory(sf); |
|
256 |
this.proxyDisabled = true; |
|
257 |
||
258 |
this.host = url.getHost(); |
|
259 |
this.url = url; |
|
260 |
port = url.getPort(); |
|
261 |
if (port == -1) { |
|
262 |
port = getDefaultPort(); |
|
263 |
} |
|
264 |
setConnectTimeout(connectTimeout); |
|
265 |
openServer(); |
|
266 |
} |
|
267 |
||
268 |
||
269 |
// This code largely ripped off from HttpClient.New, and |
|
270 |
// it uses the same keepalive cache. |
|
271 |
||
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
272 |
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
273 |
HttpURLConnection httpuc) |
2 | 274 |
throws IOException { |
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
275 |
return HttpsClient.New(sf, url, hv, true, httpuc); |
2 | 276 |
} |
277 |
||
278 |
/** See HttpClient for the model for this method. */ |
|
279 |
static HttpClient New(SSLSocketFactory sf, URL url, |
|
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
280 |
HostnameVerifier hv, boolean useCache, |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
281 |
HttpURLConnection httpuc) throws IOException { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
282 |
return HttpsClient.New(sf, url, hv, (String)null, -1, useCache, httpuc); |
2 | 283 |
} |
284 |
||
285 |
/** |
|
286 |
* Get a HTTPS client to the URL. Traffic will be tunneled through |
|
287 |
* the specified proxy server. |
|
288 |
*/ |
|
289 |
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, |
|
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
290 |
String proxyHost, int proxyPort, |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
291 |
HttpURLConnection httpuc) throws IOException { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
292 |
return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true, httpuc); |
2 | 293 |
} |
294 |
||
295 |
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, |
|
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
296 |
String proxyHost, int proxyPort, boolean useCache, |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
297 |
HttpURLConnection httpuc) |
2 | 298 |
throws IOException { |
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
299 |
return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1, |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
300 |
httpuc); |
2 | 301 |
} |
302 |
||
303 |
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, |
|
304 |
String proxyHost, int proxyPort, boolean useCache, |
|
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
305 |
int connectTimeout, HttpURLConnection httpuc) |
2 | 306 |
throws IOException { |
307 |
||
308 |
return HttpsClient.New(sf, url, hv, |
|
309 |
(proxyHost == null? null : |
|
28568
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
310 |
HttpClient.newHttpProxy(proxyHost, proxyPort, "https")), |
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
311 |
useCache, connectTimeout, httpuc); |
2 | 312 |
} |
313 |
||
314 |
static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, |
|
315 |
Proxy p, boolean useCache, |
|
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
316 |
int connectTimeout, HttpURLConnection httpuc) |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
317 |
throws IOException |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
318 |
{ |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
319 |
if (p == null) { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
320 |
p = Proxy.NO_PROXY; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
321 |
} |
28568
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
322 |
PlatformLogger logger = HttpURLConnection.getHttpLogger(); |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
323 |
if (logger.isLoggable(PlatformLogger.Level.FINEST)) { |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
324 |
logger.finest("Looking for HttpClient for URL " + url + |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
325 |
" and proxy value of " + p); |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
326 |
} |
2 | 327 |
HttpsClient ret = null; |
328 |
if (useCache) { |
|
329 |
/* see if one's already around */ |
|
330 |
ret = (HttpsClient) kac.get(url, sf); |
|
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
331 |
if (ret != null && httpuc != null && |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
332 |
httpuc.streaming() && |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
333 |
httpuc.getRequestMethod() == "POST") { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
334 |
if (!ret.available()) |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
335 |
ret = null; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
336 |
} |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
337 |
|
2 | 338 |
if (ret != null) { |
42351
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
339 |
String ak = httpuc == null ? AuthenticatorKeys.DEFAULT |
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
340 |
: httpuc.getAuthenticatorKey(); |
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
341 |
boolean compatible = ((ret.proxy != null && ret.proxy.equals(p)) || |
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
342 |
(ret.proxy == null && p == Proxy.NO_PROXY)) |
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
343 |
&& Objects.equals(ret.getAuthenticatorKey(), ak); |
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
344 |
if (compatible) { |
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
345 |
synchronized (ret) { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
346 |
ret.cachedHttpClient = true; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
347 |
assert ret.inCache; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
348 |
ret.inCache = false; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
349 |
if (httpuc != null && ret.needsTunneling()) |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
350 |
httpuc.setTunnelState(TUNNELING); |
18178
ee71c923891d
8016747: Replace deprecated PlatformLogger isLoggable(int) with isLoggable(Level)
chegar
parents:
16499
diff
changeset
|
351 |
if (logger.isLoggable(PlatformLogger.Level.FINEST)) { |
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
352 |
logger.finest("KeepAlive stream retrieved from the cache, " + ret); |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
353 |
} |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
354 |
} |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
355 |
} else { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
356 |
// We cannot return this connection to the cache as it's |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
357 |
// KeepAliveTimeout will get reset. We simply close the connection. |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
358 |
// This should be fine as it is very rare that a connection |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
359 |
// to the same host will not use the same proxy. |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
360 |
synchronized(ret) { |
28568
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
361 |
if (logger.isLoggable(PlatformLogger.Level.FINEST)) { |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
362 |
logger.finest("Not returning this connection to cache: " + ret); |
5325bdefc06b
8065994: HTTP Tunnel connection to NTLM proxy reauthenticates instead of using keep-alive
coffeys
parents:
25859
diff
changeset
|
363 |
} |
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
364 |
ret.inCache = false; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
365 |
ret.closeServer(); |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
366 |
} |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
367 |
ret = null; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
368 |
} |
2 | 369 |
} |
370 |
} |
|
371 |
if (ret == null) { |
|
372 |
ret = new HttpsClient(sf, url, p, connectTimeout); |
|
42351
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
373 |
if (httpuc != null) { |
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
374 |
ret.authenticatorKey = httpuc.getAuthenticatorKey(); |
85ed90be0ae1
8169495: Add a method to set an Authenticator on a HttpURLConnection.
dfuchs
parents:
37781
diff
changeset
|
375 |
} |
2 | 376 |
} else { |
377 |
SecurityManager security = System.getSecurityManager(); |
|
378 |
if (security != null) { |
|
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
379 |
if (ret.proxy == Proxy.NO_PROXY || ret.proxy == null) { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
380 |
security.checkConnect(InetAddress.getByName(url.getHost()).getHostAddress(), url.getPort()); |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
381 |
} else { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
382 |
security.checkConnect(url.getHost(), url.getPort()); |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
383 |
} |
2 | 384 |
} |
385 |
ret.url = url; |
|
386 |
} |
|
387 |
ret.setHostnameVerifier(hv); |
|
388 |
||
389 |
return ret; |
|
390 |
} |
|
391 |
||
392 |
// METHODS |
|
393 |
void setHostnameVerifier(HostnameVerifier hv) { |
|
394 |
this.hv = hv; |
|
395 |
} |
|
396 |
||
397 |
void setSSLSocketFactory(SSLSocketFactory sf) { |
|
398 |
sslSocketFactory = sf; |
|
399 |
} |
|
400 |
||
401 |
SSLSocketFactory getSSLSocketFactory() { |
|
402 |
return sslSocketFactory; |
|
403 |
} |
|
404 |
||
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
405 |
/** |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
406 |
* The following method, createSocket, is defined in NetworkClient |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
407 |
* and overridden here so that the socket facroty is used to create |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
408 |
* new sockets. |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
409 |
*/ |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
410 |
@Override |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
411 |
protected Socket createSocket() throws IOException { |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
412 |
try { |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
413 |
return sslSocketFactory.createSocket(); |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
414 |
} catch (SocketException se) { |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
415 |
// |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
416 |
// bug 6771432 |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
417 |
// javax.net.SocketFactory throws a SocketException with an |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
418 |
// UnsupportedOperationException as its cause to indicate that |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
419 |
// unconnected sockets have not been implemented. |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
420 |
// |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
421 |
Throwable t = se.getCause(); |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
422 |
if (t != null && t instanceof UnsupportedOperationException) { |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
423 |
return super.createSocket(); |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
424 |
} else { |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
425 |
throw se; |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
426 |
} |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
427 |
} |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
428 |
} |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
429 |
|
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
430 |
|
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
431 |
@Override |
2 | 432 |
public boolean needsTunneling() { |
433 |
return (proxy != null && proxy.type() != Proxy.Type.DIRECT |
|
434 |
&& proxy.type() != Proxy.Type.SOCKS); |
|
435 |
} |
|
436 |
||
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
437 |
@Override |
2 | 438 |
public void afterConnect() throws IOException, UnknownHostException { |
439 |
if (!isCachedConnection()) { |
|
440 |
SSLSocket s = null; |
|
441 |
SSLSocketFactory factory = sslSocketFactory; |
|
442 |
try { |
|
443 |
if (!(serverSocket instanceof SSLSocket)) { |
|
444 |
s = (SSLSocket)factory.createSocket(serverSocket, |
|
445 |
host, port, true); |
|
446 |
} else { |
|
447 |
s = (SSLSocket)serverSocket; |
|
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
448 |
if (s instanceof SSLSocketImpl) { |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
449 |
((SSLSocketImpl)s).setHost(host); |
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
450 |
} |
2 | 451 |
} |
452 |
} catch (IOException ex) { |
|
453 |
// If we fail to connect through the tunnel, try it |
|
454 |
// locally, as a last resort. If this doesn't work, |
|
455 |
// throw the original exception. |
|
456 |
try { |
|
457 |
s = (SSLSocket)factory.createSocket(host, port); |
|
458 |
} catch (IOException ignored) { |
|
459 |
throw ex; |
|
460 |
} |
|
461 |
} |
|
462 |
||
463 |
// |
|
464 |
// Force handshaking, so that we get any authentication. |
|
465 |
// Register a handshake callback so our session state tracks any |
|
466 |
// later session renegotiations. |
|
467 |
// |
|
468 |
String [] protocols = getProtocols(); |
|
469 |
String [] ciphers = getCipherSuites(); |
|
470 |
if (protocols != null) { |
|
471 |
s.setEnabledProtocols(protocols); |
|
472 |
} |
|
473 |
if (ciphers != null) { |
|
474 |
s.setEnabledCipherSuites(ciphers); |
|
475 |
} |
|
476 |
s.addHandshakeCompletedListener(this); |
|
477 |
||
7043 | 478 |
// We have two hostname verification approaches. One is in |
479 |
// SSL/TLS socket layer, where the algorithm is configured with |
|
480 |
// SSLParameters.setEndpointIdentificationAlgorithm(), and the |
|
481 |
// hostname verification is done by X509ExtendedTrustManager when |
|
482 |
// the algorithm is "HTTPS". The other one is in HTTPS layer, |
|
483 |
// where the algorithm is customized by |
|
484 |
// HttpsURLConnection.setHostnameVerifier(), and the hostname |
|
485 |
// verification is done by HostnameVerifier when the default |
|
486 |
// rules for hostname verification fail. |
|
487 |
// |
|
488 |
// The relationship between two hostname verification approaches |
|
489 |
// likes the following: |
|
490 |
// |
|
491 |
// | EIA algorithm |
|
492 |
// +---------------------------------------------- |
|
493 |
// | null | HTTPS | LDAP/other | |
|
494 |
// ------------------------------------------------------------- |
|
495 |
// | |1 |2 |3 | |
|
496 |
// HNV | default | Set HTTPS EIA | use EIA | HTTPS | |
|
497 |
// |-------------------------------------------------------- |
|
498 |
// | non - |4 |5 |6 | |
|
499 |
// | default | HTTPS/HNV | use EIA | HTTPS/HNV | |
|
500 |
// ------------------------------------------------------------- |
|
501 |
// |
|
502 |
// Abbreviation: |
|
503 |
// EIA: the endpoint identification algorithm in SSL/TLS |
|
504 |
// socket layer |
|
505 |
// HNV: the hostname verification object in HTTPS layer |
|
506 |
// Notes: |
|
507 |
// case 1. default HNV and EIA is null |
|
508 |
// Set EIA as HTTPS, hostname check done in SSL/TLS |
|
509 |
// layer. |
|
510 |
// case 2. default HNV and EIA is HTTPS |
|
511 |
// Use existing EIA, hostname check done in SSL/TLS |
|
512 |
// layer. |
|
513 |
// case 3. default HNV and EIA is other than HTTPS |
|
514 |
// Use existing EIA, EIA check done in SSL/TLS |
|
515 |
// layer, then do HTTPS check in HTTPS layer. |
|
516 |
// case 4. non-default HNV and EIA is null |
|
517 |
// No EIA, no EIA check done in SSL/TLS layer, then do |
|
518 |
// HTTPS check in HTTPS layer using HNV as override. |
|
519 |
// case 5. non-default HNV and EIA is HTTPS |
|
520 |
// Use existing EIA, hostname check done in SSL/TLS |
|
521 |
// layer. No HNV override possible. We will review this |
|
522 |
// decision and may update the architecture for JDK 7. |
|
523 |
// case 6. non-default HNV and EIA is other than HTTPS |
|
524 |
// Use existing EIA, EIA check done in SSL/TLS layer, |
|
525 |
// then do HTTPS check in HTTPS layer as override. |
|
526 |
boolean needToCheckSpoofing = true; |
|
527 |
String identification = |
|
528 |
s.getSSLParameters().getEndpointIdentificationAlgorithm(); |
|
529 |
if (identification != null && identification.length() != 0) { |
|
530 |
if (identification.equalsIgnoreCase("HTTPS")) { |
|
531 |
// Do not check server identity again out of SSLSocket, |
|
532 |
// the endpoint will be identified during TLS handshaking |
|
533 |
// in SSLSocket. |
|
534 |
needToCheckSpoofing = false; |
|
535 |
} // else, we don't understand the identification algorithm, |
|
536 |
// need to check URL spoofing here. |
|
537 |
} else { |
|
538 |
boolean isDefaultHostnameVerifier = false; |
|
539 |
||
540 |
// We prefer to let the SSLSocket do the spoof checks, but if |
|
541 |
// the application has specified a HostnameVerifier (HNV), |
|
542 |
// we will always use that. |
|
543 |
if (hv != null) { |
|
544 |
String canonicalName = hv.getClass().getCanonicalName(); |
|
545 |
if (canonicalName != null && |
|
546 |
canonicalName.equalsIgnoreCase(defaultHVCanonicalName)) { |
|
547 |
isDefaultHostnameVerifier = true; |
|
548 |
} |
|
549 |
} else { |
|
550 |
// Unlikely to happen! As the behavior is the same as the |
|
551 |
// default hostname verifier, so we prefer to let the |
|
552 |
// SSLSocket do the spoof checks. |
|
553 |
isDefaultHostnameVerifier = true; |
|
554 |
} |
|
555 |
||
556 |
if (isDefaultHostnameVerifier) { |
|
557 |
// If the HNV is the default from HttpsURLConnection, we |
|
558 |
// will do the spoof checks in SSLSocket. |
|
559 |
SSLParameters paramaters = s.getSSLParameters(); |
|
560 |
paramaters.setEndpointIdentificationAlgorithm("HTTPS"); |
|
561 |
s.setSSLParameters(paramaters); |
|
562 |
||
563 |
needToCheckSpoofing = false; |
|
564 |
} |
|
2 | 565 |
} |
566 |
||
567 |
s.startHandshake(); |
|
568 |
session = s.getSession(); |
|
569 |
// change the serverSocket and serverOutput |
|
570 |
serverSocket = s; |
|
571 |
try { |
|
572 |
serverOutput = new PrintStream( |
|
573 |
new BufferedOutputStream(serverSocket.getOutputStream()), |
|
574 |
false, encoding); |
|
575 |
} catch (UnsupportedEncodingException e) { |
|
10596
39b3a979e600
7090158: Networking Libraries don't build with javac -Werror
chegar
parents:
10419
diff
changeset
|
576 |
throw new InternalError(encoding+" encoding not found"); |
2 | 577 |
} |
578 |
||
579 |
// check URL spoofing if it has not been checked under handshaking |
|
7043 | 580 |
if (needToCheckSpoofing) { |
2 | 581 |
checkURLSpoofing(hv); |
582 |
} |
|
583 |
} else { |
|
584 |
// if we are reusing a cached https session, |
|
585 |
// we don't need to do handshaking etc. But we do need to |
|
586 |
// set the ssl session |
|
587 |
session = ((SSLSocket)serverSocket).getSession(); |
|
588 |
} |
|
589 |
} |
|
590 |
||
591 |
// Server identity checking is done according to RFC 2818: HTTP over TLS |
|
592 |
// Section 3.1 Server Identity |
|
593 |
private void checkURLSpoofing(HostnameVerifier hostnameVerifier) |
|
7043 | 594 |
throws IOException { |
2 | 595 |
// |
596 |
// Get authenticated server name, if any |
|
597 |
// |
|
598 |
String host = url.getHost(); |
|
599 |
||
600 |
// if IPv6 strip off the "[]" |
|
601 |
if (host != null && host.startsWith("[") && host.endsWith("]")) { |
|
602 |
host = host.substring(1, host.length()-1); |
|
603 |
} |
|
604 |
||
605 |
Certificate[] peerCerts = null; |
|
3957
c8fdb8fad795
6885204: JSSE should not require Kerberos to be present
vinnie
parents:
98
diff
changeset
|
606 |
String cipher = session.getCipherSuite(); |
2 | 607 |
try { |
608 |
HostnameChecker checker = HostnameChecker.getInstance( |
|
609 |
HostnameChecker.TYPE_TLS); |
|
610 |
||
50768 | 611 |
// get the subject's certificate |
612 |
peerCerts = session.getPeerCertificates(); |
|
4236 | 613 |
|
50768 | 614 |
X509Certificate peerCert; |
615 |
if (peerCerts[0] instanceof |
|
616 |
java.security.cert.X509Certificate) { |
|
617 |
peerCert = (java.security.cert.X509Certificate)peerCerts[0]; |
|
618 |
} else { |
|
619 |
throw new SSLPeerUnverifiedException(""); |
|
2 | 620 |
} |
50768 | 621 |
checker.match(host, peerCert); |
2 | 622 |
|
623 |
// if it doesn't throw an exception, we passed. Return. |
|
624 |
return; |
|
625 |
||
626 |
} catch (SSLPeerUnverifiedException e) { |
|
627 |
||
628 |
// |
|
629 |
// client explicitly changed default policy and enabled |
|
630 |
// anonymous ciphers; we can't check the standard policy |
|
631 |
// |
|
632 |
// ignore |
|
633 |
} catch (java.security.cert.CertificateException cpe) { |
|
634 |
// ignore |
|
635 |
} |
|
636 |
||
637 |
if ((cipher != null) && (cipher.indexOf("_anon_") != -1)) { |
|
638 |
return; |
|
639 |
} else if ((hostnameVerifier != null) && |
|
640 |
(hostnameVerifier.verify(host, session))) { |
|
641 |
return; |
|
642 |
} |
|
643 |
||
644 |
serverSocket.close(); |
|
645 |
session.invalidate(); |
|
646 |
||
647 |
throw new IOException("HTTPS hostname wrong: should be <" |
|
648 |
+ url.getHost() + ">"); |
|
649 |
} |
|
650 |
||
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
651 |
@Override |
2 | 652 |
protected void putInKeepAliveCache() { |
16499
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
653 |
if (inCache) { |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
654 |
assert false : "Duplicate put to keep alive cache"; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
655 |
return; |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
656 |
} |
88276d2da9c0
8009251: Add proxy handling and keep-alive fixes to jsse
robm
parents:
14342
diff
changeset
|
657 |
inCache = true; |
2 | 658 |
kac.put(url, sslSocketFactory, this); |
659 |
} |
|
660 |
||
98
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
661 |
/* |
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
662 |
* Close an idle connection to this URL (if it exists in the cache). |
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
663 |
*/ |
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
664 |
@Override |
98
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
665 |
public void closeIdleConnection() { |
10596
39b3a979e600
7090158: Networking Libraries don't build with javac -Werror
chegar
parents:
10419
diff
changeset
|
666 |
HttpClient http = kac.get(url, sslSocketFactory); |
98
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
667 |
if (http != null) { |
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
668 |
http.closeServer(); |
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
669 |
} |
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
670 |
} |
4087c83cfab8
6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert.
xuelei
parents:
2
diff
changeset
|
671 |
|
2 | 672 |
/** |
673 |
* Returns the cipher suite in use on this connection. |
|
674 |
*/ |
|
675 |
String getCipherSuite() { |
|
676 |
return session.getCipherSuite(); |
|
677 |
} |
|
678 |
||
679 |
/** |
|
680 |
* Returns the certificate chain the client sent to the |
|
681 |
* server, or null if the client did not authenticate. |
|
682 |
*/ |
|
683 |
public java.security.cert.Certificate [] getLocalCertificates() { |
|
684 |
return session.getLocalCertificates(); |
|
685 |
} |
|
686 |
||
687 |
/** |
|
688 |
* Returns the certificate chain with which the server |
|
689 |
* authenticated itself, or throw a SSLPeerUnverifiedException |
|
690 |
* if the server did not authenticate. |
|
691 |
*/ |
|
692 |
java.security.cert.Certificate [] getServerCertificates() |
|
693 |
throws SSLPeerUnverifiedException |
|
694 |
{ |
|
695 |
return session.getPeerCertificates(); |
|
696 |
} |
|
697 |
||
698 |
/** |
|
699 |
* Returns the principal with which the server authenticated |
|
700 |
* itself, or throw a SSLPeerUnverifiedException if the |
|
701 |
* server did not authenticate. |
|
702 |
*/ |
|
703 |
Principal getPeerPrincipal() |
|
704 |
throws SSLPeerUnverifiedException |
|
705 |
{ |
|
706 |
Principal principal; |
|
707 |
try { |
|
708 |
principal = session.getPeerPrincipal(); |
|
709 |
} catch (AbstractMethodError e) { |
|
710 |
// if the provider does not support it, fallback to peer certs. |
|
711 |
// return the X500Principal of the end-entity cert. |
|
712 |
java.security.cert.Certificate[] certs = |
|
713 |
session.getPeerCertificates(); |
|
10596
39b3a979e600
7090158: Networking Libraries don't build with javac -Werror
chegar
parents:
10419
diff
changeset
|
714 |
principal = ((X509Certificate)certs[0]).getSubjectX500Principal(); |
2 | 715 |
} |
716 |
return principal; |
|
717 |
} |
|
718 |
||
719 |
/** |
|
720 |
* Returns the principal the client sent to the |
|
721 |
* server, or null if the client did not authenticate. |
|
722 |
*/ |
|
723 |
Principal getLocalPrincipal() |
|
724 |
{ |
|
725 |
Principal principal; |
|
726 |
try { |
|
727 |
principal = session.getLocalPrincipal(); |
|
728 |
} catch (AbstractMethodError e) { |
|
729 |
principal = null; |
|
730 |
// if the provider does not support it, fallback to local certs. |
|
731 |
// return the X500Principal of the end-entity cert. |
|
732 |
java.security.cert.Certificate[] certs = |
|
733 |
session.getLocalCertificates(); |
|
734 |
if (certs != null) { |
|
10596
39b3a979e600
7090158: Networking Libraries don't build with javac -Werror
chegar
parents:
10419
diff
changeset
|
735 |
principal = ((X509Certificate)certs[0]).getSubjectX500Principal(); |
2 | 736 |
} |
737 |
} |
|
738 |
return principal; |
|
739 |
} |
|
740 |
||
741 |
/** |
|
52474
13266dac5fdb
8212261: Add SSLSession accessors to HttpsURLConnection and SecureCacheResponse
xuelei
parents:
50768
diff
changeset
|
742 |
* Returns the {@code SSLSession} in use on this connection. |
13266dac5fdb
8212261: Add SSLSession accessors to HttpsURLConnection and SecureCacheResponse
xuelei
parents:
50768
diff
changeset
|
743 |
*/ |
13266dac5fdb
8212261: Add SSLSession accessors to HttpsURLConnection and SecureCacheResponse
xuelei
parents:
50768
diff
changeset
|
744 |
SSLSession getSSLSession() { |
13266dac5fdb
8212261: Add SSLSession accessors to HttpsURLConnection and SecureCacheResponse
xuelei
parents:
50768
diff
changeset
|
745 |
return session; |
13266dac5fdb
8212261: Add SSLSession accessors to HttpsURLConnection and SecureCacheResponse
xuelei
parents:
50768
diff
changeset
|
746 |
} |
13266dac5fdb
8212261: Add SSLSession accessors to HttpsURLConnection and SecureCacheResponse
xuelei
parents:
50768
diff
changeset
|
747 |
|
13266dac5fdb
8212261: Add SSLSession accessors to HttpsURLConnection and SecureCacheResponse
xuelei
parents:
50768
diff
changeset
|
748 |
/** |
2 | 749 |
* This method implements the SSL HandshakeCompleted callback, |
750 |
* remembering the resulting session so that it may be queried |
|
751 |
* for the current cipher suite and peer certificates. Servers |
|
752 |
* sometimes re-initiate handshaking, so the session in use on |
|
753 |
* a given connection may change. When sessions change, so may |
|
754 |
* peer identities and cipher suites. |
|
755 |
*/ |
|
756 |
public void handshakeCompleted(HandshakeCompletedEvent event) |
|
757 |
{ |
|
758 |
session = event.getSession(); |
|
759 |
} |
|
760 |
||
761 |
/** |
|
762 |
* @return the proxy host being used for this client, or null |
|
763 |
* if we're not going through a proxy |
|
764 |
*/ |
|
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
765 |
@Override |
2 | 766 |
public String getProxyHostUsed() { |
767 |
if (!needsTunneling()) { |
|
768 |
return null; |
|
769 |
} else { |
|
5160
c0e0c9a9d338
6632169: HttpClient and HttpsClient should not try to reverse lookup IP address of a proxy server
chegar
parents:
4236
diff
changeset
|
770 |
return super.getProxyHostUsed(); |
2 | 771 |
} |
772 |
} |
|
773 |
||
774 |
/** |
|
775 |
* @return the proxy port being used for this client. Meaningless |
|
776 |
* if getProxyHostUsed() gives null. |
|
777 |
*/ |
|
5162
0dbedf4fdb8c
6614957: HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
chegar
parents:
5160
diff
changeset
|
778 |
@Override |
2 | 779 |
public int getProxyPortUsed() { |
780 |
return (proxy == null || proxy.type() == Proxy.Type.DIRECT || |
|
781 |
proxy.type() == Proxy.Type.SOCKS)? -1: |
|
782 |
((InetSocketAddress)proxy.address()).getPort(); |
|
783 |
} |
|
784 |
} |