OpenSSLServerSocketImpl.java revision 577e146ed2c9c9d166c4d30a495d95d4b171a7e8
108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project/*
208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project *
408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * you may not use this file except in compliance with the License.
608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * You may obtain a copy of the License at
708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project *
808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project *
1008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * See the License for the specific language governing permissions and
1408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * limitations under the License.
1508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */
1608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
1708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectpackage org.apache.harmony.xnet.provider.jsse;
1808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
1908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.io.IOException;
2008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.net.InetAddress;
2108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.net.Socket;
2231e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstromimport java.security.PrivateKey;
23d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstromimport java.security.interfaces.ECPrivateKey;
2431e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstromimport java.security.interfaces.DSAPrivateKey;
2531e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstromimport java.security.interfaces.RSAPrivateKey;
2631e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstromimport javax.net.ssl.SSLException;
2708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
2808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project/**
2908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * OpenSSL-based implementation of server sockets.
30f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom */
3108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectpublic class OpenSSLServerSocketImpl extends javax.net.ssl.SSLServerSocket {
32cbbd49c29da3e87cb7775ba789a0211cba0b909fBrian Carlstrom    private final SSLParametersImpl sslParameters;
332828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom    private String[] enabledProtocols = NativeCrypto.getSupportedProtocols();
342828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom    private String[] enabledCipherSuites = NativeCrypto.getDefaultCipherSuites();
35577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin    private boolean channelIdEnabled;
3608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
37f2fa9706e3ef888af9c22c4894e0c05648a86362Elliott Hughes    protected OpenSSLServerSocketImpl(SSLParametersImpl sslParameters) throws IOException {
3808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        this.sslParameters = sslParameters;
3908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
4008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
41cbbd49c29da3e87cb7775ba789a0211cba0b909fBrian Carlstrom    protected OpenSSLServerSocketImpl(int port, SSLParametersImpl sslParameters)
4208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        throws IOException {
4308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        super(port);
4408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        this.sslParameters = sslParameters;
4508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
4608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
47cbbd49c29da3e87cb7775ba789a0211cba0b909fBrian Carlstrom    protected OpenSSLServerSocketImpl(int port, int backlog, SSLParametersImpl sslParameters)
4808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        throws IOException {
4908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        super(port, backlog);
5008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        this.sslParameters = sslParameters;
5108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
5208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
5331e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom    protected OpenSSLServerSocketImpl(int port,
5431e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom                                      int backlog,
5531e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom                                      InetAddress iAddress,
56cbbd49c29da3e87cb7775ba789a0211cba0b909fBrian Carlstrom                                      SSLParametersImpl sslParameters)
5708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        throws IOException {
5808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        super(port, backlog, iAddress);
5908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        this.sslParameters = sslParameters;
6008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
6108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
6208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
6308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public boolean getEnableSessionCreation() {
6408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        return sslParameters.getEnableSessionCreation();
6508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
6608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
6708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
6808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setEnableSessionCreation(boolean flag) {
6908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        sslParameters.setEnableSessionCreation(flag);
7008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
7108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
7208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    /**
7308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * The names of the protocols' versions that may be used on this SSL
7408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * connection.
7508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @return an array of protocols names
7608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     */
7708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
7808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public String[] getSupportedProtocols() {
79f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom        return NativeCrypto.getSupportedProtocols();
8008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
8108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
8208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    /**
8308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * The names of the protocols' versions that in use on this SSL connection.
84f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom     *
8508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @return an array of protocols names
8608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     */
8708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
8808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public String[] getEnabledProtocols() {
892828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom        return enabledProtocols.clone();
9008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
9108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
9208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    /**
9308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * This method enables the protocols' versions listed by
9408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * getSupportedProtocols().
95f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom     *
9608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @param protocols names of all the protocols to enable.
97f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom     *
9808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @throws IllegalArgumentException when one or more of the names in the
9908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     *             array are not supported, or when the array is null.
10008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     */
10108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
10208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setEnabledProtocols(String[] protocols) {
1032828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom        enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols);
10408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
10508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
10608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
10708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public String[] getSupportedCipherSuites() {
108f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom        return NativeCrypto.getSupportedCipherSuites();
10908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
11008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
11108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
11208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public String[] getEnabledCipherSuites() {
1132828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom        return enabledCipherSuites.clone();
11408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
11508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
11608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    /**
117577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin     * Enables/disables the TLS Channel ID extension for this server socket.
118577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin     */
119577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin    public void setChannelIdEnabled(boolean enabled) {
120577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin      channelIdEnabled = enabled;
121577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin    }
122577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin
123577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin    /**
124577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin     * Checks whether the TLS Channel ID extension is enabled for this server socket.
125577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin     */
126577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin    public boolean isChannelIdEnabled() {
127577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin      return channelIdEnabled;
128577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin    }
129577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin
130577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin    /**
13108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * This method enables the cipher suites listed by
13208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * getSupportedCipherSuites().
13308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     *
13408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @param suites the names of all the cipher suites to enable
13508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @throws IllegalArgumentException when one or more of the ciphers in array
13608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     *         suites are not supported, or when the array is null.
13708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     */
13808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
13908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setEnabledCipherSuites(String[] suites) {
1402828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom        enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites);
14108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
14208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
14308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
14408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public boolean getWantClientAuth() {
14508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        return sslParameters.getWantClientAuth();
14608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
14708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
14808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
14908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setWantClientAuth(boolean want) {
15008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        sslParameters.setWantClientAuth(want);
15108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
15208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
15308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
15408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public boolean getNeedClientAuth() {
15508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        return sslParameters.getNeedClientAuth();
15608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
15708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
15808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
15908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setNeedClientAuth(boolean need) {
16008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        sslParameters.setNeedClientAuth(need);
16108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
16208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
16308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
16408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setUseClientMode(boolean mode) {
16508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        sslParameters.setUseClientMode(mode);
16608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
16708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
16808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
16908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public boolean getUseClientMode() {
17008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        return sslParameters.getUseClientMode();
17108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
17208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
17308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
17408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public Socket accept() throws IOException {
1759ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom
1769ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        if (!sslParameters.getUseClientMode()) {
1779ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom            checkEnabledCipherSuites();
1789ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        }
1799ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom
1809ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters,
1819ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                                                         enabledProtocols.clone(),
1825ea53c028b903ce252e08c1b67508ce8dafcff34Brian Carlstrom                                                         enabledCipherSuites.clone());
183577e146ed2c9c9d166c4d30a495d95d4b171a7e8Alex Klyubin        socket.setChannelIdEnabled(channelIdEnabled);
1849ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        implAccept(socket);
1859ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        return socket;
1869ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    }
1879ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom
1889ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    /**
1899ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom     * Check if any of the enabled cipher suites has a chance to work.
1909ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom     * Not 100% accurate, just a useful diagnostic that the RI does.
1919ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom     */
1929ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    private void checkEnabledCipherSuites() throws SSLException {
1939ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        /* Loop over all enabled cipher suites. If we find a problem,
1949ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         * we just continue to the next one. If we find one that could
1959ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         * work, we return. This basically makes sure the caller has
1969ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         * configured some appropriate certificate/key unless
1979ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         * an anonymous cipher is picked.
1989ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         */
19931e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom        for (String enabledCipherSuite : enabledCipherSuites) {
200aeb3b48a69c2294ca657acd3e8b94c9879d78b61Brian Carlstrom            if (enabledCipherSuite.equals(NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
201aeb3b48a69c2294ca657acd3e8b94c9879d78b61Brian Carlstrom                continue;
202aeb3b48a69c2294ca657acd3e8b94c9879d78b61Brian Carlstrom            }
203ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom            String keyType = CipherSuite.getByName(enabledCipherSuite).getServerKeyType();
204d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom            if (keyType == null) {
205d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                // anonymous always work
206d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                return;
207d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom            }
208ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom            if (keyType.equals(CipherSuite.KEY_TYPE_RSA)
209ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom                    || keyType.equals(CipherSuite.KEY_TYPE_DH_RSA)) {
210d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                if (checkForPrivateKey(keyType, RSAPrivateKey.class)) {
211d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                    return;
2129ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                }
213d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                continue;
21431e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom            }
215ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom            if (keyType.equals(CipherSuite.KEY_TYPE_DSA)
216ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom                    || keyType.equals(CipherSuite.KEY_TYPE_DH_DSA)) {
217d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                if (checkForPrivateKey(keyType, DSAPrivateKey.class)) {
2189ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                    return;
219d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                }
220d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                continue;
221d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom            }
222ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom            if (keyType.equals(CipherSuite.KEY_TYPE_EC)
223ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom                    || keyType.equals(CipherSuite.KEY_TYPE_EC_RSA)
224ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom                    || keyType.equals(CipherSuite.KEY_TYPE_EC_EC)) {
225d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                if (checkForPrivateKey(keyType, ECPrivateKey.class)) {
2269ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                    return;
227d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                }
228d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                continue;
22931e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom            }
230d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom            throw new IllegalStateException("Unknown key type " + keyType);
23131e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom        }
2329ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        throw new SSLException("Could not find any key store entries "
2339ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                               + "to support the enabled cipher suites.");
2349ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    }
23531e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom
2369ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    private boolean checkForPrivateKey(String keyType, Class keyClass) {
2379ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        String alias = sslParameters.getKeyManager().chooseServerAlias(keyType, null, null);
2389ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        if (alias == null) {
2399ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom            return false;
2409ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        }
2419ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        PrivateKey key = sslParameters.getKeyManager().getPrivateKey(alias);
2429ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        return (key != null && keyClass.isAssignableFrom(key.getClass()));
24308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
24408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project}
245