Home | History | Annotate | Download | only in conscrypt
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package org.conscrypt;
     18 
     19 import static org.conscrypt.Platform.wrapEngine;
     20 
     21 import java.io.IOException;
     22 import java.security.GeneralSecurityException;
     23 import java.security.KeyManagementException;
     24 import java.security.SecureRandom;
     25 import javax.net.ssl.KeyManager;
     26 import javax.net.ssl.SSLContextSpi;
     27 import javax.net.ssl.SSLEngine;
     28 import javax.net.ssl.SSLServerSocketFactory;
     29 import javax.net.ssl.SSLSocketFactory;
     30 import javax.net.ssl.TrustManager;
     31 
     32 /**
     33  * OpenSSL-backed SSLContext service provider interface.
     34  *
     35  * <p>Public to allow contruction via the provider framework.
     36  *
     37  * @hide
     38  */
     39 @Internal
     40 public abstract class OpenSSLContextImpl extends SSLContextSpi {
     41     /**
     42      * The default SSLContextImpl for use with
     43      * SSLContext.getInstance("Default"). Protected by the
     44      * DefaultSSLContextImpl.class monitor.
     45      */
     46     private static DefaultSSLContextImpl defaultSslContextImpl;
     47 
     48     /** TLS algorithm to initialize all sockets. */
     49     private final String[] algorithms;
     50 
     51     /** Client session cache. */
     52     private final ClientSessionContext clientSessionContext;
     53 
     54     /** Server session cache. */
     55     private final ServerSessionContext serverSessionContext;
     56 
     57     SSLParametersImpl sslParameters;
     58 
     59     /** Allows outside callers to get the preferred SSLContext. */
     60     static OpenSSLContextImpl getPreferred() {
     61         return new TLSv12();
     62     }
     63 
     64     OpenSSLContextImpl(String[] algorithms) {
     65         this.algorithms = algorithms;
     66         clientSessionContext = new ClientSessionContext();
     67         serverSessionContext = new ServerSessionContext();
     68     }
     69 
     70     /**
     71      * Constuctor for the DefaultSSLContextImpl.
     72      */
     73     OpenSSLContextImpl() throws GeneralSecurityException, IOException {
     74         synchronized (DefaultSSLContextImpl.class) {
     75             this.algorithms = null;
     76             if (defaultSslContextImpl == null) {
     77                 clientSessionContext = new ClientSessionContext();
     78                 serverSessionContext = new ServerSessionContext();
     79                 defaultSslContextImpl = (DefaultSSLContextImpl) this;
     80             } else {
     81                 clientSessionContext = defaultSslContextImpl.engineGetClientSessionContext();
     82                 serverSessionContext = defaultSslContextImpl.engineGetServerSessionContext();
     83             }
     84             sslParameters = new SSLParametersImpl(defaultSslContextImpl.getKeyManagers(),
     85                     defaultSslContextImpl.getTrustManagers(), null, clientSessionContext,
     86                     serverSessionContext, algorithms);
     87         }
     88     }
     89 
     90     /**
     91      * Initializes this {@code SSLContext} instance. All of the arguments are
     92      * optional, and the security providers will be searched for the required
     93      * implementations of the needed algorithms.
     94      *
     95      * @param kms the key sources or {@code null}
     96      * @param tms the trust decision sources or {@code null}
     97      * @param sr the randomness source or {@code null}
     98      * @throws KeyManagementException if initializing this instance fails
     99      */
    100     @Override
    101     public void engineInit(KeyManager[] kms, TrustManager[] tms, SecureRandom sr)
    102             throws KeyManagementException {
    103         sslParameters = new SSLParametersImpl(
    104                 kms, tms, sr, clientSessionContext, serverSessionContext, algorithms);
    105     }
    106 
    107     @Override
    108     public SSLSocketFactory engineGetSocketFactory() {
    109         if (sslParameters == null) {
    110             throw new IllegalStateException("SSLContext is not initialized.");
    111         }
    112         return Platform.wrapSocketFactoryIfNeeded(new OpenSSLSocketFactoryImpl(sslParameters));
    113     }
    114 
    115     @Override
    116     public SSLServerSocketFactory engineGetServerSocketFactory() {
    117         if (sslParameters == null) {
    118             throw new IllegalStateException("SSLContext is not initialized.");
    119         }
    120         return new OpenSSLServerSocketFactoryImpl(sslParameters);
    121     }
    122 
    123     @Override
    124     public SSLEngine engineCreateSSLEngine(String host, int port) {
    125         if (sslParameters == null) {
    126             throw new IllegalStateException("SSLContext is not initialized.");
    127         }
    128         SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
    129         p.setUseClientMode(false);
    130         return wrapEngine(new ConscryptEngine(host, port, p));
    131     }
    132 
    133     @Override
    134     public SSLEngine engineCreateSSLEngine() {
    135         if (sslParameters == null) {
    136             throw new IllegalStateException("SSLContext is not initialized.");
    137         }
    138         SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
    139         p.setUseClientMode(false);
    140         return wrapEngine(new ConscryptEngine(p));
    141     }
    142 
    143     @Override
    144     public ServerSessionContext engineGetServerSessionContext() {
    145         return serverSessionContext;
    146     }
    147 
    148     @Override
    149     public ClientSessionContext engineGetClientSessionContext() {
    150         return clientSessionContext;
    151     }
    152 
    153     /**
    154      * Public to allow construction via the provider framework.
    155      */
    156     public static final class TLSv12 extends OpenSSLContextImpl {
    157         public TLSv12() {
    158             super(NativeCrypto.TLSV12_PROTOCOLS);
    159         }
    160     }
    161 
    162     /**
    163      * Public to allow construction via the provider framework.
    164      */
    165     public static final class TLSv11 extends OpenSSLContextImpl {
    166         public TLSv11() {
    167             super(NativeCrypto.TLSV11_PROTOCOLS);
    168         }
    169     }
    170 
    171     /**
    172      * Public to allow construction via the provider framework.
    173      */
    174     public static final class TLSv1 extends OpenSSLContextImpl {
    175         public TLSv1() {
    176             super(NativeCrypto.TLSV1_PROTOCOLS);
    177         }
    178     }
    179 }
    180