1/* 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/** 27 * 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. 103 */ 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 /** 112 * Sets the default hostname verifier to be used by new instances. 113 * 114 * @param v 115 * the new default hostname verifier 116 * @throws IllegalArgumentException 117 * if the specified verifier is {@code null}. 118 */ 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. 128 * 129 * @return the default hostname verifier. 130 */ 131 public static HostnameVerifier getDefaultHostnameVerifier() { 132 return defaultHostnameVerifier; 133 } 134 135 /** 136 * Sets the default SSL socket factory to be used by new instances. 137 * 138 * @param sf 139 * the new default SSL socket factory. 140 * @throws IllegalArgumentException 141 * if the specified socket factory is {@code null}. 142 */ 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. 152 * 153 * @return the default SSL socket factory for new instances. 154 */ 155 public static SSLSocketFactory getDefaultSSLSocketFactory() { 156 return defaultSSLSocketFactory; 157 } 158 159 /** 160 * 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 /** 273 * Sets the SSL socket factory for this instance. 274 * 275 * @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}. 279 */ 280 public void setSSLSocketFactory(SSLSocketFactory sf) { 281 if (sf == null) { 282 throw new IllegalArgumentException("SSLSocketFactory is null"); 283 } 284 sslSocketFactory = sf; 285 } 286 287 /** 288 * Returns the SSL socket factory used by this instance. 289 * 290 * @return the SSL socket factory used by this instance. 291 */ 292 public SSLSocketFactory getSSLSocketFactory() { 293 return sslSocketFactory; 294 } 295 296} 297