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