1 module hunt.net.secure.conscrypt.ServerSessionContext;
2 
3 // dfmt off
4 version(WITH_HUNT_SECURITY):
5 // dfmt on
6 
7 import hunt.net.secure.conscrypt.AbstractSessionContext;
8 import hunt.net.secure.conscrypt.NativeCrypto;
9 import hunt.net.secure.conscrypt.NativeSslSession;
10 import hunt.net.secure.conscrypt.SSLServerSessionCache;
11 
12 import hunt.net.ssl.SSLSessionContext;
13 // import hunt.net.KeyCertOptions;
14 
15 
16 import hunt.Exceptions;
17 
18 /**
19  * Caches server sessions. Indexes by session ID. Users typically look up
20  * sessions using the ID provided by an SSL client.
21  *
22  */
23 final class ServerSessionContext : AbstractSessionContext {
24     private SSLServerSessionCache persistentCache;
25 
26     this(int maximumSize = 100) {
27         super(maximumSize);
28 
29         // TODO make sure SSL_CTX does not automaticaly clear sessions we want it to cache
30         // SSL_CTX_set_session_cache_mode(sslCtxNativePointer, SSL_SESS_CACHE_NO_AUTO_CLEAR);
31 
32         // TODO remove SSL_CTX session cache limit so we can manage it
33         // SSL_CTX_sess_set_cache_size(sslCtxNativePointer, 0);
34 
35         // TODO override trimToSize and removeEldestEntry to use
36         // SSL_CTX_sessions to remove from native cache
37 
38         // Set a trivial session id context. OpenSSL uses this to make
39         // sure you don't reuse sessions externalized with i2d_SSL_SESSION
40         // between apps. However our sessions are either in memory or
41         // exported to a app's SSLServerSessionCache.
42 
43         NativeCrypto.SSL_CTX_set_session_id_context(sslCtxNativePointer, cast(byte[])[' ']);
44     }
45 
46     // this(KeyCertOptions options, int maximumSize = 100) {
47     //     super(maximumSize, options);
48     //     NativeCrypto.SSL_CTX_set_session_id_context(sslCtxNativePointer, cast(byte[])[' ']);
49     // }
50 
51     /**
52      * Applications should not use this method. Instead use {@link
53      * Conscrypt#setServerSessionCache(SSLContext, SSLServerSessionCache)}.
54      */
55     void setPersistentCache(SSLServerSessionCache persistentCache) {
56         this.persistentCache = persistentCache;
57     }
58 
59     override
60     NativeSslSession getSessionFromPersistentCache(byte[] sessionId) {
61         if (persistentCache !is null) {
62             byte[] data = persistentCache.getSessionData(sessionId);
63             if (data !is null) {
64                 NativeSslSession session = NativeSslSession.newInstance(this, data, null, -1);
65                 if (session !is null && session.isValid()) {
66                     cacheSession(session);
67                     return session;
68                 }
69             }
70         }
71 
72         return null;
73     }
74 
75     override
76     void onBeforeAddSession(NativeSslSession session) {
77         // TODO: Do this in background thread.
78         if (persistentCache !is null) {
79             byte[] data = session.toBytes();
80             if (data !is null) {
81                 persistentCache.putSessionData(session.toSSLSession(), data);
82             }
83         }
84     }
85 
86     override
87     void onBeforeRemoveSession(NativeSslSession session) {
88         // Do nothing.
89     }
90 }