HttpsURLConnection.java revision 12745:f068a4ffddd2
1/*
2 * Copyright (c) 1999, 2012, 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
26package javax.net.ssl;
27
28import java.net.URL;
29import java.net.HttpURLConnection;
30import java.security.Principal;
31import 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 */
55public abstract
56class 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     *
108     * @return an ordered array of server certificates,
109     *          with the peer's own certificate first followed by
110     *          any certificate authorities.
111     * @throws SSLPeerUnverifiedException if the peer is not verified.
112     * @throws IllegalStateException if this method is called before
113     *          the connection has been established.
114     * @see #getPeerPrincipal()
115     */
116    public abstract java.security.cert.Certificate [] getServerCertificates()
117            throws SSLPeerUnverifiedException;
118
119    /**
120     * Returns the server's principal which was established as part of
121     * defining the session.
122     * <P>
123     * Note: Subclasses should override this method. If not overridden, it
124     * will default to returning the X500Principal of the server's end-entity
125     * certificate for certificate-based ciphersuites, or throw an
126     * SSLPeerUnverifiedException for non-certificate based ciphersuites,
127     * such as Kerberos.
128     *
129     * @return the server's principal. Returns an X500Principal of the
130     * end-entity certiticate for X509-based cipher suites, and
131     * KerberosPrincipal for Kerberos cipher suites.
132     *
133     * @throws SSLPeerUnverifiedException if the peer was not verified
134     * @throws IllegalStateException if this method is called before
135     *          the connection has been established.
136     *
137     * @see #getServerCertificates()
138     * @see #getLocalPrincipal()
139     *
140     * @since 1.5
141     */
142    public Principal getPeerPrincipal()
143            throws SSLPeerUnverifiedException {
144
145        java.security.cert.Certificate[] certs = getServerCertificates();
146        return ((X509Certificate)certs[0]).getSubjectX500Principal();
147    }
148
149    /**
150     * Returns the principal that was sent to the server during handshaking.
151     * <P>
152     * Note: Subclasses should override this method. If not overridden, it
153     * will default to returning the X500Principal of the end-entity certificate
154     * that was sent to the server for certificate-based ciphersuites or,
155     * return null for non-certificate based ciphersuites, such as Kerberos.
156     *
157     * @return the principal sent to the server. Returns an X500Principal
158     * of the end-entity certificate for X509-based cipher suites, and
159     * KerberosPrincipal for Kerberos cipher suites. If no principal was
160     * sent, then null is returned.
161     *
162     * @throws IllegalStateException if this method is called before
163     *          the connection has been established.
164     *
165     * @see #getLocalCertificates()
166     * @see #getPeerPrincipal()
167     *
168     * @since 1.5
169     */
170    public Principal getLocalPrincipal() {
171
172        java.security.cert.Certificate[] certs = getLocalCertificates();
173        if (certs != null) {
174            return ((X509Certificate)certs[0]).getSubjectX500Principal();
175        } else {
176            return null;
177        }
178    }
179
180    /**
181     * <code>HostnameVerifier</code> provides a callback mechanism so that
182     * implementers of this interface can supply a policy for
183     * handling the case where the host to connect to and
184     * the server name from the certificate mismatch.
185     * <p>
186     * The default implementation will deny such connections.
187     */
188    private static HostnameVerifier defaultHostnameVerifier =
189                                        new DefaultHostnameVerifier();
190
191    /*
192     * The initial default <code>HostnameVerifier</code>.  Should be
193     * updated for another other type of <code>HostnameVerifier</code>
194     * that are created.
195     */
196    private static class DefaultHostnameVerifier
197            implements HostnameVerifier {
198        @Override
199        public boolean verify(String hostname, SSLSession session) {
200            return false;
201        }
202    }
203
204    /**
205     * The <code>hostnameVerifier</code> for this object.
206     */
207    protected HostnameVerifier hostnameVerifier = defaultHostnameVerifier;
208
209    /**
210     * Sets the default <code>HostnameVerifier</code> inherited by a
211     * new instance of this class.
212     * <P>
213     * If this method is not called, the default
214     * <code>HostnameVerifier</code> assumes the connection should not
215     * be permitted.
216     *
217     * @param v the default host name verifier
218     * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
219     *          parameter is null.
220     * @throws SecurityException if a security manager exists and its
221     *         <code>checkPermission</code> method does not allow
222     *         <code>SSLPermission("setHostnameVerifier")</code>
223     * @see #getDefaultHostnameVerifier()
224     */
225    public static void setDefaultHostnameVerifier(HostnameVerifier v) {
226        if (v == null) {
227            throw new IllegalArgumentException(
228                "no default HostnameVerifier specified");
229        }
230
231        SecurityManager sm = System.getSecurityManager();
232        if (sm != null) {
233            sm.checkPermission(new SSLPermission("setHostnameVerifier"));
234        }
235        defaultHostnameVerifier = v;
236    }
237
238    /**
239     * Gets the default <code>HostnameVerifier</code> that is inherited
240     * by new instances of this class.
241     *
242     * @return the default host name verifier
243     * @see #setDefaultHostnameVerifier(HostnameVerifier)
244     */
245    public static HostnameVerifier getDefaultHostnameVerifier() {
246        return defaultHostnameVerifier;
247    }
248
249    /**
250     * Sets the <code>HostnameVerifier</code> for this instance.
251     * <P>
252     * New instances of this class inherit the default static hostname
253     * verifier set by {@link #setDefaultHostnameVerifier(HostnameVerifier)
254     * setDefaultHostnameVerifier}.  Calls to this method replace
255     * this object's <code>HostnameVerifier</code>.
256     *
257     * @param v the host name verifier
258     * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
259     *  parameter is null.
260     * @see #getHostnameVerifier()
261     * @see #setDefaultHostnameVerifier(HostnameVerifier)
262     */
263    public void setHostnameVerifier(HostnameVerifier v) {
264        if (v == null) {
265            throw new IllegalArgumentException(
266                "no HostnameVerifier specified");
267        }
268
269        hostnameVerifier = v;
270    }
271
272    /**
273     * Gets the <code>HostnameVerifier</code> in place on this instance.
274     *
275     * @return the host name verifier
276     * @see #setHostnameVerifier(HostnameVerifier)
277     * @see #setDefaultHostnameVerifier(HostnameVerifier)
278     */
279    public HostnameVerifier getHostnameVerifier() {
280        return hostnameVerifier;
281    }
282
283    private static SSLSocketFactory defaultSSLSocketFactory = null;
284
285    /**
286     * The <code>SSLSocketFactory</code> inherited when an instance
287     * of this class is created.
288     */
289    private SSLSocketFactory sslSocketFactory = getDefaultSSLSocketFactory();
290
291    /**
292     * Sets the default <code>SSLSocketFactory</code> inherited by new
293     * instances of this class.
294     * <P>
295     * The socket factories are used when creating sockets for secure
296     * https URL connections.
297     *
298     * @param sf the default SSL socket factory
299     * @throws IllegalArgumentException if the SSLSocketFactory
300     *          parameter is null.
301     * @throws SecurityException if a security manager exists and its
302     *         <code>checkSetFactory</code> method does not allow
303     *         a socket factory to be specified.
304     * @see #getDefaultSSLSocketFactory()
305     */
306    public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) {
307        if (sf == null) {
308            throw new IllegalArgumentException(
309                "no default SSLSocketFactory specified");
310        }
311
312        SecurityManager sm = System.getSecurityManager();
313        if (sm != null) {
314            sm.checkSetFactory();
315        }
316        defaultSSLSocketFactory = sf;
317    }
318
319    /**
320     * Gets the default static <code>SSLSocketFactory</code> that is
321     * inherited by new instances of this class.
322     * <P>
323     * The socket factories are used when creating sockets for secure
324     * https URL connections.
325     *
326     * @return the default <code>SSLSocketFactory</code>
327     * @see #setDefaultSSLSocketFactory(SSLSocketFactory)
328     */
329    public static SSLSocketFactory getDefaultSSLSocketFactory() {
330        if (defaultSSLSocketFactory == null) {
331            defaultSSLSocketFactory =
332                (SSLSocketFactory)SSLSocketFactory.getDefault();
333        }
334        return defaultSSLSocketFactory;
335    }
336
337    /**
338     * Sets the <code>SSLSocketFactory</code> to be used when this instance
339     * creates sockets for secure https URL connections.
340     * <P>
341     * New instances of this class inherit the default static
342     * <code>SSLSocketFactory</code> set by
343     * {@link #setDefaultSSLSocketFactory(SSLSocketFactory)
344     * setDefaultSSLSocketFactory}.  Calls to this method replace
345     * this object's <code>SSLSocketFactory</code>.
346     *
347     * @param sf the SSL socket factory
348     * @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
349     *          parameter is null.
350     * @throws SecurityException if a security manager exists and its
351     *         <code>checkSetFactory</code> method does not allow
352     *         a socket factory to be specified.
353     * @see #getSSLSocketFactory()
354     */
355    public void setSSLSocketFactory(SSLSocketFactory sf) {
356        if (sf == null) {
357            throw new IllegalArgumentException(
358                "no SSLSocketFactory specified");
359        }
360
361        SecurityManager sm = System.getSecurityManager();
362        if (sm != null) {
363            sm.checkSetFactory();
364        }
365        sslSocketFactory = sf;
366    }
367
368    /**
369     * Gets the SSL socket factory to be used when creating sockets
370     * for secure https URL connections.
371     *
372     * @return the <code>SSLSocketFactory</code>
373     * @see #setSSLSocketFactory(SSLSocketFactory)
374     */
375    public SSLSocketFactory getSSLSocketFactory() {
376        return sslSocketFactory;
377    }
378}
379