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