OpenSSLSocketImpl.java revision 059dbc04218144f985b20a228bbe98139d400d0c
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.xnet.provider.jsse; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.InetAddress; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.Socket; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.SocketException; 256df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstromimport java.security.PrivateKey; 266df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstromimport java.security.SecureRandom; 2712cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstromimport java.security.cert.CertificateEncodingException; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateException; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.X509Certificate; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 3130da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybobimport java.util.concurrent.atomic.AtomicInteger; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.logging.Logger; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.HandshakeCompletedEvent; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.HandshakeCompletedListener; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLException; 36bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport javax.net.ssl.SSLPeerUnverifiedException; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSession; 38059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstromimport javax.security.auth.x500.X500Principal; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.provider.cert.X509CertImpl; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implementation of the class OpenSSLSocketImpl 433e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom * based on OpenSSL. 44ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class only supports SSLv3 and TLSv1. This should be documented elsewhere 46ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * later, for example in the package.html or a separate reference document. 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 48ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrompublic class OpenSSLSocketImpl 49ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom extends javax.net.ssl.SSLSocket 506df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom implements NativeCrypto.SSLHandshakeCallbacks { 51ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private int sslNativePointer; 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private InputStream is; 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private OutputStream os; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Object handshakeLock = new Object(); 55ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private final Object readLock = new Object(); 56ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private final Object writeLock = new Object(); 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private SSLParameters sslParameters; 58bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private String[] enabledProtocols; 59bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private String[] enabledCipherSuites; 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private OpenSSLSessionImpl sslSession; 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Socket socket; 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean autoClose; 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean handshakeStarted = false; 64bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 65bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 66bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Not set to true until the update from native that tells us the 67bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * full handshake is complete, since SSL_do_handshake can return 68bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * before the handshake is completely done due to 69bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * handshake_cutthrough support. 70bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 71bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private boolean handshakeCompleted = false; 72bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ArrayList<HandshakeCompletedListener> listeners; 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int timeout = 0; 759d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // BEGIN android-added 769d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor private int handshakeTimeout = -1; // -1 = same as timeout; 0 = infinite 779d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // END android-added 78a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom private String wrappedHost; 79a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom private int wrappedPort; 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 8130da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob private static final AtomicInteger instanceCount = new AtomicInteger(0); 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static int getInstanceCount() { 8430da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob return instanceCount.get(); 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static void updateInstanceCount(int amount) { 8830da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob instanceCount.addAndGet(amount); 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 1 parameter 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param sslParameters Parameters for the SSL 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * context 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected OpenSSLSocketImpl(SSLParameters sslParameters) throws IOException { 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(); 100ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 104bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Create an OpenSSLSocketImpl from an OpenSSLServerSocketImpl 105bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 106bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param sslParameters Parameters for the SSL 107bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * context 108bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @throws IOException if network fails 109bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 110bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom protected OpenSSLSocketImpl(SSLParameters sslParameters, 111bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom String[] enabledProtocols, 112bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom String[] enabledCipherSuites) throws IOException { 113bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom super(); 114bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom init(sslParameters, enabledProtocols, enabledCipherSuites); 115bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 116bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 117bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 3 parameters 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1230c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom protected OpenSSLSocketImpl(String host, int port, SSLParameters sslParameters) 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(host, port); 126ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 3 parameters: 1st is InetAddress 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom protected OpenSSLSocketImpl(InetAddress address, int port, SSLParameters sslParameters) 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(address, port); 138ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 5 parameters: 1st is host 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1480c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom protected OpenSSLSocketImpl(String host, int port, 1490c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom InetAddress clientAddress, int clientPort, 1500c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLParameters sslParameters) 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(host, port, clientAddress, clientPort); 153ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 5 parameters: 1st is InetAddress 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected OpenSSLSocketImpl(InetAddress address, int port, 1630c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom InetAddress clientAddress, int clientPort, 1640c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLParameters sslParameters) 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(address, port, clientAddress, clientPort); 167ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructor with 5 parameters: 1st is socket. Enhances an existing socket 172a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom * with SSL functionality. Invoked via OpenSSLSocketImplWrapper constructor. 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected OpenSSLSocketImpl(Socket socket, String host, int port, 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean autoClose, SSLParameters sslParameters) throws IOException { 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(); 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.socket = socket; 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.timeout = socket.getSoTimeout(); 181a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom this.wrappedHost = host; 182a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom this.wrappedPort = port; 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.autoClose = autoClose; 184ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 185ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 186ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 187ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom /** 188ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * Initialize the SSL socket and set the certificates for the 189ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * future handshaking. 190ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom */ 191ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private void init(SSLParameters sslParameters) throws IOException { 192bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom init(sslParameters, 193bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.getSupportedProtocols(), 194bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.getDefaultCipherSuites()); 195ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 196ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 197ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom /** 198bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Initialize the SSL socket and set the certificates for the 199bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * future handshaking. 200ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom */ 201bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private void init(SSLParameters sslParameters, 202bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom String[] enabledProtocols, 203bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom String[] enabledCipherSuites) throws IOException { 204bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.sslParameters = sslParameters; 205bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.enabledProtocols = enabledProtocols; 206bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.enabledCipherSuites = enabledCipherSuites; 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project updateInstanceCount(1); 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the suitable session reference from the session cache container. 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return OpenSSLSessionImpl 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 215bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private OpenSSLSessionImpl getCachedClientSession(ClientSessionContext sessionContext) { 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (super.getInetAddress() == null || 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostAddress() == null || 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostName() == null) { 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2219acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom OpenSSLSessionImpl session = (OpenSSLSessionImpl) sessionContext.getSession( 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostName(), 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getPort()); 2249acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (session == null) { 2259acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2269acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2279acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom 2289acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom String protocol = session.getProtocol(); 2299acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom boolean protocolFound = false; 2309acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom for (String enabledProtocol : enabledProtocols) { 2319acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (protocol.equals(enabledProtocol)) { 2329acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom protocolFound = true; 2339acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom break; 2349acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2359acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2369acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (!protocolFound) { 2379acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2389acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2399acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom 2409acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom String cipherSuite = session.getCipherSuite(); 2419acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom boolean cipherSuiteFound = false; 2429acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom for (String enabledCipherSuite : enabledCipherSuites) { 2439acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (cipherSuite.equals(enabledCipherSuite)) { 2449acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom cipherSuiteFound = true; 2459acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom break; 2469acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2479acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2489acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (!cipherSuiteFound) { 2499acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2509acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2516df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 2529acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return session; 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Ensures that logger is lazily loaded. The outer class seems to load 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * before logging is ready. 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static class LoggerHolder { 260ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom static final Logger logger = Logger.getLogger(OpenSSLSocketImpl.class.getName()); 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Starts a TLS/SSL handshake on this connection using some native methods 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from the OpenSSL library. It can negotiate new encryption keys, change 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher suites, or initiate a new session. The certificate chain is 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * verified if the correspondent property in java.Security is set. All 268ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * listeners are notified at the end of the TLS/SSL handshake. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if network fails 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 272bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public void startHandshake() throws IOException { 273bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom startHandshake(true); 274bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 275bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 276bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 277bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Perform the handshake 278bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param full If true, disable handshake cutthrough for a fully synchronous handshake 279bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 280bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public synchronized void startHandshake(boolean full) throws IOException { 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (handshakeLock) { 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshakeStarted) { 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStarted = true; 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2896df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // note that this modifies the global seed, not something specific to the connection 2906df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final int seedLengthInBytes = NativeCrypto.RAND_SEED_LENGTH_IN_BYTES; 2916df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final SecureRandom secureRandom = sslParameters.getSecureRandomMember(); 2926df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom if (secureRandom == null) { 2936df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.RAND_load_file("/dev/urandom", seedLengthInBytes); 2946df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } else { 2956df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.RAND_seed(secureRandom.generateSeed(seedLengthInBytes)); 2966df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 2976df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 2986df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final boolean client = sslParameters.getUseClientMode(); 2996df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3006df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final int sslCtxNativePointer = (client) ? 3016df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getClientSessionContext().sslCtxNativePointer : 3026df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getServerSessionContext().sslCtxNativePointer; 3036df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3046df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom this.sslNativePointer = NativeCrypto.SSL_new(sslCtxNativePointer); 3056df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3066df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // setup server certificates and private keys. 3076df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // clients will receive a call back to request certificates. 3086df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom if (!client) { 3096df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom for (String keyType : NativeCrypto.KEY_TYPES) { 3106df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom setCertificate(sslParameters.getKeyManager().chooseServerAlias(keyType, 3116df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom null, 312059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom this)); 3136df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 3146df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 3156df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 316bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.setEnabledProtocols(sslNativePointer, enabledProtocols); 317bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.setEnabledCipherSuites(sslNativePointer, enabledCipherSuites); 318bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 319bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom boolean enableSessionCreation = sslParameters.getEnableSessionCreation(); 320bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (!enableSessionCreation) { 321bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer, 322bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom enableSessionCreation); 323bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 324bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 325bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom AbstractSessionContext sessionContext; 326bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSessionImpl session; 327bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client) { 328bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // look for client session to reuse 329bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom ClientSessionContext clientSessionContext = sslParameters.getClientSessionContext(); 330bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sessionContext = clientSessionContext; 331bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom session = getCachedClientSession(clientSessionContext); 332bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (session != null) { 333bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_set_session(sslNativePointer, session.sslSessionNativePointer); 334bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 335bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else { 336bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sessionContext = sslParameters.getServerSessionContext(); 337bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom session = null; 338bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 339bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 340bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // setup peer certificate verification 341bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client) { 3426df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // TODO support for anonymous cipher would require us to 3436df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // conditionally use SSL_VERIFY_NONE 344bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else { 345bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // needing client auth takes priority... 346bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (sslParameters.getNeedClientAuth()) { 347bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_set_verify(sslNativePointer, 348bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_VERIFY_PEER| 349bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT| 350bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_VERIFY_CLIENT_ONCE); 351bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // ... over just wanting it... 352bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else if (sslParameters.getWantClientAuth()) { 353bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_set_verify(sslNativePointer, 354bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_VERIFY_PEER| 355bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_VERIFY_CLIENT_ONCE); 356bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 357bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // ... and it defaults properly so we don't need call SSL_set_verify in the common case. 358059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 359059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // TODO Need to call SSL_CTX_set_client_CA_list to notify trusted issuers to client 360059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // 361059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // From SSL_CTX_load_verify_locations(3SSL) 362059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // In server mode, when requesting a client 363059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // certificate, the server must send the list of CAs 364059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // of which it will accept client certificates. This 365059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // list is not influenced by the contents of CAfile or 366059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // CApath and must explicitly be set using the 367059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // SSL_CTX_set_client_CA_list(3) family of functions. 368059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // 369059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom // We can get the list from sslParameters.getTrustManager().getAcceptedIssuers() 370bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 371bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 372bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client && full) { 373bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // we want to do a full synchronous handshake, so turn off cutthrough 3746df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_clear_mode(sslNativePointer, 3756df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH); 376ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 377ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 378ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // BEGIN android-added 379ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // Temporarily use a different timeout for the handshake process 380ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom int savedTimeout = timeout; 381ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom if (handshakeTimeout >= 0) { 382ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom setSoTimeout(handshakeTimeout); 383ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 384ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // END android-added 385ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 386bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 387ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom Socket socket = this.socket != null ? this.socket : this; 388bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom int sslSessionNativePointer; 389bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom try { 3906df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslSessionNativePointer 3916df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom = NativeCrypto.SSL_do_handshake(sslNativePointer, socket, this, timeout, client); 392bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (CertificateException e) { 393bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new SSLPeerUnverifiedException(e.getMessage()); 394bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 395f002bdddce924e2145a4a2b60592b7a40f4112f6Brian Carlstrom byte[] sessionId = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer); 396bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession = (OpenSSLSessionImpl) sessionContext.getSession(sessionId); 397bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (sslSession != null) { 3989acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom sslSession.lastAccessedTime = System.currentTimeMillis(); 399ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom LoggerHolder.logger.fine("Reused cached session for " 400bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom + getInetAddress() + "."); 401f002bdddce924e2145a4a2b60592b7a40f4112f6Brian Carlstrom NativeCrypto.SSL_SESSION_free(sslSessionNativePointer); 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 403bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (!enableSessionCreation) { 404bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // Should have been prevented by NativeCrypto.SSL_set_session_creation_enabled 405bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new IllegalStateException("SSL Session may not be created"); 406bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 407bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom byte[][] localCertificatesBytes = NativeCrypto.SSL_get_certificate(sslNativePointer); 408bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom X509Certificate[] localCertificates; 409bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (localCertificatesBytes == null) { 410bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom localCertificates = null; 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 412bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom localCertificates = new X509Certificate[localCertificatesBytes.length]; 413bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom for (int i = 0; i < localCertificatesBytes.length; i++) { 414059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom localCertificates[i] = new X509CertImpl(localCertificatesBytes[i]); 415bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 416ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 418a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom if (wrappedHost == null) { 419bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates, 420ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom super.getInetAddress().getHostName(), 421ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom super.getPort(), sessionContext); 422ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } else { 423bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates, 424a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom wrappedHost, wrappedPort, 425ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom sessionContext); 426ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 4270c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom // if not, putSession later in handshakeCompleted() callback 428bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (handshakeCompleted) { 429ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom sessionContext.putSession(sslSession); 4309d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor } 431bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom LoggerHolder.logger.fine("Created new session for " 432bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom + getInetAddress().getHostName() + "."); 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 435ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // BEGIN android-added 436ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // Restore the original timeout now that the handshake is complete 437ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom if (handshakeTimeout >= 0) { 438ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom setSoTimeout(savedTimeout); 439ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 440ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // END android-added 441ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 4420c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback 443bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (handshakeCompleted) { 444bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom notifyHandshakeCompletedListeners(); 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 447bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 449059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom private void setCertificate(String alias) throws IOException { 4506df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom if (alias == null) { 4516df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom return; 4526df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 4536df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 4546df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias); 45512cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom byte[] privateKeyBytes = privateKey.getEncoded(); 4566df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_use_PrivateKey(sslNativePointer, privateKeyBytes); 4576df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 4586df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias); 45912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom byte[][] certificateBytes = new byte[certificates.length][]; 46012cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom for (int i = 0; i < certificates.length; i++) { 46112cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom try { 46212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom certificateBytes[i] = certificates[i].getEncoded(); 46312cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom } catch (CertificateEncodingException e) { 46412cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom throw new IOException("Problem encoding certificate " + certificates[i], e); 46512cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom } 4666df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 4676df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_use_certificate(sslNativePointer, certificateBytes); 4686df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 4696df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // checks the last installed private key and certificate, 4706df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // so need to do this once per loop iteration 4716df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_check_private_key(sslNativePointer); 4726df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 4736df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 4746df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom /** 4756df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 4766df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * invoked via JNI from client_cert_cb 4776df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom */ 478059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) 479059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom throws IOException { 480059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 481059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom String[] keyTypes = new String[keyTypeBytes.length]; 482059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom for (int i = 0; i < keyTypeBytes.length; i++) { 483059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom keyTypes[i] = NativeCrypto.keyType(keyTypeBytes[i]); 484059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 485059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 486059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom X500Principal[] issuers; 487059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom if (asn1DerEncodedPrincipals == null) { 488059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers = null; 489059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } else { 490059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers = new X500Principal[asn1DerEncodedPrincipals.length]; 491059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) { 492059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]); 493059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 494059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 495059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 496059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom setCertificate(sslParameters.getKeyManager().chooseClientAlias(keyTypes, issuers, this)); 4976df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 4986df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 5006df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 501bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * invoked via JNI from info_callback 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 503bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public void handshakeCompleted() { 504bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom handshakeCompleted = true; 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 506bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // If sslSession is null, the handshake was completed during 507bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // the call to NativeCrypto.SSL_do_handshake and not during a 508bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // later read operation. That means we do not need to fixup 509bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // the SSLSession and session cache or notify 510bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // HandshakeCompletedListeners, it will be done in 511bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // startHandshake. 512bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (sslSession == null) { 513bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return; 514bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 516bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // reset session id from the native pointer and update the 517bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // appropriate cache. 518bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession.resetId(); 519bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom AbstractSessionContext sessionContext = 520bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom (sslParameters.getUseClientMode()) 521bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom ? sslParameters.getClientSessionContext() 522bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom : sslParameters.getServerSessionContext(); 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sessionContext.putSession(sslSession); 524bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 525bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // let listeners know we are finally done 526bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom notifyHandshakeCompletedListeners(); 527bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 528bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 529bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private void notifyHandshakeCompletedListeners() { 530bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (listeners != null && !listeners.isEmpty()) { 531bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // notify the listeners 532bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom HandshakeCompletedEvent event = 533bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom new HandshakeCompletedEvent(this, sslSession); 534bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom for (HandshakeCompletedListener listener : listeners) { 535bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom try { 536bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom listener.handshakeCompleted(event); 537bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (RuntimeException e) { 538e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // The RI runs the handlers in a separate thread, 539e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // which we do not. But we try to preserve their 540e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // behavior of logging a problem and not killing 541e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // the handshaking thread just because a listener 542e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // has a problem. 543e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom Thread thread = Thread.currentThread(); 544e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom thread.getUncaughtExceptionHandler().uncaughtException(thread, e); 545bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 546bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 547bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 5516df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 552ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 553059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom * @param bytes An array of ASN.1 DER encoded certficates 554bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param authMethod auth algorithm name 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 556bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @throws CertificateException if the certificate is untrusted 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unused") 5596df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom public void verifyCertificateChain(byte[][] bytes, String authMethod) 5606df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom throws CertificateException { 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 562e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom if (bytes == null || bytes.length == 0) { 563e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom throw new SSLException("Peer sent no certificate"); 564e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 565bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom X509Certificate[] peerCertificateChain = new X509Certificate[bytes.length]; 566bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom for (int i = 0; i < bytes.length; i++) { 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project peerCertificateChain[i] = 5686df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom new X509CertImpl( 5696df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom javax.security.cert.X509Certificate.getInstance(bytes[i]).getEncoded()); 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 571bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom boolean client = sslParameters.getUseClientMode(); 572bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client) { 5736df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getTrustManager().checkServerTrusted(peerCertificateChain, 5746df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom authMethod); 575bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else { 5766df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getTrustManager().checkClientTrusted(peerCertificateChain, 5776df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom authMethod); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 579bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 580bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (CertificateException e) { 581bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw e; 582bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (Exception e) { 583bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new RuntimeException(e); 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an input stream for this SSL socket using native calls to the 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * OpenSSL library. 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return: an input stream for reading bytes from this socket. 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws: <code>IOException</code> if an I/O error occurs when creating 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input stream, the socket is closed, the socket is not 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connected, or the socket input has been shutdown. 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InputStream getInputStream() throws IOException { 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(this) { 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (is == null) { 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project is = new SSLInputStream(); 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return is; 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an output stream for this SSL socket using native calls to the 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * OpenSSL library. 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an output stream for writing bytes to this socket. 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if an I/O error occurs when creating 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output stream, or no connection to the socket exists. 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public OutputStream getOutputStream() throws IOException { 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(this) { 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (os == null) { 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project os = new SSLOutputStream(); 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return os; 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 624bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 625bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * This method is not supported for this SSLSocket implementation 626bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * because reading from an SSLSocket may involve writing to the 627bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * network. 628bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void shutdownInput() throws IOException { 630bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new UnsupportedOperationException(); 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 633bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 634bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * This method is not supported for this SSLSocket implementation 635bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * because writing to an SSLSocket may involve reading from the 636bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * network. 637bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void shutdownOutput() throws IOException { 639bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new UnsupportedOperationException(); 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This inner class provides input data stream functionality 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the OpenSSL native implementation. It is used to 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read data received via SSL protocol. 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class SSLInputStream extends InputStream { 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLInputStream() throws IOException { 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Note: When startHandshake() throws an exception, no 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SSLInputStream object will be created. 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 653bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSocketImpl.this.startHandshake(false); 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads one byte. If there is no data in the underlying buffer, 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this operation can block until the data will be 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available. 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return read value. 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(readLock) { 6653e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom return NativeCrypto.SSL_read_byte(sslNativePointer, timeout); 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.InputStream#read(byte[],int,int) 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(byte[] b, int off, int len) throws IOException { 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(readLock) { 6753e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom return NativeCrypto.SSL_read(sslNativePointer, b, off, len, timeout); 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This inner class provides output data stream functionality 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the OpenSSL native implementation. It is used to 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * write data according to the encryption parameters given in SSL context. 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class SSLOutputStream extends OutputStream { 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLOutputStream() throws IOException { 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Note: When startHandshake() throws an exception, no 689ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * SSLOutputStream object will be created. 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 691bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSocketImpl.this.startHandshake(false); 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.OutputStream#write(int) 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void write(int b) throws IOException { 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(writeLock) { 7003e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_write_byte(sslNativePointer, b); 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.OutputStream#write(byte[],int,int) 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void write(byte[] b, int start, int len) throws IOException { 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(writeLock) { 7103e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_write(sslNativePointer, b, start, len); 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The SSL session used by this connection is returned. The SSL session 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * determines which cipher suite should be used by all connections within 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that session and which identities have the session's client and server. 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method starts the SSL handshake. 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the SSLSession. 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if the handshake fails 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SSLSession getSession() { 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 726bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom startHandshake(true); 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // return an invalid session with 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return SSLSessionImpl.NULL_SESSION; 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslSession; 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Registers a listener to be notified that a SSL handshake 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * was successfully completed on this connection. 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IllegalArgumentException</code> if listener is null. 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addHandshakeCompletedListener( 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HandshakeCompletedListener listener) { 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listener == null) { 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Provided listener is null"); 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listeners == null) { 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners = new ArrayList(); 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners.add(listener); 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The method removes a registered listener. 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if listener is null or not registered 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeHandshakeCompletedListener( 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HandshakeCompletedListener listener) { 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listener == null) { 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Provided listener is null"); 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listeners == null) { 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Provided listener is not registered"); 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!listeners.remove(listener)) { 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Provided listener is not registered"); 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if new SSL sessions may be established by this socket. 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the session may be created; false if a session already 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exists and must be resumed. 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getEnableSessionCreation() { 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getEnableSessionCreation(); 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set a flag for the socket to inhibit or to allow the creation of a new 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SSL sessions. If the flag is set to false, and there are no actual 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sessions to resume, then there will be no successful handshaking. 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param flag true if session may be created; false 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a session already exists and must be resumed. 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnableSessionCreation(boolean flag) { 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setEnableSessionCreation(flag); 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the cipher suites which could be used by the SSL connection 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * are returned. 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of cipher suite names 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getSupportedCipherSuites() { 798ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return NativeCrypto.getSupportedCipherSuites(); 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the cipher suites that are in use in the actual the SSL 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection are returned. 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of cipher suite names 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getEnabledCipherSuites() { 808bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return enabledCipherSuites.clone(); 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method enables the cipher suites listed by 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * getSupportedCipherSuites(). 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param suites names of all the cipher suites to 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * put on use 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException when one or more of the 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ciphers in array suites are not supported, or when the array 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is null. 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnabledCipherSuites(String[] suites) { 822bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites); 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the protocols' versions that may be used on this SSL 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection. 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of protocols names 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getSupportedProtocols() { 831ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return NativeCrypto.getSupportedProtocols(); 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the protocols' versions that are in use on this SSL 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection. 837ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of protocols names 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getEnabledProtocols() { 842bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return enabledProtocols.clone(); 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method enables the protocols' versions listed by 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * getSupportedProtocols(). 848ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param protocols The names of all the protocols to put on use 850ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException when one or more of the names in the 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * array are not supported, or when the array is null. 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void setEnabledProtocols(String[] protocols) { 856bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols); 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method gives true back if the SSL socket is set to client mode. 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the socket should do the handshaking as client. 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getUseClientMode() { 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getUseClientMode(); 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method set the actual SSL socket to client mode. 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param mode true if the socket starts in client 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mode 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if mode changes during 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handshake. 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void setUseClientMode(boolean mode) { 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshakeStarted) { 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Could not change the mode after the initial handshake has begun."); 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setUseClientMode(mode); 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if the SSL socket requests client's authentication. Relevant 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only for server sockets! 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if client authentication is desired, false if not. 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getWantClientAuth() { 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getWantClientAuth(); 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if the SSL socket needs client's authentication. Relevant 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only for server sockets! 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if client authentication is desired, false if not. 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getNeedClientAuth() { 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getNeedClientAuth(); 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the SSL socket to use client's authentication. Relevant only for 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * server sockets! 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param need true if client authentication is 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * desired, false if not. 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setNeedClientAuth(boolean need) { 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setNeedClientAuth(need); 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the SSL socket to use client's authentication. Relevant only for 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * server sockets! Notice that in contrast to setNeedClientAuth(..) this 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method will continue the negotiation if the client decide not to send 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * authentication credentials. 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param want true if client authentication is 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * desired, false if not. 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setWantClientAuth(boolean want) { 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setWantClientAuth(want); 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method is not supported for SSLSocket implementation. 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void sendUrgentData(int data) throws IOException { 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SocketException( 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Method sendUrgentData() is not supported."); 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method is not supported for SSLSocket implementation. 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setOOBInline(boolean on) throws SocketException { 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SocketException( 941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Methods sendUrgentData, setOOBInline are not supported."); 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the read timeout on this socket. The SO_TIMEOUT option, is specified 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in milliseconds. The read operation will block indefinitely for a zero 947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value. 948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout the read timeout value 950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SocketException if an error occurs setting the option 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void setSoTimeout(int timeout) throws SocketException { 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.setSoTimeout(timeout); 954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.timeout = timeout; 955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 9579d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // BEGIN android-added 9589d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor /** 9599d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * Set the handshake timeout on this socket. This timeout is specified in 9609d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * milliseconds and will be used only during the handshake process. 9619d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * 9629d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * @param timeout the handshake timeout value 9639d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor */ 9649d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor public synchronized void setHandshakeTimeout(int timeout) throws SocketException { 9659d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor this.handshakeTimeout = timeout; 9669d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor } 9679d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // END android-added 9689d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor 969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the SSL socket. Once closed, a socket is not available for further 971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * use anymore under any circumstance. A new socket must be created. 972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if an I/O error happens during the 974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket's closure. 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // TODO: Close SSL sockets using a background thread so they close 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // gracefully. 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (handshakeLock) { 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshakeStarted) { 982bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // prevent further attemps to start handshake 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStarted = true; 984ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 986ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom free(); 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (socket != null) { 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (autoClose && !socket.isClosed()) socket.close(); 990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!super.isClosed()) super.close(); 992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 994ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 9993e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_interrupt(sslNativePointer); 1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (writeLock) { 1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (readLock) { 1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IOException pendingException = null; 1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Shut down the SSL connection, per se. 1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshakeStarted) { 10103e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_shutdown(sslNativePointer); 1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException ex) { 1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note the exception at this point, but try to continue 1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to clean the rest of this all up before rethrowing. 1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pendingException = ex; 1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Even if the above call failed, it is still safe to free 1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the native structs, and we need to do so lest we leak 1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * memory. 1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1025ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom free(); 1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (socket != null) { 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (autoClose && !socket.isClosed()) 1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project socket.close(); 1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!super.isClosed()) 1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.close(); 1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (pendingException != null) { 1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw pendingException; 1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1043ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private void free() { 1044ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom if (sslNativePointer == 0) { 1045ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return; 1046ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 1047ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom NativeCrypto.SSL_free(sslNativePointer); 1048ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom sslNativePointer = 0; 1049ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void finalize() throws IOException { 1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1053bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Just worry about our own state. Notably we do not try and 1054bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * close anything. The SocketImpl, either our own 1055bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * PlainSocketImpl, or the Socket we are wrapping, will do 1056bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * that. This might mean we do not properly SSL_shutdown, but 1057bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * if you want to do that, properly close the socket yourself. 1058bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 1059bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * The reason why we don't try to SSL_shutdown, is that there 1060bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * can be a race between finalizers where the PlainSocketImpl 1061bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * finalizer runs first and closes the socket. However, in the 1062bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * meanwhile, the underlying file descriptor could be reused 1063bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * for another purpose. If we call SSL_shutdown, the 1064bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * underlying socket BIOs still have the old file descriptor 1065bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * and will write the close notify to some unsuspecting 1066bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * reader. 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1068bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom updateInstanceCount(-1); 1069bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom free(); 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1072