1 /*
   2  * Copyright (c) 1999, 2016, 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}
 142      * {@link Security#getProperty(String) Security} property to determine
 143      * the preferred provider order for the specified algorithm. This
 144      * may be different than the order of providers returned by
 145      * {@link Security#getProviders() Security.getProviders()}.
 146      *
 147      * @param protocol the standard name of the requested protocol.
 148      *          See the SSLContext section in the <a href=
 149      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
 150      *          Java Cryptography Architecture Standard Algorithm Name
 151      *          Documentation</a>
 152      *          for information about standard protocol names.
 153      *
 154      * @return the new {@code SSLContext} object.
 155      *
 156      * @exception NoSuchAlgorithmException if no Provider supports a
 157      *          SSLContextSpi implementation for the
 158      *          specified protocol.
 159      * @exception NullPointerException if protocol is null.
 160      *
 161      * @see java.security.Provider
 162      */
 163     public static SSLContext getInstance(String protocol)
 164             throws NoSuchAlgorithmException {
 165         GetInstance.Instance instance = GetInstance.getInstance
 166                 ("SSLContext", SSLContextSpi.class, protocol);
 167         return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
 168                 protocol);
 169     }
 170 
 171     /**
 172      * Returns a {@code SSLContext} object that implements the
 173      * specified secure socket protocol.
 174      *
 175      * <p> A new SSLContext object encapsulating the
 176      * SSLContextSpi implementation from the specified provider
 177      * is returned.  The specified provider must be registered
 178      * in the security provider list.
 179      *
 180      * <p> Note that the list of registered providers may be retrieved via
 181      * the {@link Security#getProviders() Security.getProviders()} method.
 182      *
 183      * @param protocol the standard name of the requested protocol.
 184      *          See the SSLContext section in the <a href=
 185      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
 186      *          Java Cryptography Architecture Standard Algorithm Name
 187      *          Documentation</a>
 188      *          for information about standard protocol names.
 189      *
 190      * @param provider the name of the provider.
 191      *
 192      * @return the new {@code SSLContext} object.
 193      *
 194      * @throws NoSuchAlgorithmException if a SSLContextSpi
 195      *          implementation for the specified protocol is not
 196      *          available from the specified provider.
 197      *
 198      * @throws NoSuchProviderException if the specified provider is not
 199      *          registered in the security provider list.
 200      *
 201      * @throws IllegalArgumentException if the provider name is null or empty.
 202      * @throws NullPointerException if protocol is null.
 203      *
 204      * @see java.security.Provider
 205      */
 206     public static SSLContext getInstance(String protocol, String provider)
 207             throws NoSuchAlgorithmException, NoSuchProviderException {
 208         GetInstance.Instance instance = GetInstance.getInstance
 209                 ("SSLContext", SSLContextSpi.class, protocol, provider);
 210         return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
 211                 protocol);
 212     }
 213 
 214     /**
 215      * Returns a {@code SSLContext} object that implements the
 216      * specified secure socket protocol.
 217      *
 218      * <p> A new SSLContext object encapsulating the
 219      * SSLContextSpi implementation from the specified Provider
 220      * object is returned.  Note that the specified Provider object
 221      * does not have to be registered in the provider list.
 222      *
 223      * @param protocol the standard name of the requested protocol.
 224      *          See the SSLContext section in the <a href=
 225      * "{@docRoot}/../technotes/guides/security/StandardNames.html#SSLContext">
 226      *          Java Cryptography Architecture Standard Algorithm Name
 227      *          Documentation</a>
 228      *          for information about standard protocol names.
 229      *
 230      * @param provider an instance of the provider.
 231      *
 232      * @return the new {@code SSLContext} object.
 233      *
 234      * @throws NoSuchAlgorithmException if a SSLContextSpi
 235      *          implementation for the specified protocol is not available
 236      *          from the specified Provider object.
 237      *
 238      * @throws IllegalArgumentException if the provider is null.
 239      * @throws NullPointerException if protocol is null.
 240      *
 241      * @see java.security.Provider
 242      */
 243     public static SSLContext getInstance(String protocol, Provider provider)
 244             throws NoSuchAlgorithmException {
 245         GetInstance.Instance instance = GetInstance.getInstance
 246                 ("SSLContext", SSLContextSpi.class, protocol, provider);
 247         return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
 248                 protocol);
 249     }
 250 
 251     /**
 252      * Returns the protocol name of this {@code SSLContext} object.
 253      *
 254      * <p>This is the same name that was specified in one of the
 255      * {@code getInstance} calls that created this
 256      * {@code SSLContext} object.
 257      *
 258      * @return the protocol name of this {@code SSLContext} object.
 259      */
 260     public final String getProtocol() {
 261         return this.protocol;
 262     }
 263 
 264     /**
 265      * Returns the provider of this {@code SSLContext} object.
 266      *
 267      * @return the provider of this {@code SSLContext} object
 268      */
 269     public final Provider getProvider() {
 270         return this.provider;
 271     }
 272 
 273     /**
 274      * Initializes this context. Either of the first two parameters
 275      * may be null in which case the installed security providers will
 276      * be searched for the highest priority implementation of the
 277      * appropriate factory. Likewise, the secure random parameter may
 278      * be null in which case the default implementation will be used.
 279      * <P>
 280      * Only the first instance of a particular key and/or trust manager
 281      * implementation type in the array is used.  (For example, only
 282      * the first javax.net.ssl.X509KeyManager in the array will be used.)
 283      *
 284      * @param km the sources of authentication keys or null
 285      * @param tm the sources of peer authentication trust decisions or null
 286      * @param random the source of randomness for this generator or null
 287      * @throws KeyManagementException if this operation fails
 288      */
 289     public final void init(KeyManager[] km, TrustManager[] tm,
 290                                 SecureRandom random)
 291         throws KeyManagementException {
 292         contextSpi.engineInit(km, tm, random);
 293     }
 294 
 295     /**
 296      * Returns a {@code SocketFactory} object for this
 297      * context.
 298      *
 299      * @return the {@code SocketFactory} object
 300      * @throws UnsupportedOperationException if the underlying provider
 301      *         does not implement the operation.
 302      * @throws IllegalStateException if the SSLContextImpl requires
 303      *         initialization and the {@code init()} has not been called
 304      */
 305     public final SSLSocketFactory getSocketFactory() {
 306         return contextSpi.engineGetSocketFactory();
 307     }
 308 
 309     /**
 310      * Returns a {@code ServerSocketFactory} object for
 311      * this context.
 312      *
 313      * @return the {@code ServerSocketFactory} object
 314      * @throws UnsupportedOperationException if the underlying provider
 315      *         does not implement the operation.
 316      * @throws IllegalStateException if the SSLContextImpl requires
 317      *         initialization and the {@code init()} has not been called
 318      */
 319     public final SSLServerSocketFactory getServerSocketFactory() {
 320         return contextSpi.engineGetServerSocketFactory();
 321     }
 322 
 323     /**
 324      * Creates a new {@code SSLEngine} using this context.
 325      * <P>
 326      * Applications using this factory method are providing no hints
 327      * for an internal session reuse strategy. If hints are desired,
 328      * {@link #createSSLEngine(String, int)} should be used
 329      * instead.
 330      * <P>
 331      * Some cipher suites (such as Kerberos) require remote hostname
 332      * information, in which case this factory method should not be used.
 333      *
 334      * @return  the {@code SSLEngine} object
 335      * @throws  UnsupportedOperationException if the underlying provider
 336      *          does not implement the operation.
 337      * @throws  IllegalStateException if the SSLContextImpl requires
 338      *          initialization and the {@code init()} has not been called
 339      * @since   1.5
 340      */
 341     public final SSLEngine createSSLEngine() {
 342         try {
 343             return contextSpi.engineCreateSSLEngine();
 344         } catch (AbstractMethodError e) {
 345             UnsupportedOperationException unsup =
 346                 new UnsupportedOperationException(
 347                     "Provider: " + getProvider() +
 348                     " doesn't support this operation");
 349             unsup.initCause(e);
 350             throw unsup;
 351         }
 352     }
 353 
 354     /**
 355      * Creates a new {@code SSLEngine} using this context using
 356      * advisory peer information.
 357      * <P>
 358      * Applications using this factory method are providing hints
 359      * for an internal session reuse strategy.
 360      * <P>
 361      * Some cipher suites (such as Kerberos) require remote hostname
 362      * information, in which case peerHost needs to be specified.
 363      *
 364      * @param   peerHost the non-authoritative name of the host
 365      * @param   peerPort the non-authoritative port
 366      * @return  the new {@code SSLEngine} object
 367      * @throws  UnsupportedOperationException if the underlying provider
 368      *          does not implement the operation.
 369      * @throws  IllegalStateException if the SSLContextImpl requires
 370      *          initialization and the {@code init()} has not been called
 371      * @since   1.5
 372      */
 373     public final SSLEngine createSSLEngine(String peerHost, int peerPort) {
 374         try {
 375             return contextSpi.engineCreateSSLEngine(peerHost, peerPort);
 376         } catch (AbstractMethodError e) {
 377             UnsupportedOperationException unsup =
 378                 new UnsupportedOperationException(
 379                     "Provider: " + getProvider() +
 380                     " does not support this operation");
 381             unsup.initCause(e);
 382             throw unsup;
 383         }
 384     }
 385 
 386     /**
 387      * Returns the server session context, which represents the set of
 388      * SSL sessions available for use during the handshake phase of
 389      * server-side SSL sockets.
 390      * <P>
 391      * This context may be unavailable in some environments, in which
 392      * case this method returns null. For example, when the underlying
 393      * SSL provider does not provide an implementation of SSLSessionContext
 394      * interface, this method returns null. A non-null session context
 395      * is returned otherwise.
 396      *
 397      * @return server session context bound to this SSL context
 398      */
 399     public final SSLSessionContext getServerSessionContext() {
 400         return contextSpi.engineGetServerSessionContext();
 401     }
 402 
 403     /**
 404      * Returns the client session context, which represents the set of
 405      * SSL sessions available for use during the handshake phase of
 406      * client-side SSL sockets.
 407      * <P>
 408      * This context may be unavailable in some environments, in which
 409      * case this method returns null. For example, when the underlying
 410      * SSL provider does not provide an implementation of SSLSessionContext
 411      * interface, this method returns null. A non-null session context
 412      * is returned otherwise.
 413      *
 414      * @return client session context bound to this SSL context
 415      */
 416     public final SSLSessionContext getClientSessionContext() {
 417         return contextSpi.engineGetClientSessionContext();
 418     }
 419 
 420     /**
 421      * Returns a copy of the SSLParameters indicating the default
 422      * settings for this SSL context.
 423      *
 424      * <p>The parameters will always have the ciphersuites and protocols
 425      * arrays set to non-null values.
 426      *
 427      * @return a copy of the SSLParameters object with the default settings
 428      * @throws UnsupportedOperationException if the default SSL parameters
 429      *   could not be obtained.
 430      * @since 1.6
 431      */
 432     public final SSLParameters getDefaultSSLParameters() {
 433         return contextSpi.engineGetDefaultSSLParameters();
 434     }
 435 
 436     /**
 437      * Returns a copy of the SSLParameters indicating the supported
 438      * settings for this SSL context.
 439      *
 440      * <p>The parameters will always have the ciphersuites and protocols
 441      * arrays set to non-null values.
 442      *
 443      * @return a copy of the SSLParameters object with the supported
 444      *   settings
 445      * @throws UnsupportedOperationException if the supported SSL parameters
 446      *   could not be obtained.
 447      * @since 1.6
 448      */
 449     public final SSLParameters getSupportedSSLParameters() {
 450         return contextSpi.engineGetSupportedSSLParameters();
 451     }
 452 
 453 }