1 /*
2  * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
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
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
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  *
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.
24  */

25
26 package javax.net.ssl;
27
28 import java.net.URL;
29 import java.net.HttpURLConnection;
30 import java.security.Principal;
31 import java.security.cert.X509Certificate;
32
33 /**
34  * <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
35  * with support for https-specific features.
36  * <P>
37  * See <A HREF="http://www.w3.org/pub/WWW/Protocols/">
38  * http://www.w3.org/pub/WWW/Protocols/</A> and
39  * <A HREF="http://www.ietf.org/"> RFC 2818 </A>
40  * for more details on the
41  * https specification.
42  * <P>
43  * This class uses <code>HostnameVerifier</code> and
44  * <code>SSLSocketFactory</code>.
45  * There are default implementations defined for both classes.
46  * However, the implementations can be replaced on a per-class (static) or
47  * per-instance basis.  All new <code>HttpsURLConnection</code>s instances
48  * will be assigned
49  * the "default" static values at instance creation, but they can be overriden
50  * by calling the appropriate per-instance set method(s) before
51  * <code>connect</code>ing.
52  *
53  * @since 1.4
54  */

55 public abstract
56 class HttpsURLConnection extends HttpURLConnection
57 {
58     /**
59      * Creates an <code>HttpsURLConnection</code> using the
60      * URL specified.
61      *
62      * @param url the URL
63      */

64     protected HttpsURLConnection(URL url) {
65         super(url);
66     }
67
68     /**
69      * Returns the cipher suite in use on this connection.
70      *
71      * @return the cipher suite
72      * @throws IllegalStateException if this method is called before
73      *          the connection has been established.
74      */

75     public abstract String getCipherSuite();
76
77     /**
78      * Returns the certificate(s) that were sent to the server during
79      * handshaking.
80      * <P>
81      * Note: This method is useful only when using certificate-based
82      * cipher suites.
83      * <P>
84      * When multiple certificates are available for use in a
85      * handshake, the implementation chooses what it considers the
86      * "best" certificate chain available, and transmits that to
87      * the other side.  This method allows the caller to know
88      * which certificate chain was actually sent.
89      *
90      * @return an ordered array of certificates,
91      *          with the client's own certificate first followed by any
92      *          certificate authorities.  If no certificates were sent,
93      *          then null is returned.
94      * @throws IllegalStateException if this method is called before
95      *          the connection has been established.
96      * @see #getLocalPrincipal()
97      */

98     public abstract java.security.cert.Certificate [] getLocalCertificates();
99
100     /**
101      * Returns the server's certificate chain which was established
102      * as part of defining the session.
103      * <P>
104      * Note: This method can be used only when using certificate-based
105      * cipher suites; using it with non-certificate-based cipher suites,
106      * such as Kerberos, will throw an SSLPeerUnverifiedException.
107      * <P>
108      * Note: The returned value may not be a valid certificate chain
109      * and should not be relied on for trust decisions.
110      *
111      * @return an ordered array of server certificates,
112      *          with the peer's own certificate first followed by
113      *          any certificate authorities.
114      * @throws SSLPeerUnverifiedException if the peer is not verified.
115      * @throws IllegalStateException if this method is called before
116      *          the connection has been established.
117      * @see #getPeerPrincipal()
118      */

119     public abstract java.security.cert.Certificate [] getServerCertificates()
120             throws SSLPeerUnverifiedException;
121
122     /**
123      * Returns the server's principal which was established as part of
124      * defining the session.
125      * <P>
126      * Note: Subclasses should override this method. If not overridden, it
127      * will default to returning the X500Principal of the server's end-entity
128      * certificate for certificate-based ciphersuites, or throw an
129      * SSLPeerUnverifiedException for non-certificate based ciphersuites,
130      * such as Kerberos.
131      *
132      * @return the server's principal. Returns an X500Principal of the
133      * end-entity certiticate for X509-based cipher suites, and
134      * KerberosPrincipal for Kerberos cipher suites.
135      *
136      * @throws SSLPeerUnverifiedException if the peer was not verified
137      * @throws IllegalStateException if this method is called before
138      *          the connection has been established.
139      *
140      * @see #getServerCertificates()
141      * @see #getLocalPrincipal()
142      *
143      * @since 1.5
144      */

145     public Principal getPeerPrincipal()
146             throws SSLPeerUnverifiedException {
147
148         java.security.cert.Certificate[] certs = getServerCertificates();
149         return ((X509Certificate)certs[0]).getSubjectX500Principal();
150     }
151
152     /**
153      * Returns the principal that was sent to the server during handshaking.
154      * <P>
155      * Note: Subclasses should override this method. If not overridden, it
156      * will default to returning the X500Principal of the end-entity certificate
157      * that was sent to the server for certificate-based ciphersuites or,
158      * return null for non-certificate based ciphersuites, such as Kerberos.
159      *
160      * @return the principal sent to the server. Returns an X500Principal
161      * of the end-entity certificate for X509-based cipher suites, and
162      * KerberosPrincipal for Kerberos cipher suites. If no principal was
163      * sent, then null is returned.
164      *
165      * @throws IllegalStateException if this method is called before
166      *          the connection has been established.
167      *
168      * @see #getLocalCertificates()
169      * @see #getPeerPrincipal()
170      *
171      * @since 1.5
172      */

173     public Principal getLocalPrincipal() {
174
175         java.security.cert.Certificate[] certs = getLocalCertificates();
176         if (certs != null) {
177             return ((X509Certificate)certs[0]).getSubjectX500Principal();
178         } else {
179             return null;
180         }
181     }
182
183     /**
184      * <code>HostnameVerifier</code> provides a callback mechanism so that
185      * implementers of this interface can supply a policy for
186      * handling the case where the host to connect to and
187      * the server name from the certificate mismatch.
188      * <p>
189      * The default implementation will deny such connections.
190      */

191     private static HostnameVerifier defaultHostnameVerifier =
192                                         new DefaultHostnameVerifier();
193
194     /*
195      * The initial default <code>HostnameVerifier</code>.  Should be
196      * updated for another other type of <code>HostnameVerifier</code>
197      * that are created.
198      */

199     private static class DefaultHostnameVerifier
200             implements HostnameVerifier {
201         @Override
202         public boolean verify(String hostname, SSLSession session) {
203             return false;
204         }
205     }
206
207     /**
208      * The <code>hostnameVerifier</code> for this object.
209      */

210     protected HostnameVerifier hostnameVerifier = defaultHostnameVerifier;
211
212     /**
213      * Sets the default <code>HostnameVerifier</code> inherited by a
214      * new instance of this class.
215      * <P>
216      * If this method is not called, the default
217      * <code>HostnameVerifier</code> assumes the connection should not
218      * be permitted.
219      *
220      * @param v the default host name verifier
221      * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
222      *          parameter is null.
223      * @throws SecurityException if a security manager exists and its
224      *         <code>checkPermission</code> method does not allow
225      *         <code>SSLPermission("setHostnameVerifier")</code>
226      * @see #getDefaultHostnameVerifier()
227      */

228     public static void setDefaultHostnameVerifier(HostnameVerifier v) {
229         if (v == null) {
230             throw new IllegalArgumentException(
231                 "no default HostnameVerifier specified");
232         }
233
234         SecurityManager sm = System.getSecurityManager();
235         if (sm != null) {
236             sm.checkPermission(new SSLPermission("setHostnameVerifier"));
237         }
238         defaultHostnameVerifier = v;
239     }
240
241     /**
242      * Gets the default <code>HostnameVerifier</code> that is inherited
243      * by new instances of this class.
244      *
245      * @return the default host name verifier
246      * @see #setDefaultHostnameVerifier(HostnameVerifier)
247      */

248     public static HostnameVerifier getDefaultHostnameVerifier() {
249         return defaultHostnameVerifier;
250     }
251
252     /**
253      * Sets the <code>HostnameVerifier</code> for this instance.
254      * <P>
255      * New instances of this class inherit the default static hostname
256      * verifier set by {@link #setDefaultHostnameVerifier(HostnameVerifier)
257      * setDefaultHostnameVerifier}.  Calls to this method replace
258      * this object's <code>HostnameVerifier</code>.
259      *
260      * @param v the host name verifier
261      * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
262      *  parameter is null.
263      * @see #getHostnameVerifier()
264      * @see #setDefaultHostnameVerifier(HostnameVerifier)
265      */

266     public void setHostnameVerifier(HostnameVerifier v) {
267         if (v == null) {
268             throw new IllegalArgumentException(
269                 "no HostnameVerifier specified");
270         }
271
272         hostnameVerifier = v;
273     }
274
275     /**
276      * Gets the <code>HostnameVerifier</code> in place on this instance.
277      *
278      * @return the host name verifier
279      * @see #setHostnameVerifier(HostnameVerifier)
280      * @see #setDefaultHostnameVerifier(HostnameVerifier)
281      */

282     public HostnameVerifier getHostnameVerifier() {
283         return hostnameVerifier;
284     }
285
286     private static SSLSocketFactory defaultSSLSocketFactory = null;
287
288     /**
289      * The <code>SSLSocketFactory</code> inherited when an instance
290      * of this class is created.
291      */

292     private SSLSocketFactory sslSocketFactory = getDefaultSSLSocketFactory();
293
294     /**
295      * Sets the default <code>SSLSocketFactory</code> inherited by new
296      * instances of this class.
297      * <P>
298      * The socket factories are used when creating sockets for secure
299      * https URL connections.
300      *
301      * @param sf the default SSL socket factory
302      * @throws IllegalArgumentException if the SSLSocketFactory
303      *          parameter is null.
304      * @throws SecurityException if a security manager exists and its
305      *         <code>checkSetFactory</code> method does not allow
306      *         a socket factory to be specified.
307      * @see #getDefaultSSLSocketFactory()
308      */

309     public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) {
310         if (sf == null) {
311             throw new IllegalArgumentException(
312                 "no default SSLSocketFactory specified");
313         }
314
315         SecurityManager sm = System.getSecurityManager();
316         if (sm != null) {
317             sm.checkSetFactory();
318         }
319         defaultSSLSocketFactory = sf;
320     }
321
322     /**
323      * Gets the default static <code>SSLSocketFactory</code> that is
324      * inherited by new instances of this class.
325      * <P>
326      * The socket factories are used when creating sockets for secure
327      * https URL connections.
328      *
329      * @return the default <code>SSLSocketFactory</code>
330      * @see #setDefaultSSLSocketFactory(SSLSocketFactory)
331      */

332     public static SSLSocketFactory getDefaultSSLSocketFactory() {
333         if (defaultSSLSocketFactory == null) {
334             defaultSSLSocketFactory =
335                 (SSLSocketFactory)SSLSocketFactory.getDefault();
336         }
337         return defaultSSLSocketFactory;
338     }
339
340     /**
341      * Sets the <code>SSLSocketFactory</code> to be used when this instance
342      * creates sockets for secure https URL connections.
343      * <P>
344      * New instances of this class inherit the default static
345      * <code>SSLSocketFactory</code> set by
346      * {@link #setDefaultSSLSocketFactory(SSLSocketFactory)
347      * setDefaultSSLSocketFactory}.  Calls to this method replace
348      * this object's <code>SSLSocketFactory</code>.
349      *
350      * @param sf the SSL socket factory
351      * @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
352      *          parameter is null.
353      * @throws SecurityException if a security manager exists and its
354      *         <code>checkSetFactory</code> method does not allow
355      *         a socket factory to be specified.
356      * @see #getSSLSocketFactory()
357      */

358     public void setSSLSocketFactory(SSLSocketFactory sf) {
359         if (sf == null) {
360             throw new IllegalArgumentException(
361                 "no SSLSocketFactory specified");
362         }
363
364         SecurityManager sm = System.getSecurityManager();
365         if (sm != null) {
366             sm.checkSetFactory();
367         }
368         sslSocketFactory = sf;
369     }
370
371     /**
372      * Gets the SSL socket factory to be used when creating sockets
373      * for secure https URL connections.
374      *
375      * @return the <code>SSLSocketFactory</code>
376      * @see #setSSLSocketFactory(SSLSocketFactory)
377      */

378     public SSLSocketFactory getSSLSocketFactory() {
379         return sslSocketFactory;
380     }
381 }
382