SSLCertificateSocketFactory.java revision 992f238d13fff7c21b60ef6958784a4ed2156784
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.net;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.InetAddress;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.Socket;
247ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstromimport java.net.SocketException;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.KeyManagementException;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.cert.X509Certificate;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.SocketFactory;
287fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.HostnameVerifier;
297fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.HttpsURLConnection;
301b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komaloimport javax.net.ssl.KeyManager;
317fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.SSLException;
327fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.SSLPeerUnverifiedException;
337fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.SSLSession;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.SSLSocket;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.SSLSocketFactory;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.TrustManager;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.X509TrustManager;
383c7c351a6217ac48b741740167c201a679a0ca65Brian Carlstromimport org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl;
3960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnorimport org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
4360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * SSLSocketFactory implementation with several extra features:
447fc93c36ae235115727296780dbc35101622bbd4Dan Egnor *
4560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <ul>
4660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <li>Timeout specification for SSL handshake operations
477fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <li>Hostname verification in most cases (see WARNINGs below)
4860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <li>Optional SSL session caching with {@link SSLSessionCache}
499d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * <li>Optionally bypass all SSL certificate checks
5060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * </ul>
517fc93c36ae235115727296780dbc35101622bbd4Dan Egnor *
527fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * The handshake timeout does not apply to actual TCP socket connection.
537fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * If you want a connection timeout as well, use {@link #createSocket()}
547fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * and {@link Socket#connect(SocketAddress, int)}, after which you
557fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * must verify the identity of the server you are connected to.
567fc93c36ae235115727296780dbc35101622bbd4Dan Egnor *
577fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p class="caution"><b>Most {@link SSLSocketFactory} implementations do not
587fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * verify the server's identity, allowing man-in-the-middle attacks.</b>
597fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * This implementation does check the server's certificate hostname, but only
607fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * for createSocket variants that specify a hostname.  When using methods that
617fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * use {@link InetAddress} or which return an unconnected socket, you MUST
627fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * verify the server's identity yourself to ensure a secure connection.</p>
637fc93c36ae235115727296780dbc35101622bbd4Dan Egnor *
647fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p>One way to verify the server's identity is to use
657fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@link HttpsURLConnection#getDefaultHostnameVerifier()} to get a
667fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@link HostnameVerifier} to verify the certificate hostname.
677fc93c36ae235115727296780dbc35101622bbd4Dan Egnor *
687fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p>On development devices, "setprop socket.relaxsslcheck yes" bypasses all
697fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * SSL certificate and hostname checks for testing purposes.  This setting
707fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * requires root access.
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SSLCertificateSocketFactory extends SSLSocketFactory {
7360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    private static final String TAG = "SSLCertificateSocketFactory";
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    private static final TrustManager[] INSECURE_TRUST_MANAGER = new TrustManager[] {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        new X509TrustManager() {
7760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            public X509Certificate[] getAcceptedIssuers() { return null; }
7860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            public void checkClientTrusted(X509Certificate[] certs, String authType) { }
7960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            public void checkServerTrusted(X509Certificate[] certs, String authType) { }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
837fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    private static final HostnameVerifier HOSTNAME_VERIFIER =
847fc93c36ae235115727296780dbc35101622bbd4Dan Egnor        HttpsURLConnection.getDefaultHostnameVerifier();
857fc93c36ae235115727296780dbc35101622bbd4Dan Egnor
8660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    private SSLSocketFactory mInsecureFactory = null;
8760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    private SSLSocketFactory mSecureFactory = null;
881b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    private TrustManager[] mTrustManagers = null;
891b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    private KeyManager[] mKeyManagers = null;
90f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    private byte[] mNpnProtocols = null;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    private final int mHandshakeTimeoutMillis;
9360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    private final SSLClientSessionCache mSessionCache;
949d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor    private final boolean mSecure;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    /** @deprecated Use {@link #getDefault(int)} instead. */
9728c742573ccaeb55c16bc02fb25fdd86b8d1f76aJesse Wilson    @Deprecated
9860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public SSLCertificateSocketFactory(int handshakeTimeoutMillis) {
999d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor        this(handshakeTimeoutMillis, null, true);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor    private SSLCertificateSocketFactory(
103992f238d13fff7c21b60ef6958784a4ed2156784Brian Carlstrom            int handshakeTimeoutMillis, SSLSessionCache cache, boolean secure) {
10460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        mHandshakeTimeoutMillis = handshakeTimeoutMillis;
10560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        mSessionCache = cache == null ? null : cache.mSessionCache;
1069d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor        mSecure = secure;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1109d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     * Returns a new socket factory instance with an optional handshake timeout.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
11360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     *         for none.  The socket timeout is reset to 0 after the handshake.
1147fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * @return a new SSLSocketFactory with the specified parameters
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public static SocketFactory getDefault(int handshakeTimeoutMillis) {
1179d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor        return new SSLCertificateSocketFactory(handshakeTimeoutMillis, null, true);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1219d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     * Returns a new socket factory instance with an optional handshake timeout
1229d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     * and SSL session cache.
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
12560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     *         for none.  The socket timeout is reset to 0 after the handshake.
126ff5569948fda346d95d4615de6578f82d9614be3Jesse Wilson     * @param cache The {@link SSLSessionCache} to use, or null for no cache.
1277fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * @return a new SSLSocketFactory with the specified parameters
12860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     */
1299d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor    public static SSLSocketFactory getDefault(int handshakeTimeoutMillis, SSLSessionCache cache) {
1309d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor        return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, true);
1319d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor    }
1329d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor
1339d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor    /**
1349d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     * Returns a new instance of a socket factory with all SSL security checks
1359d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     * disabled, using an optional handshake timeout and SSL session cache.
1367fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
1377fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * <p class="caution"><b>Warning:</b> Sockets created using this factory
1387fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * are vulnerable to man-in-the-middle attacks!</p>
1399d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     *
1409d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
1419d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     *         for none.  The socket timeout is reset to 0 after the handshake.
142ff5569948fda346d95d4615de6578f82d9614be3Jesse Wilson     * @param cache The {@link SSLSessionCache} to use, or null for no cache.
1437fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * @return an insecure SSLSocketFactory with the specified parameters
1449d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor     */
1459d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor    public static SSLSocketFactory getInsecure(int handshakeTimeoutMillis, SSLSessionCache cache) {
1469d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor        return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, false);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    /**
15060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     * Returns a socket factory (also named SSLSocketFactory, but in a different
15160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     * namespace) for use with the Apache HTTP stack.
15260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     *
15360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
15460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     *         for none.  The socket timeout is reset to 0 after the handshake.
155ff5569948fda346d95d4615de6578f82d9614be3Jesse Wilson     * @param cache The {@link SSLSessionCache} to use, or null for no cache.
15660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     * @return a new SocketFactory with the specified parameters
15760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor     */
15860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(
159ff5569948fda346d95d4615de6578f82d9614be3Jesse Wilson            int handshakeTimeoutMillis, SSLSessionCache cache) {
16060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return new org.apache.http.conn.ssl.SSLSocketFactory(
1619d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor                new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, true));
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1647fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    /**
1657fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * Verify the hostname of the certificate used by the other end of a
1667fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * connected socket.  You MUST call this if you did not supply a hostname
1677fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * to {@link #createSocket()}.  It is harmless to call this method
1687fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * redundantly if the hostname has already been verified.
1697fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
1707fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * <p>Wildcard certificates are allowed to verify any matching hostname,
1717fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * so "foo.bar.example.com" is verified if the peer has a certificate
1727fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * for "*.example.com".
1737fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
1747fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * @param socket An SSL socket which has been connected to a server
1757fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * @param hostname The expected hostname of the remote server
1767fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * @throws IOException if something goes wrong handshaking with the server
1777fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * @throws SSLPeerUnverifiedException if the server cannot prove its identity
1787fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
1797fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * @hide
1807fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     */
1817fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    public static void verifyHostname(Socket socket, String hostname) throws IOException {
1827fc93c36ae235115727296780dbc35101622bbd4Dan Egnor        if (!(socket instanceof SSLSocket)) {
1837fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            throw new IllegalArgumentException("Attempt to verify non-SSL socket");
1847fc93c36ae235115727296780dbc35101622bbd4Dan Egnor        }
1857fc93c36ae235115727296780dbc35101622bbd4Dan Egnor
1867fc93c36ae235115727296780dbc35101622bbd4Dan Egnor        if (!isSslCheckRelaxed()) {
1877fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            // The code at the start of OpenSSLSocketImpl.startHandshake()
1887fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            // ensures that the call is idempotent, so we can safely call it.
1897fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            SSLSocket ssl = (SSLSocket) socket;
1907fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            ssl.startHandshake();
1917fc93c36ae235115727296780dbc35101622bbd4Dan Egnor
1927fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            SSLSession session = ssl.getSession();
1937fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            if (session == null) {
1947fc93c36ae235115727296780dbc35101622bbd4Dan Egnor                throw new SSLException("Cannot verify SSL socket without session");
1957fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            }
1967fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            if (!HOSTNAME_VERIFIER.verify(hostname, session)) {
1977fc93c36ae235115727296780dbc35101622bbd4Dan Egnor                throw new SSLPeerUnverifiedException("Cannot verify hostname: " + hostname);
1987fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            }
1997fc93c36ae235115727296780dbc35101622bbd4Dan Egnor        }
2007fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    }
2017fc93c36ae235115727296780dbc35101622bbd4Dan Egnor
2021b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    private SSLSocketFactory makeSocketFactory(
2031b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo            KeyManager[] keyManagers, TrustManager[] trustManagers) {
20460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        try {
2053c7c351a6217ac48b741740167c201a679a0ca65Brian Carlstrom            OpenSSLContextImpl sslContext = new OpenSSLContextImpl();
2061b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo            sslContext.engineInit(keyManagers, trustManagers, null);
2072c42c8fbaf02be1f3ea6298077128d0c419526f0Brian Carlstrom            sslContext.engineGetClientSessionContext().setPersistentCache(mSessionCache);
20860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            return sslContext.engineGetSocketFactory();
20960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        } catch (KeyManagementException e) {
21060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            Log.wtf(TAG, e);
21160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            return (SSLSocketFactory) SSLSocketFactory.getDefault();  // Fallback
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2157fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    private static boolean isSslCheckRelaxed() {
2167fc93c36ae235115727296780dbc35101622bbd4Dan Egnor        return "1".equals(SystemProperties.get("ro.debuggable")) &&
2177fc93c36ae235115727296780dbc35101622bbd4Dan Egnor            "yes".equals(SystemProperties.get("socket.relaxsslcheck"));
2187fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    }
2197fc93c36ae235115727296780dbc35101622bbd4Dan Egnor
22060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    private synchronized SSLSocketFactory getDelegate() {
2219d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor        // Relax the SSL check if instructed (for this factory, or systemwide)
2227fc93c36ae235115727296780dbc35101622bbd4Dan Egnor        if (!mSecure || isSslCheckRelaxed()) {
22360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            if (mInsecureFactory == null) {
2249d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor                if (mSecure) {
2259d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor                    Log.w(TAG, "*** BYPASSING SSL SECURITY CHECKS (socket.relaxsslcheck=yes) ***");
2269d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor                } else {
2279d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor                    Log.w(TAG, "Bypassing SSL security checks at caller's request");
2289d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor                }
2291b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo                mInsecureFactory = makeSocketFactory(mKeyManagers, INSECURE_TRUST_MANAGER);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            return mInsecureFactory;
23260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        } else {
23360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            if (mSecureFactory == null) {
2341b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo                mSecureFactory = makeSocketFactory(mKeyManagers, mTrustManagers);
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            return mSecureFactory;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2407fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    /**
2411b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo     * Sets the {@link TrustManager}s to be used for connections made by this factory.
2421b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo     */
2431b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    public void setTrustManagers(TrustManager[] trustManager) {
2441b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        mTrustManagers = trustManager;
2451b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo
2461b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        // Clear out all cached secure factories since configurations have changed.
2471b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        mSecureFactory = null;
2481b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        // Note - insecure factories only ever use the INSECURE_TRUST_MANAGER so they need not
2491b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        // be cleared out here.
2501b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    }
2511b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo
2521b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    /**
253f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * Sets the <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next
254f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * Protocol Negotiation (NPN)</a> protocols that this peer is interested in.
255f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     *
256f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * <p>For servers this is the sequence of protocols to advertise as
257f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * supported, in order of preference. This list is sent unencrypted to
258f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * all clients that support NPN.
259f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     *
260f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * <p>For clients this is a list of supported protocols to match against the
261f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * server's list. If there is no protocol supported by both client and
262f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * server then the first protocol in the client's list will be selected.
263f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * The order of the client's protocols is otherwise insignificant.
264f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     *
2652108ead7f125536874d6de6ca1c0c4cffbf61b44Jesse Wilson     * @param npnProtocols a non-empty list of protocol byte arrays. All arrays
2662108ead7f125536874d6de6ca1c0c4cffbf61b44Jesse Wilson     *     must be non-empty and of length less than 256.
267f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     */
268f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    public void setNpnProtocols(byte[][] npnProtocols) {
269f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        this.mNpnProtocols = toNpnProtocolsList(npnProtocols);
270f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    }
271f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson
272f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    /**
273f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * Returns an array containing the concatenation of length-prefixed byte
274f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * strings.
275f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     */
276f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    static byte[] toNpnProtocolsList(byte[]... npnProtocols) {
2772108ead7f125536874d6de6ca1c0c4cffbf61b44Jesse Wilson        if (npnProtocols.length == 0) {
2782108ead7f125536874d6de6ca1c0c4cffbf61b44Jesse Wilson            throw new IllegalArgumentException("npnProtocols.length == 0");
2792108ead7f125536874d6de6ca1c0c4cffbf61b44Jesse Wilson        }
280f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        int totalLength = 0;
281f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        for (byte[] s : npnProtocols) {
282f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson            if (s.length == 0 || s.length > 255) {
283f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson                throw new IllegalArgumentException("s.length == 0 || s.length > 255: " + s.length);
284f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson            }
285f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson            totalLength += 1 + s.length;
286f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        }
287f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        byte[] result = new byte[totalLength];
288f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        int pos = 0;
289f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        for (byte[] s : npnProtocols) {
290f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson            result[pos++] = (byte) s.length;
291f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson            for (byte b : s) {
292f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson                result[pos++] = b;
293f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson            }
294f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        }
295f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        return result;
296f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    }
297f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson
298f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    /**
299f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * Returns the <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next
300f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * Protocol Negotiation (NPN)</a> protocol selected by client and server, or
301f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * null if no protocol was negotiated.
302f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     *
303f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     * @param socket a socket created by this factory.
304b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * @throws IllegalArgumentException if the socket was not created by this factory.
305f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson     */
306f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    public byte[] getNpnSelectedProtocol(Socket socket) {
307b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath        return castToOpenSSLSocket(socket).getNpnSelectedProtocol();
308f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    }
309f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson
310f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson    /**
3111b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo     * Sets the {@link KeyManager}s to be used for connections made by this factory.
3121b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo     */
3131b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    public void setKeyManagers(KeyManager[] keyManagers) {
3141b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        mKeyManagers = keyManagers;
3151b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo
3161b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        // Clear out any existing cached factories since configurations have changed.
3171b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        mSecureFactory = null;
3181b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo        mInsecureFactory = null;
3191b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    }
3201b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo
321b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath    /**
322b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * Enables <a href="http://tools.ietf.org/html/rfc5077#section-3.2">session ticket</a>
323b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * support on the given socket.
324b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     *
325b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * @param socket a socket created by this factory
326b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * @param useSessionTickets {@code true} to enable session ticket support on this socket.
327b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * @throws IllegalArgumentException if the socket was not created by this factory.
328b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     */
329b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath    public void setUseSessionTickets(Socket socket, boolean useSessionTickets) {
330b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath        castToOpenSSLSocket(socket).setUseSessionTickets(useSessionTickets);
331b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath    }
332b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath
333b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath    /**
334b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * Turns on <a href="http://tools.ietf.org/html/rfc6066#section-3">Server
335b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * Name Indication (SNI)</a> on a given socket.
336b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     *
337b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * @param socket a socket created by this factory.
338b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * @param hostName the desired SNI hostname, null to disable.
339b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     * @throws IllegalArgumentException if the socket was not created by this factory.
340b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath     */
341b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath    public void setHostname(Socket socket, String hostName) {
342b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath        castToOpenSSLSocket(socket).setHostname(hostName);
343b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath    }
344b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath
3457ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom    /**
3467ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom     * Sets this socket's SO_SNDTIMEO write timeout in milliseconds.
3477ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom     * Use 0 for no timeout.
3487ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom     * To take effect, this option must be set before the blocking method was called.
3497ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom     *
3507ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom     * @param socket a socket created by this factory.
351992f238d13fff7c21b60ef6958784a4ed2156784Brian Carlstrom     * @param timeout the desired write timeout in milliseconds.
3527ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom     * @throws IllegalArgumentException if the socket was not created by this factory.
353992f238d13fff7c21b60ef6958784a4ed2156784Brian Carlstrom     *
354992f238d13fff7c21b60ef6958784a4ed2156784Brian Carlstrom     * @hide
3557ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom     */
3567ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom    public void setSoWriteTimeout(Socket socket, int writeTimeoutMilliseconds)
3577ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom            throws SocketException {
3587ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom        castToOpenSSLSocket(socket).setSoWriteTimeout(writeTimeoutMilliseconds);
3597ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom    }
3607ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom
361b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath    private static OpenSSLSocketImpl castToOpenSSLSocket(Socket socket) {
362b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath        if (!(socket instanceof OpenSSLSocketImpl)) {
363b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath            throw new IllegalArgumentException("Socket not created by this factory: "
364b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath                    + socket);
365b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath        }
366b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath
367b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath        return (OpenSSLSocketImpl) socket;
368b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath    }
3691b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo
3701b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo    /**
3717fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * {@inheritDoc}
3727fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
373df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler     * <p>This method verifies the peer's certificate hostname after connecting
374df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler     * (unless created with {@link #getInsecure(int, SSLSessionCache)}).
3757fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     */
37660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    @Override
37760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public Socket createSocket(Socket k, String host, int port, boolean close) throws IOException {
37860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(k, host, port, close);
379f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        s.setNpnProtocols(mNpnProtocols);
38060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
381df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler        if (mSecure) {
382df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler            verifyHostname(s, host);
383df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler        }
38460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return s;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3877fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    /**
3887fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * Creates a new socket which is not connected to any remote host.
3897fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * You must use {@link Socket#connect} to connect the socket.
3907fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
3917fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * <p class="caution"><b>Warning:</b> Hostname verification is not performed
3927fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * with this method.  You MUST verify the server's identity after connecting
3937fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * the socket to avoid man-in-the-middle attacks.</p>
3947fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     */
39560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    @Override
39660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public Socket createSocket() throws IOException {
39760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket();
398f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        s.setNpnProtocols(mNpnProtocols);
39960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
40060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return s;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4037fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    /**
4047fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * {@inheritDoc}
4057fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
4067fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * <p class="caution"><b>Warning:</b> Hostname verification is not performed
4077fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * with this method.  You MUST verify the server's identity after connecting
4087fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * the socket to avoid man-in-the-middle attacks.</p>
4097fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     */
41060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    @Override
41160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public Socket createSocket(InetAddress addr, int port, InetAddress localAddr, int localPort)
41260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            throws IOException {
41360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
41460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor                addr, port, localAddr, localPort);
415f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        s.setNpnProtocols(mNpnProtocols);
41660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
41760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return s;
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4207fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    /**
4217fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * {@inheritDoc}
4227fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
4237fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * <p class="caution"><b>Warning:</b> Hostname verification is not performed
4247fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * with this method.  You MUST verify the server's identity after connecting
4257fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * the socket to avoid man-in-the-middle attacks.</p>
4267fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     */
42760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    @Override
42860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public Socket createSocket(InetAddress addr, int port) throws IOException {
42960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(addr, port);
430f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        s.setNpnProtocols(mNpnProtocols);
43160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
43260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return s;
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4357fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    /**
4367fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * {@inheritDoc}
4377fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
438df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler     * <p>This method verifies the peer's certificate hostname after connecting
439df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler     * (unless created with {@link #getInsecure(int, SSLSessionCache)}).
4407fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     */
44160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    @Override
44260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public Socket createSocket(String host, int port, InetAddress localAddr, int localPort)
44360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor            throws IOException {
44460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
44560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor                host, port, localAddr, localPort);
446f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        s.setNpnProtocols(mNpnProtocols);
44760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
448df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler        if (mSecure) {
449df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler            verifyHostname(s, host);
450df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler        }
45160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return s;
45260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    }
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4547fc93c36ae235115727296780dbc35101622bbd4Dan Egnor    /**
4557fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     * {@inheritDoc}
4567fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     *
457df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler     * <p>This method verifies the peer's certificate hostname after connecting
458df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler     * (unless created with {@link #getInsecure(int, SSLSessionCache)}).
4597fc93c36ae235115727296780dbc35101622bbd4Dan Egnor     */
46060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    @Override
46160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    public Socket createSocket(String host, int port) throws IOException {
46260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(host, port);
463f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson        s.setNpnProtocols(mNpnProtocols);
46460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        s.setHandshakeTimeout(mHandshakeTimeoutMillis);
465df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler        if (mSecure) {
466df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler            verifyHostname(s, host);
467df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler        }
46860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return s;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    @Override
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String[] getDefaultCipherSuites() {
47360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return getDelegate().getSupportedCipherSuites();
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor    @Override
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String[] getSupportedCipherSuites() {
47860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor        return getDelegate().getSupportedCipherSuites();
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
481