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 26 package javax.net.ssl; 27 28 import java.security.*; 29 import java.util.*; 30 31 import sun.security.jca.GetInstance; 32 33 /** 34 * Instances of this class represent a secure socket protocol 35 * implementation which acts as a factory for secure socket 36 * factories or <code>SSLEngine</code>s. This class is initialized 37 * with an optional set of key and trust managers and source of 38 * secure random bytes. 39 * 40 * <p> Android provides the following <code>SSLContext</code> protocols: 41 * <table> 42 * <thead> 43 * <tr> 44 * <th>Algorithm</th> 45 * <th>Supported API Levels</th> 46 * </tr> 47 * </thead> 48 * <tbody> 49 * <tr> 50 * <td>Default</td> 51 * <td>10+</td> 52 * </tr> 53 * <tr> 54 * <td>SSL</td> 55 * <td>10+</td> 56 * </tr> 57 * <tr class="deprecated"> 58 * <td>SSLv3</td> 59 * <td>10-25</td> 60 * </tr> 61 * <tr> 62 * <td>TLS</td> 63 * <td>1+</td> 64 * </tr> 65 * <tr> 66 * <td>TLSv1</td> 67 * <td>10+</td> 68 * </tr> 69 * <tr> 70 * <td>TLSv1.1</td> 71 * <td>16+</td> 72 * </tr> 73 * <tr> 74 * <td>TLSv1.2</td> 75 * <td>16+</td> 76 * </tr> 77 * <tr> 78 * <td>TLSv1.3</td> 79 * <td>29+</td> 80 * </tr> 81 * </tbody> 82 * </table> 83 * 84 * This protocol is described in the <a href= 85 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext"> 86 * SSLContext section</a> of the 87 * Java Cryptography Architecture Standard Algorithm Name Documentation. 88 * 89 * @since 1.4 90 */ 91 public class SSLContext { 92 private final Provider provider; 93 94 private final SSLContextSpi contextSpi; 95 96 private final String protocol; 97 98 /** 99 * Creates an SSLContext object. 100 * 101 * @param contextSpi the delegate 102 * @param provider the provider 103 * @param protocol the protocol 104 */ SSLContext(SSLContextSpi contextSpi, Provider provider, String protocol)105 protected SSLContext(SSLContextSpi contextSpi, Provider provider, 106 String protocol) { 107 this.contextSpi = contextSpi; 108 this.provider = provider; 109 this.protocol = protocol; 110 } 111 112 private static SSLContext defaultContext; 113 114 /** 115 * Returns the default SSL context. 116 * 117 * <p>If a default context was set using the {@link #setDefault 118 * SSLContext.setDefault()} method, it is returned. Otherwise, the first 119 * call of this method triggers the call 120 * <code>SSLContext.getInstance("Default")</code>. 121 * If successful, that object is made the default SSL context and returned. 122 * 123 * <p>The default context is immediately 124 * usable and does not require {@linkplain #init initialization}. 125 * 126 * @return the default SSL context 127 * @throws NoSuchAlgorithmException if the 128 * {@link SSLContext#getInstance SSLContext.getInstance()} call fails 129 * @since 1.6 130 */ getDefault()131 public static synchronized SSLContext getDefault() 132 throws NoSuchAlgorithmException { 133 if (defaultContext == null) { 134 defaultContext = SSLContext.getInstance("Default"); 135 } 136 return defaultContext; 137 } 138 139 // Android-changed: Additional text to strongly discouraged changing the default. 140 /** 141 * Sets the default SSL context. It will be returned by subsequent calls 142 * to {@link #getDefault}. The default context must be immediately usable 143 * and not require {@linkplain #init initialization}. 144 * <p> 145 * Developers are <em>strongly</em> discouraged from changing the default {@code SSLContext} as 146 * it is used as the Android default for secure communication by APIs like 147 * {@link SSLSocketFactory#getDefault()}, {@link SSLServerSocketFactory#getDefault()} and 148 * {@link HttpsURLConnection}. 149 * 150 * @param context the SSLContext 151 * @throws NullPointerException if context is null 152 * @throws SecurityException if a security manager exists and its 153 * <code>checkPermission</code> method does not allow 154 * <code>SSLPermission("setDefaultSSLContext")</code> 155 * @since 1.6 156 */ setDefault(SSLContext context)157 public static synchronized void setDefault(SSLContext context) { 158 if (context == null) { 159 throw new NullPointerException(); 160 } 161 SecurityManager sm = System.getSecurityManager(); 162 if (sm != null) { 163 sm.checkPermission(new SSLPermission("setDefaultSSLContext")); 164 } 165 defaultContext = context; 166 } 167 168 /** 169 * Returns a <code>SSLContext</code> object that implements the 170 * specified secure socket protocol. 171 * 172 * <p> This method traverses the list of registered security Providers, 173 * starting with the most preferred Provider. 174 * A new SSLContext object encapsulating the 175 * SSLContextSpi implementation from the first 176 * Provider that supports the specified protocol is returned. 177 * 178 * <p> Note that the list of registered providers may be retrieved via 179 * the {@link Security#getProviders() Security.getProviders()} method. 180 * 181 * @param protocol the standard name of the requested protocol. 182 * See the SSLContext section in the <a href= 183 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext"> 184 * Java Cryptography Architecture Standard Algorithm Name 185 * Documentation</a> 186 * for information about standard protocol names. 187 * 188 * @return the new <code>SSLContext</code> object. 189 * 190 * @exception NoSuchAlgorithmException if no Provider supports a 191 * SSLContextSpi implementation for the 192 * specified protocol. 193 * @exception NullPointerException if protocol is null. 194 * 195 * @see java.security.Provider 196 */ getInstance(String protocol)197 public static SSLContext getInstance(String protocol) 198 throws NoSuchAlgorithmException { 199 GetInstance.Instance instance = GetInstance.getInstance 200 ("SSLContext", SSLContextSpi.class, protocol); 201 return new SSLContext((SSLContextSpi)instance.impl, instance.provider, 202 protocol); 203 } 204 205 /** 206 * Returns a <code>SSLContext</code> object that implements the 207 * specified secure socket protocol. 208 * 209 * <p> A new SSLContext object encapsulating the 210 * SSLContextSpi implementation from the specified provider 211 * is returned. The specified provider must be registered 212 * in the security provider list. 213 * 214 * <p> Note that the list of registered providers may be retrieved via 215 * the {@link Security#getProviders() Security.getProviders()} method. 216 * 217 * @param protocol the standard name of the requested protocol. 218 * See the SSLContext section in the <a href= 219 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext"> 220 * Java Cryptography Architecture Standard Algorithm Name 221 * Documentation</a> 222 * for information about standard protocol names. 223 * 224 * @param provider the name of the provider. 225 * 226 * @return the new <code>SSLContext</code> object. 227 * 228 * @throws NoSuchAlgorithmException if a SSLContextSpi 229 * implementation for the specified protocol is not 230 * available from the specified provider. 231 * 232 * @throws NoSuchProviderException if the specified provider is not 233 * registered in the security provider list. 234 * 235 * @throws IllegalArgumentException if the provider name is null or empty. 236 * @throws NullPointerException if protocol is null. 237 * 238 * @see java.security.Provider 239 */ getInstance(String protocol, String provider)240 public static SSLContext getInstance(String protocol, String provider) 241 throws NoSuchAlgorithmException, NoSuchProviderException { 242 GetInstance.Instance instance = GetInstance.getInstance 243 ("SSLContext", SSLContextSpi.class, protocol, provider); 244 return new SSLContext((SSLContextSpi)instance.impl, instance.provider, 245 protocol); 246 } 247 248 /** 249 * Returns a <code>SSLContext</code> object that implements the 250 * specified secure socket protocol. 251 * 252 * <p> A new SSLContext object encapsulating the 253 * SSLContextSpi implementation from the specified Provider 254 * object is returned. Note that the specified Provider object 255 * does not have to be registered in the provider list. 256 * 257 * @param protocol the standard name of the requested protocol. 258 * See the SSLContext section in the <a href= 259 * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext"> 260 * Java Cryptography Architecture Standard Algorithm Name 261 * Documentation</a> 262 * for information about standard protocol names. 263 * 264 * @param provider an instance of the provider. 265 * 266 * @return the new <code>SSLContext</code> object. 267 * 268 * @throws NoSuchAlgorithmException if a SSLContextSpi 269 * implementation for the specified protocol is not available 270 * from the specified Provider object. 271 * 272 * @throws IllegalArgumentException if the provider is null. 273 * @throws NullPointerException if protocol is null. 274 * 275 * @see java.security.Provider 276 */ getInstance(String protocol, Provider provider)277 public static SSLContext getInstance(String protocol, Provider provider) 278 throws NoSuchAlgorithmException { 279 GetInstance.Instance instance = GetInstance.getInstance 280 ("SSLContext", SSLContextSpi.class, protocol, provider); 281 return new SSLContext((SSLContextSpi)instance.impl, instance.provider, 282 protocol); 283 } 284 285 /** 286 * Returns the protocol name of this <code>SSLContext</code> object. 287 * 288 * <p>This is the same name that was specified in one of the 289 * <code>getInstance</code> calls that created this 290 * <code>SSLContext</code> object. 291 * 292 * @return the protocol name of this <code>SSLContext</code> object. 293 */ getProtocol()294 public final String getProtocol() { 295 return this.protocol; 296 } 297 298 /** 299 * Returns the provider of this <code>SSLContext</code> object. 300 * 301 * @return the provider of this <code>SSLContext</code> object 302 */ getProvider()303 public final Provider getProvider() { 304 return this.provider; 305 } 306 307 /** 308 * Initializes this context. Either of the first two parameters 309 * may be null in which case the installed security providers will 310 * be searched for the highest priority implementation of the 311 * appropriate factory. Likewise, the secure random parameter may 312 * be null in which case the default implementation will be used. 313 * <P> 314 * Only the first instance of a particular key and/or trust manager 315 * implementation type in the array is used. (For example, only 316 * the first javax.net.ssl.X509KeyManager in the array will be used.) 317 * 318 * @param km the sources of authentication keys or null 319 * @param tm the sources of peer authentication trust decisions or null 320 * @param random the source of randomness for this generator or null 321 * @throws KeyManagementException if this operation fails 322 */ init(KeyManager[] km, TrustManager[] tm, SecureRandom random)323 public final void init(KeyManager[] km, TrustManager[] tm, 324 SecureRandom random) 325 throws KeyManagementException { 326 contextSpi.engineInit(km, tm, random); 327 } 328 329 /** 330 * Returns a <code>SocketFactory</code> object for this 331 * context. 332 * 333 * @return the <code>SocketFactory</code> object 334 * @throws IllegalStateException if the SSLContextImpl requires 335 * initialization and the <code>init()</code> has not been called 336 */ getSocketFactory()337 public final SSLSocketFactory getSocketFactory() { 338 return contextSpi.engineGetSocketFactory(); 339 } 340 341 /** 342 * Returns a <code>ServerSocketFactory</code> object for 343 * this context. 344 * 345 * @return the <code>ServerSocketFactory</code> object 346 * @throws IllegalStateException if the SSLContextImpl requires 347 * initialization and the <code>init()</code> has not been called 348 */ getServerSocketFactory()349 public final SSLServerSocketFactory getServerSocketFactory() { 350 return contextSpi.engineGetServerSocketFactory(); 351 } 352 353 /** 354 * Creates a new <code>SSLEngine</code> using this context. 355 * <P> 356 * Applications using this factory method are providing no hints 357 * for an internal session reuse strategy. If hints are desired, 358 * {@link #createSSLEngine(String, int)} should be used 359 * instead. 360 * <P> 361 * Some cipher suites (such as Kerberos) require remote hostname 362 * information, in which case this factory method should not be used. 363 * 364 * @return the <code>SSLEngine</code> object 365 * @throws UnsupportedOperationException if the underlying provider 366 * does not implement the operation. 367 * @throws IllegalStateException if the SSLContextImpl requires 368 * initialization and the <code>init()</code> has not been called 369 * @since 1.5 370 */ createSSLEngine()371 public final SSLEngine createSSLEngine() { 372 try { 373 return contextSpi.engineCreateSSLEngine(); 374 } catch (AbstractMethodError e) { 375 UnsupportedOperationException unsup = 376 new UnsupportedOperationException( 377 "Provider: " + getProvider() + 378 " doesn't support this operation"); 379 unsup.initCause(e); 380 throw unsup; 381 } 382 } 383 384 /** 385 * Creates a new <code>SSLEngine</code> using this context using 386 * advisory peer information. 387 * <P> 388 * Applications using this factory method are providing hints 389 * for an internal session reuse strategy. 390 * <P> 391 * Some cipher suites (such as Kerberos) require remote hostname 392 * information, in which case peerHost needs to be specified. 393 * 394 * @param peerHost the non-authoritative name of the host 395 * @param peerPort the non-authoritative port 396 * @return the new <code>SSLEngine</code> object 397 * @throws UnsupportedOperationException if the underlying provider 398 * does not implement the operation. 399 * @throws IllegalStateException if the SSLContextImpl requires 400 * initialization and the <code>init()</code> has not been called 401 * @since 1.5 402 */ createSSLEngine(String peerHost, int peerPort)403 public final SSLEngine createSSLEngine(String peerHost, int peerPort) { 404 try { 405 return contextSpi.engineCreateSSLEngine(peerHost, peerPort); 406 } catch (AbstractMethodError e) { 407 UnsupportedOperationException unsup = 408 new UnsupportedOperationException( 409 "Provider: " + getProvider() + 410 " does not support this operation"); 411 unsup.initCause(e); 412 throw unsup; 413 } 414 } 415 416 /** 417 * Returns the server session context, which represents the set of 418 * SSL sessions available for use during the handshake phase of 419 * server-side SSL sockets. 420 * <P> 421 * This context may be unavailable in some environments, in which 422 * case this method returns null. For example, when the underlying 423 * SSL provider does not provide an implementation of SSLSessionContext 424 * interface, this method returns null. A non-null session context 425 * is returned otherwise. 426 * 427 * @return server session context bound to this SSL context 428 */ getServerSessionContext()429 public final SSLSessionContext getServerSessionContext() { 430 return contextSpi.engineGetServerSessionContext(); 431 } 432 433 /** 434 * Returns the client session context, which represents the set of 435 * SSL sessions available for use during the handshake phase of 436 * client-side SSL sockets. 437 * <P> 438 * This context may be unavailable in some environments, in which 439 * case this method returns null. For example, when the underlying 440 * SSL provider does not provide an implementation of SSLSessionContext 441 * interface, this method returns null. A non-null session context 442 * is returned otherwise. 443 * 444 * @return client session context bound to this SSL context 445 */ getClientSessionContext()446 public final SSLSessionContext getClientSessionContext() { 447 return contextSpi.engineGetClientSessionContext(); 448 } 449 450 /** 451 * Returns a copy of the SSLParameters indicating the default 452 * settings for this SSL context. 453 * 454 * <p>The parameters will always have the ciphersuites and protocols 455 * arrays set to non-null values. 456 * 457 * @return a copy of the SSLParameters object with the default settings 458 * @throws UnsupportedOperationException if the default SSL parameters 459 * could not be obtained. 460 * @since 1.6 461 */ getDefaultSSLParameters()462 public final SSLParameters getDefaultSSLParameters() { 463 return contextSpi.engineGetDefaultSSLParameters(); 464 } 465 466 /** 467 * Returns a copy of the SSLParameters indicating the supported 468 * settings for this SSL context. 469 * 470 * <p>The parameters will always have the ciphersuites and protocols 471 * arrays set to non-null values. 472 * 473 * @return a copy of the SSLParameters object with the supported 474 * settings 475 * @throws UnsupportedOperationException if the supported SSL parameters 476 * could not be obtained. 477 * @since 1.6 478 */ getSupportedSSLParameters()479 public final SSLParameters getSupportedSSLParameters() { 480 return contextSpi.engineGetSupportedSSLParameters(); 481 } 482 483 } 484