1 /* 2 * Copyright (c) 1999, 2021, 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 @SuppressWarnings("removal") 136 SecurityManager sm = System.getSecurityManager(); 137 if (sm != null) { 138 sm.checkPermission(new SSLPermission("setDefaultSSLContext")); 139 } 140 141 defaultContext = context; 142 } 143 144 /** 145 * Returns a {@code SSLContext} object that implements the 146 * specified secure socket protocol. 147 * 148 * <p> This method traverses the list of registered security Providers, 149 * starting with the most preferred Provider. 150 * A new SSLContext object encapsulating the 151 * SSLContextSpi implementation from the first 152 * Provider that supports the specified protocol is returned. 153 * 154 * <p> Note that the list of registered providers may be retrieved via 155 * the {@link Security#getProviders() Security.getProviders()} method. 156 * 157 * @implNote 158 * The JDK Reference Implementation additionally uses the 159 * {@code jdk.security.provider.preferred} 160 * {@link Security#getProperty(String) Security} property to determine 161 * the preferred provider order for the specified algorithm. This 162 * may be different than the order of providers returned by 163 * {@link Security#getProviders() Security.getProviders()}. 164 * 165 * @param protocol the standard name of the requested protocol. 166 * See the SSLContext section in the <a href= 167 * "{@docRoot}/../specs/security/standard-names.html#sslcontext-algorithms"> 168 * Java Security Standard Algorithm Names Specification</a> 169 * for information about standard protocol names. 170 * 171 * @return the new {@code SSLContext} object 172 * 173 * @throws NoSuchAlgorithmException if no {@code Provider} supports a 174 * {@code SSLContextSpi} implementation for the 175 * specified protocol 176 * 177 * @throws NullPointerException if {@code protocol} is {@code null} 178 * 179 * @see java.security.Provider 180 */ getInstance(String protocol)181 public static SSLContext getInstance(String protocol) 182 throws NoSuchAlgorithmException { 183 Objects.requireNonNull(protocol, "null protocol name"); 184 GetInstance.Instance instance = GetInstance.getInstance 185 ("SSLContext", SSLContextSpi.class, protocol); 186 return new SSLContext((SSLContextSpi)instance.impl, instance.provider, 187 protocol); 188 } 189 190 /** 191 * Returns a {@code SSLContext} object that implements the 192 * specified secure socket protocol. 193 * 194 * <p> A new SSLContext object encapsulating the 195 * SSLContextSpi implementation from the specified provider 196 * is returned. The specified provider must be registered 197 * in the security provider list. 198 * 199 * <p> Note that the list of registered providers may be retrieved via 200 * the {@link Security#getProviders() Security.getProviders()} method. 201 * 202 * @param protocol the standard name of the requested protocol. 203 * See the SSLContext section in the <a href= 204 * "{@docRoot}/../specs/security/standard-names.html#sslcontext-algorithms"> 205 * Java Security Standard Algorithm Names Specification</a> 206 * for information about standard protocol names. 207 * 208 * @param provider the name of the provider. 209 * 210 * @return the new {@code SSLContext} object 211 * 212 * @throws IllegalArgumentException if the provider name is 213 * {@code null} or empty 214 * 215 * @throws NoSuchAlgorithmException if a {@code SSLContextSpi} 216 * implementation for the specified protocol is not 217 * available from the specified provider 218 * 219 * @throws NoSuchProviderException if the specified provider is not 220 * registered in the security provider list 221 * 222 * @throws NullPointerException if {@code protocol} is {@code null} 223 * 224 * @see java.security.Provider 225 */ getInstance(String protocol, String provider)226 public static SSLContext getInstance(String protocol, String provider) 227 throws NoSuchAlgorithmException, NoSuchProviderException { 228 Objects.requireNonNull(protocol, "null protocol name"); 229 GetInstance.Instance instance = GetInstance.getInstance 230 ("SSLContext", SSLContextSpi.class, protocol, provider); 231 return new SSLContext((SSLContextSpi)instance.impl, instance.provider, 232 protocol); 233 } 234 235 /** 236 * Returns a {@code SSLContext} object that implements the 237 * specified secure socket protocol. 238 * 239 * <p> A new SSLContext object encapsulating the 240 * SSLContextSpi implementation from the specified Provider 241 * object is returned. Note that the specified Provider object 242 * does not have to be registered in the provider list. 243 * 244 * @param protocol the standard name of the requested protocol. 245 * See the SSLContext section in the <a href= 246 * "{@docRoot}/../specs/security/standard-names.html#sslcontext-algorithms"> 247 * Java Security Standard Algorithm Names Specification</a> 248 * for information about standard protocol names. 249 * 250 * @param provider an instance of the provider. 251 * 252 * @return the new {@code SSLContext} object 253 * 254 * @throws IllegalArgumentException if the provider is {@code null} 255 * 256 * @throws NoSuchAlgorithmException if a {@code SSLContextSpi} 257 * implementation for the specified protocol is not available 258 * from the specified {@code Provider} object 259 * 260 * @throws NullPointerException if {@code protocol} is {@code null} 261 * 262 * @see java.security.Provider 263 */ getInstance(String protocol, Provider provider)264 public static SSLContext getInstance(String protocol, Provider provider) 265 throws NoSuchAlgorithmException { 266 Objects.requireNonNull(protocol, "null protocol name"); 267 GetInstance.Instance instance = GetInstance.getInstance 268 ("SSLContext", SSLContextSpi.class, protocol, provider); 269 return new SSLContext((SSLContextSpi)instance.impl, instance.provider, 270 protocol); 271 } 272 273 /** 274 * Returns the protocol name of this {@code SSLContext} object. 275 * 276 * <p>This is the same name that was specified in one of the 277 * {@code getInstance} calls that created this 278 * {@code SSLContext} object. 279 * 280 * @return the protocol name of this {@code SSLContext} object. 281 */ getProtocol()282 public final String getProtocol() { 283 return this.protocol; 284 } 285 286 /** 287 * Returns the provider of this {@code SSLContext} object. 288 * 289 * @return the provider of this {@code SSLContext} object 290 */ getProvider()291 public final Provider getProvider() { 292 return this.provider; 293 } 294 295 /** 296 * Initializes this context. Either of the first two parameters 297 * may be null in which case the installed security providers will 298 * be searched for the highest priority implementation of the 299 * appropriate factory. Likewise, the secure random parameter may 300 * be null in which case the default implementation will be used. 301 * <P> 302 * Only the first instance of a particular key and/or trust manager 303 * implementation type in the array is used. (For example, only 304 * the first javax.net.ssl.X509KeyManager in the array will be used.) 305 * 306 * @param km the sources of authentication keys or null 307 * @param tm the sources of peer authentication trust decisions or null 308 * @param random the source of randomness for this generator or null 309 * @throws KeyManagementException if this operation fails 310 */ init(KeyManager[] km, TrustManager[] tm, SecureRandom random)311 public final void init(KeyManager[] km, TrustManager[] tm, 312 SecureRandom random) 313 throws KeyManagementException { 314 contextSpi.engineInit(km, tm, random); 315 } 316 317 /** 318 * Returns a {@code SocketFactory} object for this 319 * context. 320 * 321 * @return the {@code SocketFactory} object 322 * @throws UnsupportedOperationException if the underlying provider 323 * does not implement the operation. 324 * @throws IllegalStateException if the SSLContextImpl requires 325 * initialization and the {@code init()} has not been called 326 */ getSocketFactory()327 public final SSLSocketFactory getSocketFactory() { 328 return contextSpi.engineGetSocketFactory(); 329 } 330 331 /** 332 * Returns a {@code ServerSocketFactory} object for 333 * this context. 334 * 335 * @return the {@code ServerSocketFactory} object 336 * @throws UnsupportedOperationException if the underlying provider 337 * does not implement the operation. 338 * @throws IllegalStateException if the SSLContextImpl requires 339 * initialization and the {@code init()} has not been called 340 */ getServerSocketFactory()341 public final SSLServerSocketFactory getServerSocketFactory() { 342 return contextSpi.engineGetServerSocketFactory(); 343 } 344 345 /** 346 * Creates a new {@code SSLEngine} using this context. 347 * <P> 348 * Applications using this factory method are providing no hints 349 * for an internal session reuse strategy. If hints are desired, 350 * {@link #createSSLEngine(String, int)} should be used 351 * instead. 352 * <P> 353 * Some cipher suites (such as Kerberos) require remote hostname 354 * information, in which case this factory method should not be used. 355 * 356 * @implNote 357 * It is provider-specific if the returned SSLEngine uses client or 358 * server mode by default for the (D)TLS connection. The JDK SunJSSE 359 * provider implementation uses server mode by default. However, it 360 * is recommended to always set the desired mode explicitly by calling 361 * {@link SSLEngine#setUseClientMode(boolean) SSLEngine.setUseClientMode()} 362 * before invoking other methods of the SSLEngine. 363 * 364 * @return the {@code SSLEngine} 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()} 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} 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 * @implNote 395 * It is provider-specific if the returned SSLEngine uses client or 396 * server mode by default for the (D)TLS connection. The JDK SunJSSE 397 * provider implementation uses server mode by default. However, it 398 * is recommended to always set the desired mode explicitly by calling 399 * {@link SSLEngine#setUseClientMode(boolean) SSLEngine.setUseClientMode()} 400 * before invoking other methods of the SSLEngine. 401 * 402 * @param peerHost the non-authoritative name of the host 403 * @param peerPort the non-authoritative port 404 * @return the new {@code SSLEngine} object 405 * @throws UnsupportedOperationException if the underlying provider 406 * does not implement the operation. 407 * @throws IllegalStateException if the SSLContextImpl requires 408 * initialization and the {@code init()} has not been called 409 * @since 1.5 410 */ createSSLEngine(String peerHost, int peerPort)411 public final SSLEngine createSSLEngine(String peerHost, int peerPort) { 412 try { 413 return contextSpi.engineCreateSSLEngine(peerHost, peerPort); 414 } catch (AbstractMethodError e) { 415 UnsupportedOperationException unsup = 416 new UnsupportedOperationException( 417 "Provider: " + getProvider() + 418 " does not support this operation"); 419 unsup.initCause(e); 420 throw unsup; 421 } 422 } 423 424 /** 425 * Returns the server session context, which represents the set of 426 * SSL sessions available for use during the handshake phase of 427 * server-side SSL sockets. 428 * <P> 429 * This context may be unavailable in some environments, in which 430 * case this method returns null. For example, when the underlying 431 * SSL provider does not provide an implementation of SSLSessionContext 432 * interface, this method returns null. A non-null session context 433 * is returned otherwise. 434 * 435 * @return server session context bound to this SSL context 436 */ getServerSessionContext()437 public final SSLSessionContext getServerSessionContext() { 438 return contextSpi.engineGetServerSessionContext(); 439 } 440 441 /** 442 * Returns the client session context, which represents the set of 443 * SSL sessions available for use during the handshake phase of 444 * client-side SSL sockets. 445 * <P> 446 * This context may be unavailable in some environments, in which 447 * case this method returns null. For example, when the underlying 448 * SSL provider does not provide an implementation of SSLSessionContext 449 * interface, this method returns null. A non-null session context 450 * is returned otherwise. 451 * 452 * @return client session context bound to this SSL context 453 */ getClientSessionContext()454 public final SSLSessionContext getClientSessionContext() { 455 return contextSpi.engineGetClientSessionContext(); 456 } 457 458 /** 459 * Returns a copy of the SSLParameters indicating the default 460 * settings for this SSL context. 461 * 462 * <p>The parameters will always have the ciphersuites and protocols 463 * arrays set to non-null values. 464 * 465 * @return a copy of the SSLParameters object with the default settings 466 * @throws UnsupportedOperationException if the default SSL parameters 467 * could not be obtained. 468 * @since 1.6 469 */ getDefaultSSLParameters()470 public final SSLParameters getDefaultSSLParameters() { 471 return contextSpi.engineGetDefaultSSLParameters(); 472 } 473 474 /** 475 * Returns a copy of the SSLParameters indicating the supported 476 * settings for this SSL context. 477 * 478 * <p>The parameters will always have the ciphersuites and protocols 479 * arrays set to non-null values. 480 * 481 * @return a copy of the SSLParameters object with the supported 482 * settings 483 * @throws UnsupportedOperationException if the supported SSL parameters 484 * could not be obtained. 485 * @since 1.6 486 */ getSupportedSSLParameters()487 public final SSLParameters getSupportedSSLParameters() { 488 return contextSpi.engineGetSupportedSSLParameters(); 489 } 490 491 } 492