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