blob: 0f22f380e39c64cc1b0f3158e6f975cd33d6b656 [file] [log] [blame]
The Android Open Source Projectadc854b2009-03-03 19:28:47 -08001/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package javax.net.ssl;
19
20import java.net.HttpURLConnection;
21import java.net.URL;
22import java.security.Principal;
23import java.security.cert.Certificate;
24import java.security.cert.X509Certificate;
25
26/**
Brian Carlstrom8bccf8c2011-04-11 17:09:07 -070027 * An {@link HttpURLConnection} for HTTPS (<a
28 * href="http://tools.ietf.org/html/rfc2818">RFC 2818</a>). A
29 * connected {@code HttpsURLConnection} allows access to the
30 * negotiated cipher suite, the server certificate chain, and the
31 * client certificate chain if any.
32 *
33 * <h3>Providing an application specific X509TrustManager</h3>
34 *
35 * If an application wants to trust Certificate Authority (CA)
36 * certificates that are not part of the system, it should specify its
37 * own {@code X509TrustManager} via a {@code SSLSocketFactory} set on
38 * the {@code HttpsURLConnection}. The {@code X509TrustManager} can be
39 * created based on a {@code KeyStore} using a {@code
40 * TrustManagerFactory} to supply trusted CA certificates. Note that
41 * self-signed certificates are effectively their own CA and can be
42 * trusted by including them in a {@code KeyStore}.
43 *
44 * <p>For example, to trust a set of certificates specified by a {@code KeyStore}:
45 * <pre> {@code
46 * KeyStore keyStore = ...;
47 * TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
48 * tmf.init(keyStore);
49 *
50 * SSLContext context = SSLContext.getInstance("TLS");
51 * context.init(null, tmf.getTrustManagers(), null);
52 *
53 * URL url = new URL("https://www.example.com/");
54 * HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
55 * urlConnection.setSSLSocketFactory(context.getSocketFactory());
56 * InputStream in = urlConnection.getInputStream();
57 * }</pre>
58 *
59 * <p>It is possible to implement {@code X509TrustManager} directly
60 * instead of using one created by a {@code
61 * TrustManagerFactory}. While this is straightforward in the insecure
62 * case of allowing all certificate chains to pass verification,
63 * writing a proper implementation will usually want to take advantage
64 * of {@link java.security.cert.CertPathValidator
65 * CertPathValidator}. In general, it might be better to write a
66 * custom {@code KeyStore} implementation to pass to the {@code
67 * TrustManagerFactory} than to try and write a custom {@code
68 * X509TrustManager}.
69 *
70 * <h3>Providing an application specific X509KeyManager</h3>
71 *
72 * A custom {@code X509KeyManager} can be used to supply a client
73 * certificate and its associated private key to authenticate a
74 * connection to the server. The {@code X509KeyManager} can be created
75 * based on a {@code KeyStore} using a {@code KeyManagerFactory}.
76 *
77 * <p>For example, to supply client certificates from a {@code KeyStore}:
78 * <pre> {@code
79 * KeyStore keyStore = ...;
80 * KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
81 * kmf.init(keyStore);
82 *
83 * SSLContext context = SSLContext.getInstance("TLS");
84 * context.init(kmf.getKeyManagers(), null, null);
85 *
86 * URL url = new URL("https://www.example.com/");
87 * HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
88 * urlConnection.setSSLSocketFactory(context.getSocketFactory());
89 * InputStream in = urlConnection.getInputStream();
90 * }</pre>
91 *
92 * <p>A {@code X509KeyManager} can also be implemented directly. This
93 * can allow an application to return a certificate and private key
94 * from a non-{@code KeyStore} source or to specify its own logic for
95 * selecting a specific credential to use when many may be present in
96 * a single {@code KeyStore}.
97 *
98 * <h3>TLS Intolerance Support</h3>
99 *
100 * This class attempts to create secure connections using common TLS
101 * extensions and SSL deflate compression. Should that fail, the
102 * connection will be retried with SSLv3 only.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800103 */
104public abstract class HttpsURLConnection extends HttpURLConnection {
105
106 private static HostnameVerifier defaultHostnameVerifier = new DefaultHostnameVerifier();
107
108 private static SSLSocketFactory defaultSSLSocketFactory = (SSLSocketFactory) SSLSocketFactory
109 .getDefault();
110
111 /**
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800112 * Sets the default hostname verifier to be used by new instances.
Jesse Wilsonf9215792009-08-25 16:30:17 -0700113 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800114 * @param v
115 * the new default hostname verifier
116 * @throws IllegalArgumentException
117 * if the specified verifier is {@code null}.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800118 */
119 public static void setDefaultHostnameVerifier(HostnameVerifier v) {
120 if (v == null) {
121 throw new IllegalArgumentException("HostnameVerifier is null");
122 }
123 defaultHostnameVerifier = v;
124 }
125
126 /**
127 * Returns the default hostname verifier.
Jesse Wilsonf9215792009-08-25 16:30:17 -0700128 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800129 * @return the default hostname verifier.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800130 */
131 public static HostnameVerifier getDefaultHostnameVerifier() {
132 return defaultHostnameVerifier;
133 }
134
135 /**
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800136 * Sets the default SSL socket factory to be used by new instances.
Jesse Wilsonf9215792009-08-25 16:30:17 -0700137 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800138 * @param sf
139 * the new default SSL socket factory.
140 * @throws IllegalArgumentException
141 * if the specified socket factory is {@code null}.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800142 */
143 public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) {
144 if (sf == null) {
145 throw new IllegalArgumentException("SSLSocketFactory is null");
146 }
147 defaultSSLSocketFactory = sf;
148 }
149
150 /**
151 * Returns the default SSL socket factory for new instances.
Jesse Wilsonf9215792009-08-25 16:30:17 -0700152 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800153 * @return the default SSL socket factory for new instances.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800154 */
155 public static SSLSocketFactory getDefaultSSLSocketFactory() {
156 return defaultSSLSocketFactory;
157 }
158
159 /**
Jesse Wilsonf9215792009-08-25 16:30:17 -0700160 * The host name verifier used by this connection. It is initialized from
161 * the default hostname verifier
162 * {@link #setDefaultHostnameVerifier(HostnameVerifier)} or
163 * {@link #getDefaultHostnameVerifier()}.
164 */
165 protected HostnameVerifier hostnameVerifier;
166
167 private SSLSocketFactory sslSocketFactory;
168
169 /**
170 * Creates a new {@code HttpsURLConnection} with the specified {@code URL}.
171 *
172 * @param url
173 * the {@code URL} to connect to.
174 */
175 protected HttpsURLConnection(URL url) {
176 super(url);
177 hostnameVerifier = defaultHostnameVerifier;
178 sslSocketFactory = defaultSSLSocketFactory;
179 }
180
181 /**
182 * Returns the name of the cipher suite negotiated during the SSL handshake.
183 *
184 * @return the name of the cipher suite negotiated during the SSL handshake.
185 * @throws IllegalStateException
186 * if no connection has been established yet.
187 */
188 public abstract String getCipherSuite();
189
190 /**
191 * Returns the list of local certificates used during the handshake. These
192 * certificates were sent to the peer.
193 *
194 * @return Returns the list of certificates used during the handshake with
195 * the local identity certificate followed by CAs, or {@code null}
196 * if no certificates were used during the handshake.
197 * @throws IllegalStateException
198 * if no connection has been established yet.
199 */
200 public abstract Certificate[] getLocalCertificates();
201
202 /**
203 * Return the list of certificates identifying the peer during the
204 * handshake.
205 *
206 * @return the list of certificates identifying the peer with the peer's
207 * identity certificate followed by CAs.
208 * @throws SSLPeerUnverifiedException
209 * if the identity of the peer has not been verified..
210 * @throws IllegalStateException
211 * if no connection has been established yet.
212 */
213 public abstract Certificate[] getServerCertificates() throws SSLPeerUnverifiedException;
214
215 /**
216 * Returns the {@code Principal} identifying the peer.
217 *
218 * @return the {@code Principal} identifying the peer.
219 * @throws SSLPeerUnverifiedException
220 * if the identity of the peer has not been verified.
221 * @throws IllegalStateException
222 * if no connection has been established yet.
223 */
224 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
225 Certificate[] certs = getServerCertificates();
226 if (certs == null || certs.length == 0 || (!(certs[0] instanceof X509Certificate))) {
227 throw new SSLPeerUnverifiedException("No server's end-entity certificate");
228 }
229 return ((X509Certificate) certs[0]).getSubjectX500Principal();
230 }
231
232 /**
233 * Returns the {@code Principal} used to identify the local host during the handshake.
234 *
235 * @return the {@code Principal} used to identify the local host during the handshake, or
236 * {@code null} if none was used.
237 * @throws IllegalStateException
238 * if no connection has been established yet.
239 */
240 public Principal getLocalPrincipal() {
241 Certificate[] certs = getLocalCertificates();
242 if (certs == null || certs.length == 0 || (!(certs[0] instanceof X509Certificate))) {
243 return null;
244 }
245 return ((X509Certificate) certs[0]).getSubjectX500Principal();
246 }
247
248 /**
249 * Sets the hostname verifier for this instance.
250 *
251 * @param v
252 * the hostname verifier for this instance.
253 * @throws IllegalArgumentException
254 * if the specified verifier is {@code null}.
255 */
256 public void setHostnameVerifier(HostnameVerifier v) {
257 if (v == null) {
258 throw new IllegalArgumentException("HostnameVerifier is null");
259 }
260 hostnameVerifier = v;
261 }
262
263 /**
264 * Returns the hostname verifier used by this instance.
265 *
266 * @return the hostname verifier used by this instance.
267 */
268 public HostnameVerifier getHostnameVerifier() {
269 return hostnameVerifier;
270 }
271
272 /**
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800273 * Sets the SSL socket factory for this instance.
Jesse Wilsonf9215792009-08-25 16:30:17 -0700274 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800275 * @param sf
276 * the SSL socket factory to be used by this instance.
277 * @throws IllegalArgumentException
278 * if the specified socket factory is {@code null}.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800279 */
280 public void setSSLSocketFactory(SSLSocketFactory sf) {
281 if (sf == null) {
282 throw new IllegalArgumentException("SSLSocketFactory is null");
283 }
Jesse Wilsonf9215792009-08-25 16:30:17 -0700284 sslSocketFactory = sf;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800285 }
286
287 /**
288 * Returns the SSL socket factory used by this instance.
Jesse Wilsonf9215792009-08-25 16:30:17 -0700289 *
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800290 * @return the SSL socket factory used by this instance.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800291 */
292 public SSLSocketFactory getSSLSocketFactory() {
Jesse Wilsonf9215792009-08-25 16:30:17 -0700293 return sslSocketFactory;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800294 }
295
296}