001 /*
002 * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.net.ssl;
027
028 import java.net.URL;
029 import java.net.HttpURLConnection;
030 import java.security.Principal;
031 import java.security.cert.X509Certificate;
032 import javax.security.auth.x500.X500Principal;
033
034 /**
035 * <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
036 * with support for https-specific features.
037 * <P>
038 * See <A HREF="http://www.w3.org/pub/WWW/Protocols/">
039 * http://www.w3.org/pub/WWW/Protocols/</A> and
040 * <A HREF="http://www.ietf.org/"> RFC 2818 </A>
041 * for more details on the
042 * https specification.
043 * <P>
044 * This class uses <code>HostnameVerifier</code> and
045 * <code>SSLSocketFactory</code>.
046 * There are default implementations defined for both classes.
047 * However, the implementations can be replaced on a per-class (static) or
048 * per-instance basis. All new <code>HttpsURLConnection</code>s instances
049 * will be assigned
050 * the "default" static values at instance creation, but they can be overriden
051 * by calling the appropriate per-instance set method(s) before
052 * <code>connect</code>ing.
053 *
054 * @since 1.4
055 * @version 1.33
056 */
057 abstract public class HttpsURLConnection extends HttpURLConnection {
058 /**
059 * Creates an <code>HttpsURLConnection</code> using the
060 * URL specified.
061 *
062 * @param url the URL
063 */
064 protected HttpsURLConnection(URL url) {
065 super (url);
066 }
067
068 /**
069 * Returns the cipher suite in use on this connection.
070 *
071 * @return the cipher suite
072 * @throws IllegalStateException if this method is called before
073 * the connection has been established.
074 */
075 public abstract String getCipherSuite();
076
077 /**
078 * Returns the certificate(s) that were sent to the server during
079 * handshaking.
080 * <P>
081 * Note: This method is useful only when using certificate-based
082 * cipher suites.
083 * <P>
084 * When multiple certificates are available for use in a
085 * handshake, the implementation chooses what it considers the
086 * "best" certificate chain available, and transmits that to
087 * the other side. This method allows the caller to know
088 * which certificate chain was actually sent.
089 *
090 * @return an ordered array of certificates,
091 * with the client's own certificate first followed by any
092 * certificate authorities. If no certificates were sent,
093 * then null is returned.
094 * @throws IllegalStateException if this method is called before
095 * the connection has been established.
096 * @see #getLocalPrincipal()
097 */
098 public abstract java.security.cert.Certificate[] getLocalCertificates();
099
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 ((X500Principal) ((X509Certificate) certs[0])
147 .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 */
171 public Principal getLocalPrincipal() {
172
173 java.security.cert.Certificate[] certs = getLocalCertificates();
174 if (certs != null) {
175 return ((X500Principal) ((X509Certificate) certs[0])
176 .getSubjectX500Principal());
177 } else {
178 return null;
179 }
180 }
181
182 /**
183 * <code>HostnameVerifier</code> provides a callback mechanism so that
184 * implementers of this interface can supply a policy for
185 * handling the case where the host to connect to and
186 * the server name from the certificate mismatch.
187 * <p>
188 * The default implementation will deny such connections.
189 */
190 private static HostnameVerifier defaultHostnameVerifier;
191
192 /**
193 * Initialize the default <code>HostnameVerifier</code>.
194 */
195 static {
196 try {
197 defaultHostnameVerifier = new sun.net.www.protocol.https.DefaultHostnameVerifier();
198 } catch (NoClassDefFoundError e) {
199 defaultHostnameVerifier = new DefaultHostnameVerifier();
200 }
201 }
202
203 /*
204 * The initial default <code>HostnameVerifier</code>. Should be
205 * updated for another other type of <code>HostnameVerifier</code>
206 * that are created.
207 */
208 private static class DefaultHostnameVerifier implements
209 HostnameVerifier {
210 public boolean verify(String hostname, SSLSession session) {
211 return false;
212 }
213 }
214
215 /**
216 * The <code>hostnameVerifier</code> for this object.
217 */
218 protected HostnameVerifier hostnameVerifier = defaultHostnameVerifier;
219
220 /**
221 * Sets the default <code>HostnameVerifier</code> inherited by a
222 * new instance of this class.
223 * <P>
224 * If this method is not called, the default
225 * <code>HostnameVerifier</code> assumes the connection should not
226 * be permitted.
227 *
228 * @param v the default host name verifier
229 * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
230 * parameter is null.
231 * @throws SecurityException if a security manager exists and its
232 * <code>checkPermission</code> method does not allow
233 * <code>SSLPermission("setHostnameVerifier")</code>
234 * @see #getDefaultHostnameVerifier()
235 */
236 public static void setDefaultHostnameVerifier(HostnameVerifier v) {
237 if (v == null) {
238 throw new IllegalArgumentException(
239 "no default HostnameVerifier specified");
240 }
241
242 SecurityManager sm = System.getSecurityManager();
243 if (sm != null) {
244 sm
245 .checkPermission(new SSLPermission(
246 "setHostnameVerifier"));
247 }
248 defaultHostnameVerifier = v;
249 }
250
251 /**
252 * Gets the default <code>HostnameVerifier</code> that is inherited
253 * by new instances of this class.
254 *
255 * @return the default host name verifier
256 * @see #setDefaultHostnameVerifier(HostnameVerifier)
257 */
258 public static HostnameVerifier getDefaultHostnameVerifier() {
259 return defaultHostnameVerifier;
260 }
261
262 /**
263 * Sets the <code>HostnameVerifier</code> for this instance.
264 * <P>
265 * New instances of this class inherit the default static hostname
266 * verifier set by {@link #setDefaultHostnameVerifier(HostnameVerifier)
267 * setDefaultHostnameVerifier}. Calls to this method replace
268 * this object's <code>HostnameVerifier</code>.
269 *
270 * @param v the host name verifier
271 * @throws IllegalArgumentException if the <code>HostnameVerifier</code>
272 * parameter is null.
273 * @see #getHostnameVerifier()
274 * @see #setDefaultHostnameVerifier(HostnameVerifier)
275 */
276 public void setHostnameVerifier(HostnameVerifier v) {
277 if (v == null) {
278 throw new IllegalArgumentException(
279 "no HostnameVerifier specified");
280 }
281
282 hostnameVerifier = v;
283 }
284
285 /**
286 * Gets the <code>HostnameVerifier</code> in place on this instance.
287 *
288 * @return the host name verifier
289 * @see #setHostnameVerifier(HostnameVerifier)
290 * @see #setDefaultHostnameVerifier(HostnameVerifier)
291 */
292 public HostnameVerifier getHostnameVerifier() {
293 return hostnameVerifier;
294 }
295
296 private static SSLSocketFactory defaultSSLSocketFactory = null;
297
298 /**
299 * The <code>SSLSocketFactory</code> inherited when an instance
300 * of this class is created.
301 */
302 private SSLSocketFactory sslSocketFactory = getDefaultSSLSocketFactory();
303
304 /**
305 * Sets the default <code>SSLSocketFactory</code> inherited by new
306 * instances of this class.
307 * <P>
308 * The socket factories are used when creating sockets for secure
309 * https URL connections.
310 *
311 * @param sf the default SSL socket factory
312 * @throws IllegalArgumentException if the SSLSocketFactory
313 * parameter is null.
314 * @throws SecurityException if a security manager exists and its
315 * <code>checkSetFactory</code> method does not allow
316 * a socket factory to be specified.
317 * @see #getDefaultSSLSocketFactory()
318 */
319 public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) {
320 if (sf == null) {
321 throw new IllegalArgumentException(
322 "no default SSLSocketFactory specified");
323 }
324
325 SecurityManager sm = System.getSecurityManager();
326 if (sm != null) {
327 sm.checkSetFactory();
328 }
329 defaultSSLSocketFactory = sf;
330 }
331
332 /**
333 * Gets the default static <code>SSLSocketFactory</code> that is
334 * inherited by new instances of this class.
335 * <P>
336 * The socket factories are used when creating sockets for secure
337 * https URL connections.
338 *
339 * @return the default <code>SSLSocketFactory</code>
340 * @see #setDefaultSSLSocketFactory(SSLSocketFactory)
341 */
342 public static SSLSocketFactory getDefaultSSLSocketFactory() {
343 if (defaultSSLSocketFactory == null) {
344 defaultSSLSocketFactory = (SSLSocketFactory) SSLSocketFactory
345 .getDefault();
346 }
347 return defaultSSLSocketFactory;
348 }
349
350 /**
351 * Sets the <code>SSLSocketFactory</code> to be used when this instance
352 * creates sockets for secure https URL connections.
353 * <P>
354 * New instances of this class inherit the default static
355 * <code>SSLSocketFactory</code> set by
356 * {@link #setDefaultSSLSocketFactory(SSLSocketFactory)
357 * setDefaultSSLSocketFactory}. Calls to this method replace
358 * this object's <code>SSLSocketFactory</code>.
359 *
360 * @param sf the SSL socket factory
361 * @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
362 * parameter is null.
363 * @see #getSSLSocketFactory()
364 */
365 public void setSSLSocketFactory(SSLSocketFactory sf) {
366 if (sf == null) {
367 throw new IllegalArgumentException(
368 "no SSLSocketFactory specified");
369 }
370
371 sslSocketFactory = sf;
372 }
373
374 /**
375 * Gets the SSL socket factory to be used when creating sockets
376 * for secure https URL connections.
377 *
378 * @return the <code>SSLSocketFactory</code>
379 * @see #setSSLSocketFactory(SSLSocketFactory)
380 */
381 public SSLSocketFactory getSSLSocketFactory() {
382 return sslSocketFactory;
383 }
384 }
|