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; 21ed065024a59cf008ba711ff79e223ed99cb8b7c5John Reck 22ed065024a59cf008ba711ff79e223ed99cb8b7c5John Reckimport com.android.internal.os.RoSystemProperties; 237fdce769c3ef3885ec8f1716bdeedfc8b056a1d7Kenny Rootimport com.android.org.conscrypt.Conscrypt; 2412e752225aa96888358294be0d725d499a1c9f03Kenny Rootimport com.android.org.conscrypt.OpenSSLContextImpl; 2512e752225aa96888358294be0d725d499a1c9f03Kenny Rootimport com.android.org.conscrypt.OpenSSLSocketImpl; 2612e752225aa96888358294be0d725d499a1c9f03Kenny Rootimport com.android.org.conscrypt.SSLClientSessionCache; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.InetAddress; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.Socket; 307ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstromimport java.net.SocketException; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.KeyManagementException; 32ac5eb03a7c317e21573155b88641f4f1daef2eb9Alex Klyubinimport java.security.PrivateKey; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.cert.X509Certificate; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.SocketFactory; 357fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.HostnameVerifier; 367fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.HttpsURLConnection; 371b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komaloimport javax.net.ssl.KeyManager; 387fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.SSLException; 397fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.SSLPeerUnverifiedException; 407fc93c36ae235115727296780dbc35101622bbd4Dan Egnorimport javax.net.ssl.SSLSession; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.SSLSocket; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.SSLSocketFactory; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.TrustManager; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport javax.net.ssl.X509TrustManager; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 4760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * SSLSocketFactory implementation with several extra features: 487fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 4960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <ul> 5060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <li>Timeout specification for SSL handshake operations 517fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <li>Hostname verification in most cases (see WARNINGs below) 5260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * <li>Optional SSL session caching with {@link SSLSessionCache} 539d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * <li>Optionally bypass all SSL certificate checks 5460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * </ul> 557fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 567fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * The handshake timeout does not apply to actual TCP socket connection. 577fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * If you want a connection timeout as well, use {@link #createSocket()} 587fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * and {@link Socket#connect(SocketAddress, int)}, after which you 597fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * must verify the identity of the server you are connected to. 607fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 617fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p class="caution"><b>Most {@link SSLSocketFactory} implementations do not 627fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * verify the server's identity, allowing man-in-the-middle attacks.</b> 637fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * This implementation does check the server's certificate hostname, but only 647fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * for createSocket variants that specify a hostname. When using methods that 657fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * use {@link InetAddress} or which return an unconnected socket, you MUST 66f72e8263c7e08d3e4a04de29c17bbada2bd2829aJonathan Dormody * verify the server's identity yourself to ensure a secure connection. 67f72e8263c7e08d3e4a04de29c17bbada2bd2829aJonathan Dormody * 68f72e8263c7e08d3e4a04de29c17bbada2bd2829aJonathan Dormody * Refer to 69f72e8263c7e08d3e4a04de29c17bbada2bd2829aJonathan Dormody * <a href="https://developer.android.com/training/articles/security-gms-provider.html"> 70f72e8263c7e08d3e4a04de29c17bbada2bd2829aJonathan Dormody * Updating Your Security Provider to Protect Against SSL Exploits</a> 71f72e8263c7e08d3e4a04de29c17bbada2bd2829aJonathan Dormody * for further information.</p> 727fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 737fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p>One way to verify the server's identity is to use 747fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@link HttpsURLConnection#getDefaultHostnameVerifier()} to get a 757fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@link HostnameVerifier} to verify the certificate hostname. 767fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 777fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p>On development devices, "setprop socket.relaxsslcheck yes" bypasses all 787fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * SSL certificate and hostname checks for testing purposes. This setting 797fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * requires root access. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SSLCertificateSocketFactory extends SSLSocketFactory { 8260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private static final String TAG = "SSLCertificateSocketFactory"; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private static final TrustManager[] INSECURE_TRUST_MANAGER = new TrustManager[] { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new X509TrustManager() { 8660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public X509Certificate[] getAcceptedIssuers() { return null; } 8760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public void checkClientTrusted(X509Certificate[] certs, String authType) { } 8860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public void checkServerTrusted(X509Certificate[] certs, String authType) { } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private SSLSocketFactory mInsecureFactory = null; 9360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private SSLSocketFactory mSecureFactory = null; 941b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo private TrustManager[] mTrustManagers = null; 951b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo private KeyManager[] mKeyManagers = null; 96f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson private byte[] mNpnProtocols = null; 97100d7290264338c6536739abd59879aaaa812537Kenny Root private byte[] mAlpnProtocols = null; 98ac5eb03a7c317e21573155b88641f4f1daef2eb9Alex Klyubin private PrivateKey mChannelIdPrivateKey = null; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private final int mHandshakeTimeoutMillis; 10160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private final SSLClientSessionCache mSessionCache; 1029d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor private final boolean mSecure; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor /** @deprecated Use {@link #getDefault(int)} instead. */ 10528c742573ccaeb55c16bc02fb25fdd86b8d1f76aJesse Wilson @Deprecated 10660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public SSLCertificateSocketFactory(int handshakeTimeoutMillis) { 1079d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor this(handshakeTimeoutMillis, null, true); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor private SSLCertificateSocketFactory( 111992f238d13fff7c21b60ef6958784a4ed2156784Brian Carlstrom int handshakeTimeoutMillis, SSLSessionCache cache, boolean secure) { 11260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor mHandshakeTimeoutMillis = handshakeTimeoutMillis; 11360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor mSessionCache = cache == null ? null : cache.mSessionCache; 1149d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor mSecure = secure; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1189d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * Returns a new socket factory instance with an optional handshake timeout. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0 12160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * for none. The socket timeout is reset to 0 after the handshake. 1227fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * @return a new SSLSocketFactory with the specified parameters 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public static SocketFactory getDefault(int handshakeTimeoutMillis) { 1259d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor return new SSLCertificateSocketFactory(handshakeTimeoutMillis, null, true); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1299d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * Returns a new socket factory instance with an optional handshake timeout 1309d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * and SSL session cache. 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0 13360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * for none. The socket timeout is reset to 0 after the handshake. 134ff5569948fda346d95d4615de6578f82d9614be3Jesse Wilson * @param cache The {@link SSLSessionCache} to use, or null for no cache. 1357fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * @return a new SSLSocketFactory with the specified parameters 13660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor */ 1379d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor public static SSLSocketFactory getDefault(int handshakeTimeoutMillis, SSLSessionCache cache) { 1389d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, true); 1399d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor } 1409d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor 1419d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor /** 1429d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * Returns a new instance of a socket factory with all SSL security checks 1439d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * disabled, using an optional handshake timeout and SSL session cache. 1447fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 1457fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p class="caution"><b>Warning:</b> Sockets created using this factory 146e19ca078bf1778a344366672de020e63a80252a9Kenny Root * are vulnerable to man-in-the-middle attacks!</p> 1479d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * 1489d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0 1499d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor * for none. The socket timeout is reset to 0 after the handshake. 150ff5569948fda346d95d4615de6578f82d9614be3Jesse Wilson * @param cache The {@link SSLSessionCache} to use, or null for no cache. 1517fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * @return an insecure SSLSocketFactory with the specified parameters 1529d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor */ 1539d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor public static SSLSocketFactory getInsecure(int handshakeTimeoutMillis, SSLSessionCache cache) { 1549d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, false); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor /** 15860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * Returns a socket factory (also named SSLSocketFactory, but in a different 15960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * namespace) for use with the Apache HTTP stack. 16060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * 16160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0 16260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * for none. The socket timeout is reset to 0 after the handshake. 163ff5569948fda346d95d4615de6578f82d9614be3Jesse Wilson * @param cache The {@link SSLSessionCache} to use, or null for no cache. 16460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @return a new SocketFactory with the specified parameters 165823675fdbb7f974b8e2fa9fbb71774b32487582dNarayan Kamath * 166823675fdbb7f974b8e2fa9fbb71774b32487582dNarayan Kamath * @deprecated Use {@link #getDefault()} along with a {@link javax.net.ssl.HttpsURLConnection} 167823675fdbb7f974b8e2fa9fbb71774b32487582dNarayan Kamath * instead. The Apache HTTP client is no longer maintained and may be removed in a future 168823675fdbb7f974b8e2fa9fbb71774b32487582dNarayan Kamath * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 169823675fdbb7f974b8e2fa9fbb71774b32487582dNarayan Kamath * for further details. 170406e1ed9883010928cfb42246cfd2710ebf3da74Narayan Kamath * 171406e1ed9883010928cfb42246cfd2710ebf3da74Narayan Kamath * @removed 17260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor */ 173823675fdbb7f974b8e2fa9fbb71774b32487582dNarayan Kamath @Deprecated 17460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory( 175ff5569948fda346d95d4615de6578f82d9614be3Jesse Wilson int handshakeTimeoutMillis, SSLSessionCache cache) { 17660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return new org.apache.http.conn.ssl.SSLSocketFactory( 1779d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, true)); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1807fc93c36ae235115727296780dbc35101622bbd4Dan Egnor /** 1817fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * Verify the hostname of the certificate used by the other end of a 1827fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * connected socket. You MUST call this if you did not supply a hostname 1837fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * to {@link #createSocket()}. It is harmless to call this method 1847fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * redundantly if the hostname has already been verified. 1857fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 1867fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p>Wildcard certificates are allowed to verify any matching hostname, 1877fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * so "foo.bar.example.com" is verified if the peer has a certificate 1887fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * for "*.example.com". 1897fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 1907fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * @param socket An SSL socket which has been connected to a server 1917fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * @param hostname The expected hostname of the remote server 1927fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * @throws IOException if something goes wrong handshaking with the server 1937fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * @throws SSLPeerUnverifiedException if the server cannot prove its identity 1947fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 1957fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * @hide 1967fc93c36ae235115727296780dbc35101622bbd4Dan Egnor */ 1977fc93c36ae235115727296780dbc35101622bbd4Dan Egnor public static void verifyHostname(Socket socket, String hostname) throws IOException { 1987fc93c36ae235115727296780dbc35101622bbd4Dan Egnor if (!(socket instanceof SSLSocket)) { 1997fc93c36ae235115727296780dbc35101622bbd4Dan Egnor throw new IllegalArgumentException("Attempt to verify non-SSL socket"); 2007fc93c36ae235115727296780dbc35101622bbd4Dan Egnor } 2017fc93c36ae235115727296780dbc35101622bbd4Dan Egnor 2027fc93c36ae235115727296780dbc35101622bbd4Dan Egnor if (!isSslCheckRelaxed()) { 2037fc93c36ae235115727296780dbc35101622bbd4Dan Egnor // The code at the start of OpenSSLSocketImpl.startHandshake() 2047fc93c36ae235115727296780dbc35101622bbd4Dan Egnor // ensures that the call is idempotent, so we can safely call it. 2057fc93c36ae235115727296780dbc35101622bbd4Dan Egnor SSLSocket ssl = (SSLSocket) socket; 2067fc93c36ae235115727296780dbc35101622bbd4Dan Egnor ssl.startHandshake(); 2077fc93c36ae235115727296780dbc35101622bbd4Dan Egnor 2087fc93c36ae235115727296780dbc35101622bbd4Dan Egnor SSLSession session = ssl.getSession(); 2097fc93c36ae235115727296780dbc35101622bbd4Dan Egnor if (session == null) { 2107fc93c36ae235115727296780dbc35101622bbd4Dan Egnor throw new SSLException("Cannot verify SSL socket without session"); 2117fc93c36ae235115727296780dbc35101622bbd4Dan Egnor } 212928ee1e48fa89302d02fdf8a8a2c7315d7195e7cKenny Root if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session)) { 2137fc93c36ae235115727296780dbc35101622bbd4Dan Egnor throw new SSLPeerUnverifiedException("Cannot verify hostname: " + hostname); 2147fc93c36ae235115727296780dbc35101622bbd4Dan Egnor } 2157fc93c36ae235115727296780dbc35101622bbd4Dan Egnor } 2167fc93c36ae235115727296780dbc35101622bbd4Dan Egnor } 2177fc93c36ae235115727296780dbc35101622bbd4Dan Egnor 2181b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo private SSLSocketFactory makeSocketFactory( 2191b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo KeyManager[] keyManagers, TrustManager[] trustManagers) { 22060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor try { 2217fdce769c3ef3885ec8f1716bdeedfc8b056a1d7Kenny Root OpenSSLContextImpl sslContext = (OpenSSLContextImpl) Conscrypt.newPreferredSSLContextSpi(); 2221b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo sslContext.engineInit(keyManagers, trustManagers, null); 2232c42c8fbaf02be1f3ea6298077128d0c419526f0Brian Carlstrom sslContext.engineGetClientSessionContext().setPersistentCache(mSessionCache); 22460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return sslContext.engineGetSocketFactory(); 22560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor } catch (KeyManagementException e) { 22660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor Log.wtf(TAG, e); 22760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return (SSLSocketFactory) SSLSocketFactory.getDefault(); // Fallback 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2317fc93c36ae235115727296780dbc35101622bbd4Dan Egnor private static boolean isSslCheckRelaxed() { 232ed065024a59cf008ba711ff79e223ed99cb8b7c5John Reck return RoSystemProperties.DEBUGGABLE && 233ed065024a59cf008ba711ff79e223ed99cb8b7c5John Reck SystemProperties.getBoolean("socket.relaxsslcheck", false); 2347fc93c36ae235115727296780dbc35101622bbd4Dan Egnor } 2357fc93c36ae235115727296780dbc35101622bbd4Dan Egnor 23660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor private synchronized SSLSocketFactory getDelegate() { 2379d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor // Relax the SSL check if instructed (for this factory, or systemwide) 2387fc93c36ae235115727296780dbc35101622bbd4Dan Egnor if (!mSecure || isSslCheckRelaxed()) { 23960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor if (mInsecureFactory == null) { 2409d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor if (mSecure) { 2419d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor Log.w(TAG, "*** BYPASSING SSL SECURITY CHECKS (socket.relaxsslcheck=yes) ***"); 242e19ca078bf1778a344366672de020e63a80252a9Kenny Root } else { 243e19ca078bf1778a344366672de020e63a80252a9Kenny Root Log.w(TAG, "Bypassing SSL security checks at caller's request"); 2449d4b57545300c6de1722094404ae09bf0f6be937Dan Egnor } 2451b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo mInsecureFactory = makeSocketFactory(mKeyManagers, INSECURE_TRUST_MANAGER); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return mInsecureFactory; 24860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor } else { 24960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor if (mSecureFactory == null) { 2501b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo mSecureFactory = makeSocketFactory(mKeyManagers, mTrustManagers); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return mSecureFactory; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2567fc93c36ae235115727296780dbc35101622bbd4Dan Egnor /** 2571b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo * Sets the {@link TrustManager}s to be used for connections made by this factory. 2581b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo */ 2591b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo public void setTrustManagers(TrustManager[] trustManager) { 2601b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo mTrustManagers = trustManager; 2611b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo 2621b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo // Clear out all cached secure factories since configurations have changed. 2631b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo mSecureFactory = null; 2641b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo // Note - insecure factories only ever use the INSECURE_TRUST_MANAGER so they need not 2651b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo // be cleared out here. 2661b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo } 2671b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo 2681b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo /** 269f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * Sets the <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next 270f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * Protocol Negotiation (NPN)</a> protocols that this peer is interested in. 271f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * 272f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * <p>For servers this is the sequence of protocols to advertise as 273f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * supported, in order of preference. This list is sent unencrypted to 274f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * all clients that support NPN. 275f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * 276f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * <p>For clients this is a list of supported protocols to match against the 277f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * server's list. If there is no protocol supported by both client and 278f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * server then the first protocol in the client's list will be selected. 279f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * The order of the client's protocols is otherwise insignificant. 280f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * 2812108ead7f125536874d6de6ca1c0c4cffbf61b44Jesse Wilson * @param npnProtocols a non-empty list of protocol byte arrays. All arrays 2822108ead7f125536874d6de6ca1c0c4cffbf61b44Jesse Wilson * must be non-empty and of length less than 256. 283f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson */ 284f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson public void setNpnProtocols(byte[][] npnProtocols) { 285100d7290264338c6536739abd59879aaaa812537Kenny Root this.mNpnProtocols = toLengthPrefixedList(npnProtocols); 286100d7290264338c6536739abd59879aaaa812537Kenny Root } 287100d7290264338c6536739abd59879aaaa812537Kenny Root 288100d7290264338c6536739abd59879aaaa812537Kenny Root /** 289100d7290264338c6536739abd59879aaaa812537Kenny Root * Sets the 290100d7290264338c6536739abd59879aaaa812537Kenny Root * <a href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-01"> 291100d7290264338c6536739abd59879aaaa812537Kenny Root * Application Layer Protocol Negotiation (ALPN)</a> protocols that this peer 292100d7290264338c6536739abd59879aaaa812537Kenny Root * is interested in. 293100d7290264338c6536739abd59879aaaa812537Kenny Root * 294100d7290264338c6536739abd59879aaaa812537Kenny Root * <p>For servers this is the sequence of protocols to advertise as 295100d7290264338c6536739abd59879aaaa812537Kenny Root * supported, in order of preference. This list is sent unencrypted to 296100d7290264338c6536739abd59879aaaa812537Kenny Root * all clients that support ALPN. 297100d7290264338c6536739abd59879aaaa812537Kenny Root * 298100d7290264338c6536739abd59879aaaa812537Kenny Root * <p>For clients this is a list of supported protocols to match against the 299100d7290264338c6536739abd59879aaaa812537Kenny Root * server's list. If there is no protocol supported by both client and 300100d7290264338c6536739abd59879aaaa812537Kenny Root * server then the first protocol in the client's list will be selected. 301100d7290264338c6536739abd59879aaaa812537Kenny Root * The order of the client's protocols is otherwise insignificant. 302100d7290264338c6536739abd59879aaaa812537Kenny Root * 303100d7290264338c6536739abd59879aaaa812537Kenny Root * @param protocols a non-empty list of protocol byte arrays. All arrays 304100d7290264338c6536739abd59879aaaa812537Kenny Root * must be non-empty and of length less than 256. 305100d7290264338c6536739abd59879aaaa812537Kenny Root * @hide 306100d7290264338c6536739abd59879aaaa812537Kenny Root */ 307100d7290264338c6536739abd59879aaaa812537Kenny Root public void setAlpnProtocols(byte[][] protocols) { 308100d7290264338c6536739abd59879aaaa812537Kenny Root this.mAlpnProtocols = toLengthPrefixedList(protocols); 309f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson } 310f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson 311f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson /** 312f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * Returns an array containing the concatenation of length-prefixed byte 313f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * strings. 314f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson */ 315100d7290264338c6536739abd59879aaaa812537Kenny Root static byte[] toLengthPrefixedList(byte[]... items) { 316100d7290264338c6536739abd59879aaaa812537Kenny Root if (items.length == 0) { 317100d7290264338c6536739abd59879aaaa812537Kenny Root throw new IllegalArgumentException("items.length == 0"); 3182108ead7f125536874d6de6ca1c0c4cffbf61b44Jesse Wilson } 319f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson int totalLength = 0; 320100d7290264338c6536739abd59879aaaa812537Kenny Root for (byte[] s : items) { 321f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson if (s.length == 0 || s.length > 255) { 322f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson throw new IllegalArgumentException("s.length == 0 || s.length > 255: " + s.length); 323f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson } 324f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson totalLength += 1 + s.length; 325f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson } 326f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson byte[] result = new byte[totalLength]; 327f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson int pos = 0; 328100d7290264338c6536739abd59879aaaa812537Kenny Root for (byte[] s : items) { 329f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson result[pos++] = (byte) s.length; 330f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson for (byte b : s) { 331f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson result[pos++] = b; 332f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson } 333f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson } 334f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson return result; 335f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson } 336f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson 337f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson /** 338f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * Returns the <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next 339f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * Protocol Negotiation (NPN)</a> protocol selected by client and server, or 340f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * null if no protocol was negotiated. 341f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * 342f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson * @param socket a socket created by this factory. 343b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * @throws IllegalArgumentException if the socket was not created by this factory. 344f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson */ 345f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson public byte[] getNpnSelectedProtocol(Socket socket) { 346b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath return castToOpenSSLSocket(socket).getNpnSelectedProtocol(); 347f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson } 348f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson 349f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson /** 350100d7290264338c6536739abd59879aaaa812537Kenny Root * Returns the 351100d7290264338c6536739abd59879aaaa812537Kenny Root * <a href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-01">Application 352100d7290264338c6536739abd59879aaaa812537Kenny Root * Layer Protocol Negotiation (ALPN)</a> protocol selected by client and server, or null 353100d7290264338c6536739abd59879aaaa812537Kenny Root * if no protocol was negotiated. 354100d7290264338c6536739abd59879aaaa812537Kenny Root * 355100d7290264338c6536739abd59879aaaa812537Kenny Root * @param socket a socket created by this factory. 356100d7290264338c6536739abd59879aaaa812537Kenny Root * @throws IllegalArgumentException if the socket was not created by this factory. 357100d7290264338c6536739abd59879aaaa812537Kenny Root * @hide 358100d7290264338c6536739abd59879aaaa812537Kenny Root */ 359100d7290264338c6536739abd59879aaaa812537Kenny Root public byte[] getAlpnSelectedProtocol(Socket socket) { 360100d7290264338c6536739abd59879aaaa812537Kenny Root return castToOpenSSLSocket(socket).getAlpnSelectedProtocol(); 361100d7290264338c6536739abd59879aaaa812537Kenny Root } 362100d7290264338c6536739abd59879aaaa812537Kenny Root 363100d7290264338c6536739abd59879aaaa812537Kenny Root /** 3641b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo * Sets the {@link KeyManager}s to be used for connections made by this factory. 3651b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo */ 3661b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo public void setKeyManagers(KeyManager[] keyManagers) { 3671b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo mKeyManagers = keyManagers; 3681b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo 3691b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo // Clear out any existing cached factories since configurations have changed. 3701b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo mSecureFactory = null; 3711b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo mInsecureFactory = null; 3721b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo } 3731b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo 374b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath /** 375ac5eb03a7c317e21573155b88641f4f1daef2eb9Alex Klyubin * Sets the private key to be used for TLS Channel ID by connections made by this 3764ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin * factory. 3774ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin * 3784ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables 3794ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin * TLS Channel ID). The private key has to be an Elliptic Curve (EC) key based on the 3804ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin * NIST P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1). 3814ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin * 3824ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin * @hide 3834ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin */ 384ac5eb03a7c317e21573155b88641f4f1daef2eb9Alex Klyubin public void setChannelIdPrivateKey(PrivateKey privateKey) { 3854ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin mChannelIdPrivateKey = privateKey; 3864ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin } 3874ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin 3884ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin /** 389b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * Enables <a href="http://tools.ietf.org/html/rfc5077#section-3.2">session ticket</a> 390b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * support on the given socket. 391b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * 392b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * @param socket a socket created by this factory 393b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * @param useSessionTickets {@code true} to enable session ticket support on this socket. 394b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * @throws IllegalArgumentException if the socket was not created by this factory. 395b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath */ 396b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath public void setUseSessionTickets(Socket socket, boolean useSessionTickets) { 397b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath castToOpenSSLSocket(socket).setUseSessionTickets(useSessionTickets); 398b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath } 399b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath 400b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath /** 401b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * Turns on <a href="http://tools.ietf.org/html/rfc6066#section-3">Server 402b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * Name Indication (SNI)</a> on a given socket. 403b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * 404b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * @param socket a socket created by this factory. 405b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * @param hostName the desired SNI hostname, null to disable. 406b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath * @throws IllegalArgumentException if the socket was not created by this factory. 407b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath */ 408b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath public void setHostname(Socket socket, String hostName) { 409b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath castToOpenSSLSocket(socket).setHostname(hostName); 410b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath } 411b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath 4127ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom /** 4137ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom * Sets this socket's SO_SNDTIMEO write timeout in milliseconds. 4147ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom * Use 0 for no timeout. 4157ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom * To take effect, this option must be set before the blocking method was called. 4167ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom * 4177ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom * @param socket a socket created by this factory. 418992f238d13fff7c21b60ef6958784a4ed2156784Brian Carlstrom * @param timeout the desired write timeout in milliseconds. 4197ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom * @throws IllegalArgumentException if the socket was not created by this factory. 420992f238d13fff7c21b60ef6958784a4ed2156784Brian Carlstrom * 421992f238d13fff7c21b60ef6958784a4ed2156784Brian Carlstrom * @hide 4227ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom */ 4237ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom public void setSoWriteTimeout(Socket socket, int writeTimeoutMilliseconds) 4247ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom throws SocketException { 4257ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom castToOpenSSLSocket(socket).setSoWriteTimeout(writeTimeoutMilliseconds); 4267ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom } 4277ab7a8b582b29d34ec0fdbd0c727e225f350bb30Brian Carlstrom 428b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath private static OpenSSLSocketImpl castToOpenSSLSocket(Socket socket) { 429b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath if (!(socket instanceof OpenSSLSocketImpl)) { 430b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath throw new IllegalArgumentException("Socket not created by this factory: " 431b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath + socket); 432b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath } 433b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath 434b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath return (OpenSSLSocketImpl) socket; 435b4db962da0fecd9a6f2714148bbdea023610842fNarayan Kamath } 4361b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo 4371b52806e21270ccbe90d27f3dd93cbee1a81d09eBen Komalo /** 4387fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@inheritDoc} 4397fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 440df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler * <p>This method verifies the peer's certificate hostname after connecting 441df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler * (unless created with {@link #getInsecure(int, SSLSessionCache)}). 4427fc93c36ae235115727296780dbc35101622bbd4Dan Egnor */ 44360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 44460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(Socket k, String host, int port, boolean close) throws IOException { 44560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(k, host, port, close); 446f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson s.setNpnProtocols(mNpnProtocols); 447100d7290264338c6536739abd59879aaaa812537Kenny Root s.setAlpnProtocols(mAlpnProtocols); 44860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 4494ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin s.setChannelIdPrivateKey(mChannelIdPrivateKey); 450df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler if (mSecure) { 451df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler verifyHostname(s, host); 452df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler } 45360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4567fc93c36ae235115727296780dbc35101622bbd4Dan Egnor /** 4577fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * Creates a new socket which is not connected to any remote host. 4587fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * You must use {@link Socket#connect} to connect the socket. 4597fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 4607fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p class="caution"><b>Warning:</b> Hostname verification is not performed 4617fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * with this method. You MUST verify the server's identity after connecting 4627fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * the socket to avoid man-in-the-middle attacks.</p> 4637fc93c36ae235115727296780dbc35101622bbd4Dan Egnor */ 46460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 46560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket() throws IOException { 46660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(); 467f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson s.setNpnProtocols(mNpnProtocols); 468100d7290264338c6536739abd59879aaaa812537Kenny Root s.setAlpnProtocols(mAlpnProtocols); 46960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 4704ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin s.setChannelIdPrivateKey(mChannelIdPrivateKey); 47160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4747fc93c36ae235115727296780dbc35101622bbd4Dan Egnor /** 4757fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@inheritDoc} 4767fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 4777fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p class="caution"><b>Warning:</b> Hostname verification is not performed 4787fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * with this method. You MUST verify the server's identity after connecting 4797fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * the socket to avoid man-in-the-middle attacks.</p> 4807fc93c36ae235115727296780dbc35101622bbd4Dan Egnor */ 48160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 48260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(InetAddress addr, int port, InetAddress localAddr, int localPort) 48360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor throws IOException { 48460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket( 48560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor addr, port, localAddr, localPort); 486f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson s.setNpnProtocols(mNpnProtocols); 487100d7290264338c6536739abd59879aaaa812537Kenny Root s.setAlpnProtocols(mAlpnProtocols); 48860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 4894ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin s.setChannelIdPrivateKey(mChannelIdPrivateKey); 49060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4937fc93c36ae235115727296780dbc35101622bbd4Dan Egnor /** 4947fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@inheritDoc} 4957fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 4967fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * <p class="caution"><b>Warning:</b> Hostname verification is not performed 4977fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * with this method. You MUST verify the server's identity after connecting 4987fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * the socket to avoid man-in-the-middle attacks.</p> 4997fc93c36ae235115727296780dbc35101622bbd4Dan Egnor */ 50060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 50160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(InetAddress addr, int port) throws IOException { 50260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(addr, port); 503f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson s.setNpnProtocols(mNpnProtocols); 504100d7290264338c6536739abd59879aaaa812537Kenny Root s.setAlpnProtocols(mAlpnProtocols); 50560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 5064ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin s.setChannelIdPrivateKey(mChannelIdPrivateKey); 50760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5107fc93c36ae235115727296780dbc35101622bbd4Dan Egnor /** 5117fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@inheritDoc} 5127fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 513df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler * <p>This method verifies the peer's certificate hostname after connecting 514df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler * (unless created with {@link #getInsecure(int, SSLSessionCache)}). 5157fc93c36ae235115727296780dbc35101622bbd4Dan Egnor */ 51660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 51760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(String host, int port, InetAddress localAddr, int localPort) 51860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor throws IOException { 51960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket( 52060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor host, port, localAddr, localPort); 521f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson s.setNpnProtocols(mNpnProtocols); 522100d7290264338c6536739abd59879aaaa812537Kenny Root s.setAlpnProtocols(mAlpnProtocols); 52360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 5244ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin s.setChannelIdPrivateKey(mChannelIdPrivateKey); 525df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler if (mSecure) { 526df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler verifyHostname(s, host); 527df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler } 52860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 52960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5317fc93c36ae235115727296780dbc35101622bbd4Dan Egnor /** 5327fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * {@inheritDoc} 5337fc93c36ae235115727296780dbc35101622bbd4Dan Egnor * 534df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler * <p>This method verifies the peer's certificate hostname after connecting 535df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler * (unless created with {@link #getInsecure(int, SSLSessionCache)}). 5367fc93c36ae235115727296780dbc35101622bbd4Dan Egnor */ 53760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 53860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public Socket createSocket(String host, int port) throws IOException { 53960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(host, port); 540f5fb5e80963abeabdf0ff10dcee068344235082eJesse Wilson s.setNpnProtocols(mNpnProtocols); 541100d7290264338c6536739abd59879aaaa812537Kenny Root s.setAlpnProtocols(mAlpnProtocols); 54260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor s.setHandshakeTimeout(mHandshakeTimeoutMillis); 5434ef6c9b6a16c9b65699705aaa64977fc60dd3331Alex Klyubin s.setChannelIdPrivateKey(mChannelIdPrivateKey); 544df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler if (mSecure) { 545df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler verifyHostname(s, host); 546df27c0c26209fe04de332497beafcafc1fbaad2bAndrew Stadler } 54760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return s; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String[] getDefaultCipherSuites() { 552019118af67c60448030540deca37d972c8839d38Alex Klyubin return getDelegate().getDefaultCipherSuites(); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor @Override 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String[] getSupportedCipherSuites() { 55760586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return getDelegate().getSupportedCipherSuites(); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 560