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