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