blob: c3e3c304db7498b1619f8cfb467b058901b1b92f [file] [log] [blame]
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001/*
Narayan Kamath2c87ad32015-12-21 13:53:32 +00002 * Copyright (C) 2014 The Android Open Source Project
Przemyslaw Szczepaniak89e6fad2017-03-29 17:17:34 +01003 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00004 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation. Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27package javax.net.ssl;
28
29import java.net.URL;
30import java.net.HttpURLConnection;
31import java.security.Principal;
32import java.security.cert.X509Certificate;
Pete Bentley6f0f8c12019-12-18 14:06:39 +000033import libcore.api.CorePlatformApi;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000034
35/**
36 * <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
37 * with support for https-specific features.
38 * <P>
39 * See <A HREF="http://www.w3.org/pub/WWW/Protocols/">
40 * http://www.w3.org/pub/WWW/Protocols/</A> and
41 * <A HREF="http://www.ietf.org/"> RFC 2818 </A>
42 * for more details on the
43 * https specification.
44 * <P>
45 * This class uses <code>HostnameVerifier</code> and
46 * <code>SSLSocketFactory</code>.
47 * There are default implementations defined for both classes.
48 * However, the implementations can be replaced on a per-class (static) or
49 * per-instance basis. All new <code>HttpsURLConnection</code>s instances
50 * will be assigned
51 * the "default" static values at instance creation, but they can be overriden
52 * by calling the appropriate per-instance set method(s) before
53 * <code>connect</code>ing.
54 *
55 * @since 1.4
56 */
57abstract public
58class HttpsURLConnection extends HttpURLConnection
59{
60 /**
61 * Creates an <code>HttpsURLConnection</code> using the
62 * URL specified.
63 *
64 * @param url the URL
65 */
66 protected HttpsURLConnection(URL url) {
67 super(url);
68 }
69
70 /**
71 * Returns the cipher suite in use on this connection.
72 *
73 * @return the cipher suite
74 * @throws IllegalStateException if this method is called before
75 * the connection has been established.
76 */
77 public abstract String getCipherSuite();
78
79 /**
80 * Returns the certificate(s) that were sent to the server during
81 * handshaking.
82 * <P>
83 * Note: This method is useful only when using certificate-based
84 * cipher suites.
85 * <P>
86 * When multiple certificates are available for use in a
87 * handshake, the implementation chooses what it considers the
88 * "best" certificate chain available, and transmits that to
89 * the other side. This method allows the caller to know
90 * which certificate chain was actually sent.
91 *
92 * @return an ordered array of certificates,
93 * with the client's own certificate first followed by any
94 * certificate authorities. If no certificates were sent,
95 * then null is returned.
96 * @throws IllegalStateException if this method is called before
97 * the connection has been established.
98 * @see #getLocalPrincipal()
99 */
100 public abstract java.security.cert.Certificate [] getLocalCertificates();
101
102 /**
103 * Returns the server's certificate chain which was established
104 * as part of defining the session.
105 * <P>
106 * Note: This method can be used only when using certificate-based
107 * cipher suites; using it with non-certificate-based cipher suites,
108 * such as Kerberos, will throw an SSLPeerUnverifiedException.
109 *
110 * @return an ordered array of server certificates,
111 * with the peer's own certificate first followed by
112 * any certificate authorities.
113 * @throws SSLPeerUnverifiedException if the peer is not verified.
114 * @throws IllegalStateException if this method is called before
115 * the connection has been established.
116 * @see #getPeerPrincipal()
117 */
118 public abstract java.security.cert.Certificate [] getServerCertificates()
119 throws SSLPeerUnverifiedException;
120
121 /**
122 * Returns the server's principal which was established as part of
123 * defining the session.
124 * <P>
125 * Note: Subclasses should override this method. If not overridden, it
126 * will default to returning the X500Principal of the server's end-entity
127 * certificate for certificate-based ciphersuites, or throw an
128 * SSLPeerUnverifiedException for non-certificate based ciphersuites,
129 * such as Kerberos.
130 *
131 * @return the server's principal. Returns an X500Principal of the
132 * end-entity certiticate for X509-based cipher suites, and
133 * KerberosPrincipal for Kerberos cipher suites.
134 *
135 * @throws SSLPeerUnverifiedException if the peer was not verified
136 * @throws IllegalStateException if this method is called before
137 * the connection has been established.
138 *
139 * @see #getServerCertificates()
140 * @see #getLocalPrincipal()
141 *
142 * @since 1.5
143 */
144 public Principal getPeerPrincipal()
145 throws SSLPeerUnverifiedException {
146
147 java.security.cert.Certificate[] certs = getServerCertificates();
Przemyslaw Szczepaniak89e6fad2017-03-29 17:17:34 +0100148 return ((X509Certificate)certs[0]).getSubjectX500Principal();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000149 }
150
151 /**
152 * Returns the principal that was sent to the server during handshaking.
153 * <P>
154 * Note: Subclasses should override this method. If not overridden, it
155 * will default to returning the X500Principal of the end-entity certificate
156 * that was sent to the server for certificate-based ciphersuites or,
157 * return null for non-certificate based ciphersuites, such as Kerberos.
158 *
159 * @return the principal sent to the server. Returns an X500Principal
160 * of the end-entity certificate for X509-based cipher suites, and
161 * KerberosPrincipal for Kerberos cipher suites. If no principal was
162 * sent, then null is returned.
163 *
164 * @throws IllegalStateException if this method is called before
165 * the connection has been established.
166 *
167 * @see #getLocalCertificates()
168 * @see #getPeerPrincipal()
169 *
170 * @since 1.5
171 */
172 public Principal getLocalPrincipal() {
173
174 java.security.cert.Certificate[] certs = getLocalCertificates();
175 if (certs != null) {
Przemyslaw Szczepaniak89e6fad2017-03-29 17:17:34 +0100176 return ((X509Certificate)certs[0]).getSubjectX500Principal();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000177 } else {
178 return null;
179 }
180 }
181
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100182 // BEGIN Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
Adam Vartanian09828c02017-05-10 13:50:54 +0100183 // The RI default hostname verifier is a static member of the class, which means
184 // it's created when the class is initialized. As well, its default verifier
185 // just fails all verification attempts, whereas we use OkHttp's verifier.
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100186 /*
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000187 * Holds the default instance so class preloading doesn't create an instance of
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100188 * it.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000189 */
Pete Bentley6f0f8c12019-12-18 14:06:39 +0000190 private static final String OK_HOSTNAME_VERIFIER_CLASS
191 = "com.android.okhttp.internal.tls.OkHostnameVerifier";
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100192 private static class NoPreloadHolder {
193 public static HostnameVerifier defaultHostnameVerifier;
194 static {
195 try {
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000196 /**
197 * <code>HostnameVerifier</code> provides a callback mechanism so that
198 * implementers of this interface can supply a policy for
199 * handling the case where the host to connect to and
200 * the server name from the certificate mismatch.
201 */
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100202 defaultHostnameVerifier = (HostnameVerifier)
Pete Bentley6f0f8c12019-12-18 14:06:39 +0000203 Class.forName(OK_HOSTNAME_VERIFIER_CLASS)
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100204 .getField("INSTANCE").get(null);
205 } catch (Exception e) {
206 throw new AssertionError("Failed to obtain okhttp HostnameVerifier", e);
207 }
208 }
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100209 }
210
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000211 /**
212 * The <code>hostnameVerifier</code> for this object.
213 */
Neil Fullerde890da2019-03-08 16:24:38 +0000214 protected HostnameVerifier hostnameVerifier = NoPreloadHolder.defaultHostnameVerifier;
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100215 // END Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000216
Neil Fuller9f208402019-03-08 16:21:22 +0000217 // Android-changed: Modified the documentation to explain side effects / discourage method use.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000218 /**
219 * Sets the default <code>HostnameVerifier</code> inherited by a
220 * new instance of this class.
Neil Fuller9f208402019-03-08 16:21:22 +0000221 * <p>
222 * Developers are <em>strongly</em> discouraged from changing the default
223 * {@code HostnameVerifier} as {@link #getDefaultHostnameVerifier()} is used by several
224 * classes for hostname verification on Android.
225 * <table>
226 * <tr>
227 * <th>User</th>
228 * <th>Effect</th>
229 * </tr>
230 * <tr>
231 * <td>Android's default {@link TrustManager}, as used with Android's default
232 * {@link SSLContext}, {@link SSLSocketFactory} and {@link SSLSocket} implementations.
233 * </td>
234 * <td>The {@code HostnameVerifier} is used to verify the peer's
235 * certificate hostname after connecting if {@code
236 * SSLParameters.setEndpointIdentificationAlgorithm("HTTPS")} has been called.
237 * Instances use the <em>current</em> default {@code HostnameVerifier} at verification
238 * time.</td>
239 * </tr>
240 * <tr>
241 * <td>{@link android.net.SSLCertificateSocketFactory}</td>
242 * <td>The current default {@code HostnameVerifier} is used from various {@code
243 * createSocket} methods. See {@link android.net.SSLCertificateSocketFactory} for
244 * details; for example {@link
245 * android.net.SSLCertificateSocketFactory#createSocket(String, int)}.
246 * </td>
247 * </tr>
248 * <tr>
249 * <td>Android's default {@link HttpsURLConnection} implementation.</td>
250 * <td>The {@code HostnameVerifier} is used after a successful TLS handshake to verify
251 * the URI host against the TLS session server. Instances use the default {@code
252 * HostnameVerifier} set <em>when they were created</em> unless overridden with {@link
253 * #setHostnameVerifier(HostnameVerifier)}.
254 * Android's <code>HttpsURLConnection</code> relies on the {@code HostnameVerifier}
255 * for the <em>entire</em> hostname verification step.</td>
256 * </tr>
257 * </table>
258 * <p>
259 * If this method is not called, the default <code>HostnameVerifier</code> will check the
260 * hostname according to RFC 2818.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000261 *
262 * @param v the default host name verifier
263 * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
264 * parameter is null.
265 * @throws SecurityException if a security manager exists and its
266 * <code>checkPermission</code> method does not allow
267 * <code>SSLPermission("setHostnameVerifier")</code>
268 * @see #getDefaultHostnameVerifier()
269 */
270 public static void setDefaultHostnameVerifier(HostnameVerifier v) {
271 if (v == null) {
272 throw new IllegalArgumentException(
273 "no default HostnameVerifier specified");
274 }
275
276 SecurityManager sm = System.getSecurityManager();
277 if (sm != null) {
278 sm.checkPermission(new SSLPermission("setHostnameVerifier"));
279 }
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100280 // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
281 // defaultHostnameVerifier = v;
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100282 NoPreloadHolder.defaultHostnameVerifier = v;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000283 }
284
285 /**
286 * Gets the default <code>HostnameVerifier</code> that is inherited
287 * by new instances of this class.
288 *
289 * @return the default host name verifier
290 * @see #setDefaultHostnameVerifier(HostnameVerifier)
291 */
292 public static HostnameVerifier getDefaultHostnameVerifier() {
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100293 // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
294 // return defaultHostnameVerifier;
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000295 return NoPreloadHolder.defaultHostnameVerifier;
Piotr Jastrzebskif7ab2bc2015-05-06 14:00:00 +0100296 }
297
Neil Fuller9f208402019-03-08 16:21:22 +0000298 // Android-changed: Modified the documentation to explain Android behavior.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000299 /**
300 * Sets the <code>HostnameVerifier</code> for this instance.
301 * <P>
302 * New instances of this class inherit the default static hostname
303 * verifier set by {@link #setDefaultHostnameVerifier(HostnameVerifier)
304 * setDefaultHostnameVerifier}. Calls to this method replace
305 * this object's <code>HostnameVerifier</code>.
Neil Fuller9f208402019-03-08 16:21:22 +0000306 * <p>
307 * Android's <code>HttpsURLConnection</code> relies on the {@code HostnameVerifier}
308 * for the <em>entire</em> hostname verification step.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000309 *
310 * @param v the host name verifier
311 * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
312 * parameter is null.
313 * @see #getHostnameVerifier()
314 * @see #setDefaultHostnameVerifier(HostnameVerifier)
315 */
316 public void setHostnameVerifier(HostnameVerifier v) {
317 if (v == null) {
318 throw new IllegalArgumentException(
319 "no HostnameVerifier specified");
320 }
321
322 hostnameVerifier = v;
323 }
324
Pete Bentley6f0f8c12019-12-18 14:06:39 +0000325 // BEGIN Android-added: Core platform API to obtain a strict hostname verifier
326 /**
327 * Obtains a stricter <code>HostnameVerifier</code>.
328 *
329 * The <code>HostnameVerifier</code> returned by this method will reject certificates
330 * with wildcards for top-level domains such "*.com".
331 *
332 * @see com.squareup.okhttp.internal.tls.OkHostnameVerifier
333 *
334 * @hide
335 */
336 @CorePlatformApi
337 public static HostnameVerifier getStrictHostnameVerifier() {
338 try {
339 return (HostnameVerifier) Class
340 .forName(OK_HOSTNAME_VERIFIER_CLASS)
341 .getMethod("strictInstance")
342 .invoke(null);
343 } catch (Exception e) {
344 return null;
345 }
346 }
347 // END Android-added: Core platform API to obtain a strict hostname verifier
348
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000349 /**
350 * Gets the <code>HostnameVerifier</code> in place on this instance.
351 *
352 * @return the host name verifier
353 * @see #setHostnameVerifier(HostnameVerifier)
354 * @see #setDefaultHostnameVerifier(HostnameVerifier)
355 */
356 public HostnameVerifier getHostnameVerifier() {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000357 return hostnameVerifier;
358 }
359
360 private static SSLSocketFactory defaultSSLSocketFactory = null;
361
362 /**
363 * The <code>SSLSocketFactory</code> inherited when an instance
364 * of this class is created.
365 */
366 private SSLSocketFactory sslSocketFactory = getDefaultSSLSocketFactory();
367
368 /**
369 * Sets the default <code>SSLSocketFactory</code> inherited by new
370 * instances of this class.
371 * <P>
372 * The socket factories are used when creating sockets for secure
373 * https URL connections.
374 *
375 * @param sf the default SSL socket factory
376 * @throws IllegalArgumentException if the SSLSocketFactory
377 * parameter is null.
378 * @throws SecurityException if a security manager exists and its
379 * <code>checkSetFactory</code> method does not allow
380 * a socket factory to be specified.
381 * @see #getDefaultSSLSocketFactory()
382 */
383 public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) {
384 if (sf == null) {
385 throw new IllegalArgumentException(
386 "no default SSLSocketFactory specified");
387 }
388
389 SecurityManager sm = System.getSecurityManager();
390 if (sm != null) {
391 sm.checkSetFactory();
392 }
393 defaultSSLSocketFactory = sf;
394 }
395
396 /**
397 * Gets the default static <code>SSLSocketFactory</code> that is
398 * inherited by new instances of this class.
399 * <P>
400 * The socket factories are used when creating sockets for secure
401 * https URL connections.
402 *
403 * @return the default <code>SSLSocketFactory</code>
404 * @see #setDefaultSSLSocketFactory(SSLSocketFactory)
405 */
406 public static SSLSocketFactory getDefaultSSLSocketFactory() {
407 if (defaultSSLSocketFactory == null) {
408 defaultSSLSocketFactory =
409 (SSLSocketFactory)SSLSocketFactory.getDefault();
410 }
411 return defaultSSLSocketFactory;
412 }
413
414 /**
415 * Sets the <code>SSLSocketFactory</code> to be used when this instance
416 * creates sockets for secure https URL connections.
417 * <P>
418 * New instances of this class inherit the default static
419 * <code>SSLSocketFactory</code> set by
420 * {@link #setDefaultSSLSocketFactory(SSLSocketFactory)
421 * setDefaultSSLSocketFactory}. Calls to this method replace
422 * this object's <code>SSLSocketFactory</code>.
423 *
424 * @param sf the SSL socket factory
425 * @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
426 * parameter is null.
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100427 * @throws SecurityException if a security manager exists and its
428 * <code>checkSetFactory</code> method does not allow
429 * a socket factory to be specified.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000430 * @see #getSSLSocketFactory()
431 */
432 public void setSSLSocketFactory(SSLSocketFactory sf) {
433 if (sf == null) {
434 throw new IllegalArgumentException(
435 "no SSLSocketFactory specified");
436 }
437
438 SecurityManager sm = System.getSecurityManager();
439 if (sm != null) {
440 sm.checkSetFactory();
441 }
442 sslSocketFactory = sf;
443 }
444
445 /**
446 * Gets the SSL socket factory to be used when creating sockets
447 * for secure https URL connections.
448 *
449 * @return the <code>SSLSocketFactory</code>
450 * @see #setSSLSocketFactory(SSLSocketFactory)
451 */
452 public SSLSocketFactory getSSLSocketFactory() {
453 return sslSocketFactory;
454 }
455}