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