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