1 /*
2 * Copyright 1999-2008 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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 }