OpenSSLSocketImpl.java revision f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8a
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 195900e5546059f05d5e58e5732e4d08d83b8b7574Brad Fitzpatrickimport dalvik.system.BlockGuard; 20f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstromimport dalvik.system.CloseGuard; 21df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstromimport java.io.FileDescriptor; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.InetAddress; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.Socket; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.SocketException; 286df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstromimport java.security.PrivateKey; 296df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstromimport java.security.SecureRandom; 3012cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstromimport java.security.cert.CertificateEncodingException; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateException; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.X509Certificate; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 3430da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybobimport java.util.concurrent.atomic.AtomicInteger; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.logging.Logger; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.HandshakeCompletedEvent; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.HandshakeCompletedListener; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLException; 39bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport javax.net.ssl.SSLPeerUnverifiedException; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSession; 41f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstromimport javax.net.ssl.X509TrustManager; 42059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstromimport javax.security.auth.x500.X500Principal; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.provider.cert.X509CertImpl; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 464559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Implementation of the class OpenSSLSocketImpl based on OpenSSL. 474559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <p> 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class only supports SSLv3 and TLSv1. This should be documented elsewhere 49ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * later, for example in the package.html or a separate reference document. 504559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <p> 514559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Extensions to SSLSocket include: 524559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <ul> 534559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <li>handshake timeout 544559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <li>compression methods 554559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <li>session tickets 564559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <li>Server Name Indication 574559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * </ul> 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 59ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrompublic class OpenSSLSocketImpl 60ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom extends javax.net.ssl.SSLSocket 616df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom implements NativeCrypto.SSLHandshakeCallbacks { 62df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom 63ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private int sslNativePointer; 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private InputStream is; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private OutputStream os; 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Object handshakeLock = new Object(); 67ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private final Object readLock = new Object(); 68ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private final Object writeLock = new Object(); 696812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom private SSLParametersImpl sslParameters; 70bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private String[] enabledProtocols; 71bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private String[] enabledCipherSuites; 724559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom private String[] enabledCompressionMethods; 734559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom private boolean useSessionTickets; 744559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom private String hostname; 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private OpenSSLSessionImpl sslSession; 76df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom private final Socket socket; 77df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom private final FileDescriptor fd; 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean autoClose; 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean handshakeStarted = false; 80f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom private final CloseGuard guard = CloseGuard.getUnopened(); 81bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 82bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 83bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Not set to true until the update from native that tells us the 84bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * full handshake is complete, since SSL_do_handshake can return 85bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * before the handshake is completely done due to 86bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * handshake_cutthrough support. 87bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 88bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private boolean handshakeCompleted = false; 89bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ArrayList<HandshakeCompletedListener> listeners; 91a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 92a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom /** 93a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom * Local cache of timeout to avoid getsockopt on every read and 94a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom * write for non-wrapped sockets. Note that 95a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom * OpenSSLSocketImplWrapper overrides setSoTimeout and 96a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom * getSoTimeout to delegate to the wrapped socket. 97a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom */ 98a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom private int timeoutMilliseconds = 0; 99a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1009d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // BEGIN android-added 101a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom private int handshakeTimeoutMilliseconds = -1; // -1 = same as timeout; 0 = infinite 1029d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // END android-added 103a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom private String wrappedHost; 104a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom private int wrappedPort; 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10630da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob private static final AtomicInteger instanceCount = new AtomicInteger(0); 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static int getInstanceCount() { 10930da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob return instanceCount.get(); 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static void updateInstanceCount(int amount) { 11330da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob instanceCount.addAndGet(amount); 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 1 parameter 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param sslParameters Parameters for the SSL 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * context 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1236812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected OpenSSLSocketImpl(SSLParametersImpl sslParameters) throws IOException { 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(); 125df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.socket = this; 126df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.fd = NativeCrypto.getFileDescriptor(socket); 127ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 131bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Create an OpenSSLSocketImpl from an OpenSSLServerSocketImpl 132bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 133bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param sslParameters Parameters for the SSL 134bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * context 135bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @throws IOException if network fails 136bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 1376812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected OpenSSLSocketImpl(SSLParametersImpl sslParameters, 138bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom String[] enabledProtocols, 1394559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String[] enabledCipherSuites, 1404559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String[] enabledCompressionMethods) throws IOException { 141bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom super(); 142df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.socket = this; 143df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.fd = NativeCrypto.getFileDescriptor(socket); 1444559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom init(sslParameters, enabledProtocols, enabledCipherSuites, enabledCompressionMethods); 145bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 146bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 147bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 3 parameters 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1536812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected OpenSSLSocketImpl(String host, int port, SSLParametersImpl sslParameters) 154df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom throws IOException { 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(host, port); 156df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.socket = this; 157df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.fd = NativeCrypto.getFileDescriptor(socket); 158ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 3 parameters: 1st is InetAddress 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1676812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected OpenSSLSocketImpl(InetAddress address, int port, SSLParametersImpl sslParameters) 168df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom throws IOException { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(address, port); 170df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.socket = this; 171df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.fd = NativeCrypto.getFileDescriptor(socket); 172ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 5 parameters: 1st is host 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1820c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom protected OpenSSLSocketImpl(String host, int port, 1830c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom InetAddress clientAddress, int clientPort, 1846812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom SSLParametersImpl sslParameters) 185df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom throws IOException { 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(host, port, clientAddress, clientPort); 187df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.socket = this; 188df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.fd = NativeCrypto.getFileDescriptor(socket); 189ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 5 parameters: 1st is InetAddress 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected OpenSSLSocketImpl(InetAddress address, int port, 1990c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom InetAddress clientAddress, int clientPort, 2006812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom SSLParametersImpl sslParameters) 201df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom throws IOException { 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(address, port, clientAddress, clientPort); 203df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.socket = this; 204df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.fd = NativeCrypto.getFileDescriptor(socket); 205ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructor with 5 parameters: 1st is socket. Enhances an existing socket 210a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom * with SSL functionality. Invoked via OpenSSLSocketImplWrapper constructor. 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected OpenSSLSocketImpl(Socket socket, String host, int port, 2156812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom boolean autoClose, SSLParametersImpl sslParameters) throws IOException { 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(); 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.socket = socket; 218df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom this.fd = NativeCrypto.getFileDescriptor(socket); 219a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom this.wrappedHost = host; 220a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom this.wrappedPort = port; 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.autoClose = autoClose; 222ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 223a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 224a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom // this.timeout is not set intentionally. 225a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom // OpenSSLSocketImplWrapper.getSoTimeout will delegate timeout 226a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom // to wrapped socket 227ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 228ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 229ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom /** 230ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * Initialize the SSL socket and set the certificates for the 231ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * future handshaking. 232ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom */ 2336812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom private void init(SSLParametersImpl sslParameters) throws IOException { 234bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom init(sslParameters, 235bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.getSupportedProtocols(), 2364559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom NativeCrypto.getDefaultCipherSuites(), 2374559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom NativeCrypto.getDefaultCompressionMethods()); 238ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 239ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 240ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom /** 241bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Initialize the SSL socket and set the certificates for the 242bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * future handshaking. 243ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom */ 2446812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom private void init(SSLParametersImpl sslParameters, 245bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom String[] enabledProtocols, 2464559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String[] enabledCipherSuites, 2474559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String[] enabledCompressionMethods) throws IOException { 248bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.sslParameters = sslParameters; 249bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.enabledProtocols = enabledProtocols; 250bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.enabledCipherSuites = enabledCipherSuites; 2514559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom this.enabledCompressionMethods = enabledCompressionMethods; 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project updateInstanceCount(1); 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the suitable session reference from the session cache container. 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return OpenSSLSessionImpl 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 260bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private OpenSSLSessionImpl getCachedClientSession(ClientSessionContext sessionContext) { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (super.getInetAddress() == null || 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostAddress() == null || 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostName() == null) { 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2669acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom OpenSSLSessionImpl session = (OpenSSLSessionImpl) sessionContext.getSession( 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostName(), 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getPort()); 2699acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (session == null) { 2709acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2719acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2729acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom 2739acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom String protocol = session.getProtocol(); 2749acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom boolean protocolFound = false; 2759acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom for (String enabledProtocol : enabledProtocols) { 2769acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (protocol.equals(enabledProtocol)) { 2779acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom protocolFound = true; 2789acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom break; 2799acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2809acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2819acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (!protocolFound) { 2829acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2839acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2849acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom 2859acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom String cipherSuite = session.getCipherSuite(); 2869acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom boolean cipherSuiteFound = false; 2879acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom for (String enabledCipherSuite : enabledCipherSuites) { 2889acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (cipherSuite.equals(enabledCipherSuite)) { 2899acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom cipherSuiteFound = true; 2909acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom break; 2919acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2929acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2939acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (!cipherSuiteFound) { 2949acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2959acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2966df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 2974559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String compressionMethod = session.getCompressionMethod(); 2984559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom boolean compressionMethodFound = false; 2994559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom for (String enabledCompressionMethod : enabledCompressionMethods) { 3004559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom if (compressionMethod.equals(enabledCompressionMethod)) { 3014559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom compressionMethodFound = true; 3024559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom break; 3034559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 3044559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 3054559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom if (!compressionMethodFound) { 3064559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return null; 3074559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 3084559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 3099acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return session; 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Ensures that logger is lazily loaded. The outer class seems to load 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * before logging is ready. 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static class LoggerHolder { 317ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom static final Logger logger = Logger.getLogger(OpenSSLSocketImpl.class.getName()); 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Starts a TLS/SSL handshake on this connection using some native methods 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from the OpenSSL library. It can negotiate new encryption keys, change 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher suites, or initiate a new session. The certificate chain is 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * verified if the correspondent property in java.Security is set. All 325ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * listeners are notified at the end of the TLS/SSL handshake. 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if network fails 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 3294559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 330bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public void startHandshake() throws IOException { 331bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom startHandshake(true); 332bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 333bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 334bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 3355f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom * Checks whether the socket is closed, and throws an exception. 3365f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom * 3375f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom * @throws SocketException 3385f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom * if the socket is closed. 3395f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom */ 3405f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom private void checkOpen() throws SocketException { 3415f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom if (isClosed()) { 3425f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom throw new SocketException("Socket is closed"); 3435f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 3445f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 3455f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom 3465f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom /** 347bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Perform the handshake 348bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param full If true, disable handshake cutthrough for a fully synchronous handshake 349bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 350bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public synchronized void startHandshake(boolean full) throws IOException { 3515f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (handshakeLock) { 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshakeStarted) { 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStarted = true; 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 3606df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // note that this modifies the global seed, not something specific to the connection 3616df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final int seedLengthInBytes = NativeCrypto.RAND_SEED_LENGTH_IN_BYTES; 3626df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final SecureRandom secureRandom = sslParameters.getSecureRandomMember(); 3636df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom if (secureRandom == null) { 3646df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.RAND_load_file("/dev/urandom", seedLengthInBytes); 3656df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } else { 3666df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.RAND_seed(secureRandom.generateSeed(seedLengthInBytes)); 3676df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 3686df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3696df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final boolean client = sslParameters.getUseClientMode(); 3706df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3716df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final int sslCtxNativePointer = (client) ? 3726df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getClientSessionContext().sslCtxNativePointer : 3736df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getServerSessionContext().sslCtxNativePointer; 3746df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 375f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom this.sslNativePointer = 0; 376f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom boolean exception = true; 377f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom try { 378f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sslNativePointer = NativeCrypto.SSL_new(sslCtxNativePointer); 379f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom guard.open("close"); 3806df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 381f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // setup server certificates and private keys. 382f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // clients will receive a call back to request certificates. 383f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (!client) { 384f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom for (String keyType : NativeCrypto.KEY_TYPES) { 385f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom try { 386f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom setCertificate(sslParameters.getKeyManager().chooseServerAlias(keyType, 387f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom null, 388f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom this)); 389f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } catch (CertificateEncodingException e) { 390f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom throw new IOException(e); 391f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 392ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 3936df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 3946df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 395f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.setEnabledProtocols(sslNativePointer, enabledProtocols); 396f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.setEnabledCipherSuites(sslNativePointer, enabledCipherSuites); 397f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (enabledCompressionMethods.length != 0) { 398f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.setEnabledCompressionMethods(sslNativePointer, 399f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom enabledCompressionMethods); 400f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 401f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (useSessionTickets) { 402f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_clear_options(sslNativePointer, NativeCrypto.SSL_OP_NO_TICKET); 403f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 404f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (hostname != null) { 405f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_set_tlsext_host_name(sslNativePointer, hostname); 406f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 407bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 408f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom boolean enableSessionCreation = sslParameters.getEnableSessionCreation(); 409f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (!enableSessionCreation) { 410f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer, 411f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom enableSessionCreation); 412bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 413bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 414f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom AbstractSessionContext sessionContext; 415f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom OpenSSLSessionImpl session; 416f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (client) { 417f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // look for client session to reuse 418f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom ClientSessionContext clientSessionContext = sslParameters.getClientSessionContext(); 419f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sessionContext = clientSessionContext; 420f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom session = getCachedClientSession(clientSessionContext); 421f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (session != null) { 422f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_set_session(sslNativePointer, 423f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom session.sslSessionNativePointer); 424f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 425ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } else { 426f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sessionContext = sslParameters.getServerSessionContext(); 427f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom session = null; 428ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 429059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 430f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // setup peer certificate verification 431f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (client) { 432f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // TODO support for anonymous cipher would require us to 433f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // conditionally use SSL_VERIFY_NONE 434f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } else { 435f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // needing client auth takes priority... 436f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom boolean certRequested = false; 437f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (sslParameters.getNeedClientAuth()) { 438f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_set_verify(sslNativePointer, 439f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_VERIFY_PEER 440f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT); 441f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom certRequested = true; 442f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // ... over just wanting it... 443f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } else if (sslParameters.getWantClientAuth()) { 444f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_set_verify(sslNativePointer, 445f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_VERIFY_PEER); 446f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom certRequested = true; 447f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // ... and it defaults properly so don't call SSL_set_verify in the common case. 448f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } else { 449f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom certRequested = false; 450f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 451f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 452f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (certRequested) { 453f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom X509TrustManager trustManager = sslParameters.getTrustManager(); 454f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom X509Certificate[] issuers = trustManager.getAcceptedIssuers(); 455f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (issuers != null && issuers.length != 0) { 456f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom byte[][] issuersBytes; 457f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom try { 458f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom issuersBytes = NativeCrypto.encodeIssuerX509Principals(issuers); 459f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } catch (CertificateEncodingException e) { 460f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom throw new IOException("Problem encoding principals", e); 461f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 462f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_set_client_CA_list(sslNativePointer, issuersBytes); 463ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 464ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 465ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 466ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 467f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (client && full) { 468f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // we want to do a full synchronous handshake, so turn off cutthrough 469f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_clear_mode(sslNativePointer, 470f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH); 471f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 472ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 473f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // BEGIN android-added 474f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // Temporarily use a different timeout for the handshake process 475f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom int savedTimeoutMilliseconds = getSoTimeout(); 476f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (handshakeTimeoutMilliseconds >= 0) { 477f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom setSoTimeout(handshakeTimeoutMilliseconds); 478f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 479f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // END android-added 480bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 481f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom int sslSessionNativePointer; 482f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom try { 483f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sslSessionNativePointer = NativeCrypto.SSL_do_handshake(sslNativePointer, fd, this, 484f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom getSoTimeout(), client); 485f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } catch (CertificateException e) { 486f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom throw new SSLPeerUnverifiedException(e.getMessage()); 487bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 488f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom byte[] sessionId = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer); 489f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sslSession = (OpenSSLSessionImpl) sessionContext.getSession(sessionId); 490f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (sslSession != null) { 491f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sslSession.lastAccessedTime = System.currentTimeMillis(); 492f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom LoggerHolder.logger.fine("Reused cached session for " 493f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom + getInetAddress() + "."); 494f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom NativeCrypto.SSL_SESSION_free(sslSessionNativePointer); 495f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } else { 496f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (!enableSessionCreation) { 497f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // Should have been prevented by NativeCrypto.SSL_set_session_creation_enabled 498f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom throw new IllegalStateException("SSL Session may not be created"); 499f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 500f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom X509Certificate[] localCertificates 501f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom = createCertChain(NativeCrypto.SSL_get_certificate(sslNativePointer)); 502f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom X509Certificate[] peerCertificates 503f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom = createCertChain(NativeCrypto.SSL_get_peer_cert_chain(sslNativePointer)); 504f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (wrappedHost == null) { 505f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, 506f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom localCertificates, peerCertificates, 507f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom super.getInetAddress().getHostName(), 508f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom super.getPort(), sessionContext); 509f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } else { 510f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, 511f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom localCertificates, peerCertificates, 512f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom wrappedHost, wrappedPort, 513f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sessionContext); 514f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 515f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // if not, putSession later in handshakeCompleted() callback 516f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (handshakeCompleted) { 517f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom sessionContext.putSession(sslSession); 518f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 519f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom LoggerHolder.logger.fine("Created new session for " 520f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom + getInetAddress().getHostName() + "."); 521ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 522f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 523f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // BEGIN android-added 524f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // Restore the original timeout now that the handshake is complete 525f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (handshakeTimeoutMilliseconds >= 0) { 526f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom setSoTimeout(savedTimeoutMilliseconds); 5279d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor } 528f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // END android-added 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 530f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback 531f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (handshakeCompleted) { 532f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom notifyHandshakeCompletedListeners(); 533f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 534ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 535f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom exception = false; 536f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } finally { 537f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // on exceptional exit, free the native content immediate to avoid CloseGuard warning 538f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom if (exception) { 539f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom free(); 540f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 542df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 544df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom /** 545df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom * Return a possibly null array of X509Certificates given the 546df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom * possibly null array of DER encoded bytes. 547df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom */ 548df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom private static X509Certificate[] createCertChain(byte[][] certificatesBytes) { 549df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom if (certificatesBytes == null) { 550df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom return null; 551df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } 552df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom X509Certificate[] certificates = new X509Certificate[certificatesBytes.length]; 553df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom for (int i = 0; i < certificatesBytes.length; i++) { 554df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom try { 555df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom certificates[i] = new X509CertImpl(certificatesBytes[i]); 556df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } catch (IOException e) { 557df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom return null; 558df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } 559df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } 560df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom return certificates; 561bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 563ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom private void setCertificate(String alias) throws CertificateEncodingException, SSLException { 5646df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom if (alias == null) { 5656df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom return; 5666df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 5676df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 5686df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias); 56912cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom byte[] privateKeyBytes = privateKey.getEncoded(); 5706df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_use_PrivateKey(sslNativePointer, privateKeyBytes); 5716df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 5726df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias); 573ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom byte[][] certificateBytes = NativeCrypto.encodeCertificates(certificates); 5746df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_use_certificate(sslNativePointer, certificateBytes); 5756df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 5766df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // checks the last installed private key and certificate, 5776df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // so need to do this once per loop iteration 5786df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_check_private_key(sslNativePointer); 5796df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 5806df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 5816df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom /** 5826df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 5836df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * invoked via JNI from client_cert_cb 5846df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom */ 585059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) 586ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throws CertificateEncodingException, SSLException { 587059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 588059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom String[] keyTypes = new String[keyTypeBytes.length]; 589059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom for (int i = 0; i < keyTypeBytes.length; i++) { 590059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom keyTypes[i] = NativeCrypto.keyType(keyTypeBytes[i]); 591059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 592059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 593059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom X500Principal[] issuers; 594059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom if (asn1DerEncodedPrincipals == null) { 595059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers = null; 596059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } else { 597059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers = new X500Principal[asn1DerEncodedPrincipals.length]; 598059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) { 599059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]); 600059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 601059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 602059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom setCertificate(sslParameters.getKeyManager().chooseClientAlias(keyTypes, issuers, this)); 6036df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 6046df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 6066df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 607bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * invoked via JNI from info_callback 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 609bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public void handshakeCompleted() { 610bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom handshakeCompleted = true; 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 612bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // If sslSession is null, the handshake was completed during 613bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // the call to NativeCrypto.SSL_do_handshake and not during a 614bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // later read operation. That means we do not need to fixup 615bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // the SSLSession and session cache or notify 616bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // HandshakeCompletedListeners, it will be done in 617bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // startHandshake. 618bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (sslSession == null) { 619bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return; 620bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 622bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // reset session id from the native pointer and update the 623bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // appropriate cache. 624bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession.resetId(); 625bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom AbstractSessionContext sessionContext = 626bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom (sslParameters.getUseClientMode()) 627bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom ? sslParameters.getClientSessionContext() 628bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom : sslParameters.getServerSessionContext(); 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sessionContext.putSession(sslSession); 630bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 631bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // let listeners know we are finally done 632bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom notifyHandshakeCompletedListeners(); 633bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 634bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 635bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private void notifyHandshakeCompletedListeners() { 636bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (listeners != null && !listeners.isEmpty()) { 637bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // notify the listeners 638bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom HandshakeCompletedEvent event = 639bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom new HandshakeCompletedEvent(this, sslSession); 640bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom for (HandshakeCompletedListener listener : listeners) { 641bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom try { 642bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom listener.handshakeCompleted(event); 643bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (RuntimeException e) { 644e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // The RI runs the handlers in a separate thread, 645e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // which we do not. But we try to preserve their 646e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // behavior of logging a problem and not killing 647e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // the handshaking thread just because a listener 648e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // has a problem. 649e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom Thread thread = Thread.currentThread(); 650e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom thread.getUncaughtExceptionHandler().uncaughtException(thread, e); 651bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 652bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 653bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 6576df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 658ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 659059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom * @param bytes An array of ASN.1 DER encoded certficates 660bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param authMethod auth algorithm name 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 662bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @throws CertificateException if the certificate is untrusted 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unused") 6656df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom public void verifyCertificateChain(byte[][] bytes, String authMethod) 6666df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom throws CertificateException { 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 668e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom if (bytes == null || bytes.length == 0) { 669e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom throw new SSLException("Peer sent no certificate"); 670e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 671bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom X509Certificate[] peerCertificateChain = new X509Certificate[bytes.length]; 672bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom for (int i = 0; i < bytes.length; i++) { 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project peerCertificateChain[i] = 6746df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom new X509CertImpl( 6756df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom javax.security.cert.X509Certificate.getInstance(bytes[i]).getEncoded()); 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 677bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom boolean client = sslParameters.getUseClientMode(); 678bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client) { 6796df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getTrustManager().checkServerTrusted(peerCertificateChain, 6806df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom authMethod); 681bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else { 6826df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getTrustManager().checkClientTrusted(peerCertificateChain, 6836df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom authMethod); 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 685bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 686bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (CertificateException e) { 687bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw e; 688bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (Exception e) { 689bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new RuntimeException(e); 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an input stream for this SSL socket using native calls to the 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * OpenSSL library. 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return: an input stream for reading bytes from this socket. 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws: <code>IOException</code> if an I/O error occurs when creating 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input stream, the socket is closed, the socket is not 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connected, or the socket input has been shutdown. 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7024559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InputStream getInputStream() throws IOException { 7045f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 705ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (this) { 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (is == null) { 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project is = new SSLInputStream(); 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return is; 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 * Returns an output stream for this SSL socket using native calls to the 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * OpenSSL library. 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an output stream for writing bytes to this socket. 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if an I/O error occurs when creating 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output stream, or no connection to the socket exists. 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7224559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public OutputStream getOutputStream() throws IOException { 7245f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 725ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (this) { 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (os == null) { 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project os = new SSLOutputStream(); 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return os; 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 734bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 735bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * This method is not supported for this SSLSocket implementation 736bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * because reading from an SSLSocket may involve writing to the 737bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * network. 738bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 7394559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void shutdownInput() throws IOException { 741bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new UnsupportedOperationException(); 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 744bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 745bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * This method is not supported for this SSLSocket implementation 746bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * because writing to an SSLSocket may involve reading from the 747bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * network. 748bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 7494559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void shutdownOutput() throws IOException { 751bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new UnsupportedOperationException(); 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This inner class provides input data stream functionality 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the OpenSSL native implementation. It is used to 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read data received via SSL protocol. 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class SSLInputStream extends InputStream { 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLInputStream() throws IOException { 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Note: When startHandshake() throws an exception, no 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SSLInputStream object will be created. 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 765bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSocketImpl.this.startHandshake(false); 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads one byte. If there is no data in the underlying buffer, 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this operation can block until the data will be 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available. 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return read value. 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7754559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 7775f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 7785900e5546059f05d5e58e5732e4d08d83b8b7574Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 779ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (readLock) { 780df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom return NativeCrypto.SSL_read_byte(sslNativePointer, fd, OpenSSLSocketImpl.this, 781df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom getSoTimeout()); 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.InputStream#read(byte[],int,int) 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7894559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(byte[] b, int off, int len) throws IOException { 7915f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 7925900e5546059f05d5e58e5732e4d08d83b8b7574Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 793ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (b == null) { 794ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new NullPointerException("b == null"); 795ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 796ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if ((len | off) < 0 || len > b.length - off) { 797ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new IndexOutOfBoundsException(); 798ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 799ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (0 == len) { 800ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom return 0; 801ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 802ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (readLock) { 803df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom return NativeCrypto.SSL_read(sslNativePointer, fd, OpenSSLSocketImpl.this, 804df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom b, off, len, getSoTimeout()); 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This inner class provides output data stream functionality 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the OpenSSL native implementation. It is used to 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * write data according to the encryption parameters given in SSL context. 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class SSLOutputStream extends OutputStream { 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLOutputStream() throws IOException { 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Note: When startHandshake() throws an exception, no 818ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * SSLOutputStream object will be created. 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 820bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSocketImpl.this.startHandshake(false); 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.OutputStream#write(int) 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8274559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void write(int b) throws IOException { 8295f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 8305900e5546059f05d5e58e5732e4d08d83b8b7574Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 831ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (writeLock) { 832df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom NativeCrypto.SSL_write_byte(sslNativePointer, fd, OpenSSLSocketImpl.this, b); 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.OutputStream#write(byte[],int,int) 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8404559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void write(byte[] b, int start, int len) throws IOException { 8425f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 8435900e5546059f05d5e58e5732e4d08d83b8b7574Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 844ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (b == null) { 845ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new NullPointerException("b == null"); 846ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 847ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if ((len | start) < 0 || len > b.length - start) { 848ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new IndexOutOfBoundsException(); 849ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 850ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (len == 0) { 851ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom return; 852ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 853ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (writeLock) { 854df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom NativeCrypto.SSL_write(sslNativePointer, fd, OpenSSLSocketImpl.this, b, start, len); 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The SSL session used by this connection is returned. The SSL session 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * determines which cipher suite should be used by all connections within 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that session and which identities have the session's client and server. 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method starts the SSL handshake. 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the SSLSession. 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if the handshake fails 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8684559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SSLSession getSession() { 870df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom if (sslSession == null) { 871df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom try { 872df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom startHandshake(true); 873df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } catch (IOException e) { 874df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom // return an invalid session with 875df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" 876df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom return SSLSessionImpl.NULL_SESSION; 877df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslSession; 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Registers a listener to be notified that a SSL handshake 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * was successfully completed on this connection. 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IllegalArgumentException</code> if listener is null. 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8874559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addHandshakeCompletedListener( 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HandshakeCompletedListener listener) { 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listener == null) { 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Provided listener is null"); 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listeners == null) { 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners = new ArrayList(); 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners.add(listener); 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The method removes a registered listener. 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if listener is null or not registered 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9034559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeHandshakeCompletedListener( 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HandshakeCompletedListener listener) { 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listener == null) { 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Provided listener is null"); 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listeners == null) { 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Provided listener is not registered"); 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!listeners.remove(listener)) { 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Provided listener is not registered"); 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if new SSL sessions may be established by this socket. 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the session may be created; false if a session already 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exists and must be resumed. 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9254559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getEnableSessionCreation() { 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getEnableSessionCreation(); 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set a flag for the socket to inhibit or to allow the creation of a new 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SSL sessions. If the flag is set to false, and there are no actual 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sessions to resume, then there will be no successful handshaking. 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param flag true if session may be created; false 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a session already exists and must be resumed. 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9384559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnableSessionCreation(boolean flag) { 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setEnableSessionCreation(flag); 941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the cipher suites which could be used by the SSL connection 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * are returned. 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of cipher suite names 947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9484559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getSupportedCipherSuites() { 950ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return NativeCrypto.getSupportedCipherSuites(); 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the cipher suites that are in use in the actual the SSL 955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection are returned. 956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of cipher suite names 958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9594559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getEnabledCipherSuites() { 961bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return enabledCipherSuites.clone(); 962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method enables the cipher suites listed by 966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * getSupportedCipherSuites(). 967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param suites names of all the cipher suites to 969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * put on use 970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException when one or more of the 971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ciphers in array suites are not supported, or when the array 972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is null. 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9744559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnabledCipherSuites(String[] suites) { 976bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites); 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the protocols' versions that may be used on this SSL 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection. 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of protocols names 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9844559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getSupportedProtocols() { 986ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return NativeCrypto.getSupportedProtocols(); 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the protocols' versions that are in use on this SSL 991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection. 992ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of protocols names 994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getEnabledProtocols() { 997bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return enabledProtocols.clone(); 998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method enables the protocols' versions listed by 1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * getSupportedProtocols(). 1003ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 10044559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @param protocols The names of all the protocols to allow 1005ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException when one or more of the names in the 1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * array are not supported, or when the array is null. 1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 10104559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setEnabledProtocols(String[] protocols) { 1011bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols); 1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 10154559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * The names of the compression methods that may be used on this SSL 10164559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * connection. 10174559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @return an array of compression methods 10184559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10194559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public String[] getSupportedCompressionMethods() { 10204559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return NativeCrypto.getSupportedCompressionMethods(); 10214559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10224559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10234559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 10244559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * The names of the compression methods versions that are in use 10254559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * on this SSL connection. 10264559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10274559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @return an array of compression methods 10284559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10294559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public String[] getEnabledCompressionMethods() { 10304559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return enabledCompressionMethods.clone(); 10314559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10324559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10334559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 10344559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method enables the compression method listed by 10354559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * getSupportedCompressionMethods(). 10364559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10374559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @param methods The names of all the compression methods to allow 10384559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10394559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @throws IllegalArgumentException when one or more of the names in the 10404559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * array are not supported, or when the array is null. 10414559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10424559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setEnabledCompressionMethods (String[] methods) { 10434559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom enabledCompressionMethods = NativeCrypto.checkEnabledCompressionMethods(methods); 10444559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10454559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10464559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 10474559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method enables session ticket support. 10484559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10494559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @param useSessionTickets True to enable session tickets 10504559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10514559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setUseSessionTickets(boolean useSessionTickets) { 10524559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom this.useSessionTickets = useSessionTickets; 10534559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10544559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10554559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 10564559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method gives true back if the SSL socket is set to client mode. 10574559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10584559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @return true if the socket should do the handshaking as client. 10594559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10604559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public boolean getUseSessionTickets() { 10614559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return useSessionTickets; 10624559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10634559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10644559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 10654559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method enables Server Name Indication 10664559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10674559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @param hostname the desired SNI hostname, or null to disable 10684559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10694559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setHostname(String hostname) { 10704559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom this.hostname = hostname; 10714559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10724559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10734559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 10744559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method returns the current SNI hostname 10754559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10764559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @return a host name if SNI is enabled, or null otherwise 10774559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10784559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public String getHostname() { 10794559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return hostname; 10804559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10814559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10824559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method gives true back if the SSL socket is set to client mode. 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the socket should do the handshaking as client. 1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getUseClientMode() { 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getUseClientMode(); 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method set the actual SSL socket to client mode. 1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param mode true if the socket starts in client 1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mode 1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if mode changes during 1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handshake. 1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10994559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 11004559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setUseClientMode(boolean mode) { 1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshakeStarted) { 1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Could not change the mode after the initial handshake has begun."); 1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setUseClientMode(mode); 1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if the SSL socket requests client's authentication. Relevant 1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only for server sockets! 1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if client authentication is desired, false if not. 1113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11144559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getWantClientAuth() { 1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getWantClientAuth(); 1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if the SSL socket needs client's authentication. Relevant 1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only for server sockets! 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if client authentication is desired, false if not. 1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11254559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getNeedClientAuth() { 1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getNeedClientAuth(); 1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the SSL socket to use client's authentication. Relevant only for 1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * server sockets! 1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param need true if client authentication is 1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * desired, false if not. 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11374559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setNeedClientAuth(boolean need) { 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setNeedClientAuth(need); 1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the SSL socket to use client's authentication. Relevant only for 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * server sockets! Notice that in contrast to setNeedClientAuth(..) this 1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method will continue the negotiation if the client decide not to send 1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * authentication credentials. 1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param want true if client authentication is 1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * desired, false if not. 1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11514559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setWantClientAuth(boolean want) { 1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setWantClientAuth(want); 1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method is not supported for SSLSocket implementation. 1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11594559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void sendUrgentData(int data) throws IOException { 1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SocketException( 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Method sendUrgentData() is not supported."); 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method is not supported for SSLSocket implementation. 1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11684559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setOOBInline(boolean on) throws SocketException { 1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SocketException( 1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Methods sendUrgentData, setOOBInline are not supported."); 1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the read timeout on this socket. The SO_TIMEOUT option, is specified 1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in milliseconds. The read operation will block indefinitely for a zero 1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value. 1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout the read timeout value 1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SocketException if an error occurs setting the option 1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11824559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1183a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom public void setSoTimeout(int timeoutMilliseconds) throws SocketException { 1184a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom super.setSoTimeout(timeoutMilliseconds); 1185a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom this.timeoutMilliseconds = timeoutMilliseconds; 1186a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom } 1187a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1188a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom @Override 1189a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom public int getSoTimeout() throws SocketException { 1190a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom return timeoutMilliseconds; 1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11939d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // BEGIN android-added 11949d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor /** 11959d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * Set the handshake timeout on this socket. This timeout is specified in 11969d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * milliseconds and will be used only during the handshake process. 11979d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * 11989d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * @param timeout the handshake timeout value 11999d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor */ 1200a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom public void setHandshakeTimeout(int timeoutMilliseconds) throws SocketException { 1201a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom this.handshakeTimeoutMilliseconds = timeoutMilliseconds; 12029d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor } 12039d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // END android-added 12049d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor 1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the SSL socket. Once closed, a socket is not available for further 1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * use anymore under any circumstance. A new socket must be created. 1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if an I/O error happens during the 1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket's closure. 1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 12124559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // TODO: Close SSL sockets using a background thread so they close 1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // gracefully. 1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (handshakeLock) { 1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshakeStarted) { 1219bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // prevent further attemps to start handshake 1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStarted = true; 1221ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 1223ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom free(); 1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1225df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom if (socket != this) { 1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (autoClose && !socket.isClosed()) socket.close(); 1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!super.isClosed()) super.close(); 1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1231ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 12363e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_interrupt(sslNativePointer); 1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (writeLock) { 1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (readLock) { 1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IOException pendingException = null; 1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Shut down the SSL connection, per se. 1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshakeStarted) { 12475900e5546059f05d5e58e5732e4d08d83b8b7574Brad Fitzpatrick BlockGuard.getThreadPolicy().onNetwork(); 1248df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom NativeCrypto.SSL_shutdown(sslNativePointer, fd, this); 1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException ex) { 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note the exception at this point, but try to continue 1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to clean the rest of this all up before rethrowing. 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pendingException = ex; 1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Even if the above call failed, it is still safe to free 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the native structs, and we need to do so lest we leak 1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * memory. 1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1263ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom free(); 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1265df9c090e85c4d052cdd17b5f981819be86a56737Brian Carlstrom if (socket != this) { 1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (autoClose && !socket.isClosed()) 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project socket.close(); 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!super.isClosed()) 1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.close(); 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (pendingException != null) { 1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw pendingException; 1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1281ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private void free() { 1282ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom if (sslNativePointer == 0) { 1283ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return; 1284ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 1285ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom NativeCrypto.SSL_free(sslNativePointer); 1286ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom sslNativePointer = 0; 1287f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom guard.close(); 1288ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1290e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom @Override protected void finalize() throws Throwable { 1291e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom try { 1292e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom /* 1293e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * Just worry about our own state. Notably we do not try and 1294e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * close anything. The SocketImpl, either our own 1295e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * PlainSocketImpl, or the Socket we are wrapping, will do 1296e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * that. This might mean we do not properly SSL_shutdown, but 1297e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * if you want to do that, properly close the socket yourself. 1298e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * 1299e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * The reason why we don't try to SSL_shutdown, is that there 1300e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * can be a race between finalizers where the PlainSocketImpl 1301e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * finalizer runs first and closes the socket. However, in the 1302e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * meanwhile, the underlying file descriptor could be reused 1303e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * for another purpose. If we call SSL_shutdown, the 1304e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * underlying socket BIOs still have the old file descriptor 1305e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * and will write the close notify to some unsuspecting 1306e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom * reader. 1307e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom */ 1308f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom guard.warnIfOpen(); 1309e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom updateInstanceCount(-1); 1310e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom free(); 1311e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } finally { 1312e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom super.finalize(); 1313e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } 1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1316