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 
     27 import org.apache.harmony.security.fortress.Engine;
     28 
     29 
     30 /**
     31  * The public API for secure socket protocol implementations. It acts as factory
     32  * for {@code SSLSocketFactory}'s and {@code SSLEngine}s.
     33  */
     34 public class SSLContext {
     35     // StoreSSLContext service name
     36     private static final String SERVICE = "SSLContext";
     37 
     38     // Used to access common engine functionality
     39     private static Engine engine = new Engine(SERVICE);
     40 
     41     /**
     42      * Creates a new {@code SSLContext} instance for the specified protocol.
     43      *
     44      * @param protocol
     45      *            the requested protocol to create a context for.
     46      * @return the created {@code SSLContext} instance.
     47      * @throws NoSuchAlgorithmException
     48      *             if no installed provider can provide the requested protocol
     49      * @throws NullPointerException
     50      *             if {@code protocol} is {@code null} (instead of
     51      *             NoSuchAlgorithmException as in 1.4 release)
     52      */
     53     public static SSLContext getInstance(String protocol) throws NoSuchAlgorithmException {
     54         if (protocol == null) {
     55             throw new NullPointerException("protocol is null");
     56         }
     57         synchronized (engine) {
     58             engine.getInstance(protocol, null);
     59             return new SSLContext((SSLContextSpi) engine.spi, engine.provider, protocol);
     60         }
     61     }
     62 
     63     /**
     64      * Creates a new {@code SSLContext} instance for the specified protocol from
     65      * the specified provider.
     66      *
     67      * @param protocol
     68      *            the requested protocol to create a context for.
     69      * @param provider
     70      *            the name of the provider that provides the requested protocol.
     71      * @return an {@code SSLContext} for the requested protocol.
     72      * @throws NoSuchAlgorithmException
     73      *             if the specified provider cannot provider the requested
     74      *             protocol.
     75      * @throws NoSuchProviderException
     76      *             if the specified provider does not exits.
     77      * @throws NullPointerException
     78      *             if {@code protocol} is {@code null} (instead of
     79      *             NoSuchAlgorithmException as in 1.4 release)
     80      */
     81     public static SSLContext getInstance(String protocol, String provider)
     82             throws NoSuchAlgorithmException, NoSuchProviderException {
     83         if (provider == null) {
     84             throw new IllegalArgumentException("Provider is null");
     85         }
     86         if (provider.length() == 0) {
     87             throw new IllegalArgumentException("Provider is empty");
     88         }
     89         Provider impProvider = Security.getProvider(provider);
     90         if (impProvider == null) {
     91             throw new NoSuchProviderException(provider);
     92         }
     93         return getInstance(protocol, impProvider);
     94     }
     95 
     96     /**
     97      * Creates a new {@code SSLContext} instance for the specified protocol from
     98      * the specified provider.
     99      *
    100      * @param protocol
    101      *            the requested protocol to create a context for
    102      * @param provider
    103      *            the provider that provides the requested protocol.
    104      * @return an {@code SSLContext} for the requested protocol.
    105      * @throws NoSuchAlgorithmException
    106      *             if the specified provider cannot provide the requested
    107      *             protocol.
    108      * @throws NullPointerException
    109      *             if {@code protocol} is {@code null} (instead of
    110      *             NoSuchAlgorithmException as in 1.4 release)
    111      */
    112     public static SSLContext getInstance(String protocol, Provider provider)
    113             throws NoSuchAlgorithmException {
    114         if (provider == null) {
    115             throw new IllegalArgumentException("provider is null");
    116         }
    117         if (protocol == null) {
    118             throw new NullPointerException("protocol is null");
    119         }
    120         synchronized (engine) {
    121             engine.getInstance(protocol, provider, null);
    122             return new SSLContext((SSLContextSpi) engine.spi, provider, protocol);
    123         }
    124     }
    125 
    126     private final Provider provider;
    127 
    128     private final SSLContextSpi spiImpl;
    129 
    130     private final String protocol;
    131 
    132     /**
    133      * Creates a new {@code SSLContext}.
    134      *
    135      * @param contextSpi
    136      *            the implementation delegate.
    137      * @param provider
    138      *            the provider.
    139      * @param protocol
    140      *            the protocol name.
    141      */
    142     protected SSLContext(SSLContextSpi contextSpi, Provider provider, String protocol) {
    143         this.provider = provider;
    144         this.protocol = protocol;
    145         this.spiImpl = contextSpi;
    146     }
    147 
    148     /**
    149      * Returns the name of the secure socket protocol of this instance.
    150      *
    151      * @return the name of the secure socket protocol of this instance.
    152      */
    153     public final String getProtocol() {
    154         return protocol;
    155     }
    156 
    157     /**
    158      * Returns the provider of this {@code SSLContext} instance.
    159      *
    160      * @return the provider of this {@code SSLContext} instance.
    161      */
    162     public final Provider getProvider() {
    163         return provider;
    164     }
    165 
    166     /**
    167      * Initializes this {@code SSLContext} instance. All of the arguments are
    168      * optional, and the security providers will be searched for the required
    169      * implementations of the needed algorithms.
    170      *
    171      * @param km
    172      *            the key sources or {@code null}.
    173      * @param tm
    174      *            the trust decision sources or {@code null}.
    175      * @param sr
    176      *            the randomness source or {@code null.}
    177      * @throws KeyManagementException
    178      *             if initializing this instance fails.
    179      */
    180     public final void init(KeyManager[] km, TrustManager[] tm, SecureRandom sr)
    181             throws KeyManagementException {
    182         spiImpl.engineInit(km, tm, sr);
    183     }
    184 
    185     /**
    186      * Returns a socket factory for this instance.
    187      *
    188      * @return a socket factory for this instance.
    189      */
    190     public final SSLSocketFactory getSocketFactory() {
    191         return spiImpl.engineGetSocketFactory();
    192     }
    193 
    194     /**
    195      * Returns a server socket factory for this instance.
    196      *
    197      * @return a server socket factory for this instance.
    198      */
    199     public final SSLServerSocketFactory getServerSocketFactory() {
    200         return spiImpl.engineGetServerSocketFactory();
    201     }
    202 
    203     /**
    204      * Creates an {@code SSLEngine} instance from this context.
    205      *
    206      * @return an {@code SSLEngine} instance from this context.
    207      * @throws UnsupportedOperationException
    208      *             if the provider does not support the operation.
    209      */
    210     public final SSLEngine createSSLEngine() {
    211         return spiImpl.engineCreateSSLEngine();
    212     }
    213 
    214     /**
    215      * Creates an {@code SSLEngine} instance from this context with the
    216      * specified hostname and port.
    217      *
    218      * @param peerHost
    219      *            the name of the host
    220      * @param peerPort
    221      *            the port
    222      * @return an {@code SSLEngine} instance from this context.
    223      * @throws UnsupportedOperationException
    224      *             if the provider does not support the operation.
    225      */
    226     public final SSLEngine createSSLEngine(String peerHost, int peerPort) {
    227         return spiImpl.engineCreateSSLEngine(peerHost, peerPort);
    228     }
    229 
    230     /**
    231      * Returns the SSL session context that encapsulates the set of SSL sessions
    232      * that can be used for handshake of server-side SSL sockets.
    233      *
    234      * @return the SSL server session context for this context or {@code null}
    235      *         if the underlying provider does not provide an implementation of
    236      *         the {@code SSLSessionContext} interface.
    237      */
    238     public final SSLSessionContext getServerSessionContext() {
    239         return spiImpl.engineGetServerSessionContext();
    240     }
    241 
    242     /**
    243      * Returns the SSL session context that encapsulates the set of SSL sessions
    244      * that can be used for handshake of client-side SSL sockets.
    245      *
    246      * @return the SSL client session context for this context or {@code null}
    247      *         if the underlying provider does not provide an implementation of
    248      *         the {@code SSLSessionContext} interface.
    249      */
    250     public final SSLSessionContext getClientSessionContext() {
    251         return spiImpl.engineGetClientSessionContext();
    252     }
    253 }
    254