1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.conscrypt;
18
19import javax.net.ssl.SSLSession;
20
21/**
22 * Caches server sessions. Indexes by session ID. Users typically look up
23 * sessions using the ID provided by an SSL client.
24 */
25public class ServerSessionContext extends AbstractSessionContext {
26
27    private SSLServerSessionCache persistentCache;
28
29    public ServerSessionContext() {
30        super(100, 0);
31
32        // TODO make sure SSL_CTX does not automaticaly clear sessions we want it to cache
33        // SSL_CTX_set_session_cache_mode(sslCtxNativePointer, SSL_SESS_CACHE_NO_AUTO_CLEAR);
34
35        // TODO remove SSL_CTX session cache limit so we can manage it
36        // SSL_CTX_sess_set_cache_size(sslCtxNativePointer, 0);
37
38        // TODO override trimToSize and removeEldestEntry to use
39        // SSL_CTX_sessions to remove from native cache
40
41        // Set a trivial session id context. OpenSSL uses this to make
42        // sure you don't reuse sessions externalized with i2d_SSL_SESSION
43        // between apps. However our sessions are either in memory or
44        // exported to a app's SSLServerSessionCache.
45        NativeCrypto.SSL_CTX_set_session_id_context(sslCtxNativePointer, new byte[] { ' ' });
46    }
47
48    public void setPersistentCache(SSLServerSessionCache persistentCache) {
49        this.persistentCache = persistentCache;
50    }
51
52    @Override
53    protected void sessionRemoved(SSLSession session) {}
54
55    @Override
56    public SSLSession getSession(byte[] sessionId) {
57        SSLSession session = super.getSession(sessionId);
58        if (session != null) {
59            return session;
60        }
61
62        // Check persistent cache.
63        if (persistentCache != null) {
64            byte[] data = persistentCache.getSessionData(sessionId);
65            if (data != null) {
66                session = toSession(data, null, -1);
67                if (session != null && session.isValid()) {
68                    super.putSession(session);
69                    return session;
70                }
71            }
72        }
73
74        return null;
75    }
76
77    @Override
78    void putSession(SSLSession session) {
79        super.putSession(session);
80
81        // TODO: In background thread.
82        if (persistentCache != null) {
83            byte[] data = toBytes(session);
84            if (data != null) {
85                persistentCache.putSessionData(session, data);
86            }
87        }
88    }
89}
90