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