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