blob: 143fa5ef92d9dbc3f3c8694c253eab035cfcf4f1 [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;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000033
34/**
35 * <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
36 * with support for https-specific features.
37 * <P>
38 * See <A HREF="http://www.w3.org/pub/WWW/Protocols/">
39 * http://www.w3.org/pub/WWW/Protocols/</A> and
40 * <A HREF="http://www.ietf.org/"> RFC 2818 </A>
41 * for more details on the
42 * https specification.
43 * <P>
44 * This class uses <code>HostnameVerifier</code> and
45 * <code>SSLSocketFactory</code>.
46 * There are default implementations defined for both classes.
47 * However, the implementations can be replaced on a per-class (static) or
48 * per-instance basis. All new <code>HttpsURLConnection</code>s instances
49 * will be assigned
50 * the "default" static values at instance creation, but they can be overriden
51 * by calling the appropriate per-instance set method(s) before
52 * <code>connect</code>ing.
53 *
54 * @since 1.4
55 */
56abstract public
57class HttpsURLConnection extends HttpURLConnection
58{
59 /**
60 * Creates an <code>HttpsURLConnection</code> using the
61 * URL specified.
62 *
63 * @param url the URL
64 */
65 protected HttpsURLConnection(URL url) {
66 super(url);
67 }
68
69 /**
70 * Returns the cipher suite in use on this connection.
71 *
72 * @return the cipher suite
73 * @throws IllegalStateException if this method is called before
74 * the connection has been established.
75 */
76 public abstract String getCipherSuite();
77
78 /**
79 * Returns the certificate(s) that were sent to the server during
80 * handshaking.
81 * <P>
82 * Note: This method is useful only when using certificate-based
83 * cipher suites.
84 * <P>
85 * When multiple certificates are available for use in a
86 * handshake, the implementation chooses what it considers the
87 * "best" certificate chain available, and transmits that to
88 * the other side. This method allows the caller to know
89 * which certificate chain was actually sent.
90 *
91 * @return an ordered array of certificates,
92 * with the client's own certificate first followed by any
93 * certificate authorities. If no certificates were sent,
94 * then null is returned.
95 * @throws IllegalStateException if this method is called before
96 * the connection has been established.
97 * @see #getLocalPrincipal()
98 */
99 public abstract java.security.cert.Certificate [] getLocalCertificates();
100
101 /**
102 * Returns the server's certificate chain which was established
103 * as part of defining the session.
104 * <P>
105 * Note: This method can be used only when using certificate-based
106 * cipher suites; using it with non-certificate-based cipher suites,
107 * such as Kerberos, will throw an SSLPeerUnverifiedException.
108 *
109 * @return an ordered array of server certificates,
110 * with the peer's own certificate first followed by
111 * any certificate authorities.
112 * @throws SSLPeerUnverifiedException if the peer is not verified.
113 * @throws IllegalStateException if this method is called before
114 * the connection has been established.
115 * @see #getPeerPrincipal()
116 */
117 public abstract java.security.cert.Certificate [] getServerCertificates()
118 throws SSLPeerUnverifiedException;
119
120 /**
121 * Returns the server's principal which was established as part of
122 * defining the session.
123 * <P>
124 * Note: Subclasses should override this method. If not overridden, it
125 * will default to returning the X500Principal of the server's end-entity
126 * certificate for certificate-based ciphersuites, or throw an
127 * SSLPeerUnverifiedException for non-certificate based ciphersuites,
128 * such as Kerberos.
129 *
130 * @return the server's principal. Returns an X500Principal of the
131 * end-entity certiticate for X509-based cipher suites, and
132 * KerberosPrincipal for Kerberos cipher suites.
133 *
134 * @throws SSLPeerUnverifiedException if the peer was not verified
135 * @throws IllegalStateException if this method is called before
136 * the connection has been established.
137 *
138 * @see #getServerCertificates()
139 * @see #getLocalPrincipal()
140 *
141 * @since 1.5
142 */
143 public Principal getPeerPrincipal()
144 throws SSLPeerUnverifiedException {
145
146 java.security.cert.Certificate[] certs = getServerCertificates();
Przemyslaw Szczepaniak89e6fad2017-03-29 17:17:34 +0100147 return ((X509Certificate)certs[0]).getSubjectX500Principal();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000148 }
149
150 /**
151 * Returns the principal that was sent to the server during handshaking.
152 * <P>
153 * Note: Subclasses should override this method. If not overridden, it
154 * will default to returning the X500Principal of the end-entity certificate
155 * that was sent to the server for certificate-based ciphersuites or,
156 * return null for non-certificate based ciphersuites, such as Kerberos.
157 *
158 * @return the principal sent to the server. Returns an X500Principal
159 * of the end-entity certificate for X509-based cipher suites, and
160 * KerberosPrincipal for Kerberos cipher suites. If no principal was
161 * sent, then null is returned.
162 *
163 * @throws IllegalStateException if this method is called before
164 * the connection has been established.
165 *
166 * @see #getLocalCertificates()
167 * @see #getPeerPrincipal()
168 *
169 * @since 1.5
170 */
171 public Principal getLocalPrincipal() {
172
173 java.security.cert.Certificate[] certs = getLocalCertificates();
174 if (certs != null) {
Przemyslaw Szczepaniak89e6fad2017-03-29 17:17:34 +0100175 return ((X509Certificate)certs[0]).getSubjectX500Principal();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000176 } else {
177 return null;
178 }
179 }
180
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100181 // BEGIN Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
Adam Vartanian09828c02017-05-10 13:50:54 +0100182 // The RI default hostname verifier is a static member of the class, which means
183 // it's created when the class is initialized. As well, its default verifier
184 // just fails all verification attempts, whereas we use OkHttp's verifier.
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100185 /*
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000186 * Holds the default instance so class preloading doesn't create an instance of
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100187 * it.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000188 */
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100189 private static class NoPreloadHolder {
190 public static HostnameVerifier defaultHostnameVerifier;
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000191 public static final Class<? extends HostnameVerifier> originalDefaultHostnameVerifierClass;
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100192 static {
193 try {
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000194 /**
195 * <code>HostnameVerifier</code> provides a callback mechanism so that
196 * implementers of this interface can supply a policy for
197 * handling the case where the host to connect to and
198 * the server name from the certificate mismatch.
199 */
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100200 defaultHostnameVerifier = (HostnameVerifier)
201 Class.forName("com.android.okhttp.internal.tls.OkHostnameVerifier")
202 .getField("INSTANCE").get(null);
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000203 originalDefaultHostnameVerifierClass = defaultHostnameVerifier.getClass();
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100204 } catch (Exception e) {
205 throw new AssertionError("Failed to obtain okhttp HostnameVerifier", e);
206 }
207 }
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100208 }
209
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000210 /**
211 * The <code>hostnameVerifier</code> for this object.
212 */
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000213 protected HostnameVerifier hostnameVerifier;
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100214 // END Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000215
Neil Fuller9f208402019-03-08 16:21:22 +0000216 // Android-changed: Modified the documentation to explain side effects / discourage method use.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000217 /**
218 * Sets the default <code>HostnameVerifier</code> inherited by a
219 * new instance of this class.
Neil Fuller9f208402019-03-08 16:21:22 +0000220 * <p>
221 * Developers are <em>strongly</em> discouraged from changing the default
222 * {@code HostnameVerifier} as {@link #getDefaultHostnameVerifier()} is used by several
223 * classes for hostname verification on Android.
224 * <table>
225 * <tr>
226 * <th>User</th>
227 * <th>Effect</th>
228 * </tr>
229 * <tr>
230 * <td>Android's default {@link TrustManager}, as used with Android's default
231 * {@link SSLContext}, {@link SSLSocketFactory} and {@link SSLSocket} implementations.
232 * </td>
233 * <td>The {@code HostnameVerifier} is used to verify the peer's
234 * certificate hostname after connecting if {@code
235 * SSLParameters.setEndpointIdentificationAlgorithm("HTTPS")} has been called.
236 * Instances use the <em>current</em> default {@code HostnameVerifier} at verification
237 * time.</td>
238 * </tr>
239 * <tr>
240 * <td>{@link android.net.SSLCertificateSocketFactory}</td>
241 * <td>The current default {@code HostnameVerifier} is used from various {@code
242 * createSocket} methods. See {@link android.net.SSLCertificateSocketFactory} for
243 * details; for example {@link
244 * android.net.SSLCertificateSocketFactory#createSocket(String, int)}.
245 * </td>
246 * </tr>
247 * <tr>
248 * <td>Android's default {@link HttpsURLConnection} implementation.</td>
249 * <td>The {@code HostnameVerifier} is used after a successful TLS handshake to verify
250 * the URI host against the TLS session server. Instances use the default {@code
251 * HostnameVerifier} set <em>when they were created</em> unless overridden with {@link
252 * #setHostnameVerifier(HostnameVerifier)}.
253 * Android's <code>HttpsURLConnection</code> relies on the {@code HostnameVerifier}
254 * for the <em>entire</em> hostname verification step.</td>
255 * </tr>
256 * </table>
257 * <p>
258 * If this method is not called, the default <code>HostnameVerifier</code> will check the
259 * hostname according to RFC 2818.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000260 *
261 * @param v the default host name verifier
262 * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
263 * parameter is null.
264 * @throws SecurityException if a security manager exists and its
265 * <code>checkPermission</code> method does not allow
266 * <code>SSLPermission("setHostnameVerifier")</code>
267 * @see #getDefaultHostnameVerifier()
268 */
269 public static void setDefaultHostnameVerifier(HostnameVerifier v) {
270 if (v == null) {
271 throw new IllegalArgumentException(
272 "no default HostnameVerifier specified");
273 }
274
275 SecurityManager sm = System.getSecurityManager();
276 if (sm != null) {
277 sm.checkPermission(new SSLPermission("setHostnameVerifier"));
278 }
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100279 // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
280 // defaultHostnameVerifier = v;
Przemyslaw Szczepaniak419d15f2015-09-28 16:24:00 +0100281 NoPreloadHolder.defaultHostnameVerifier = v;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000282 }
283
284 /**
285 * Gets the default <code>HostnameVerifier</code> that is inherited
286 * by new instances of this class.
287 *
288 * @return the default host name verifier
289 * @see #setDefaultHostnameVerifier(HostnameVerifier)
290 */
291 public static HostnameVerifier getDefaultHostnameVerifier() {
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100292 // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
293 // return defaultHostnameVerifier;
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000294 return NoPreloadHolder.defaultHostnameVerifier;
Piotr Jastrzebskif7ab2bc2015-05-06 14:00:00 +0100295 }
296
Neil Fuller9f208402019-03-08 16:21:22 +0000297 // Android-changed: Modified the documentation to explain Android behavior.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000298 /**
299 * Sets the <code>HostnameVerifier</code> for this instance.
300 * <P>
301 * New instances of this class inherit the default static hostname
302 * verifier set by {@link #setDefaultHostnameVerifier(HostnameVerifier)
303 * setDefaultHostnameVerifier}. Calls to this method replace
304 * this object's <code>HostnameVerifier</code>.
Neil Fuller9f208402019-03-08 16:21:22 +0000305 * <p>
306 * Android's <code>HttpsURLConnection</code> relies on the {@code HostnameVerifier}
307 * for the <em>entire</em> hostname verification step.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000308 *
309 * @param v the host name verifier
310 * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
311 * parameter is null.
312 * @see #getHostnameVerifier()
313 * @see #setDefaultHostnameVerifier(HostnameVerifier)
314 */
315 public void setHostnameVerifier(HostnameVerifier v) {
316 if (v == null) {
317 throw new IllegalArgumentException(
318 "no HostnameVerifier specified");
319 }
320
321 hostnameVerifier = v;
322 }
323
324 /**
325 * Gets the <code>HostnameVerifier</code> in place on this instance.
326 *
327 * @return the host name verifier
328 * @see #setHostnameVerifier(HostnameVerifier)
329 * @see #setDefaultHostnameVerifier(HostnameVerifier)
330 */
331 public HostnameVerifier getHostnameVerifier() {
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100332 // Android-added: Use the default verifier if none is set.
333 // Note that this also has the side effect of *setting* (if unset)
334 // hostnameVerifier to be the default one. It's not clear why this
335 // was done (commit abd00f0eaa46f71f98e75a631c268c812d1ec7c1) but
336 // we're keeping this behavior for lack of a strong reason to do
337 // otherwise.
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000338 if (hostnameVerifier == null) {
Sergio Giroabd00f02015-11-27 14:47:50 +0000339 hostnameVerifier = NoPreloadHolder.defaultHostnameVerifier;
Sergio Giro2e1b9c62015-11-25 15:59:03 +0000340 }
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000341 return hostnameVerifier;
342 }
343
344 private static SSLSocketFactory defaultSSLSocketFactory = null;
345
346 /**
347 * The <code>SSLSocketFactory</code> inherited when an instance
348 * of this class is created.
349 */
350 private SSLSocketFactory sslSocketFactory = getDefaultSSLSocketFactory();
351
352 /**
353 * Sets the default <code>SSLSocketFactory</code> inherited by new
354 * instances of this class.
355 * <P>
356 * The socket factories are used when creating sockets for secure
357 * https URL connections.
358 *
359 * @param sf the default SSL socket factory
360 * @throws IllegalArgumentException if the SSLSocketFactory
361 * parameter is null.
362 * @throws SecurityException if a security manager exists and its
363 * <code>checkSetFactory</code> method does not allow
364 * a socket factory to be specified.
365 * @see #getDefaultSSLSocketFactory()
366 */
367 public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) {
368 if (sf == null) {
369 throw new IllegalArgumentException(
370 "no default SSLSocketFactory specified");
371 }
372
373 SecurityManager sm = System.getSecurityManager();
374 if (sm != null) {
375 sm.checkSetFactory();
376 }
377 defaultSSLSocketFactory = sf;
378 }
379
380 /**
381 * Gets the default static <code>SSLSocketFactory</code> that is
382 * inherited by new instances of this class.
383 * <P>
384 * The socket factories are used when creating sockets for secure
385 * https URL connections.
386 *
387 * @return the default <code>SSLSocketFactory</code>
388 * @see #setDefaultSSLSocketFactory(SSLSocketFactory)
389 */
390 public static SSLSocketFactory getDefaultSSLSocketFactory() {
391 if (defaultSSLSocketFactory == null) {
392 defaultSSLSocketFactory =
393 (SSLSocketFactory)SSLSocketFactory.getDefault();
394 }
395 return defaultSSLSocketFactory;
396 }
397
398 /**
399 * Sets the <code>SSLSocketFactory</code> to be used when this instance
400 * creates sockets for secure https URL connections.
401 * <P>
402 * New instances of this class inherit the default static
403 * <code>SSLSocketFactory</code> set by
404 * {@link #setDefaultSSLSocketFactory(SSLSocketFactory)
405 * setDefaultSSLSocketFactory}. Calls to this method replace
406 * this object's <code>SSLSocketFactory</code>.
407 *
408 * @param sf the SSL socket factory
409 * @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
410 * parameter is null.
Tobias Thiererae3e6a42018-05-01 14:10:47 +0100411 * @throws SecurityException if a security manager exists and its
412 * <code>checkSetFactory</code> method does not allow
413 * a socket factory to be specified.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000414 * @see #getSSLSocketFactory()
415 */
416 public void setSSLSocketFactory(SSLSocketFactory sf) {
417 if (sf == null) {
418 throw new IllegalArgumentException(
419 "no SSLSocketFactory specified");
420 }
421
422 SecurityManager sm = System.getSecurityManager();
423 if (sm != null) {
424 sm.checkSetFactory();
425 }
426 sslSocketFactory = sf;
427 }
428
429 /**
430 * Gets the SSL socket factory to be used when creating sockets
431 * for secure https URL connections.
432 *
433 * @return the <code>SSLSocketFactory</code>
434 * @see #setSSLSocketFactory(SSLSocketFactory)
435 */
436 public SSLSocketFactory getSSLSocketFactory() {
437 return sslSocketFactory;
438 }
439}