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