SSLSessionImpl.java revision 29b3bd4475263c4a16c6850d45aca045ed4a926a
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.xnet.provider.jsse;
19
20import java.security.Principal;
21import java.security.SecureRandom;
22import java.security.cert.Certificate;
23import java.security.cert.CertificateEncodingException;
24import java.security.cert.X509Certificate;
25import java.util.HashMap;
26import java.util.Map;
27import javax.net.ssl.SSLPeerUnverifiedException;
28import javax.net.ssl.SSLSession;
29import javax.net.ssl.SSLSessionBindingEvent;
30import javax.net.ssl.SSLSessionBindingListener;
31import javax.net.ssl.SSLSessionContext;
32import libcore.util.EmptyArray;
33
34public final class SSLSessionImpl implements SSLSession, Cloneable  {
35
36    /** Session object reporting an invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" */
37    public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(null);
38
39    private long creationTime;
40    private boolean isValid = true;
41    private final Map<String, Object> values = new HashMap<String, Object>();
42
43    byte[] id;
44    long lastAccessedTime;
45    ProtocolVersion protocol;
46    CipherSuite cipherSuite;
47    SSLSessionContext context;
48    X509Certificate[] localCertificates;
49    X509Certificate[] peerCertificates;
50    private String peerHost;
51    private int peerPort = -1;
52    byte[] master_secret;
53    byte[] clientRandom;
54    byte[] serverRandom;
55    final boolean isServer;
56
57    public SSLSessionImpl(CipherSuite cipher_suite, SecureRandom secureRandom) {
58        creationTime = System.currentTimeMillis();
59        lastAccessedTime = creationTime;
60        if (cipher_suite == null) {
61            this.cipherSuite = CipherSuite.SSL_NULL_WITH_NULL_NULL;
62            id = EmptyArray.BYTE;
63            isServer = false;
64            isValid = false;
65        } else {
66            this.cipherSuite = cipher_suite;
67            id = new byte[32];
68            secureRandom.nextBytes(id);
69            long time = creationTime / 1000;
70            id[28] = (byte) ((time & 0xFF000000) >>> 24);
71            id[29] = (byte) ((time & 0x00FF0000) >>> 16);
72            id[30] = (byte) ((time & 0x0000FF00) >>> 8);
73            id[31] = (byte) ((time & 0x000000FF));
74            isServer = true;
75        }
76
77    }
78
79    public SSLSessionImpl(SecureRandom secureRandom) {
80        this(null, secureRandom);
81    }
82
83    public int getApplicationBufferSize() {
84        return SSLRecordProtocol.MAX_DATA_LENGTH;
85    }
86
87    public String getCipherSuite() {
88        return cipherSuite.getName();
89    }
90
91    public long getCreationTime() {
92        return creationTime;
93    }
94
95    public byte[] getId() {
96        return id;
97    }
98
99    public long getLastAccessedTime() {
100        return lastAccessedTime;
101    }
102
103    public Certificate[] getLocalCertificates() {
104        return localCertificates;
105    }
106
107    public Principal getLocalPrincipal() {
108        if (localCertificates != null && localCertificates.length > 0) {
109            return localCertificates[0].getSubjectX500Principal();
110        }
111        return null;
112    }
113
114    public int getPacketBufferSize() {
115        return SSLRecordProtocol.MAX_SSL_PACKET_SIZE;
116    }
117
118    public javax.security.cert.X509Certificate[] getPeerCertificateChain()
119            throws SSLPeerUnverifiedException {
120        if (peerCertificates == null) {
121            throw new SSLPeerUnverifiedException("No peer certificate");
122        }
123        javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[peerCertificates.length];
124        for (int i = 0; i < certs.length; i++) {
125            try {
126                certs[i] = javax.security.cert.X509Certificate.getInstance(peerCertificates[i]
127                        .getEncoded());
128            } catch (javax.security.cert.CertificateException ignored) {
129            } catch (CertificateEncodingException ignored) {
130            }
131        }
132        return certs;
133    }
134
135    public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
136        if (peerCertificates == null) {
137            throw new SSLPeerUnverifiedException("No peer certificate");
138        }
139        return peerCertificates;
140    }
141
142    public String getPeerHost() {
143        return peerHost;
144    }
145
146    public int getPeerPort() {
147        return peerPort;
148    }
149
150    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
151        if (peerCertificates == null) {
152            throw new SSLPeerUnverifiedException("No peer certificate");
153        }
154        return peerCertificates[0].getSubjectX500Principal();
155    }
156
157    public String getProtocol() {
158        return (protocol == null) ? "NONE" : protocol.name;
159    }
160
161    public SSLSessionContext getSessionContext() {
162        return context;
163    }
164
165    public Object getValue(String name) {
166        if (name == null) {
167            throw new IllegalArgumentException("name == null");
168        }
169        return values.get(name);
170    }
171
172    public String[] getValueNames() {
173        return values.keySet().toArray(new String[values.size()]);
174    }
175
176    public void invalidate() {
177        isValid = false;
178        context = null;
179    }
180
181    public boolean isValid() {
182        if (isValid && context != null && context.getSessionTimeout() != 0
183                && lastAccessedTime + context.getSessionTimeout() > System.currentTimeMillis()) {
184            isValid = false;
185        }
186        return isValid;
187    }
188
189    public void putValue(String name, Object value) {
190        if (name == null || value == null) {
191            throw new IllegalArgumentException("name == null || value == null");
192        }
193        Object old = values.put(name, value);
194        if (value instanceof SSLSessionBindingListener) {
195            ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name));
196        }
197        if (old instanceof SSLSessionBindingListener) {
198            ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name));
199        }
200
201    }
202
203    public void removeValue(String name) {
204        if (name == null) {
205            throw new IllegalArgumentException("name == null");
206        }
207        Object old = values.remove(name);
208        if (old instanceof SSLSessionBindingListener) {
209            SSLSessionBindingListener listener = (SSLSessionBindingListener) old;
210            listener.valueUnbound(new SSLSessionBindingEvent(this, name));
211        }
212    }
213
214    @Override
215    public Object clone() {
216        try {
217            return super.clone();
218        } catch (CloneNotSupportedException e) {
219            throw new AssertionError(e);
220        }
221    }
222
223    void setPeer(String peerHost, int peerPort) {
224        this.peerHost = peerHost;
225        this.peerPort = peerPort;
226    }
227}
228