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.conscrypt;
19
20import org.conscrypt.util.EmptyArray;
21
22import java.security.Principal;
23import java.security.SecureRandom;
24import java.security.cert.Certificate;
25import java.util.HashMap;
26import javax.net.ssl.SSLPeerUnverifiedException;
27import javax.net.ssl.SSLSession;
28import javax.net.ssl.SSLSessionBindingEvent;
29import javax.net.ssl.SSLSessionBindingListener;
30import javax.net.ssl.SSLSessionContext;
31
32public final class SSLNullSession implements SSLSession, Cloneable {
33
34    /*
35     * Holds default instances so class preloading doesn't create an instance of
36     * it.
37     */
38    private static class DefaultHolder {
39        public static final SSLNullSession NULL_SESSION = new SSLNullSession();
40    }
41
42    private final HashMap<String, Object> values = new HashMap<String, Object>();
43
44    long creationTime;
45    long lastAccessedTime;
46
47    public static SSLSession getNullSession() {
48        return DefaultHolder.NULL_SESSION;
49    }
50
51    public SSLNullSession() {
52        creationTime = System.currentTimeMillis();
53        lastAccessedTime = creationTime;
54    }
55
56    @Override
57    public int getApplicationBufferSize() {
58        return SSLRecordProtocol.MAX_DATA_LENGTH;
59    }
60
61    @Override
62    public String getCipherSuite() {
63        return "SSL_NULL_WITH_NULL_NULL";
64    }
65
66    @Override
67    public long getCreationTime() {
68        return creationTime;
69    }
70
71    @Override
72    public byte[] getId() {
73        return EmptyArray.BYTE;
74    }
75
76    @Override
77    public long getLastAccessedTime() {
78        return lastAccessedTime;
79    }
80
81    @Override
82    public Certificate[] getLocalCertificates() {
83        return null;
84    }
85
86    @Override
87    public Principal getLocalPrincipal() {
88        return null;
89    }
90
91    @Override
92    public int getPacketBufferSize() {
93        return SSLRecordProtocol.MAX_SSL_PACKET_SIZE;
94    }
95
96    @Override
97    public javax.security.cert.X509Certificate[] getPeerCertificateChain()
98            throws SSLPeerUnverifiedException {
99        throw new SSLPeerUnverifiedException("No peer certificate");
100    }
101
102    @Override
103    public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
104        throw new SSLPeerUnverifiedException("No peer certificate");
105    }
106
107    @Override
108    public String getPeerHost() {
109        return null;
110    }
111
112    @Override
113    public int getPeerPort() {
114        return -1;
115    }
116
117    @Override
118    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
119        throw new SSLPeerUnverifiedException("No peer certificate");
120    }
121
122    @Override
123    public String getProtocol() {
124        return "NONE";
125    }
126
127    @Override
128    public SSLSessionContext getSessionContext() {
129        return null;
130    }
131
132    @Override
133    public Object getValue(String name) {
134        if (name == null) {
135            throw new IllegalArgumentException("name == null");
136        }
137        return values.get(name);
138    }
139
140    @Override
141    public String[] getValueNames() {
142        return values.keySet().toArray(new String[values.size()]);
143    }
144
145    @Override
146    public void invalidate() {
147    }
148
149    @Override
150    public boolean isValid() {
151        return false;
152    }
153
154    @Override
155    public void putValue(String name, Object value) {
156        if (name == null || value == null) {
157            throw new IllegalArgumentException("name == null || value == null");
158        }
159        Object old = values.put(name, value);
160        if (value instanceof SSLSessionBindingListener) {
161            ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name));
162        }
163        if (old instanceof SSLSessionBindingListener) {
164            ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name));
165        }
166
167    }
168
169    @Override
170    public void removeValue(String name) {
171        if (name == null) {
172            throw new IllegalArgumentException("name == null");
173        }
174        Object old = values.remove(name);
175        if (old instanceof SSLSessionBindingListener) {
176            SSLSessionBindingListener listener = (SSLSessionBindingListener) old;
177            listener.valueUnbound(new SSLSessionBindingEvent(this, name));
178        }
179    }
180}
181