OpenSSLSocketImpl.java revision 5f2e6872311240319509aed64d9f58cd5b64719b
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.xnet.provider.jsse; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.InetAddress; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.Socket; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.SocketException; 256df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstromimport java.security.PrivateKey; 266df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstromimport java.security.SecureRandom; 2712cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstromimport java.security.cert.CertificateEncodingException; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertificateException; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.X509Certificate; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 3130da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybobimport java.util.concurrent.atomic.AtomicInteger; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.logging.Logger; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.HandshakeCompletedEvent; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.HandshakeCompletedListener; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLException; 36bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport javax.net.ssl.SSLPeerUnverifiedException; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSession; 38059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstromimport javax.security.auth.x500.X500Principal; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.provider.cert.X509CertImpl; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 424559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Implementation of the class OpenSSLSocketImpl based on OpenSSL. 434559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <p> 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class only supports SSLv3 and TLSv1. This should be documented elsewhere 45ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * later, for example in the package.html or a separate reference document. 464559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <p> 474559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Extensions to SSLSocket include: 484559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <ul> 494559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <li>handshake timeout 504559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <li>compression methods 514559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <li>session tickets 524559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * <li>Server Name Indication 534559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * </ul> 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 55ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrompublic class OpenSSLSocketImpl 56ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom extends javax.net.ssl.SSLSocket 576df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom implements NativeCrypto.SSLHandshakeCallbacks { 58ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private int sslNativePointer; 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private InputStream is; 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private OutputStream os; 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Object handshakeLock = new Object(); 62ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private final Object readLock = new Object(); 63ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private final Object writeLock = new Object(); 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private SSLParameters sslParameters; 65bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private String[] enabledProtocols; 66bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private String[] enabledCipherSuites; 674559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom private String[] enabledCompressionMethods; 684559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom private boolean useSessionTickets; 694559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom private String hostname; 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private OpenSSLSessionImpl sslSession; 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Socket socket; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean autoClose; 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean handshakeStarted = false; 74bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 75bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 76bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Not set to true until the update from native that tells us the 77bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * full handshake is complete, since SSL_do_handshake can return 78bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * before the handshake is completely done due to 79bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * handshake_cutthrough support. 80bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 81bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private boolean handshakeCompleted = false; 82bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ArrayList<HandshakeCompletedListener> listeners; 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int timeout = 0; 859d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // BEGIN android-added 869d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor private int handshakeTimeout = -1; // -1 = same as timeout; 0 = infinite 879d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // END android-added 88a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom private String wrappedHost; 89a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom private int wrappedPort; 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 9130da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob private static final AtomicInteger instanceCount = new AtomicInteger(0); 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static int getInstanceCount() { 9430da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob return instanceCount.get(); 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static void updateInstanceCount(int amount) { 9830da60bf992bd5f2ef15ffcd8a3ebb17937d23d0crazybob instanceCount.addAndGet(amount); 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 1 parameter 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param sslParameters Parameters for the SSL 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * context 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected OpenSSLSocketImpl(SSLParameters sslParameters) throws IOException { 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(); 110ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 114bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Create an OpenSSLSocketImpl from an OpenSSLServerSocketImpl 115bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 116bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param sslParameters Parameters for the SSL 117bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * context 118bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @throws IOException if network fails 119bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 120bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom protected OpenSSLSocketImpl(SSLParameters sslParameters, 121bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom String[] enabledProtocols, 1224559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String[] enabledCipherSuites, 1234559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String[] enabledCompressionMethods) throws IOException { 124bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom super(); 1254559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom init(sslParameters, enabledProtocols, enabledCipherSuites, enabledCompressionMethods); 126bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 127bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 128bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 3 parameters 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom protected OpenSSLSocketImpl(String host, int port, SSLParameters sslParameters) 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(host, port); 137ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 3 parameters: 1st is InetAddress 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom protected OpenSSLSocketImpl(InetAddress address, int port, SSLParameters sslParameters) 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(address, port); 149ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 5 parameters: 1st is host 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1590c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom protected OpenSSLSocketImpl(String host, int port, 1600c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom InetAddress clientAddress, int clientPort, 1610c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLParameters sslParameters) 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(host, port, clientAddress, clientPort); 164ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor with 5 parameters: 1st is InetAddress 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.UnknownHostException host not defined 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected OpenSSLSocketImpl(InetAddress address, int port, 1740c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom InetAddress clientAddress, int clientPort, 1750c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLParameters sslParameters) 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(address, port, clientAddress, clientPort); 178ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructor with 5 parameters: 1st is socket. Enhances an existing socket 183a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom * with SSL functionality. Invoked via OpenSSLSocketImplWrapper constructor. 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException if network fails 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected OpenSSLSocketImpl(Socket socket, String host, int port, 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean autoClose, SSLParameters sslParameters) throws IOException { 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(); 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.socket = socket; 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.timeout = socket.getSoTimeout(); 192a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom this.wrappedHost = host; 193a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom this.wrappedPort = port; 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.autoClose = autoClose; 195ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom init(sslParameters); 196ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 197ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 198ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom /** 199ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * Initialize the SSL socket and set the certificates for the 200ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * future handshaking. 201ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom */ 202ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private void init(SSLParameters sslParameters) throws IOException { 203bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom init(sslParameters, 204bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.getSupportedProtocols(), 2054559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom NativeCrypto.getDefaultCipherSuites(), 2064559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom NativeCrypto.getDefaultCompressionMethods()); 207ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 208ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 209ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom /** 210bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Initialize the SSL socket and set the certificates for the 211bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * future handshaking. 212ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom */ 213bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private void init(SSLParameters sslParameters, 214bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom String[] enabledProtocols, 2154559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String[] enabledCipherSuites, 2164559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String[] enabledCompressionMethods) throws IOException { 217bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.sslParameters = sslParameters; 218bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.enabledProtocols = enabledProtocols; 219bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.enabledCipherSuites = enabledCipherSuites; 2204559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom this.enabledCompressionMethods = enabledCompressionMethods; 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project updateInstanceCount(1); 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the suitable session reference from the session cache container. 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return OpenSSLSessionImpl 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 229bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private OpenSSLSessionImpl getCachedClientSession(ClientSessionContext sessionContext) { 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (super.getInetAddress() == null || 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostAddress() == null || 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostName() == null) { 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2359acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom OpenSSLSessionImpl session = (OpenSSLSessionImpl) sessionContext.getSession( 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getInetAddress().getHostName(), 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.getPort()); 2389acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (session == null) { 2399acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2409acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2419acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom 2429acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom String protocol = session.getProtocol(); 2439acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom boolean protocolFound = false; 2449acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom for (String enabledProtocol : enabledProtocols) { 2459acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (protocol.equals(enabledProtocol)) { 2469acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom protocolFound = true; 2479acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom break; 2489acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2499acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2509acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (!protocolFound) { 2519acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2529acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2539acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom 2549acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom String cipherSuite = session.getCipherSuite(); 2559acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom boolean cipherSuiteFound = false; 2569acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom for (String enabledCipherSuite : enabledCipherSuites) { 2579acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (cipherSuite.equals(enabledCipherSuite)) { 2589acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom cipherSuiteFound = true; 2599acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom break; 2609acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2619acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2629acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (!cipherSuiteFound) { 2639acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return null; 2649acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 2656df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 2664559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom String compressionMethod = session.getCompressionMethod(); 2674559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom boolean compressionMethodFound = false; 2684559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom for (String enabledCompressionMethod : enabledCompressionMethods) { 2694559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom if (compressionMethod.equals(enabledCompressionMethod)) { 2704559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom compressionMethodFound = true; 2714559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom break; 2724559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 2734559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 2744559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom if (!compressionMethodFound) { 2754559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return null; 2764559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 2774559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 2789acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return session; 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Ensures that logger is lazily loaded. The outer class seems to load 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * before logging is ready. 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static class LoggerHolder { 286ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom static final Logger logger = Logger.getLogger(OpenSSLSocketImpl.class.getName()); 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Starts a TLS/SSL handshake on this connection using some native methods 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from the OpenSSL library. It can negotiate new encryption keys, change 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher suites, or initiate a new session. The certificate chain is 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * verified if the correspondent property in java.Security is set. All 294ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * listeners are notified at the end of the TLS/SSL handshake. 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if network fails 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2984559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 299bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public void startHandshake() throws IOException { 300bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom startHandshake(true); 301bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 302bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 303bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 3045f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom * Checks whether the socket is closed, and throws an exception. 3055f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom * 3065f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom * @throws SocketException 3075f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom * if the socket is closed. 3085f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom */ 3095f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom private void checkOpen() throws SocketException { 3105f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom if (isClosed()) { 3115f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom throw new SocketException("Socket is closed"); 3125f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 3135f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 3145f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom 3155f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom /** 316bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Perform the handshake 317bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param full If true, disable handshake cutthrough for a fully synchronous handshake 318bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 319bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public synchronized void startHandshake(boolean full) throws IOException { 3205f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (handshakeLock) { 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshakeStarted) { 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStarted = true; 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 3296df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // note that this modifies the global seed, not something specific to the connection 3306df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final int seedLengthInBytes = NativeCrypto.RAND_SEED_LENGTH_IN_BYTES; 3316df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final SecureRandom secureRandom = sslParameters.getSecureRandomMember(); 3326df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom if (secureRandom == null) { 3336df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.RAND_load_file("/dev/urandom", seedLengthInBytes); 3346df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } else { 3356df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.RAND_seed(secureRandom.generateSeed(seedLengthInBytes)); 3366df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 3376df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3386df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final boolean client = sslParameters.getUseClientMode(); 3396df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3406df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom final int sslCtxNativePointer = (client) ? 3416df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getClientSessionContext().sslCtxNativePointer : 3426df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getServerSessionContext().sslCtxNativePointer; 3436df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3446df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom this.sslNativePointer = NativeCrypto.SSL_new(sslCtxNativePointer); 3456df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 3466df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // setup server certificates and private keys. 3476df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // clients will receive a call back to request certificates. 3486df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom if (!client) { 3496df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom for (String keyType : NativeCrypto.KEY_TYPES) { 350ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom try { 351ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom setCertificate(sslParameters.getKeyManager().chooseServerAlias(keyType, 352ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom null, 353ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom this)); 354ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } catch (CertificateEncodingException e) { 355ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new IOException(e); 356ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 3576df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 3586df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 3596df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 360bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.setEnabledProtocols(sslNativePointer, enabledProtocols); 361bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.setEnabledCipherSuites(sslNativePointer, enabledCipherSuites); 3624559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom if (enabledCompressionMethods.length != 0) { 3634559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom NativeCrypto.setEnabledCompressionMethods(sslNativePointer, enabledCompressionMethods); 3644559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 3654559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom if (useSessionTickets) { 3664559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom NativeCrypto.SSL_clear_options(sslNativePointer, NativeCrypto.SSL_OP_NO_TICKET); 3674559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 3684559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom if (hostname != null) { 3694559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom NativeCrypto.SSL_set_tlsext_host_name(sslNativePointer, hostname); 3704559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 371bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 372bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom boolean enableSessionCreation = sslParameters.getEnableSessionCreation(); 373bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (!enableSessionCreation) { 374bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer, 375bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom enableSessionCreation); 376bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 377bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 378bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom AbstractSessionContext sessionContext; 379bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSessionImpl session; 380bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client) { 381bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // look for client session to reuse 382bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom ClientSessionContext clientSessionContext = sslParameters.getClientSessionContext(); 383bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sessionContext = clientSessionContext; 384bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom session = getCachedClientSession(clientSessionContext); 385bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (session != null) { 386bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_set_session(sslNativePointer, session.sslSessionNativePointer); 387bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 388bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else { 389bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sessionContext = sslParameters.getServerSessionContext(); 390bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom session = null; 391bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 392bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 393bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // setup peer certificate verification 394bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client) { 3956df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // TODO support for anonymous cipher would require us to 3966df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // conditionally use SSL_VERIFY_NONE 397bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else { 398bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // needing client auth takes priority... 399ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom boolean certRequested = false; 400bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (sslParameters.getNeedClientAuth()) { 401bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_set_verify(sslNativePointer, 402ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom NativeCrypto.SSL_VERIFY_PEER 403ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT); 404ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom certRequested = true; 405bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // ... over just wanting it... 406bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else if (sslParameters.getWantClientAuth()) { 407bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom NativeCrypto.SSL_set_verify(sslNativePointer, 408e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom NativeCrypto.SSL_VERIFY_PEER); 409ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom certRequested = true; 410bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // ... and it defaults properly so we don't need call SSL_set_verify in the common case. 411ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } else { 412ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom certRequested = false; 413ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 414059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 415ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (certRequested) { 416ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom X509Certificate[] issuers = sslParameters.getTrustManager().getAcceptedIssuers(); 417ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (issuers != null) { 418ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom byte[][] issuersBytes; 419ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom try { 420ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom issuersBytes = NativeCrypto.encodeIssuerX509Principals(issuers); 421ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } catch (CertificateEncodingException e) { 422ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new IOException("Problem encoding principals", e); 423ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 424ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom NativeCrypto.SSL_set_client_CA_list(sslNativePointer, issuersBytes); 425ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 426ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 427bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 428bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 429bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client && full) { 430bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // we want to do a full synchronous handshake, so turn off cutthrough 4316df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_clear_mode(sslNativePointer, 4326df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH); 433ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 434ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 435ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // BEGIN android-added 436ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // Temporarily use a different timeout for the handshake process 437ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom int savedTimeout = timeout; 438ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom if (handshakeTimeout >= 0) { 439ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom setSoTimeout(handshakeTimeout); 440ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 441ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // END android-added 442ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 443bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 444ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom Socket socket = this.socket != null ? this.socket : this; 445bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom int sslSessionNativePointer; 446bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom try { 4476df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslSessionNativePointer 4486df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom = NativeCrypto.SSL_do_handshake(sslNativePointer, socket, this, timeout, client); 449bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (CertificateException e) { 450bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new SSLPeerUnverifiedException(e.getMessage()); 451bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 452f002bdddce924e2145a4a2b60592b7a40f4112f6Brian Carlstrom byte[] sessionId = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer); 453bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession = (OpenSSLSessionImpl) sessionContext.getSession(sessionId); 454bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (sslSession != null) { 4559acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom sslSession.lastAccessedTime = System.currentTimeMillis(); 456ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom LoggerHolder.logger.fine("Reused cached session for " 457bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom + getInetAddress() + "."); 458f002bdddce924e2145a4a2b60592b7a40f4112f6Brian Carlstrom NativeCrypto.SSL_SESSION_free(sslSessionNativePointer); 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 460bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (!enableSessionCreation) { 461bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // Should have been prevented by NativeCrypto.SSL_set_session_creation_enabled 462bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new IllegalStateException("SSL Session may not be created"); 463bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 464bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom byte[][] localCertificatesBytes = NativeCrypto.SSL_get_certificate(sslNativePointer); 465bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom X509Certificate[] localCertificates; 466bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (localCertificatesBytes == null) { 467bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom localCertificates = null; 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 469bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom localCertificates = new X509Certificate[localCertificatesBytes.length]; 470bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom for (int i = 0; i < localCertificatesBytes.length; i++) { 471059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom localCertificates[i] = new X509CertImpl(localCertificatesBytes[i]); 472bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 473ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 475a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom if (wrappedHost == null) { 476bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates, 477ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom super.getInetAddress().getHostName(), 478ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom super.getPort(), sessionContext); 479ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } else { 480bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates, 481a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom wrappedHost, wrappedPort, 482ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom sessionContext); 483ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 4840c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom // if not, putSession later in handshakeCompleted() callback 485bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (handshakeCompleted) { 486ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom sessionContext.putSession(sslSession); 4879d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor } 488bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom LoggerHolder.logger.fine("Created new session for " 489bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom + getInetAddress().getHostName() + "."); 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 492ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // BEGIN android-added 493ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // Restore the original timeout now that the handshake is complete 494ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom if (handshakeTimeout >= 0) { 495ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom setSoTimeout(savedTimeout); 496ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 497ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // END android-added 498ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 4990c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback 500bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (handshakeCompleted) { 501bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom notifyHandshakeCompletedListeners(); 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 504bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 506ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom private void setCertificate(String alias) throws CertificateEncodingException, SSLException { 5076df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom if (alias == null) { 5086df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom return; 5096df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 5106df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 5116df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias); 51212cd1f00c2fa1a7f37bf644cecdf7588bdc0b0a9Brian Carlstrom byte[] privateKeyBytes = privateKey.getEncoded(); 5136df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_use_PrivateKey(sslNativePointer, privateKeyBytes); 5146df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 5156df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias); 516ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom byte[][] certificateBytes = NativeCrypto.encodeCertificates(certificates); 5176df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_use_certificate(sslNativePointer, certificateBytes); 5186df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 5196df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // checks the last installed private key and certificate, 5206df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom // so need to do this once per loop iteration 5216df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom NativeCrypto.SSL_check_private_key(sslNativePointer); 5226df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 5236df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 5246df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom /** 5256df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 5266df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * invoked via JNI from client_cert_cb 5276df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom */ 528059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) 529ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throws CertificateEncodingException, SSLException { 530059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 531059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom String[] keyTypes = new String[keyTypeBytes.length]; 532059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom for (int i = 0; i < keyTypeBytes.length; i++) { 533059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom keyTypes[i] = NativeCrypto.keyType(keyTypeBytes[i]); 534059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 535059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 536059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom X500Principal[] issuers; 537059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom if (asn1DerEncodedPrincipals == null) { 538059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers = null; 539059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } else { 540059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers = new X500Principal[asn1DerEncodedPrincipals.length]; 541059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) { 542059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]); 543059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 544059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 545059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom setCertificate(sslParameters.getKeyManager().chooseClientAlias(keyTypes, issuers, this)); 5466df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom } 5476df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 5496df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 550bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * invoked via JNI from info_callback 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 552bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public void handshakeCompleted() { 553bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom handshakeCompleted = true; 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 555bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // If sslSession is null, the handshake was completed during 556bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // the call to NativeCrypto.SSL_do_handshake and not during a 557bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // later read operation. That means we do not need to fixup 558bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // the SSLSession and session cache or notify 559bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // HandshakeCompletedListeners, it will be done in 560bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // startHandshake. 561bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (sslSession == null) { 562bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return; 563bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 565bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // reset session id from the native pointer and update the 566bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // appropriate cache. 567bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sslSession.resetId(); 568bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom AbstractSessionContext sessionContext = 569bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom (sslParameters.getUseClientMode()) 570bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom ? sslParameters.getClientSessionContext() 571bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom : sslParameters.getServerSessionContext(); 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sessionContext.putSession(sslSession); 573bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 574bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // let listeners know we are finally done 575bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom notifyHandshakeCompletedListeners(); 576bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 577bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 578bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private void notifyHandshakeCompletedListeners() { 579bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (listeners != null && !listeners.isEmpty()) { 580bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // notify the listeners 581bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom HandshakeCompletedEvent event = 582bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom new HandshakeCompletedEvent(this, sslSession); 583bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom for (HandshakeCompletedListener listener : listeners) { 584bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom try { 585bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom listener.handshakeCompleted(event); 586bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (RuntimeException e) { 587e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // The RI runs the handlers in a separate thread, 588e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // which we do not. But we try to preserve their 589e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // behavior of logging a problem and not killing 590e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // the handshaking thread just because a listener 591e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom // has a problem. 592e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom Thread thread = Thread.currentThread(); 593e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom thread.getUncaughtExceptionHandler().uncaughtException(thread, e); 594bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 595bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 596bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 6006df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom * Implementation of NativeCrypto.SSLHandshakeCallbacks 601ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 602059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom * @param bytes An array of ASN.1 DER encoded certficates 603bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @param authMethod auth algorithm name 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 605bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * @throws CertificateException if the certificate is untrusted 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("unused") 6086df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom public void verifyCertificateChain(byte[][] bytes, String authMethod) 6096df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom throws CertificateException { 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 611e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom if (bytes == null || bytes.length == 0) { 612e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom throw new SSLException("Peer sent no certificate"); 613e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 614bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom X509Certificate[] peerCertificateChain = new X509Certificate[bytes.length]; 615bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom for (int i = 0; i < bytes.length; i++) { 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project peerCertificateChain[i] = 6176df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom new X509CertImpl( 6186df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom javax.security.cert.X509Certificate.getInstance(bytes[i]).getEncoded()); 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 620bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom boolean client = sslParameters.getUseClientMode(); 621bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (client) { 6226df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getTrustManager().checkServerTrusted(peerCertificateChain, 6236df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom authMethod); 624bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else { 6256df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom sslParameters.getTrustManager().checkClientTrusted(peerCertificateChain, 6266df6339ecd4662d351c622a59533cbbe9f275ffdBrian Carlstrom authMethod); 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 628bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 629bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (CertificateException e) { 630bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw e; 631bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } catch (Exception e) { 632bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new RuntimeException(e); 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an input stream for this SSL socket using native calls to the 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * OpenSSL library. 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return: an input stream for reading bytes from this socket. 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws: <code>IOException</code> if an I/O error occurs when creating 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input stream, the socket is closed, the socket is not 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connected, or the socket input has been shutdown. 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6454559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InputStream getInputStream() throws IOException { 6475f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 648ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (this) { 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (is == null) { 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project is = new SSLInputStream(); 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return is; 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an output stream for this SSL socket using native calls to the 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * OpenSSL library. 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an output stream for writing bytes to this socket. 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if an I/O error occurs when creating 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output stream, or no connection to the socket exists. 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6654559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public OutputStream getOutputStream() throws IOException { 6675f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 668ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (this) { 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (os == null) { 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project os = new SSLOutputStream(); 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return os; 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 677bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 678bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * This method is not supported for this SSLSocket implementation 679bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * because reading from an SSLSocket may involve writing to the 680bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * network. 681bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 6824559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void shutdownInput() throws IOException { 684bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new UnsupportedOperationException(); 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 687bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 688bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * This method is not supported for this SSLSocket implementation 689bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * because writing to an SSLSocket may involve reading from the 690bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * network. 691bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 6924559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void shutdownOutput() throws IOException { 694bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom throw new UnsupportedOperationException(); 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This inner class provides input data stream functionality 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the OpenSSL native implementation. It is used to 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read data received via SSL protocol. 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class SSLInputStream extends InputStream { 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLInputStream() throws IOException { 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Note: When startHandshake() throws an exception, no 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SSLInputStream object will be created. 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 708bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSocketImpl.this.startHandshake(false); 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads one byte. If there is no data in the underlying buffer, 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this operation can block until the data will be 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available. 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return read value. 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7184559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 7205f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 721ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (readLock) { 7223e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom return NativeCrypto.SSL_read_byte(sslNativePointer, timeout); 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.InputStream#read(byte[],int,int) 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7304559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(byte[] b, int off, int len) throws IOException { 7325f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 733ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (b == null) { 734ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new NullPointerException("b == null"); 735ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 736ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if ((len | off) < 0 || len > b.length - off) { 737ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new IndexOutOfBoundsException(); 738ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 739ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (0 == len) { 740ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom return 0; 741ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 742ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (readLock) { 7433e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom return NativeCrypto.SSL_read(sslNativePointer, b, off, len, timeout); 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This inner class provides output data stream functionality 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the OpenSSL native implementation. It is used to 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * write data according to the encryption parameters given in SSL context. 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private class SSLOutputStream extends OutputStream { 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLOutputStream() throws IOException { 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Note: When startHandshake() throws an exception, no 757ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * SSLOutputStream object will be created. 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 759bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSocketImpl.this.startHandshake(false); 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.OutputStream#write(int) 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7664559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void write(int b) throws IOException { 7685f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 769ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (writeLock) { 7703e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_write_byte(sslNativePointer, b); 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Method acts as described in spec for superclass. 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.OutputStream#write(byte[],int,int) 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7784559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void write(byte[] b, int start, int len) throws IOException { 7805f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom checkOpen(); 781ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (b == null) { 782ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new NullPointerException("b == null"); 783ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 784ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if ((len | start) < 0 || len > b.length - start) { 785ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom throw new IndexOutOfBoundsException(); 786ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 787ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom if (len == 0) { 788ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom return; 789ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom } 790ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom synchronized (writeLock) { 7913e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_write(sslNativePointer, b, start, len); 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The SSL session used by this connection is returned. The SSL session 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * determines which cipher suite should be used by all connections within 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that session and which identities have the session's client and server. 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method starts the SSL handshake. 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the SSLSession. 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if the handshake fails 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8054559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SSLSession getSession() { 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 808bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom startHandshake(true); 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // return an invalid session with 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return SSLSessionImpl.NULL_SESSION; 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslSession; 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Registers a listener to be notified that a SSL handshake 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * was successfully completed on this connection. 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IllegalArgumentException</code> if listener is null. 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8224559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addHandshakeCompletedListener( 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HandshakeCompletedListener listener) { 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listener == null) { 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Provided listener is null"); 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listeners == null) { 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners = new ArrayList(); 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project listeners.add(listener); 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The method removes a registered listener. 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if listener is null or not registered 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8384559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeHandshakeCompletedListener( 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project HandshakeCompletedListener listener) { 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listener == null) { 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Provided listener is null"); 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (listeners == null) { 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Provided listener is not registered"); 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!listeners.remove(listener)) { 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Provided listener is not registered"); 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if new SSL sessions may be established by this socket. 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the session may be created; false if a session already 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exists and must be resumed. 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8604559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getEnableSessionCreation() { 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getEnableSessionCreation(); 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set a flag for the socket to inhibit or to allow the creation of a new 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SSL sessions. If the flag is set to false, and there are no actual 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sessions to resume, then there will be no successful handshaking. 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param flag true if session may be created; false 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a session already exists and must be resumed. 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8734559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnableSessionCreation(boolean flag) { 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setEnableSessionCreation(flag); 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the cipher suites which could be used by the SSL connection 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * are returned. 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of cipher suite names 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8834559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getSupportedCipherSuites() { 885ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return NativeCrypto.getSupportedCipherSuites(); 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the cipher suites that are in use in the actual the SSL 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection are returned. 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of cipher suite names 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8944559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getEnabledCipherSuites() { 896bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return enabledCipherSuites.clone(); 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method enables the cipher suites listed by 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * getSupportedCipherSuites(). 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param suites names of all the cipher suites to 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * put on use 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException when one or more of the 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ciphers in array suites are not supported, or when the array 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is null. 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9094559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnabledCipherSuites(String[] suites) { 911bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites); 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the protocols' versions that may be used on this SSL 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection. 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of protocols names 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9194559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getSupportedProtocols() { 921ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return NativeCrypto.getSupportedProtocols(); 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The names of the protocols' versions that are in use on this SSL 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connection. 927ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of protocols names 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getEnabledProtocols() { 932bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return enabledProtocols.clone(); 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method enables the protocols' versions listed by 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * getSupportedProtocols(). 938ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 9394559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @param protocols The names of all the protocols to allow 940ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * 941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException when one or more of the names in the 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * array are not supported, or when the array is null. 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 9454559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setEnabledProtocols(String[] protocols) { 946bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols); 947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 9504559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * The names of the compression methods that may be used on this SSL 9514559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * connection. 9524559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @return an array of compression methods 9534559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 9544559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public String[] getSupportedCompressionMethods() { 9554559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return NativeCrypto.getSupportedCompressionMethods(); 9564559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 9574559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 9584559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 9594559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * The names of the compression methods versions that are in use 9604559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * on this SSL connection. 9614559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 9624559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @return an array of compression methods 9634559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 9644559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public String[] getEnabledCompressionMethods() { 9654559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return enabledCompressionMethods.clone(); 9664559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 9674559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 9684559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 9694559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method enables the compression method listed by 9704559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * getSupportedCompressionMethods(). 9714559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 9724559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @param methods The names of all the compression methods to allow 9734559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 9744559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @throws IllegalArgumentException when one or more of the names in the 9754559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * array are not supported, or when the array is null. 9764559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 9774559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setEnabledCompressionMethods (String[] methods) { 9784559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom enabledCompressionMethods = NativeCrypto.checkEnabledCompressionMethods(methods); 9794559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 9804559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 9814559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 9824559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method enables session ticket support. 9834559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 9844559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @param useSessionTickets True to enable session tickets 9854559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 9864559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setUseSessionTickets(boolean useSessionTickets) { 9874559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom this.useSessionTickets = useSessionTickets; 9884559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 9894559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 9904559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 9914559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method gives true back if the SSL socket is set to client mode. 9924559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 9934559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @return true if the socket should do the handshaking as client. 9944559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 9954559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public boolean getUseSessionTickets() { 9964559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return useSessionTickets; 9974559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 9984559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 9994559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 10004559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method enables Server Name Indication 10014559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10024559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @param hostname the desired SNI hostname, or null to disable 10034559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10044559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setHostname(String hostname) { 10054559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom this.hostname = hostname; 10064559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10074559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10084559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 10094559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * This method returns the current SNI hostname 10104559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 10114559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * @return a host name if SNI is enabled, or null otherwise 10124559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom */ 10134559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public String getHostname() { 10144559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom return hostname; 10154559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom } 10164559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom 10174559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom /** 1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method gives true back if the SSL socket is set to client mode. 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the socket should do the handshaking as client. 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getUseClientMode() { 1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getUseClientMode(); 1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method set the actual SSL socket to client mode. 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param mode true if the socket starts in client 1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mode 1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if mode changes during 1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handshake. 1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10344559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 10354559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setUseClientMode(boolean mode) { 1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshakeStarted) { 1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Could not change the mode after the initial handshake has begun."); 1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setUseClientMode(mode); 1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if the SSL socket requests client's authentication. Relevant 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only for server sockets! 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if client authentication is desired, false if not. 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10494559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getWantClientAuth() { 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getWantClientAuth(); 1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns true if the SSL socket needs client's authentication. Relevant 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only for server sockets! 1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if client authentication is desired, false if not. 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10604559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getNeedClientAuth() { 1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getNeedClientAuth(); 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the SSL socket to use client's authentication. Relevant only for 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * server sockets! 1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param need true if client authentication is 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * desired, false if not. 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10724559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setNeedClientAuth(boolean need) { 1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setNeedClientAuth(need); 1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the SSL socket to use client's authentication. Relevant only for 1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * server sockets! Notice that in contrast to setNeedClientAuth(..) this 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method will continue the negotiation if the client decide not to send 1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * authentication credentials. 1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param want true if client authentication is 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * desired, false if not. 1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10864559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setWantClientAuth(boolean want) { 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setWantClientAuth(want); 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method is not supported for SSLSocket implementation. 1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10944559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void sendUrgentData(int data) throws IOException { 1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SocketException( 1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Method sendUrgentData() is not supported."); 1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method is not supported for SSLSocket implementation. 1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11034559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setOOBInline(boolean on) throws SocketException { 1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SocketException( 1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Methods sendUrgentData, setOOBInline are not supported."); 1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the read timeout on this socket. The SO_TIMEOUT option, is specified 1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in milliseconds. The read operation will block indefinitely for a zero 1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value. 1113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout the read timeout value 1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SocketException if an error occurs setting the option 1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11174559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 11184559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setSoTimeout(int timeout) throws SocketException { 1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.setSoTimeout(timeout); 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.timeout = timeout; 1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11239d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // BEGIN android-added 11249d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor /** 11259d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * Set the handshake timeout on this socket. This timeout is specified in 11269d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * milliseconds and will be used only during the handshake process. 11279d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * 11289d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor * @param timeout the handshake timeout value 11299d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor */ 11304559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom public void setHandshakeTimeout(int timeout) throws SocketException { 11319d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor this.handshakeTimeout = timeout; 11329d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor } 11339d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor // END android-added 11349d48f97ae59510bac2b91dac2cc22d519cbf1bc7Dan Egnor 1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the SSL socket. Once closed, a socket is not available for further 1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * use anymore under any circumstance. A new socket must be created. 1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IOException</code> if an I/O error happens during the 1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket's closure. 1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11424559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // TODO: Close SSL sockets using a background thread so they close 1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // gracefully. 1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (handshakeLock) { 1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshakeStarted) { 1149bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom // prevent further attemps to start handshake 1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStarted = true; 1151ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 1153ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom free(); 1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (socket != null) { 1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (autoClose && !socket.isClosed()) socket.close(); 1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!super.isClosed()) super.close(); 1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1161ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11663e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_interrupt(sslNativePointer); 1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (writeLock) { 1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (readLock) { 1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IOException pendingException = null; 1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Shut down the SSL connection, per se. 1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshakeStarted) { 11773e24c53ecc31b840e51869c295785d5a2f8b31ebBrian Carlstrom NativeCrypto.SSL_shutdown(sslNativePointer); 1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException ex) { 1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note the exception at this point, but try to continue 1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to clean the rest of this all up before rethrowing. 1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pendingException = ex; 1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Even if the above call failed, it is still safe to free 1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the native structs, and we need to do so lest we leak 1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * memory. 1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1192ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom free(); 1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (socket != null) { 1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (autoClose && !socket.isClosed()) 1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project socket.close(); 1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!super.isClosed()) 1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.close(); 1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (pendingException != null) { 1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw pendingException; 1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1210ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom private void free() { 1211ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom if (sslNativePointer == 0) { 1212ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom return; 1213ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 1214ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom NativeCrypto.SSL_free(sslNativePointer); 1215ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom sslNativePointer = 0; 1216ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 12184559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom @Override 1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void finalize() throws IOException { 1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1221bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Just worry about our own state. Notably we do not try and 1222bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * close anything. The SocketImpl, either our own 1223bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * PlainSocketImpl, or the Socket we are wrapping, will do 1224bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * that. This might mean we do not properly SSL_shutdown, but 1225bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * if you want to do that, properly close the socket yourself. 1226bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 1227bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * The reason why we don't try to SSL_shutdown, is that there 1228bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * can be a race between finalizers where the PlainSocketImpl 1229bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * finalizer runs first and closes the socket. However, in the 1230bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * meanwhile, the underlying file descriptor could be reused 1231bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * for another purpose. If we call SSL_shutdown, the 1232bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * underlying socket BIOs still have the old file descriptor 1233bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * and will write the close notify to some unsuspecting 1234bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * reader. 1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1236bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom updateInstanceCount(-1); 1237bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom free(); 1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1240