OpenSSLServerSocketImpl.java revision f2fa9706e3ef888af9c22c4894e0c05648a86362
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 Project * This class only supports SSLv3 and TLSv1. This should be documented elsewhere
3208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * later, for example in the package.html or a separate reference document.
33f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom */
3408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectpublic class OpenSSLServerSocketImpl extends javax.net.ssl.SSLServerSocket {
35cbbd49c29da3e87cb7775ba789a0211cba0b909fBrian Carlstrom    private final SSLParametersImpl sslParameters;
362828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom    private String[] enabledProtocols = NativeCrypto.getSupportedProtocols();
372828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom    private String[] enabledCipherSuites = NativeCrypto.getDefaultCipherSuites();
380b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom    private String[] enabledCompressionMethods = NativeCrypto.getDefaultCompressionMethods();
3908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
40f2fa9706e3ef888af9c22c4894e0c05648a86362Elliott Hughes    protected OpenSSLServerSocketImpl(SSLParametersImpl sslParameters) throws IOException {
4108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        this.sslParameters = sslParameters;
4208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
4308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
44cbbd49c29da3e87cb7775ba789a0211cba0b909fBrian Carlstrom    protected OpenSSLServerSocketImpl(int port, SSLParametersImpl sslParameters)
4508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        throws IOException {
4608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        super(port);
4708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        this.sslParameters = sslParameters;
4808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
4908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
50cbbd49c29da3e87cb7775ba789a0211cba0b909fBrian Carlstrom    protected OpenSSLServerSocketImpl(int port, int backlog, SSLParametersImpl sslParameters)
5108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        throws IOException {
5208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        super(port, backlog);
5308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        this.sslParameters = sslParameters;
5408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
5508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
5631e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom    protected OpenSSLServerSocketImpl(int port,
5731e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom                                      int backlog,
5831e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom                                      InetAddress iAddress,
59cbbd49c29da3e87cb7775ba789a0211cba0b909fBrian Carlstrom                                      SSLParametersImpl sslParameters)
6008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        throws IOException {
6108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        super(port, backlog, iAddress);
6208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        this.sslParameters = sslParameters;
6308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
6408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
6508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
6608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public boolean getEnableSessionCreation() {
6708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        return sslParameters.getEnableSessionCreation();
6808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
6908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
7008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
7108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setEnableSessionCreation(boolean flag) {
7208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        sslParameters.setEnableSessionCreation(flag);
7308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
7408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
7508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    /**
7608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * The names of the protocols' versions that may be used on this SSL
7708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * connection.
7808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @return an array of protocols names
7908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     */
8008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
8108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public String[] getSupportedProtocols() {
82f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom        return NativeCrypto.getSupportedProtocols();
8308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
8408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
8508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    /**
8608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * The names of the protocols' versions that in use on this SSL connection.
87f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom     *
8808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @return an array of protocols names
8908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     */
9008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
9108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public String[] getEnabledProtocols() {
922828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom        return enabledProtocols.clone();
9308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
9408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
9508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    /**
9608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * This method enables the protocols' versions listed by
9708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * getSupportedProtocols().
98f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom     *
9908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @param protocols names of all the protocols to enable.
100f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom     *
10108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @throws IllegalArgumentException when one or more of the names in the
10208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     *             array are not supported, or when the array is null.
10308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     */
10408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
10508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setEnabledProtocols(String[] protocols) {
1062828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom        enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols);
10708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
10808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
10908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
11008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public String[] getSupportedCipherSuites() {
111f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom        return NativeCrypto.getSupportedCipherSuites();
11208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
11308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
11408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
11508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public String[] getEnabledCipherSuites() {
1162828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom        return enabledCipherSuites.clone();
11708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
11808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
11908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    /**
12008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * This method enables the cipher suites listed by
12108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * getSupportedCipherSuites().
12208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     *
12308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @param suites the names of all the cipher suites to enable
12408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     * @throws IllegalArgumentException when one or more of the ciphers in array
12508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     *         suites are not supported, or when the array is null.
12608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project     */
12708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
12808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setEnabledCipherSuites(String[] suites) {
1292828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom        enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites);
13008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
13108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
1320b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom    public String[] getSupportedCompressionMethods() {
1330b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom        return NativeCrypto.getSupportedCompressionMethods();
1340b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom    }
1350b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom
1360b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom    public String[] getEnabledCompressionMethods() {
1370b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom        return enabledCompressionMethods.clone();
1380b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom    }
1390b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom
1400b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom    /**
1410b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom     * This method enables the compression methods listed by
1420b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom     * getSupportedCompressionMethods().
1430b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom     *
1440b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom     * @param suites the names of all the compression methods to enable
1450b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom     * @throws IllegalArgumentException when one or more of the ciphers in array
1460b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom     *         suites are not supported, or when the array is null.
1470b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom     */
1480b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom    public void setEnabledCompressionMethods(String[] methods) {
1490b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom        enabledCompressionMethods = NativeCrypto.checkEnabledCompressionMethods(methods);
1500b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom    }
1510b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom
15208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
15308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public boolean getWantClientAuth() {
15408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        return sslParameters.getWantClientAuth();
15508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
15608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
15708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
15808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setWantClientAuth(boolean want) {
15908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        sslParameters.setWantClientAuth(want);
16008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
16108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
16208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
16308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public boolean getNeedClientAuth() {
16408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        return sslParameters.getNeedClientAuth();
16508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
16608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
16708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
16808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setNeedClientAuth(boolean need) {
16908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        sslParameters.setNeedClientAuth(need);
17008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
17108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
17208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
17308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public void setUseClientMode(boolean mode) {
17408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        sslParameters.setUseClientMode(mode);
17508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
17608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
17708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
17808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public boolean getUseClientMode() {
17908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project        return sslParameters.getUseClientMode();
18008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
18108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project
18208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    @Override
18308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    public Socket accept() throws IOException {
1849ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom
1859ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        if (!sslParameters.getUseClientMode()) {
1869ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom            checkEnabledCipherSuites();
1879ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        }
1889ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom
1899ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters,
1909ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                                                         enabledProtocols.clone(),
1910b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom                                                         enabledCipherSuites.clone(),
1920b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom                                                         enabledCompressionMethods.clone());
1939ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        implAccept(socket);
1949ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        return socket;
1959ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    }
1969ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom
1979ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    /**
1989ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom     * Check if any of the enabled cipher suites has a chance to work.
1999ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom     * Not 100% accurate, just a useful diagnostic that the RI does.
2009ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom     */
2019ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    private void checkEnabledCipherSuites() throws SSLException {
2029ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        /* Loop over all enabled cipher suites. If we find a problem,
2039ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         * we just continue to the next one. If we find one that could
2049ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         * work, we return. This basically makes sure the caller has
2059ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         * configured some appropriate certificate/key unless
2069ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         * an anonymous cipher is picked.
2079ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom         */
20831e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom        for (String enabledCipherSuite : enabledCipherSuites) {
209aeb3b48a69c2294ca657acd3e8b94c9879d78b61Brian Carlstrom            if (enabledCipherSuite.equals(NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
210aeb3b48a69c2294ca657acd3e8b94c9879d78b61Brian Carlstrom                continue;
211aeb3b48a69c2294ca657acd3e8b94c9879d78b61Brian Carlstrom            }
212ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom            String keyType = CipherSuite.getByName(enabledCipherSuite).getServerKeyType();
213d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom            if (keyType == null) {
214d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                // anonymous always work
215d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                return;
216d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom            }
217ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom            if (keyType.equals(CipherSuite.KEY_TYPE_RSA)
218ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom                    || keyType.equals(CipherSuite.KEY_TYPE_DH_RSA)) {
219d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                if (checkForPrivateKey(keyType, RSAPrivateKey.class)) {
220d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                    return;
2219ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                }
222d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                continue;
22331e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom            }
224ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom            if (keyType.equals(CipherSuite.KEY_TYPE_DSA)
225ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom                    || keyType.equals(CipherSuite.KEY_TYPE_DH_DSA)) {
226d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                if (checkForPrivateKey(keyType, DSAPrivateKey.class)) {
2279ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                    return;
228d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                }
229d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                continue;
230d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom            }
231ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom            if (keyType.equals(CipherSuite.KEY_TYPE_EC)
232ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom                    || keyType.equals(CipherSuite.KEY_TYPE_EC_RSA)
233ea8732bc2631141874302bc25ee2795a89f4922fBrian Carlstrom                    || keyType.equals(CipherSuite.KEY_TYPE_EC_EC)) {
234d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                if (checkForPrivateKey(keyType, ECPrivateKey.class)) {
2359ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                    return;
236d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                }
237d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom                continue;
23831e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom            }
239d5eeb213edc60ad4c33f1cec353899ab0957dd25Brian Carlstrom            throw new IllegalStateException("Unknown key type " + keyType);
24031e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom        }
2419ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        throw new SSLException("Could not find any key store entries "
2429ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom                               + "to support the enabled cipher suites.");
2439ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    }
24431e4294cb041d6f3914e5d1d8800e92aeb7ed523Brian Carlstrom
2459ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom    private boolean checkForPrivateKey(String keyType, Class keyClass) {
2469ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        String alias = sslParameters.getKeyManager().chooseServerAlias(keyType, null, null);
2479ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        if (alias == null) {
2489ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom            return false;
2499ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        }
2509ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        PrivateKey key = sslParameters.getKeyManager().getPrivateKey(alias);
2519ad6792f005170fcc79ddc23b87f9d9a6e27046eBrian Carlstrom        return (key != null && keyClass.isAssignableFrom(key.getClass()));
25208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project    }
25308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project}
254