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