198a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom/* 298a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * Copyright (C) 2010 The Android Open Source Project 398a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * 498a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 598a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * you may not use this file except in compliance with the License. 698a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * You may obtain a copy of the License at 798a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * 898a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 998a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * 1098a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 1198a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 1298a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1398a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * See the License for the specific language governing permissions and 1498a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * limitations under the License. 1598a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom */ 1698a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom 17860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpackage org.conscrypt; 1898a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom 1998a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstromimport java.io.IOException; 2098a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstromimport java.security.GeneralSecurityException; 21680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubinimport java.security.KeyManagementException; 22680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubinimport java.security.SecureRandom; 23680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubinimport javax.net.ssl.KeyManager; 24680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubinimport javax.net.ssl.SSLContextSpi; 25680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubinimport javax.net.ssl.SSLEngine; 2698a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstromimport javax.net.ssl.SSLServerSocketFactory; 2798a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstromimport javax.net.ssl.SSLSocketFactory; 28680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubinimport javax.net.ssl.TrustManager; 2998a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom 3098a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom/** 31680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * OpenSSL-backed SSLContext service provider interface. 3298a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom */ 33680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubinpublic class OpenSSLContextImpl extends SSLContextSpi { 34680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 35680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin /** 36680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * The default SSLContextImpl for use with SSLContext.getInstance("Default"). 37680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * Protected by the DefaultSSLContextImpl.class monitor. 38680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin */ 39680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin private static DefaultSSLContextImpl DEFAULT_SSL_CONTEXT_IMPL; 40680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 41680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin /** Client session cache. */ 42680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin private final ClientSessionContext clientSessionContext; 43680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 44680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin /** Server session cache. */ 45680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin private final ServerSessionContext serverSessionContext; 46680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 47680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin protected SSLParametersImpl sslParameters; 48680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 49680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin public OpenSSLContextImpl() { 50680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin clientSessionContext = new ClientSessionContext(); 51680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin serverSessionContext = new ServerSessionContext(); 52680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 53680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 54680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin /** 55680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * Constuctor for the DefaultSSLContextImpl. 56680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * @param dummy is null, used to distinguish this case from the 57680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * public OpenSSLContextImpl() constructor. 58680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin */ 59680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin protected OpenSSLContextImpl(DefaultSSLContextImpl dummy) 60680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin throws GeneralSecurityException, IOException { 61680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin synchronized (DefaultSSLContextImpl.class) { 62680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin if (DEFAULT_SSL_CONTEXT_IMPL == null) { 63680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin clientSessionContext = new ClientSessionContext(); 64680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin serverSessionContext = new ServerSessionContext(); 65680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin DEFAULT_SSL_CONTEXT_IMPL = (DefaultSSLContextImpl)this; 66680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } else { 67680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin clientSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetClientSessionContext(); 68680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin serverSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetServerSessionContext(); 69680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 70680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin sslParameters = new SSLParametersImpl(DEFAULT_SSL_CONTEXT_IMPL.getKeyManagers(), 71680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin DEFAULT_SSL_CONTEXT_IMPL.getTrustManagers(), 72680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin null, 73680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin clientSessionContext, 74680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin serverSessionContext); 75680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 76680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 77680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 78680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin /** 79680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * Initializes this {@code SSLContext} instance. All of the arguments are 80680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * optional, and the security providers will be searched for the required 81680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * implementations of the needed algorithms. 82680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * 83680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * @param kms the key sources or {@code null} 84680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * @param tms the trust decision sources or {@code null} 85680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * @param sr the randomness source or {@code null} 86680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin * @throws KeyManagementException if initializing this instance fails 87680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin */ 88680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin @Override 89680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin public void engineInit(KeyManager[] kms, TrustManager[] tms, 90680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin SecureRandom sr) throws KeyManagementException { 91680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin sslParameters = new SSLParametersImpl(kms, tms, sr, 92680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin clientSessionContext, serverSessionContext); 93680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 94680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 95680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin @Override 96680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin public SSLSocketFactory engineGetSocketFactory() { 97680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin if (sslParameters == null) { 98680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin throw new IllegalStateException("SSLContext is not initialized."); 99680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 100680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin return new OpenSSLSocketFactoryImpl(sslParameters); 101680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 102680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 103680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin @Override 104680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin public SSLServerSocketFactory engineGetServerSocketFactory() { 105680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin if (sslParameters == null) { 106680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin throw new IllegalStateException("SSLContext is not initialized."); 107680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 108680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin return new OpenSSLServerSocketFactoryImpl(sslParameters); 109680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 110680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 111680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin @Override 112680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin public SSLEngine engineCreateSSLEngine(String host, int port) { 113f878e438660d93f8689b864165230492e7a412d4Kenny Root if (sslParameters == null) { 114f878e438660d93f8689b864165230492e7a412d4Kenny Root throw new IllegalStateException("SSLContext is not initialized."); 115f878e438660d93f8689b864165230492e7a412d4Kenny Root } 116f878e438660d93f8689b864165230492e7a412d4Kenny Root SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone(); 117f878e438660d93f8689b864165230492e7a412d4Kenny Root p.setUseClientMode(false); 118f878e438660d93f8689b864165230492e7a412d4Kenny Root return new OpenSSLEngineImpl(host, port, p); 119680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 120680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 121680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin @Override 122680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin public SSLEngine engineCreateSSLEngine() { 123f878e438660d93f8689b864165230492e7a412d4Kenny Root if (sslParameters == null) { 124f878e438660d93f8689b864165230492e7a412d4Kenny Root throw new IllegalStateException("SSLContext is not initialized."); 125f878e438660d93f8689b864165230492e7a412d4Kenny Root } 126f878e438660d93f8689b864165230492e7a412d4Kenny Root SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone(); 127f878e438660d93f8689b864165230492e7a412d4Kenny Root p.setUseClientMode(false); 128f878e438660d93f8689b864165230492e7a412d4Kenny Root return new OpenSSLEngineImpl(p); 129680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 130680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 131680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin @Override 132680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin public ServerSessionContext engineGetServerSessionContext() { 133680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin return serverSessionContext; 134680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 135680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin 136680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin @Override 137680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin public ClientSessionContext engineGetClientSessionContext() { 138680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin return clientSessionContext; 139680ce427fbccaab1dc477b1f2501adba9695e4ddAlex Klyubin } 14098a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom} 141