OpenSSLSocketImpl.java revision ed2760e0dea39695b164af6d07ea9860e7c1fa49
108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project/* 208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * you may not use this file except in compliance with the License. 608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * You may obtain a copy of the License at 708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 1008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * See the License for the specific language governing permissions and 1408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * limitations under the License. 1508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 1608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 1708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectpackage org.apache.harmony.xnet.provider.jsse; 1808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 19ed2760e0dea39695b164af6d07ea9860e7c1fa49Brad Fitzpatrickimport dalvik.system.BlockGuard; 2008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.io.IOException; 2108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.io.InputStream; 2208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.io.OutputStream; 2308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.net.InetAddress; 2408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.net.Socket; 2508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.net.SocketException; 2698ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstromimport java.security.PrivateKey; 2798ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstromimport java.security.SecureRandom; 281f42e0a4d7d28b8fc20833e0be05ad17dcfa8ea0Brian Carlstromimport java.security.cert.CertificateEncodingException; 2908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.security.cert.CertificateException; 3008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.security.cert.X509Certificate; 3108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.util.ArrayList; 32f7923f6b146ae1a750fb733cf03f9db27e68b5dacrazybobimport java.util.concurrent.atomic.AtomicInteger; 3308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport java.util.logging.Logger; 3408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport javax.net.ssl.HandshakeCompletedEvent; 3508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport javax.net.ssl.HandshakeCompletedListener; 3608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport javax.net.ssl.SSLException; 372828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstromimport javax.net.ssl.SSLPeerUnverifiedException; 3808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport javax.net.ssl.SSLSession; 3998a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstromimport javax.security.auth.x500.X500Principal; 4008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport org.apache.harmony.security.provider.cert.X509CertImpl; 4108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 4208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project/** 430b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * Implementation of the class OpenSSLSocketImpl based on OpenSSL. 440b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * <p> 4508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This class only supports SSLv3 and TLSv1. This should be documented elsewhere 46f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * later, for example in the package.html or a separate reference document. 470b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * <p> 480b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * Extensions to SSLSocket include: 490b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * <ul> 500b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * <li>handshake timeout 510b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * <li>compression methods 520b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * <li>session tickets 530b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * <li>Server Name Indication 540b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * </ul> 5508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 56f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrompublic class OpenSSLSocketImpl 57f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom extends javax.net.ssl.SSLSocket 5898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom implements NativeCrypto.SSLHandshakeCallbacks { 59f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom private int sslNativePointer; 6008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private InputStream is; 6108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private OutputStream os; 6208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private final Object handshakeLock = new Object(); 63f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom private final Object readLock = new Object(); 64f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom private final Object writeLock = new Object(); 6508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private SSLParameters sslParameters; 662828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom private String[] enabledProtocols; 672828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom private String[] enabledCipherSuites; 680b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom private String[] enabledCompressionMethods; 690b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom private boolean useSessionTickets; 700b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom private String hostname; 7108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private OpenSSLSessionImpl sslSession; 7208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private Socket socket; 7308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private boolean autoClose; 7408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private boolean handshakeStarted = false; 752828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 762828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom /** 772828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * Not set to true until the update from native that tells us the 782828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * full handshake is complete, since SSL_do_handshake can return 792828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * before the handshake is completely done due to 802828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * handshake_cutthrough support. 812828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom */ 822828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom private boolean handshakeCompleted = false; 832828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 8408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private ArrayList<HandshakeCompletedListener> listeners; 8508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private int timeout = 0; 86331900211d05cd282141a3a50cb1db626f418b2cDan Egnor // BEGIN android-added 87331900211d05cd282141a3a50cb1db626f418b2cDan Egnor private int handshakeTimeout = -1; // -1 = same as timeout; 0 = infinite 88331900211d05cd282141a3a50cb1db626f418b2cDan Egnor // END android-added 896e0361de414915ae9929f55f6a8e0266a67506efBrian Carlstrom private String wrappedHost; 906e0361de414915ae9929f55f6a8e0266a67506efBrian Carlstrom private int wrappedPort; 9108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 92f7923f6b146ae1a750fb733cf03f9db27e68b5dacrazybob private static final AtomicInteger instanceCount = new AtomicInteger(0); 9308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 9408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public static int getInstanceCount() { 95f7923f6b146ae1a750fb733cf03f9db27e68b5dacrazybob return instanceCount.get(); 9608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 9708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 9808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private static void updateInstanceCount(int amount) { 99f7923f6b146ae1a750fb733cf03f9db27e68b5dacrazybob instanceCount.addAndGet(amount); 10008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 10108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 10208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 10308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Class constructor with 1 parameter 10408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 10508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param sslParameters Parameters for the SSL 10608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * context 10708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IOException if network fails 10808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 10908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project protected OpenSSLSocketImpl(SSLParameters sslParameters) throws IOException { 11008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super(); 111f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom init(sslParameters); 11208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 11308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 11408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 1152828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * Create an OpenSSLSocketImpl from an OpenSSLServerSocketImpl 1162828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * 1172828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * @param sslParameters Parameters for the SSL 1182828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * context 1192828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * @throws IOException if network fails 1202828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom */ 1212828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom protected OpenSSLSocketImpl(SSLParameters sslParameters, 1222828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom String[] enabledProtocols, 1230b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom String[] enabledCipherSuites, 1240b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom String[] enabledCompressionMethods) throws IOException { 1252828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom super(); 1260b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom init(sslParameters, enabledProtocols, enabledCipherSuites, enabledCompressionMethods); 1272828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 1282828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 1292828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom /** 13008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Class constructor with 3 parameters 13108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 13208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IOException if network fails 13308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws java.net.UnknownHostException host not defined 13408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 135c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom protected OpenSSLSocketImpl(String host, int port, SSLParameters sslParameters) 13608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throws IOException { 13708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super(host, port); 138f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom init(sslParameters); 13908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 14008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 14108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 14208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Class constructor with 3 parameters: 1st is InetAddress 14308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 14408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IOException if network fails 14508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws java.net.UnknownHostException host not defined 14608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 147c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom protected OpenSSLSocketImpl(InetAddress address, int port, SSLParameters sslParameters) 14808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throws IOException { 14908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super(address, port); 150f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom init(sslParameters); 15108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 15208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 15308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 15408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 15508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Class constructor with 5 parameters: 1st is host 15608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 15708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IOException if network fails 15808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws java.net.UnknownHostException host not defined 15908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 160c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom protected OpenSSLSocketImpl(String host, int port, 161c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom InetAddress clientAddress, int clientPort, 162c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom SSLParameters sslParameters) 16308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throws IOException { 16408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super(host, port, clientAddress, clientPort); 165f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom init(sslParameters); 16608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 16708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 16808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 16908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Class constructor with 5 parameters: 1st is InetAddress 17008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 17108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IOException if network fails 17208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws java.net.UnknownHostException host not defined 17308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 17408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project protected OpenSSLSocketImpl(InetAddress address, int port, 175c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom InetAddress clientAddress, int clientPort, 176c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom SSLParameters sslParameters) 17708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throws IOException { 17808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super(address, port, clientAddress, clientPort); 179f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom init(sslParameters); 18008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 18108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 18208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 18308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Constructor with 5 parameters: 1st is socket. Enhances an existing socket 1846e0361de414915ae9929f55f6a8e0266a67506efBrian Carlstrom * with SSL functionality. Invoked via OpenSSLSocketImplWrapper constructor. 18508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 18608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IOException if network fails 18708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 18808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project protected OpenSSLSocketImpl(Socket socket, String host, int port, 18908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project boolean autoClose, SSLParameters sslParameters) throws IOException { 19008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super(); 19108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project this.socket = socket; 19208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project this.timeout = socket.getSoTimeout(); 1936e0361de414915ae9929f55f6a8e0266a67506efBrian Carlstrom this.wrappedHost = host; 1946e0361de414915ae9929f55f6a8e0266a67506efBrian Carlstrom this.wrappedPort = port; 19508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project this.autoClose = autoClose; 196f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom init(sslParameters); 197f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 198f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom 199f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom /** 200f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * Initialize the SSL socket and set the certificates for the 201f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * future handshaking. 202f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom */ 203f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom private void init(SSLParameters sslParameters) throws IOException { 2042828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom init(sslParameters, 2052828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom NativeCrypto.getSupportedProtocols(), 2060b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom NativeCrypto.getDefaultCipherSuites(), 2070b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom NativeCrypto.getDefaultCompressionMethods()); 208f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 209f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom 210f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom /** 2112828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * Initialize the SSL socket and set the certificates for the 2122828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * future handshaking. 213f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom */ 2142828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom private void init(SSLParameters sslParameters, 2152828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom String[] enabledProtocols, 2160b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom String[] enabledCipherSuites, 2170b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom String[] enabledCompressionMethods) throws IOException { 2182828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom this.sslParameters = sslParameters; 2192828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom this.enabledProtocols = enabledProtocols; 2202828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom this.enabledCipherSuites = enabledCipherSuites; 2210b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom this.enabledCompressionMethods = enabledCompressionMethods; 22208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project updateInstanceCount(1); 22308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 22408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 22508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 22608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Gets the suitable session reference from the session cache container. 22708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 22808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return OpenSSLSessionImpl 22908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 2302828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom private OpenSSLSessionImpl getCachedClientSession(ClientSessionContext sessionContext) { 23108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (super.getInetAddress() == null || 23208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super.getInetAddress().getHostAddress() == null || 23308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super.getInetAddress().getHostName() == null) { 23408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return null; 23508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 23661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom OpenSSLSessionImpl session = (OpenSSLSessionImpl) sessionContext.getSession( 23708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super.getInetAddress().getHostName(), 23808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super.getPort()); 23961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (session == null) { 24061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom return null; 24161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 24261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom 24361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom String protocol = session.getProtocol(); 24461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom boolean protocolFound = false; 24561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom for (String enabledProtocol : enabledProtocols) { 24661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (protocol.equals(enabledProtocol)) { 24761b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom protocolFound = true; 24861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom break; 24961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 25061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 25161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (!protocolFound) { 25261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom return null; 25361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 25461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom 25561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom String cipherSuite = session.getCipherSuite(); 25661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom boolean cipherSuiteFound = false; 25761b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom for (String enabledCipherSuite : enabledCipherSuites) { 25861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (cipherSuite.equals(enabledCipherSuite)) { 25961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom cipherSuiteFound = true; 26061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom break; 26161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 26261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 26361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (!cipherSuiteFound) { 26461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom return null; 26561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 26698ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 2670b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom String compressionMethod = session.getCompressionMethod(); 2680b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom boolean compressionMethodFound = false; 2690b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom for (String enabledCompressionMethod : enabledCompressionMethods) { 2700b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom if (compressionMethod.equals(enabledCompressionMethod)) { 2710b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom compressionMethodFound = true; 2720b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom break; 2730b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 2740b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 2750b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom if (!compressionMethodFound) { 2760b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom return null; 2770b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 2780b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom 27961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom return session; 28008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 28108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 28208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 28308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Ensures that logger is lazily loaded. The outer class seems to load 28408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * before logging is ready. 28508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 28608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project static class LoggerHolder { 287f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom static final Logger logger = Logger.getLogger(OpenSSLSocketImpl.class.getName()); 28808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 28908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 29008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 29108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Starts a TLS/SSL handshake on this connection using some native methods 29208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * from the OpenSSL library. It can negotiate new encryption keys, change 29308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * cipher suites, or initiate a new session. The certificate chain is 29408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * verified if the correspondent property in java.Security is set. All 295f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * listeners are notified at the end of the TLS/SSL handshake. 29608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 29708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws <code>IOException</code> if network fails 29808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 2990b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 3002828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom public void startHandshake() throws IOException { 3012828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom startHandshake(true); 3022828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 3032828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 3042828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom /** 305a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom * Checks whether the socket is closed, and throws an exception. 306a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom * 307a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom * @throws SocketException 308a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom * if the socket is closed. 309a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom */ 310a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom private void checkOpen() throws SocketException { 311a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom if (isClosed()) { 312a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom throw new SocketException("Socket is closed"); 313a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom } 314a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom } 315a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom 316a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom /** 3172828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * Perform the handshake 3182828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * @param full If true, disable handshake cutthrough for a fully synchronous handshake 3192828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom */ 3202828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom public synchronized void startHandshake(boolean full) throws IOException { 321a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom checkOpen(); 32208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project synchronized (handshakeLock) { 32308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (!handshakeStarted) { 32408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project handshakeStarted = true; 32508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } else { 32608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return; 32708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 32808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 32908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 33098ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom // note that this modifies the global seed, not something specific to the connection 33198ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom final int seedLengthInBytes = NativeCrypto.RAND_SEED_LENGTH_IN_BYTES; 33298ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom final SecureRandom secureRandom = sslParameters.getSecureRandomMember(); 33398ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom if (secureRandom == null) { 33498ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom NativeCrypto.RAND_load_file("/dev/urandom", seedLengthInBytes); 33598ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom } else { 33698ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom NativeCrypto.RAND_seed(secureRandom.generateSeed(seedLengthInBytes)); 33798ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom } 33898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 33998ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom final boolean client = sslParameters.getUseClientMode(); 34098ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 34198ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom final int sslCtxNativePointer = (client) ? 34298ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom sslParameters.getClientSessionContext().sslCtxNativePointer : 34398ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom sslParameters.getServerSessionContext().sslCtxNativePointer; 34498ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 34598ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom this.sslNativePointer = NativeCrypto.SSL_new(sslCtxNativePointer); 34698ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 34798ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom // setup server certificates and private keys. 34898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom // clients will receive a call back to request certificates. 34998ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom if (!client) { 35098ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom for (String keyType : NativeCrypto.KEY_TYPES) { 351f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom try { 352f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom setCertificate(sslParameters.getKeyManager().chooseServerAlias(keyType, 353f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom null, 354f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom this)); 355f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } catch (CertificateEncodingException e) { 356f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom throw new IOException(e); 357f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 35898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom } 35998ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom } 36098ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 3612828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom NativeCrypto.setEnabledProtocols(sslNativePointer, enabledProtocols); 3622828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom NativeCrypto.setEnabledCipherSuites(sslNativePointer, enabledCipherSuites); 3630b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom if (enabledCompressionMethods.length != 0) { 3640b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom NativeCrypto.setEnabledCompressionMethods(sslNativePointer, enabledCompressionMethods); 3650b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 3660b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom if (useSessionTickets) { 3670b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom NativeCrypto.SSL_clear_options(sslNativePointer, NativeCrypto.SSL_OP_NO_TICKET); 3680b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 3690b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom if (hostname != null) { 3700b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom NativeCrypto.SSL_set_tlsext_host_name(sslNativePointer, hostname); 3710b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 3722828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 3732828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom boolean enableSessionCreation = sslParameters.getEnableSessionCreation(); 3742828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (!enableSessionCreation) { 3752828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer, 3762828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom enableSessionCreation); 3772828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 3782828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 3792828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom AbstractSessionContext sessionContext; 3802828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom OpenSSLSessionImpl session; 3812828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (client) { 3822828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // look for client session to reuse 3832828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom ClientSessionContext clientSessionContext = sslParameters.getClientSessionContext(); 3842828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom sessionContext = clientSessionContext; 3852828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom session = getCachedClientSession(clientSessionContext); 3862828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (session != null) { 3872828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom NativeCrypto.SSL_set_session(sslNativePointer, session.sslSessionNativePointer); 3882828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 3892828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } else { 3902828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom sessionContext = sslParameters.getServerSessionContext(); 3912828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom session = null; 3922828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 3932828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 3942828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // setup peer certificate verification 3952828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (client) { 39698ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom // TODO support for anonymous cipher would require us to 39798ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom // conditionally use SSL_VERIFY_NONE 3982828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } else { 3992828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // needing client auth takes priority... 400f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom boolean certRequested = false; 4012828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (sslParameters.getNeedClientAuth()) { 4022828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom NativeCrypto.SSL_set_verify(sslNativePointer, 403f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom NativeCrypto.SSL_VERIFY_PEER 404f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT); 405f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom certRequested = true; 4062828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // ... over just wanting it... 4072828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } else if (sslParameters.getWantClientAuth()) { 4082828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom NativeCrypto.SSL_set_verify(sslNativePointer, 40956f7ba2c845a74b0f6d1ec662b36776fa636dd67Brian Carlstrom NativeCrypto.SSL_VERIFY_PEER); 410f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom certRequested = true; 4112828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // ... and it defaults properly so we don't need call SSL_set_verify in the common case. 412f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } else { 413f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom certRequested = false; 414f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 41598a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom 416f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom if (certRequested) { 417f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom X509Certificate[] issuers = sslParameters.getTrustManager().getAcceptedIssuers(); 418f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom if (issuers != null) { 419f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom byte[][] issuersBytes; 420f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom try { 421f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom issuersBytes = NativeCrypto.encodeIssuerX509Principals(issuers); 422f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } catch (CertificateEncodingException e) { 423f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom throw new IOException("Problem encoding principals", e); 424f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 425f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom NativeCrypto.SSL_set_client_CA_list(sslNativePointer, issuersBytes); 426f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 427f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 4282828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 4292828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 4302828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (client && full) { 4312828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // we want to do a full synchronous handshake, so turn off cutthrough 43298ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom NativeCrypto.SSL_clear_mode(sslNativePointer, 43398ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH); 434f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 435f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom 436f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom // BEGIN android-added 437f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom // Temporarily use a different timeout for the handshake process 438f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom int savedTimeout = timeout; 439f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom if (handshakeTimeout >= 0) { 440f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom setSoTimeout(handshakeTimeout); 441f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 442f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom // END android-added 443f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom 4442828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 445f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom Socket socket = this.socket != null ? this.socket : this; 4462828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom int sslSessionNativePointer; 4472828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom try { 44898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom sslSessionNativePointer 44998ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom = NativeCrypto.SSL_do_handshake(sslNativePointer, socket, this, timeout, client); 4502828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } catch (CertificateException e) { 4512828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom throw new SSLPeerUnverifiedException(e.getMessage()); 4522828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 453743b57452909b1734068f9bd22f87f45d48fe87bBrian Carlstrom byte[] sessionId = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer); 4542828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom sslSession = (OpenSSLSessionImpl) sessionContext.getSession(sessionId); 4552828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (sslSession != null) { 45661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom sslSession.lastAccessedTime = System.currentTimeMillis(); 457f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom LoggerHolder.logger.fine("Reused cached session for " 4582828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom + getInetAddress() + "."); 459743b57452909b1734068f9bd22f87f45d48fe87bBrian Carlstrom NativeCrypto.SSL_SESSION_free(sslSessionNativePointer); 46008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } else { 4612828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (!enableSessionCreation) { 4622828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // Should have been prevented by NativeCrypto.SSL_set_session_creation_enabled 4632828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom throw new IllegalStateException("SSL Session may not be created"); 4642828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 4652828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom byte[][] localCertificatesBytes = NativeCrypto.SSL_get_certificate(sslNativePointer); 4662828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom X509Certificate[] localCertificates; 4672828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (localCertificatesBytes == null) { 4682828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom localCertificates = null; 46908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } else { 4702828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom localCertificates = new X509Certificate[localCertificatesBytes.length]; 4712828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom for (int i = 0; i < localCertificatesBytes.length; i++) { 47298a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom localCertificates[i] = new X509CertImpl(localCertificatesBytes[i]); 4732828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 474f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 47508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 4766e0361de414915ae9929f55f6a8e0266a67506efBrian Carlstrom if (wrappedHost == null) { 4772828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates, 478f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom super.getInetAddress().getHostName(), 479f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom super.getPort(), sessionContext); 480f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } else { 4812828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates, 4826e0361de414915ae9929f55f6a8e0266a67506efBrian Carlstrom wrappedHost, wrappedPort, 483f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom sessionContext); 484f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 485c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom // if not, putSession later in handshakeCompleted() callback 4862828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (handshakeCompleted) { 487f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom sessionContext.putSession(sslSession); 488331900211d05cd282141a3a50cb1db626f418b2cDan Egnor } 4892828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom LoggerHolder.logger.fine("Created new session for " 4902828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom + getInetAddress().getHostName() + "."); 49108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 49208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 493f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom // BEGIN android-added 494f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom // Restore the original timeout now that the handshake is complete 495f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom if (handshakeTimeout >= 0) { 496f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom setSoTimeout(savedTimeout); 497f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 498f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom // END android-added 499f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom 500c7eac25a7d55812eaaecd8a8a5cdaac3a28b2bf5Brian Carlstrom // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback 5012828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (handshakeCompleted) { 5022828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom notifyHandshakeCompletedListeners(); 50308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 50408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 5052828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 50608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 507f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom private void setCertificate(String alias) throws CertificateEncodingException, SSLException { 50898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom if (alias == null) { 50998ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom return; 51098ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom } 51198ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 51298ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias); 5131f42e0a4d7d28b8fc20833e0be05ad17dcfa8ea0Brian Carlstrom byte[] privateKeyBytes = privateKey.getEncoded(); 51498ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom NativeCrypto.SSL_use_PrivateKey(sslNativePointer, privateKeyBytes); 51598ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 51698ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias); 517f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom byte[][] certificateBytes = NativeCrypto.encodeCertificates(certificates); 51898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom NativeCrypto.SSL_use_certificate(sslNativePointer, certificateBytes); 51998ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 52098ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom // checks the last installed private key and certificate, 52198ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom // so need to do this once per loop iteration 52298ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom NativeCrypto.SSL_check_private_key(sslNativePointer); 52398ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom } 52498ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 52598ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom /** 52698ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 52798ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom * invoked via JNI from client_cert_cb 52898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom */ 52998a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) 530f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom throws CertificateEncodingException, SSLException { 53198a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom 53298a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom String[] keyTypes = new String[keyTypeBytes.length]; 53398a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom for (int i = 0; i < keyTypeBytes.length; i++) { 53498a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom keyTypes[i] = NativeCrypto.keyType(keyTypeBytes[i]); 53598a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom } 53698a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom 53798a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom X500Principal[] issuers; 53898a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom if (asn1DerEncodedPrincipals == null) { 53998a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom issuers = null; 54098a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom } else { 54198a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom issuers = new X500Principal[asn1DerEncodedPrincipals.length]; 54298a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) { 54398a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]); 54498a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom } 54598a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom } 54698a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom setCertificate(sslParameters.getKeyManager().chooseClientAlias(keyTypes, issuers, this)); 54798ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom } 54898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom 54908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 55098ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 5512828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * invoked via JNI from info_callback 55208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 5532828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom public void handshakeCompleted() { 5542828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom handshakeCompleted = true; 55508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 5562828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // If sslSession is null, the handshake was completed during 5572828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // the call to NativeCrypto.SSL_do_handshake and not during a 5582828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // later read operation. That means we do not need to fixup 5592828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // the SSLSession and session cache or notify 5602828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // HandshakeCompletedListeners, it will be done in 5612828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // startHandshake. 5622828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (sslSession == null) { 5632828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom return; 5642828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 56508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 5662828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // reset session id from the native pointer and update the 5672828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // appropriate cache. 5682828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom sslSession.resetId(); 5692828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom AbstractSessionContext sessionContext = 5702828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom (sslParameters.getUseClientMode()) 5712828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom ? sslParameters.getClientSessionContext() 5722828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom : sslParameters.getServerSessionContext(); 57308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project sessionContext.putSession(sslSession); 5742828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 5752828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // let listeners know we are finally done 5762828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom notifyHandshakeCompletedListeners(); 5772828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 5782828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 5792828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom private void notifyHandshakeCompletedListeners() { 5802828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (listeners != null && !listeners.isEmpty()) { 5812828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // notify the listeners 5822828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom HandshakeCompletedEvent event = 5832828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom new HandshakeCompletedEvent(this, sslSession); 5842828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom for (HandshakeCompletedListener listener : listeners) { 5852828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom try { 5862828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom listener.handshakeCompleted(event); 5872828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } catch (RuntimeException e) { 588371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom // The RI runs the handlers in a separate thread, 589371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom // which we do not. But we try to preserve their 590371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom // behavior of logging a problem and not killing 591371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom // the handshaking thread just because a listener 592371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom // has a problem. 593371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom Thread thread = Thread.currentThread(); 594371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom thread.getUncaughtExceptionHandler().uncaughtException(thread, e); 5952828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 5962828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 5972828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } 59808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 59908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 60008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 60198ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 602f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * 60398a43fda08c8dae8b308fb91756fb121ec1c8ac2Brian Carlstrom * @param bytes An array of ASN.1 DER encoded certficates 6042828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * @param authMethod auth algorithm name 60508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 6062828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * @throws CertificateException if the certificate is untrusted 60708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 60808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project @SuppressWarnings("unused") 60998ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom public void verifyCertificateChain(byte[][] bytes, String authMethod) 61098ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom throws CertificateException { 61108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project try { 612371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom if (bytes == null || bytes.length == 0) { 613371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom throw new SSLException("Peer sent no certificate"); 614371c4e83bab807ee4fd7ffab9d36a5f31a55dc46Brian Carlstrom } 6152828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom X509Certificate[] peerCertificateChain = new X509Certificate[bytes.length]; 6162828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom for (int i = 0; i < bytes.length; i++) { 61708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project peerCertificateChain[i] = 61898ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom new X509CertImpl( 61998ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom javax.security.cert.X509Certificate.getInstance(bytes[i]).getEncoded()); 62008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 6212828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom boolean client = sslParameters.getUseClientMode(); 6222828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom if (client) { 62398ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom sslParameters.getTrustManager().checkServerTrusted(peerCertificateChain, 62498ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom authMethod); 6252828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } else { 62698ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom sslParameters.getTrustManager().checkClientTrusted(peerCertificateChain, 62798ec0ef4090e2e7a2f98a9171140e549e2220cacBrian Carlstrom authMethod); 62808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 6292828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom 6302828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } catch (CertificateException e) { 6312828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom throw e; 6322828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom } catch (Exception e) { 6332828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom throw new RuntimeException(e); 63408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 63508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 63608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 63708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 63808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Returns an input stream for this SSL socket using native calls to the 63908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * OpenSSL library. 64008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 64108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return: an input stream for reading bytes from this socket. 64208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws: <code>IOException</code> if an I/O error occurs when creating 64308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * the input stream, the socket is closed, the socket is not 64408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * connected, or the socket input has been shutdown. 64508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 6460b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 64708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public InputStream getInputStream() throws IOException { 648a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom checkOpen(); 649f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom synchronized (this) { 65008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (is == null) { 65108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project is = new SSLInputStream(); 65208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 65308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 65408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return is; 65508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 65608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 65708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 65808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 65908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Returns an output stream for this SSL socket using native calls to the 66008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * OpenSSL library. 66108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 66208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return an output stream for writing bytes to this socket. 66308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws <code>IOException</code> if an I/O error occurs when creating 66408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * the output stream, or no connection to the socket exists. 66508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 6660b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 66708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public OutputStream getOutputStream() throws IOException { 668a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom checkOpen(); 669f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom synchronized (this) { 67008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (os == null) { 67108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project os = new SSLOutputStream(); 67208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 67308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 67408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return os; 67508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 67608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 67708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 6782828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom /** 6792828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * This method is not supported for this SSLSocket implementation 6802828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * because reading from an SSLSocket may involve writing to the 6812828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * network. 6822828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom */ 6830b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 68408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void shutdownInput() throws IOException { 6852828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom throw new UnsupportedOperationException(); 68608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 68708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 6882828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom /** 6892828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * This method is not supported for this SSLSocket implementation 6902828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * because writing to an SSLSocket may involve reading from the 6912828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * network. 6922828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom */ 6930b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 69408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void shutdownOutput() throws IOException { 6952828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom throw new UnsupportedOperationException(); 69608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 69708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 69808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 69908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This inner class provides input data stream functionality 70008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * for the OpenSSL native implementation. It is used to 70108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * read data received via SSL protocol. 70208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 70308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private class SSLInputStream extends InputStream { 70408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project SSLInputStream() throws IOException { 70508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 70608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /* Note: When startHandshake() throws an exception, no 70708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * SSLInputStream object will be created. 70808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 7092828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom OpenSSLSocketImpl.this.startHandshake(false); 71008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 71108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 71208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 71308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Reads one byte. If there is no data in the underlying buffer, 71408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * this operation can block until the data will be 71508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * available. 71608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return read value. 71708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws <code>IOException</code> 71808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 7190b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 72008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public int read() throws IOException { 721a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom checkOpen(); 722ed2760e0dea39695b164af6d07ea9860e7c1fa49Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 723f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom synchronized (readLock) { 72458a44774b954fed596ee22307a231de783ea8121Brian Carlstrom return NativeCrypto.SSL_read_byte(sslNativePointer, timeout); 72508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 72608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 72708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 72808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 72908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Method acts as described in spec for superclass. 73008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @see java.io.InputStream#read(byte[],int,int) 73108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 7320b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 73308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public int read(byte[] b, int off, int len) throws IOException { 734a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom checkOpen(); 735ed2760e0dea39695b164af6d07ea9860e7c1fa49Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 736f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom if (b == null) { 737f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom throw new NullPointerException("b == null"); 738f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 739f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom if ((len | off) < 0 || len > b.length - off) { 740f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom throw new IndexOutOfBoundsException(); 741f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 742f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom if (0 == len) { 743f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom return 0; 744f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 745f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom synchronized (readLock) { 74658a44774b954fed596ee22307a231de783ea8121Brian Carlstrom return NativeCrypto.SSL_read(sslNativePointer, b, off, len, timeout); 74708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 74808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 74908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 75008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 75108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 75208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This inner class provides output data stream functionality 75308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * for the OpenSSL native implementation. It is used to 75408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * write data according to the encryption parameters given in SSL context. 75508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 75608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project private class SSLOutputStream extends OutputStream { 75708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project SSLOutputStream() throws IOException { 75808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 75908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /* Note: When startHandshake() throws an exception, no 760f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * SSLOutputStream object will be created. 76108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 7622828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom OpenSSLSocketImpl.this.startHandshake(false); 76308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 76408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 76508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 76608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Method acts as described in spec for superclass. 76708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @see java.io.OutputStream#write(int) 76808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 7690b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 77008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void write(int b) throws IOException { 771a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom checkOpen(); 772ed2760e0dea39695b164af6d07ea9860e7c1fa49Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 773f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom synchronized (writeLock) { 77458a44774b954fed596ee22307a231de783ea8121Brian Carlstrom NativeCrypto.SSL_write_byte(sslNativePointer, b); 77508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 77608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 77708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 77808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 77908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Method acts as described in spec for superclass. 78008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @see java.io.OutputStream#write(byte[],int,int) 78108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 7820b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 78308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void write(byte[] b, int start, int len) throws IOException { 784a2770d6e45dd961b24543ffbde7fa41bd548e7e8Brian Carlstrom checkOpen(); 785ed2760e0dea39695b164af6d07ea9860e7c1fa49Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 786f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom if (b == null) { 787f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom throw new NullPointerException("b == null"); 788f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 789f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom if ((len | start) < 0 || len > b.length - start) { 790f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom throw new IndexOutOfBoundsException(); 791f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 792f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom if (len == 0) { 793f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom return; 794f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom } 795f52606090f0f7160c2c7a85069959c1124151d79Brian Carlstrom synchronized (writeLock) { 79658a44774b954fed596ee22307a231de783ea8121Brian Carlstrom NativeCrypto.SSL_write(sslNativePointer, b, start, len); 79708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 79808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 79908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 80008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 80108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 80208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 80308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * The SSL session used by this connection is returned. The SSL session 80408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * determines which cipher suite should be used by all connections within 80508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * that session and which identities have the session's client and server. 80608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This method starts the SSL handshake. 80708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return the SSLSession. 80808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws <code>IOException</code> if the handshake fails 80908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 8100b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 81108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public SSLSession getSession() { 81208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project try { 8132828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom startHandshake(true); 81408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } catch (IOException e) { 81508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // return an invalid session with 81608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" 81708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return SSLSessionImpl.NULL_SESSION; 81808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 81908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return sslSession; 82008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 82108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 82208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 82308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Registers a listener to be notified that a SSL handshake 82408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * was successfully completed on this connection. 82508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws <code>IllegalArgumentException</code> if listener is null. 82608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 8270b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 82808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void addHandshakeCompletedListener( 82908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project HandshakeCompletedListener listener) { 83008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (listener == null) { 83108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw new IllegalArgumentException("Provided listener is null"); 83208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 83308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (listeners == null) { 83408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project listeners = new ArrayList(); 83508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 83608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project listeners.add(listener); 83708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 83808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 83908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 84008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * The method removes a registered listener. 84108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IllegalArgumentException if listener is null or not registered 84208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 8430b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 84408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void removeHandshakeCompletedListener( 84508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project HandshakeCompletedListener listener) { 84608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (listener == null) { 84708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw new IllegalArgumentException("Provided listener is null"); 84808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 84908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (listeners == null) { 85008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw new IllegalArgumentException( 85108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project "Provided listener is not registered"); 85208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 85308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (!listeners.remove(listener)) { 85408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw new IllegalArgumentException( 85508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project "Provided listener is not registered"); 85608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 85708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 85808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 85908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 86008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Returns true if new SSL sessions may be established by this socket. 86108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 86208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return true if the session may be created; false if a session already 86308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * exists and must be resumed. 86408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 8650b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 86608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public boolean getEnableSessionCreation() { 86708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return sslParameters.getEnableSessionCreation(); 86808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 86908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 87008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 87108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Set a flag for the socket to inhibit or to allow the creation of a new 87208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * SSL sessions. If the flag is set to false, and there are no actual 87308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * sessions to resume, then there will be no successful handshaking. 87408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 87508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param flag true if session may be created; false 87608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * if a session already exists and must be resumed. 87708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 8780b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 87908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void setEnableSessionCreation(boolean flag) { 88008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project sslParameters.setEnableSessionCreation(flag); 88108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 88208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 88308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 88408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * The names of the cipher suites which could be used by the SSL connection 88508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * are returned. 88608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return an array of cipher suite names 88708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 8880b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 88908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public String[] getSupportedCipherSuites() { 890f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom return NativeCrypto.getSupportedCipherSuites(); 89108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 89208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 89308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 89408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * The names of the cipher suites that are in use in the actual the SSL 89508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * connection are returned. 89608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 89708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return an array of cipher suite names 89808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 8990b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 90008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public String[] getEnabledCipherSuites() { 9012828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom return enabledCipherSuites.clone(); 90208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 90308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 90408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 90508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This method enables the cipher suites listed by 90608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * getSupportedCipherSuites(). 90708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 90808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param suites names of all the cipher suites to 90908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * put on use 91008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IllegalArgumentException when one or more of the 91108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * ciphers in array suites are not supported, or when the array 91208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * is null. 91308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 9140b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 91508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void setEnabledCipherSuites(String[] suites) { 9162828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites); 91708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 91808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 91908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 92008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * The names of the protocols' versions that may be used on this SSL 92108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * connection. 92208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return an array of protocols names 92308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 9240b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 92508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public String[] getSupportedProtocols() { 926f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom return NativeCrypto.getSupportedProtocols(); 92708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 92808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 92908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 93008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * The names of the protocols' versions that are in use on this SSL 93108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * connection. 932f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * 93308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return an array of protocols names 93408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 93508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project @Override 93608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public String[] getEnabledProtocols() { 9372828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom return enabledProtocols.clone(); 93808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 93908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 94008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 94108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This method enables the protocols' versions listed by 94208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * getSupportedProtocols(). 943f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * 9440b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @param protocols The names of all the protocols to allow 945f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom * 94608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IllegalArgumentException when one or more of the names in the 94708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * array are not supported, or when the array is null. 94808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 94908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project @Override 9500b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public void setEnabledProtocols(String[] protocols) { 9512828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols); 95208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 95308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 95408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 9550b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * The names of the compression methods that may be used on this SSL 9560b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * connection. 9570b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @return an array of compression methods 9580b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom */ 9590b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public String[] getSupportedCompressionMethods() { 9600b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom return NativeCrypto.getSupportedCompressionMethods(); 9610b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 9620b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom 9630b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom /** 9640b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * The names of the compression methods versions that are in use 9650b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * on this SSL connection. 9660b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * 9670b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @return an array of compression methods 9680b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom */ 9690b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public String[] getEnabledCompressionMethods() { 9700b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom return enabledCompressionMethods.clone(); 9710b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 9720b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom 9730b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom /** 9740b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * This method enables the compression method listed by 9750b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * getSupportedCompressionMethods(). 9760b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * 9770b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @param methods The names of all the compression methods to allow 9780b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * 9790b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @throws IllegalArgumentException when one or more of the names in the 9800b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * array are not supported, or when the array is null. 9810b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom */ 9820b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public void setEnabledCompressionMethods (String[] methods) { 9830b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom enabledCompressionMethods = NativeCrypto.checkEnabledCompressionMethods(methods); 9840b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 9850b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom 9860b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom /** 9870b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * This method enables session ticket support. 9880b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * 9890b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @param useSessionTickets True to enable session tickets 9900b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom */ 9910b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public void setUseSessionTickets(boolean useSessionTickets) { 9920b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom this.useSessionTickets = useSessionTickets; 9930b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 9940b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom 9950b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom /** 9960b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * This method gives true back if the SSL socket is set to client mode. 9970b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * 9980b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @return true if the socket should do the handshaking as client. 9990b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom */ 10000b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public boolean getUseSessionTickets() { 10010b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom return useSessionTickets; 10020b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 10030b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom 10040b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom /** 10050b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * This method enables Server Name Indication 10060b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * 10070b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @param hostname the desired SNI hostname, or null to disable 10080b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom */ 10090b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public void setHostname(String hostname) { 10100b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom this.hostname = hostname; 10110b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 10120b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom 10130b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom /** 10140b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * This method returns the current SNI hostname 10150b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * 10160b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom * @return a host name if SNI is enabled, or null otherwise 10170b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom */ 10180b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public String getHostname() { 10190b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom return hostname; 10200b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom } 10210b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom 10220b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom /** 102308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This method gives true back if the SSL socket is set to client mode. 102408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 102508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return true if the socket should do the handshaking as client. 102608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 102708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public boolean getUseClientMode() { 102808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return sslParameters.getUseClientMode(); 102908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 103008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 103108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 103208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This method set the actual SSL socket to client mode. 103308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 103408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param mode true if the socket starts in client 103508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * mode 103608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws IllegalArgumentException if mode changes during 103708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * handshake. 103808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 10390b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 10400b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public void setUseClientMode(boolean mode) { 104108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (handshakeStarted) { 104208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw new IllegalArgumentException( 104308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project "Could not change the mode after the initial handshake has begun."); 104408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 104508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project sslParameters.setUseClientMode(mode); 104608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 104708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 104808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 104908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Returns true if the SSL socket requests client's authentication. Relevant 105008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * only for server sockets! 105108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 105208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return true if client authentication is desired, false if not. 105308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 10540b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 105508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public boolean getWantClientAuth() { 105608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return sslParameters.getWantClientAuth(); 105708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 105808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 105908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 106008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Returns true if the SSL socket needs client's authentication. Relevant 106108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * only for server sockets! 106208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 106308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return true if client authentication is desired, false if not. 106408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 10650b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 106608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public boolean getNeedClientAuth() { 106708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return sslParameters.getNeedClientAuth(); 106808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 106908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 107008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 107108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Sets the SSL socket to use client's authentication. Relevant only for 107208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * server sockets! 107308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 107408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param need true if client authentication is 107508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * desired, false if not. 107608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 10770b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 107808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void setNeedClientAuth(boolean need) { 107908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project sslParameters.setNeedClientAuth(need); 108008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 108108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 108208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 108308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Sets the SSL socket to use client's authentication. Relevant only for 108408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * server sockets! Notice that in contrast to setNeedClientAuth(..) this 108508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * method will continue the negotiation if the client decide not to send 108608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * authentication credentials. 108708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 108808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param want true if client authentication is 108908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * desired, false if not. 109008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 10910b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 109208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void setWantClientAuth(boolean want) { 109308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project sslParameters.setWantClientAuth(want); 109408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 109508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 109608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 109708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This method is not supported for SSLSocket implementation. 109808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 10990b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 110008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void sendUrgentData(int data) throws IOException { 110108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw new SocketException( 110208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project "Method sendUrgentData() is not supported."); 110308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 110408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 110508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 110608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * This method is not supported for SSLSocket implementation. 110708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 11080b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 110908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void setOOBInline(boolean on) throws SocketException { 111008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw new SocketException( 111108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project "Methods sendUrgentData, setOOBInline are not supported."); 111208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 111308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 111408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 111508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Set the read timeout on this socket. The SO_TIMEOUT option, is specified 111608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * in milliseconds. The read operation will block indefinitely for a zero 111708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * value. 111808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 111908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param timeout the read timeout value 112008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws SocketException if an error occurs setting the option 112108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 11220b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 11230b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public void setSoTimeout(int timeout) throws SocketException { 112408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super.setSoTimeout(timeout); 112508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project this.timeout = timeout; 112608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 112708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 1128331900211d05cd282141a3a50cb1db626f418b2cDan Egnor // BEGIN android-added 1129331900211d05cd282141a3a50cb1db626f418b2cDan Egnor /** 1130331900211d05cd282141a3a50cb1db626f418b2cDan Egnor * Set the handshake timeout on this socket. This timeout is specified in 1131331900211d05cd282141a3a50cb1db626f418b2cDan Egnor * milliseconds and will be used only during the handshake process. 1132331900211d05cd282141a3a50cb1db626f418b2cDan Egnor * 1133331900211d05cd282141a3a50cb1db626f418b2cDan Egnor * @param timeout the handshake timeout value 1134331900211d05cd282141a3a50cb1db626f418b2cDan Egnor */ 11350b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom public void setHandshakeTimeout(int timeout) throws SocketException { 1136331900211d05cd282141a3a50cb1db626f418b2cDan Egnor this.handshakeTimeout = timeout; 1137331900211d05cd282141a3a50cb1db626f418b2cDan Egnor } 1138331900211d05cd282141a3a50cb1db626f418b2cDan Egnor // END android-added 1139331900211d05cd282141a3a50cb1db626f418b2cDan Egnor 114008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 114108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Closes the SSL socket. Once closed, a socket is not available for further 114208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * use anymore under any circumstance. A new socket must be created. 114308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 114408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @throws <code>IOException</code> if an I/O error happens during the 114508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * socket's closure. 114608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 11470b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 114808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public void close() throws IOException { 114908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // TODO: Close SSL sockets using a background thread so they close 115008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // gracefully. 115108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 115208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project synchronized (handshakeLock) { 115308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (!handshakeStarted) { 11542828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // prevent further attemps to start handshake 115508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project handshakeStarted = true; 1156f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom 115708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project synchronized (this) { 1158f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom free(); 115908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 116008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (socket != null) { 116108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (autoClose && !socket.isClosed()) socket.close(); 116208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } else { 116308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (!super.isClosed()) super.close(); 116408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 116508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 1166f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom 116708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return; 116808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 116908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 117008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 117158a44774b954fed596ee22307a231de783ea8121Brian Carlstrom NativeCrypto.SSL_interrupt(sslNativePointer); 117208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 117308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project synchronized (this) { 117408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project synchronized (writeLock) { 117508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project synchronized (readLock) { 117608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 117708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project IOException pendingException = null; 117808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 117908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // Shut down the SSL connection, per se. 118008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project try { 118108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (handshakeStarted) { 1182ed2760e0dea39695b164af6d07ea9860e7c1fa49Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 118358a44774b954fed596ee22307a231de783ea8121Brian Carlstrom NativeCrypto.SSL_shutdown(sslNativePointer); 118408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 118508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } catch (IOException ex) { 118608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /* 118708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Note the exception at this point, but try to continue 118808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * to clean the rest of this all up before rethrowing. 118908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 119008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project pendingException = ex; 119108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 119208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 119308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /* 119408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Even if the above call failed, it is still safe to free 119508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * the native structs, and we need to do so lest we leak 119608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * memory. 119708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 1198f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom free(); 119908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 120008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (socket != null) { 120108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (autoClose && !socket.isClosed()) 120208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project socket.close(); 120308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } else { 120408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (!super.isClosed()) 120508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project super.close(); 120608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 120708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 120808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (pendingException != null) { 120908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw pendingException; 121008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 121108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 121208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 121308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 121408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 121508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 1216f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom private void free() { 1217f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom if (sslNativePointer == 0) { 1218f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom return; 1219f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 1220f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom NativeCrypto.SSL_free(sslNativePointer); 1221f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom sslNativePointer = 0; 1222f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 122308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 12240b26b4367f0af550809c12ecea934723f16e7393Brian Carlstrom @Override 122508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project protected void finalize() throws IOException { 122608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /* 12272828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * Just worry about our own state. Notably we do not try and 12282828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * close anything. The SocketImpl, either our own 12292828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * PlainSocketImpl, or the Socket we are wrapping, will do 12302828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * that. This might mean we do not properly SSL_shutdown, but 12312828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * if you want to do that, properly close the socket yourself. 12322828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * 12332828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * The reason why we don't try to SSL_shutdown, is that there 12342828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * can be a race between finalizers where the PlainSocketImpl 12352828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * finalizer runs first and closes the socket. However, in the 12362828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * meanwhile, the underlying file descriptor could be reused 12372828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * for another purpose. If we call SSL_shutdown, the 12382828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * underlying socket BIOs still have the old file descriptor 12392828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * and will write the close notify to some unsuspecting 12402828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom * reader. 124108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 12422828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom updateInstanceCount(-1); 12432828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom free(); 124408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 124508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project} 1246