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.security.Principal; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.Certificate; 22df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstromimport java.security.cert.CertificateEncodingException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.X509Certificate; 2429b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilsonimport java.util.HashMap; 254071cf16af7a9a7234856d3ff1837df0da168c6cBrian Carlstromimport java.util.Map; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLPeerUnverifiedException; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSession; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSessionBindingEvent; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSessionBindingListener; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSessionContext; 31df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstromimport javax.security.cert.CertificateException; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implementation of the class OpenSSLSessionImpl 35f002bdddce924e2145a4a2b60592b7a40f4112f6Brian Carlstrom * based on OpenSSL. 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class OpenSSLSessionImpl implements SSLSession { 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39a7ae90de24809b266bb5efdc9033a3261e31f521Brian Carlstrom private long creationTime = 0; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long lastAccessedTime = 0; 41df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom final X509Certificate[] localCertificates; 42df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom final X509Certificate[] peerCertificates; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isValid = true; 4529b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson private final Map<String, Object> values = new HashMap<String, Object>(); 4612e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom private volatile javax.security.cert.X509Certificate[] peerCertificateChain; 47ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom protected int sslSessionNativePointer; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String peerHost; 49a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom private int peerPort = -1; 509acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom private String cipherSuite; 519acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom private String protocol; 52bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private AbstractSessionContext sessionContext; 53bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom private byte[] id; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class constructor creates an SSL session context given the appropriate 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SSL parameters. 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 59bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom protected OpenSSLSessionImpl(int sslSessionNativePointer, X509Certificate[] localCertificates, 60df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom X509Certificate[] peerCertificates, String peerHost, int peerPort, 61df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom AbstractSessionContext sessionContext) { 62ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom this.sslSessionNativePointer = sslSessionNativePointer; 63bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.localCertificates = localCertificates; 64df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom this.peerCertificates = peerCertificates; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.peerHost = peerHost; 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.peerPort = peerPort; 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.sessionContext = sessionContext; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 71ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * Constructs a session from a byte[] containing DER data. This 72ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * allows loading the saved session. 73ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom * @throws IOException 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 75bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom OpenSSLSessionImpl(byte[] derData, 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String peerHost, int peerPort, 77df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom X509Certificate[] peerCertificates, 78ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom AbstractSessionContext sessionContext) 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 80ef628d1464e57552403ad43366e153c1ef50b926Brian Carlstrom this(NativeCrypto.d2i_SSL_SESSION(derData), 81bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom null, 82df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom peerCertificates, 83ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom peerHost, 84ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom peerPort, 85ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom sessionContext); 86ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom // TODO move this check into native code so we can throw an error with more information 87ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom if (this.sslSessionNativePointer == 0) { 88ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom throw new IOException("Invalid session data"); 89ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the identifier of the actual SSL session 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return array of sessions' identifiers. 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 96ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom public byte[] getId() { 97bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (id == null) { 98bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom resetId(); 99bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 100bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom return id; 101ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 102ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 103e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom /** 104e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * Reset the id field to the current value found in the native 105e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * SSL_SESSION. It can change during the lifetime of the session 106e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * because while a session is created during initial handshake, 107e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * with handshake_cutthrough, the SSL_do_handshake may return 108e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * before we have read the session ticket from the server side and 109e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * therefore have computed no id based on the SHA of the ticket. 110e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom */ 111bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom void resetId() { 112f002bdddce924e2145a4a2b60592b7a40f4112f6Brian Carlstrom id = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer); 113bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Get the session object in DER format. This allows saving the session 117f002bdddce924e2145a4a2b60592b7a40f4112f6Brian Carlstrom * data or sharing it with other processes. 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 119ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom byte[] getEncoded() { 120f002bdddce924e2145a4a2b60592b7a40f4112f6Brian Carlstrom return NativeCrypto.i2d_SSL_SESSION(sslSessionNativePointer); 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 122ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the creation time of the SSL session. 12558ee024b48f87139f268a1de5aa0f54fe5edb9c9Elliott Hughes * @return the session's creation time in milliseconds since the epoch 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 127ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom public long getCreationTime() { 128a7ae90de24809b266bb5efdc9033a3261e31f521Brian Carlstrom if (creationTime == 0) { 129a7ae90de24809b266bb5efdc9033a3261e31f521Brian Carlstrom creationTime = NativeCrypto.SSL_SESSION_get_time(sslSessionNativePointer); 130a7ae90de24809b266bb5efdc9033a3261e31f521Brian Carlstrom } 131a7ae90de24809b266bb5efdc9033a3261e31f521Brian Carlstrom return creationTime; 132ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 133ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1354559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the last time this concrete SSL session was accessed. Accessing 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * here is to mean that a new connection with the same SSL context data was 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * established. 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 13958ee024b48f87139f268a1de5aa0f54fe5edb9c9Elliott Hughes * @return the session's last access time in milliseconds since the epoch 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getLastAccessedTime() { 14258ee024b48f87139f268a1de5aa0f54fe5edb9c9Elliott Hughes return (lastAccessedTime == 0) ? getCreationTime() : lastAccessedTime; 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1464559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the largest buffer size for the application's data bound to this 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * concrete SSL session. 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the largest buffer size 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getApplicationBufferSize() { 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return SSLRecordProtocol.MAX_DATA_LENGTH; 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1554559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the largest SSL/TLS packet size one can expect for this concrete 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SSL session. 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the largest packet size 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getPacketBufferSize() { 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return SSLRecordProtocol.MAX_SSL_PACKET_SIZE; 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1644559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the principal (subject) of this concrete SSL session used in the 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handshaking phase of the connection. 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a X509 certificate or null if no principal was defined 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Principal getLocalPrincipal() { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (localCertificates != null && localCertificates.length > 0) { 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return localCertificates[0].getSubjectX500Principal(); 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1774559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the certificate(s) of the principal (subject) of this concrete SSL 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * session used in the handshaking phase of the connection. The OpenSSL 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * native method supports only RSA certificates. 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of certificates (the local one first and then eventually 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that of the certification authority) or null if no certificate 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * were used during the handshaking phase. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Certificate[] getLocalCertificates() { 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return localCertificates; 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1894559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the certificate(s) of the peer in this SSL session 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * used in the handshaking phase of the connection. 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Please notice hat this method is superseded by 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>getPeerCertificates()</code>. 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of X509 certificates (the peer's one first and then 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * eventually that of the certification authority) or null if no 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificate were used during the SSL connection. 19658ee024b48f87139f268a1de5aa0f54fe5edb9c9Elliott Hughes * @throws <code>SSLPeerUnverifiedCertificateException</code> if either a 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not X509 certificate was used (i.e. Kerberos certificates) or the 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * peer could not be verified. 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 200a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom public javax.security.cert.X509Certificate[] getPeerCertificateChain() 201a653cca054f36de92bbef8498be3f0f01d9d6119Brian Carlstrom throws SSLPeerUnverifiedException { 202df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom checkPeerCertificatesPresent(); 20312e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom javax.security.cert.X509Certificate[] result = peerCertificateChain; 20412e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom if (result == null) { 20512e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom // single-check idiom 20612e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom peerCertificateChain = result = createPeerCertificateChain(); 20712e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom } 20812e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom return result; 20912e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom } 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 21112e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom /** 21212e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom * Provide a value to initialize the volatile peerCertificateChain 21312e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom * field based on the native SSL_SESSION 21412e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom */ 21512e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom private javax.security.cert.X509Certificate[] createPeerCertificateChain() 21612e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom throws SSLPeerUnverifiedException { 21712e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom try { 21812e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom javax.security.cert.X509Certificate[] chain 219df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom = new javax.security.cert.X509Certificate[peerCertificates.length]; 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 221df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom for (int i = 0; i < peerCertificates.length; i++) { 222df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom byte[] encoded = peerCertificates[i].getEncoded(); 223df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom chain[i] = javax.security.cert.X509Certificate.getInstance(encoded); 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 22512e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom return chain; 226df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } catch (CertificateEncodingException e) { 2272915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage()); 2282915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom exception.initCause(exception); 2292915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom throw exception; 230df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom } catch (CertificateException e) { 2312915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage()); 2322915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom exception.initCause(exception); 2332915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom throw exception; 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 23829b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson * Return the identity of the peer in this SSL session 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * determined via certificate(s). 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of X509 certificates (the peer's one first and then 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * eventually that of the certification authority) or null if no 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificate were used during the SSL connection. 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>SSLPeerUnverifiedException</code> if either a not X509 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificate was used (i.e. Kerberos certificates) or the peer 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * could not be verified. 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { 248df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom checkPeerCertificatesPresent(); 249df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom return peerCertificates; 25012e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom } 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25212e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom /** 253df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom * Throw SSLPeerUnverifiedException on null or empty peerCertificates array 25412e10c1c6f9324693b1dad96ab57fada2b771f11Brian Carlstrom */ 255df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom private void checkPeerCertificatesPresent() throws SSLPeerUnverifiedException { 256df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom if (peerCertificates == null || peerCertificates.length == 0) { 257df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom throw new SSLPeerUnverifiedException("No peer certificates"); 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The identity of the principal that was used by the peer during the SSL 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handshake phase is returned by this method. 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a X500Principal of the last certificate for X509-based 265df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom * cipher suites. 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>SSLPeerUnverifiedException</code> if either a not X509 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificate was used (i.e. Kerberos certificates) or the 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * peer does not exist. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { 272df349b3eaf4d1fa0643ab722173bc3bf20a266f5Brian Carlstrom checkPeerCertificatesPresent(); 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return peerCertificates[0].getSubjectX500Principal(); 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The peer's host name used in this SSL session is returned. It is the host 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * name of the client for the server; and that of the server for the client. 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It is not a reliable way to get a fully qualified host name: it is mainly 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * used internally to implement links for a temporary cache of SSL sessions. 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the host name of the peer, or null if no information is 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available. 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getPeerHost() { 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return peerHost; 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2914559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the peer's port number for the actual SSL session. It is the port 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number of the client for the server; and that of the server for the 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * client. It is not a reliable way to get a peer's port number: it is 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mainly used internally to implement links for a temporary cache of SSL 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sessions. 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the peer's port number, or -1 if no one is available. 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getPeerPort() { 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return peerPort; 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3044559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns a string identifier of the crypto tools used in the actual SSL 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * session. For example AES_256_WITH_MD5. 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 307ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom public String getCipherSuite() { 3089acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (cipherSuite == null) { 3099acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom String name = NativeCrypto.SSL_SESSION_cipher(sslSessionNativePointer); 3104559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom cipherSuite = NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.get(name); 3119acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (cipherSuite == null) { 3129acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom cipherSuite = name; 3139acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 3149acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 3159acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return cipherSuite; 316ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 317ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3194559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the standard version name of the SSL protocol used in all 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connections pertaining to this SSL session. 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 322ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom public String getProtocol() { 3239acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom if (protocol == null) { 3249acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom protocol = NativeCrypto.SSL_SESSION_get_version(sslSessionNativePointer); 3259acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom } 3269acacc36bafda869c6e9cc63786cdddd995ca96aBrian Carlstrom return protocol; 327ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom } 328ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3304559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the context to which the actual SSL session is bound. A SSL 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * context consists of (1) a possible delegate, (2) a provider and (3) a 332ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes * protocol. 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the SSL context used for this session, or null if it is 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * unavailable. 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SSLSessionContext getSessionContext() { 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sessionContext; 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3414559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns a boolean flag signaling whether a SSL session is valid 3424559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * and available for resuming or joining or not. 3434559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if this session may be resumed. 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isValid() { 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLSessionContext context = sessionContext; 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isValid 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && context != null 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && context.getSessionTimeout() != 0 351a7ae90de24809b266bb5efdc9033a3261e31f521Brian Carlstrom && getCreationTime() + (context.getSessionTimeout() * 1000) 352a7ae90de24809b266bb5efdc9033a3261e31f521Brian Carlstrom < System.currentTimeMillis()) { 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isValid = false; 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isValid; 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It invalidates a SSL session forbidding any resumption. 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void invalidate() { 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isValid = false; 363bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom sessionContext = null; 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3674559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns the object which is bound to the the input parameter name. 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This name is a sort of link to the data of the SSL session's application 36920484654bc7c2407da40226d5188acfc37ee1c2bElliott Hughes * layer, if any exists. 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name the name of the binding to find. 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value bound to that name, or null if the binding does not 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exist. 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IllegalArgumentException</code> if the argument is null. 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object getValue(String name) { 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name == null) { 37829b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson throw new IllegalArgumentException("name == null"); 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 38029b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson return values.get(name); 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3844559b1d37edcb5d7f1da086cf2e3290388d74f46Brian Carlstrom * Returns an array with the names (sort of links) of all the data 38520484654bc7c2407da40226d5188acfc37ee1c2bElliott Hughes * objects of the application layer bound into the SSL session. 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a non-null (possibly empty) array of names of the data objects 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * bound to this SSL session. 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getValueNames() { 39129b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson return values.keySet().toArray(new String[values.size()]); 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A link (name) with the specified value object of the SSL session's 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * application layer data is created or replaced. If the new (or existing) 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value object implements the <code>SSLSessionBindingListener</code> 39820484654bc7c2407da40226d5188acfc37ee1c2bElliott Hughes * interface, that object will be notified in due course. 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name the name of the link (no null are 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * accepted!) 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value data object that shall be bound to 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * name. 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IllegalArgumentException</code> if one or both 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * argument(s) is null. 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putValue(String name, Object value) { 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name == null || value == null) { 40929b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson throw new IllegalArgumentException("name == null || value == null"); 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 41129b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson Object old = values.put(name, value); 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value instanceof SSLSessionBindingListener) { 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ((SSLSessionBindingListener) value) 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .valueBound(new SSLSessionBindingEvent(this, name)); 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 416ecd469016485b59ea886faea126796af968a6b47Elliott Hughes if (old instanceof SSLSessionBindingListener) { 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ((SSLSessionBindingListener) old) 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .valueUnbound(new SSLSessionBindingEvent(this, name)); 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes a link (name) with the specified value object of the SSL 424ecd469016485b59ea886faea126796af968a6b47Elliott Hughes * session's application layer data. 425ecd469016485b59ea886faea126796af968a6b47Elliott Hughes * 426ecd469016485b59ea886faea126796af968a6b47Elliott Hughes * <p>If the value object implements the <code>SSLSessionBindingListener</code> 427ecd469016485b59ea886faea126796af968a6b47Elliott Hughes * interface, the object will receive a <code>valueUnbound</code> notification. 428ecd469016485b59ea886faea126796af968a6b47Elliott Hughes * 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name the name of the link (no null are 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * accepted!) 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws <code>IllegalArgumentException</code> if the argument is null. 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeValue(String name) { 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name == null) { 43529b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson throw new IllegalArgumentException("name == null"); 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 43729b3bd4475263c4a16c6850d45aca045ed4a926aJesse Wilson Object old = values.remove(name); 438ecd469016485b59ea886faea126796af968a6b47Elliott Hughes if (old instanceof SSLSessionBindingListener) { 439ecd469016485b59ea886faea126796af968a6b47Elliott Hughes SSLSessionBindingListener listener = (SSLSessionBindingListener) old; 440ecd469016485b59ea886faea126796af968a6b47Elliott Hughes listener.valueUnbound(new SSLSessionBindingEvent(this, name)); 441ecd469016485b59ea886faea126796af968a6b47Elliott Hughes } 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 444e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom @Override protected void finalize() throws Throwable { 445e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom try { 446e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom NativeCrypto.SSL_SESSION_free(sslSessionNativePointer); 447e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } finally { 448e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom super.finalize(); 449e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 452