Home | History | Annotate | Download | only in ssl
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package javax.net.ssl;
     19 
     20 import java.security.KeyManagementException;
     21 import java.security.NoSuchAlgorithmException;
     22 import java.security.NoSuchProviderException;
     23 import java.security.Provider;
     24 import java.security.SecureRandom;
     25 import java.security.Security;
     26 import org.apache.harmony.security.fortress.Engine;
     27 
     28 
     29 /**
     30  * The public API for secure socket protocol implementations. It acts as factory
     31  * for {@code SSLSocketFactory}'s and {@code SSLEngine}s.
     32  */
     33 public class SSLContext {
     34     // StoreSSLContext service name
     35     private static final String SERVICE = "SSLContext";
     36 
     37     // Used to access common engine functionality
     38     private static final Engine ENGINE = new Engine(SERVICE);
     39 
     40     /**
     41      * Default SSLContext that can be replaced with SSLContext.setDefault()
     42      */
     43     private static SSLContext DEFAULT;
     44 
     45     /**
     46      * Returns the default SSLContext.
     47      *
     48      * The default SSL context can be set with {@link #setDefault}. If
     49      * not, one will be created with {@code
     50      * SSLContext.getInstance("Default")}, which will already be
     51      * initialized.
     52      *
     53      * @throws NoSuchAlgorithmException if there is a problem creating
     54      * the default instance.
     55      * @since 1.6
     56      */
     57     public static SSLContext getDefault() throws NoSuchAlgorithmException {
     58         synchronized (ENGINE) {
     59             if (DEFAULT == null) {
     60                 DEFAULT = SSLContext.getInstance("Default");
     61             }
     62             return DEFAULT;
     63         }
     64     }
     65 
     66     /**
     67      * Sets the default SSLContext instance as returned by {@link
     68      * #getDefault()} to a non-null initialized value.
     69      *
     70      * @throws NullPointerException on a null argument
     71      * @since 1.6
     72      */
     73     public static void setDefault(SSLContext sslContext) {
     74         if (sslContext == null) {
     75             throw new NullPointerException("sslContext == null");
     76         }
     77         synchronized (ENGINE) {
     78             DEFAULT = sslContext;
     79         }
     80     }
     81 
     82     /**
     83      * Creates a new {@code SSLContext} instance for the specified protocol.
     84      *
     85      * @param protocol
     86      *            the requested protocol to create a context for.
     87      * @return the created {@code SSLContext} instance.
     88      * @throws NoSuchAlgorithmException
     89      *             if no installed provider can provide the requested protocol
     90      * @throws NullPointerException
     91      *             if {@code protocol} is {@code null} (instead of
     92      *             NoSuchAlgorithmException as in 1.4 release)
     93      */
     94     public static SSLContext getInstance(String protocol) throws NoSuchAlgorithmException {
     95         if (protocol == null) {
     96             throw new NullPointerException("protocol == null");
     97         }
     98         Engine.SpiAndProvider sap = ENGINE.getInstance(protocol, null);
     99         return new SSLContext((SSLContextSpi) sap.spi, sap.provider, protocol);
    100     }
    101 
    102     /**
    103      * Creates a new {@code SSLContext} instance for the specified protocol from
    104      * the specified provider.
    105      *
    106      * @param protocol
    107      *            the requested protocol to create a context for.
    108      * @param provider
    109      *            the name of the provider that provides the requested protocol.
    110      * @return an {@code SSLContext} for the requested protocol.
    111      * @throws NoSuchAlgorithmException
    112      *             if the specified provider cannot provider the requested
    113      *             protocol.
    114      * @throws NoSuchProviderException
    115      *             if the specified provider does not exits.
    116      * @throws NullPointerException
    117      *             if {@code protocol} is {@code null} (instead of
    118      *             NoSuchAlgorithmException as in 1.4 release)
    119      */
    120     public static SSLContext getInstance(String protocol, String provider)
    121             throws NoSuchAlgorithmException, NoSuchProviderException {
    122         if (provider == null) {
    123             throw new IllegalArgumentException("Provider is null");
    124         }
    125         if (provider.length() == 0) {
    126             throw new IllegalArgumentException("Provider is empty");
    127         }
    128         Provider impProvider = Security.getProvider(provider);
    129         if (impProvider == null) {
    130             throw new NoSuchProviderException(provider);
    131         }
    132         return getInstance(protocol, impProvider);
    133     }
    134 
    135     /**
    136      * Creates a new {@code SSLContext} instance for the specified protocol from
    137      * the specified provider.
    138      *
    139      * @param protocol
    140      *            the requested protocol to create a context for
    141      * @param provider
    142      *            the provider that provides the requested protocol.
    143      * @return an {@code SSLContext} for the requested protocol.
    144      * @throws NoSuchAlgorithmException
    145      *             if the specified provider cannot provide the requested
    146      *             protocol.
    147      * @throws NullPointerException
    148      *             if {@code protocol} is {@code null} (instead of
    149      *             NoSuchAlgorithmException as in 1.4 release)
    150      */
    151     public static SSLContext getInstance(String protocol, Provider provider)
    152             throws NoSuchAlgorithmException {
    153         if (provider == null) {
    154             throw new IllegalArgumentException("provider is null");
    155         }
    156         if (protocol == null) {
    157             throw new NullPointerException("protocol == null");
    158         }
    159         Object spi = ENGINE.getInstance(protocol, provider, null);
    160         return new SSLContext((SSLContextSpi) spi, provider, protocol);
    161     }
    162 
    163     private final Provider provider;
    164 
    165     private final SSLContextSpi spiImpl;
    166 
    167     private final String protocol;
    168 
    169     /**
    170      * Creates a new {@code SSLContext}.
    171      *
    172      * @param contextSpi
    173      *            the implementation delegate.
    174      * @param provider
    175      *            the provider.
    176      * @param protocol
    177      *            the protocol name.
    178      */
    179     protected SSLContext(SSLContextSpi contextSpi, Provider provider, String protocol) {
    180         this.provider = provider;
    181         this.protocol = protocol;
    182         this.spiImpl = contextSpi;
    183     }
    184 
    185     /**
    186      * Returns the name of the secure socket protocol of this instance.
    187      *
    188      * @return the name of the secure socket protocol of this instance.
    189      */
    190     public final String getProtocol() {
    191         return protocol;
    192     }
    193 
    194     /**
    195      * Returns the provider of this {@code SSLContext} instance.
    196      *
    197      * @return the provider of this {@code SSLContext} instance.
    198      */
    199     public final Provider getProvider() {
    200         return provider;
    201     }
    202 
    203     /**
    204      * Initializes this {@code SSLContext} instance. All of the arguments are
    205      * optional, and the security providers will be searched for the required
    206      * implementations of the needed algorithms.
    207      *
    208      * @param km
    209      *            the key sources or {@code null}.
    210      * @param tm
    211      *            the trust decision sources or {@code null}.
    212      * @param sr
    213      *            the randomness source or {@code null.}
    214      * @throws KeyManagementException
    215      *             if initializing this instance fails.
    216      */
    217     public final void init(KeyManager[] km, TrustManager[] tm, SecureRandom sr)
    218             throws KeyManagementException {
    219         spiImpl.engineInit(km, tm, sr);
    220     }
    221 
    222     /**
    223      * Returns a socket factory for this instance.
    224      *
    225      * @return a socket factory for this instance.
    226      */
    227     public final SSLSocketFactory getSocketFactory() {
    228         return spiImpl.engineGetSocketFactory();
    229     }
    230 
    231     /**
    232      * Returns a server socket factory for this instance.
    233      *
    234      * @return a server socket factory for this instance.
    235      */
    236     public final SSLServerSocketFactory getServerSocketFactory() {
    237         return spiImpl.engineGetServerSocketFactory();
    238     }
    239 
    240     /**
    241      * Creates an {@code SSLEngine} instance from this context.
    242      *
    243      * @return an {@code SSLEngine} instance from this context.
    244      * @throws UnsupportedOperationException
    245      *             if the provider does not support the operation.
    246      */
    247     public final SSLEngine createSSLEngine() {
    248         return spiImpl.engineCreateSSLEngine();
    249     }
    250 
    251     /**
    252      * Creates an {@code SSLEngine} instance from this context with the
    253      * specified hostname and port.
    254      *
    255      * @param peerHost
    256      *            the name of the host
    257      * @param peerPort
    258      *            the port
    259      * @return an {@code SSLEngine} instance from this context.
    260      * @throws UnsupportedOperationException
    261      *             if the provider does not support the operation.
    262      */
    263     public final SSLEngine createSSLEngine(String peerHost, int peerPort) {
    264         return spiImpl.engineCreateSSLEngine(peerHost, peerPort);
    265     }
    266 
    267     /**
    268      * Returns the SSL session context that encapsulates the set of SSL sessions
    269      * that can be used for handshake of server-side SSL sockets.
    270      *
    271      * @return the SSL server session context for this context or {@code null}
    272      *         if the underlying provider does not provide an implementation of
    273      *         the {@code SSLSessionContext} interface.
    274      */
    275     public final SSLSessionContext getServerSessionContext() {
    276         return spiImpl.engineGetServerSessionContext();
    277     }
    278 
    279     /**
    280      * Returns the SSL session context that encapsulates the set of SSL sessions
    281      * that can be used for handshake of client-side SSL sockets.
    282      *
    283      * @return the SSL client session context for this context or {@code null}
    284      *         if the underlying provider does not provide an implementation of
    285      *         the {@code SSLSessionContext} interface.
    286      */
    287     public final SSLSessionContext getClientSessionContext() {
    288         return spiImpl.engineGetClientSessionContext();
    289     }
    290 
    291     /**
    292      * Returns the default SSL handshake parameters for SSLSockets
    293      * created by this SSLContext.
    294      *
    295      * @throws UnsupportedOperationException
    296      * @since 1.6
    297      */
    298     public final SSLParameters getDefaultSSLParameters() {
    299         return spiImpl.engineGetDefaultSSLParameters();
    300     }
    301 
    302     /**
    303      * Returns SSL handshake parameters for SSLSockets that includes
    304      * all supported cipher suites and protocols.
    305      *
    306      * @throws UnsupportedOperationException
    307      * @since 1.6
    308      */
    309     public final SSLParameters getSupportedSSLParameters() {
    310         return spiImpl.engineGetSupportedSSLParameters();
    311     }
    312 }
    313