• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
4  * 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 
27 package javax.net.ssl;
28 
29 import java.net.URL;
30 import java.net.HttpURLConnection;
31 import java.security.Principal;
32 import java.security.cert.X509Certificate;
33 
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  */
56 abstract public
57 class HttpsURLConnection extends HttpURLConnection
58 {
59     /**
60      * Creates an <code>HttpsURLConnection</code> using the
61      * URL specified.
62      *
63      * @param url the URL
64      */
HttpsURLConnection(URL url)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      */
getCipherSuite()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      */
getLocalCertificates()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      */
getServerCertificates()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      */
getPeerPrincipal()143     public Principal getPeerPrincipal()
144             throws SSLPeerUnverifiedException {
145 
146         java.security.cert.Certificate[] certs = getServerCertificates();
147         return ((X509Certificate)certs[0]).getSubjectX500Principal();
148     }
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      */
getLocalPrincipal()171     public Principal getLocalPrincipal() {
172 
173         java.security.cert.Certificate[] certs = getLocalCertificates();
174         if (certs != null) {
175             return ((X509Certificate)certs[0]).getSubjectX500Principal();
176         } else {
177             return null;
178         }
179     }
180 
181     // BEGIN Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
182     // 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.
185     /*
186      * Holds the default instance so class preloading doesn't create an instance of
187      * it.
188      */
189     private static class NoPreloadHolder {
190         public static HostnameVerifier defaultHostnameVerifier;
191         public static final Class<? extends HostnameVerifier> originalDefaultHostnameVerifierClass;
192         static {
193             try {
194                 /**
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                   */
200                 defaultHostnameVerifier = (HostnameVerifier)
201                         Class.forName("com.android.okhttp.internal.tls.OkHostnameVerifier")
202                         .getField("INSTANCE").get(null);
203                 originalDefaultHostnameVerifierClass = defaultHostnameVerifier.getClass();
204             } catch (Exception e) {
205                 throw new AssertionError("Failed to obtain okhttp HostnameVerifier", e);
206             }
207         }
208     }
209 
210     /**
211      * The <code>hostnameVerifier</code> for this object.
212      */
213     protected HostnameVerifier hostnameVerifier;
214     // END Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
215 
216     // Android-changed: Modified the documentation to explain side effects / discourage method use.
217     /**
218      * Sets the default <code>HostnameVerifier</code> inherited by a
219      * new instance of this class.
220      * <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.
260      *
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      */
setDefaultHostnameVerifier(HostnameVerifier v)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         }
279         // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
280         // defaultHostnameVerifier = v;
281         NoPreloadHolder.defaultHostnameVerifier = v;
282     }
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      */
getDefaultHostnameVerifier()291     public static HostnameVerifier getDefaultHostnameVerifier() {
292         // Android-changed: Use holder class idiom for a lazily-created OkHttp hostname verifier.
293         // return defaultHostnameVerifier;
294         return NoPreloadHolder.defaultHostnameVerifier;
295     }
296 
297     // Android-changed: Modified the documentation to explain Android behavior.
298     /**
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>.
305      * <p>
306      * Android's <code>HttpsURLConnection</code> relies on the {@code HostnameVerifier}
307      * for the <em>entire</em> hostname verification step.
308      *
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      */
setHostnameVerifier(HostnameVerifier v)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      */
getHostnameVerifier()331     public HostnameVerifier getHostnameVerifier() {
332         // 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.
338         if (hostnameVerifier == null) {
339             hostnameVerifier = NoPreloadHolder.defaultHostnameVerifier;
340         }
341         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      */
setDefaultSSLSocketFactory(SSLSocketFactory sf)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      */
getDefaultSSLSocketFactory()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.
411      * @throws SecurityException if a security manager exists and its
412      *         <code>checkSetFactory</code> method does not allow
413      *         a socket factory to be specified.
414      * @see #getSSLSocketFactory()
415      */
setSSLSocketFactory(SSLSocketFactory sf)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      */
getSSLSocketFactory()436     public SSLSocketFactory getSSLSocketFactory() {
437         return sslSocketFactory;
438     }
439 }
440