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