1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1838375a4d0b3d34e2babbd2f6a013976c7c439696Kenny Rootpackage org.conscrypt;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
200c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstromimport java.io.IOException;
21018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilsonimport java.security.GeneralSecurityException;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.KeyManagementException;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.SecureRandom;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.KeyManager;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLContextSpi;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLEngine;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLServerSocketFactory;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSocketFactory;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.TrustManager;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implementation of SSLContext service provider interface.
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class SSLContextImpl extends SSLContextSpi {
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    /**
370c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom     * The default SSLContextImpl for use with SSLContext.getInstance("Default").
380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom     * Protected by the DefaultSSLContextImpl.class monitor.
390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom     */
400c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    private static DefaultSSLContextImpl DEFAULT_SSL_CONTEXT_IMPL;
410c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /** Client session cache. */
430c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    private final ClientSessionContext clientSessionContext;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /** Server session cache. */
460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    private final ServerSessionContext serverSessionContext;
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
486812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom    protected SSLParametersImpl sslParameters;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SSLContextImpl() {
510c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        clientSessionContext = new ClientSessionContext();
520c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        serverSessionContext = new ServerSessionContext();
530c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    }
54059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom
550c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    /**
560c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom     * Constuctor for the DefaultSSLContextImpl.
570c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom     * @param dummy is null, used to distinguish this case from the
580c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom     * public SSLContextImpl() constructor.
590c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom     */
600c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom    protected SSLContextImpl(DefaultSSLContextImpl dummy)
610c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            throws GeneralSecurityException, IOException {
620c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        synchronized (DefaultSSLContextImpl.class) {
630c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            if (DEFAULT_SSL_CONTEXT_IMPL == null) {
640c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                clientSessionContext = new ClientSessionContext();
650c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                serverSessionContext = new ServerSessionContext();
660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                DEFAULT_SSL_CONTEXT_IMPL = (DefaultSSLContextImpl)this;
670c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            } else {
680c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                clientSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetClientSessionContext();
690c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                serverSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetServerSessionContext();
700c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            }
716812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom            sslParameters = new SSLParametersImpl(DEFAULT_SSL_CONTEXT_IMPL.getKeyManagers(),
726812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom                                                  DEFAULT_SSL_CONTEXT_IMPL.getTrustManagers(),
736812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom                                                  null,
746812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom                                                  clientSessionContext,
756812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom                                                  serverSessionContext);
760c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        }
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Initializes this {@code SSLContext} instance. All of the arguments are
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * optional, and the security providers will be searched for the required
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementations of the needed algorithms.
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param kms the key sources or {@code null}
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tms the trust decision sources or {@code null}
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param sr the randomness source or {@code null}
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws KeyManagementException if initializing this instance fails
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
89f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom    @Override
90f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom    public void engineInit(KeyManager[] kms, TrustManager[] tms,
91f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom            SecureRandom sr) throws KeyManagementException {
926812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom        sslParameters = new SSLParametersImpl(kms, tms, sr,
936812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom                                              clientSessionContext, serverSessionContext);
94f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom    }
95f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom
96059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom    @Override
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SSLSocketFactory engineGetSocketFactory() {
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (sslParameters == null) {
990c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            throw new IllegalStateException("SSLContext is not initialized.");
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
101059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        return new SSLSocketFactoryImpl(sslParameters);
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
104f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson    @Override
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SSLServerSocketFactory engineGetServerSocketFactory() {
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (sslParameters == null) {
1070c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            throw new IllegalStateException("SSLContext is not initialized.");
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
109059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom        return new SSLServerSocketFactoryImpl(sslParameters);
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
112f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson    @Override
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SSLEngine engineCreateSSLEngine(String host, int port) {
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (sslParameters == null) {
1150c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            throw new IllegalStateException("SSLContext is not initialized.");
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1176812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom        SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
1180c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        p.setUseClientMode(false);
1190c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        return new SSLEngineImpl(host, port, p);
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
122f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson    @Override
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SSLEngine engineCreateSSLEngine() {
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (sslParameters == null) {
1250c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            throw new IllegalStateException("SSLContext is not initialized.");
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1276812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom        SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
1280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        p.setUseClientMode(false);
1290c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom        return new SSLEngineImpl(p);
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
132f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson    @Override
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ServerSessionContext engineGetServerSessionContext() {
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return serverSessionContext;
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
137f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson    @Override
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ClientSessionContext engineGetClientSessionContext() {
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return clientSessionContext;
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
141d1c610c2a641157df80aa8aefefc49393074f507Elliott Hughes}
142