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