xref: /aosp_15_r20/external/mbedtls/library/ssl_cache.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi  *  SSL session cache implementation
3*62c56f98SSadaf Ebrahimi  *
4*62c56f98SSadaf Ebrahimi  *  Copyright The Mbed TLS Contributors
5*62c56f98SSadaf Ebrahimi  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6*62c56f98SSadaf Ebrahimi  */
7*62c56f98SSadaf Ebrahimi /*
8*62c56f98SSadaf Ebrahimi  * These session callbacks use a simple chained list
9*62c56f98SSadaf Ebrahimi  * to store and retrieve the session information.
10*62c56f98SSadaf Ebrahimi  */
11*62c56f98SSadaf Ebrahimi 
12*62c56f98SSadaf Ebrahimi #include "common.h"
13*62c56f98SSadaf Ebrahimi 
14*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_CACHE_C)
15*62c56f98SSadaf Ebrahimi 
16*62c56f98SSadaf Ebrahimi #include "mbedtls/platform.h"
17*62c56f98SSadaf Ebrahimi 
18*62c56f98SSadaf Ebrahimi #include "mbedtls/ssl_cache.h"
19*62c56f98SSadaf Ebrahimi #include "ssl_misc.h"
20*62c56f98SSadaf Ebrahimi #include "mbedtls/error.h"
21*62c56f98SSadaf Ebrahimi 
22*62c56f98SSadaf Ebrahimi #include <string.h>
23*62c56f98SSadaf Ebrahimi 
mbedtls_ssl_cache_init(mbedtls_ssl_cache_context * cache)24*62c56f98SSadaf Ebrahimi void mbedtls_ssl_cache_init(mbedtls_ssl_cache_context *cache)
25*62c56f98SSadaf Ebrahimi {
26*62c56f98SSadaf Ebrahimi     memset(cache, 0, sizeof(mbedtls_ssl_cache_context));
27*62c56f98SSadaf Ebrahimi 
28*62c56f98SSadaf Ebrahimi     cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT;
29*62c56f98SSadaf Ebrahimi     cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES;
30*62c56f98SSadaf Ebrahimi 
31*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
32*62c56f98SSadaf Ebrahimi     mbedtls_mutex_init(&cache->mutex);
33*62c56f98SSadaf Ebrahimi #endif
34*62c56f98SSadaf Ebrahimi }
35*62c56f98SSadaf Ebrahimi 
36*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_cache_find_entry(mbedtls_ssl_cache_context * cache,unsigned char const * session_id,size_t session_id_len,mbedtls_ssl_cache_entry ** dst)37*62c56f98SSadaf Ebrahimi static int ssl_cache_find_entry(mbedtls_ssl_cache_context *cache,
38*62c56f98SSadaf Ebrahimi                                 unsigned char const *session_id,
39*62c56f98SSadaf Ebrahimi                                 size_t session_id_len,
40*62c56f98SSadaf Ebrahimi                                 mbedtls_ssl_cache_entry **dst)
41*62c56f98SSadaf Ebrahimi {
42*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND;
43*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
44*62c56f98SSadaf Ebrahimi     mbedtls_time_t t = mbedtls_time(NULL);
45*62c56f98SSadaf Ebrahimi #endif
46*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_entry *cur;
47*62c56f98SSadaf Ebrahimi 
48*62c56f98SSadaf Ebrahimi     for (cur = cache->chain; cur != NULL; cur = cur->next) {
49*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
50*62c56f98SSadaf Ebrahimi         if (cache->timeout != 0 &&
51*62c56f98SSadaf Ebrahimi             (int) (t - cur->timestamp) > cache->timeout) {
52*62c56f98SSadaf Ebrahimi             continue;
53*62c56f98SSadaf Ebrahimi         }
54*62c56f98SSadaf Ebrahimi #endif
55*62c56f98SSadaf Ebrahimi 
56*62c56f98SSadaf Ebrahimi         if (session_id_len != cur->session_id_len ||
57*62c56f98SSadaf Ebrahimi             memcmp(session_id, cur->session_id,
58*62c56f98SSadaf Ebrahimi                    cur->session_id_len) != 0) {
59*62c56f98SSadaf Ebrahimi             continue;
60*62c56f98SSadaf Ebrahimi         }
61*62c56f98SSadaf Ebrahimi 
62*62c56f98SSadaf Ebrahimi         break;
63*62c56f98SSadaf Ebrahimi     }
64*62c56f98SSadaf Ebrahimi 
65*62c56f98SSadaf Ebrahimi     if (cur != NULL) {
66*62c56f98SSadaf Ebrahimi         *dst = cur;
67*62c56f98SSadaf Ebrahimi         ret = 0;
68*62c56f98SSadaf Ebrahimi     }
69*62c56f98SSadaf Ebrahimi 
70*62c56f98SSadaf Ebrahimi     return ret;
71*62c56f98SSadaf Ebrahimi }
72*62c56f98SSadaf Ebrahimi 
73*62c56f98SSadaf Ebrahimi 
mbedtls_ssl_cache_get(void * data,unsigned char const * session_id,size_t session_id_len,mbedtls_ssl_session * session)74*62c56f98SSadaf Ebrahimi int mbedtls_ssl_cache_get(void *data,
75*62c56f98SSadaf Ebrahimi                           unsigned char const *session_id,
76*62c56f98SSadaf Ebrahimi                           size_t session_id_len,
77*62c56f98SSadaf Ebrahimi                           mbedtls_ssl_session *session)
78*62c56f98SSadaf Ebrahimi {
79*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
80*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
81*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_entry *entry;
82*62c56f98SSadaf Ebrahimi 
83*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
84*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) {
85*62c56f98SSadaf Ebrahimi         return ret;
86*62c56f98SSadaf Ebrahimi     }
87*62c56f98SSadaf Ebrahimi #endif
88*62c56f98SSadaf Ebrahimi 
89*62c56f98SSadaf Ebrahimi     ret = ssl_cache_find_entry(cache, session_id, session_id_len, &entry);
90*62c56f98SSadaf Ebrahimi     if (ret != 0) {
91*62c56f98SSadaf Ebrahimi         goto exit;
92*62c56f98SSadaf Ebrahimi     }
93*62c56f98SSadaf Ebrahimi 
94*62c56f98SSadaf Ebrahimi     ret = mbedtls_ssl_session_load(session,
95*62c56f98SSadaf Ebrahimi                                    entry->session,
96*62c56f98SSadaf Ebrahimi                                    entry->session_len);
97*62c56f98SSadaf Ebrahimi     if (ret != 0) {
98*62c56f98SSadaf Ebrahimi         goto exit;
99*62c56f98SSadaf Ebrahimi     }
100*62c56f98SSadaf Ebrahimi 
101*62c56f98SSadaf Ebrahimi     ret = 0;
102*62c56f98SSadaf Ebrahimi 
103*62c56f98SSadaf Ebrahimi exit:
104*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
105*62c56f98SSadaf Ebrahimi     if (mbedtls_mutex_unlock(&cache->mutex) != 0) {
106*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
107*62c56f98SSadaf Ebrahimi     }
108*62c56f98SSadaf Ebrahimi #endif
109*62c56f98SSadaf Ebrahimi 
110*62c56f98SSadaf Ebrahimi     return ret;
111*62c56f98SSadaf Ebrahimi }
112*62c56f98SSadaf Ebrahimi 
113*62c56f98SSadaf Ebrahimi /* zeroize a cache entry */
ssl_cache_entry_zeroize(mbedtls_ssl_cache_entry * entry)114*62c56f98SSadaf Ebrahimi static void ssl_cache_entry_zeroize(mbedtls_ssl_cache_entry *entry)
115*62c56f98SSadaf Ebrahimi {
116*62c56f98SSadaf Ebrahimi     if (entry == NULL) {
117*62c56f98SSadaf Ebrahimi         return;
118*62c56f98SSadaf Ebrahimi     }
119*62c56f98SSadaf Ebrahimi 
120*62c56f98SSadaf Ebrahimi     /* zeroize and free session structure */
121*62c56f98SSadaf Ebrahimi     if (entry->session != NULL) {
122*62c56f98SSadaf Ebrahimi         mbedtls_zeroize_and_free(entry->session, entry->session_len);
123*62c56f98SSadaf Ebrahimi     }
124*62c56f98SSadaf Ebrahimi 
125*62c56f98SSadaf Ebrahimi     /* zeroize the whole entry structure */
126*62c56f98SSadaf Ebrahimi     mbedtls_platform_zeroize(entry, sizeof(mbedtls_ssl_cache_entry));
127*62c56f98SSadaf Ebrahimi }
128*62c56f98SSadaf Ebrahimi 
129*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_cache_pick_writing_slot(mbedtls_ssl_cache_context * cache,unsigned char const * session_id,size_t session_id_len,mbedtls_ssl_cache_entry ** dst)130*62c56f98SSadaf Ebrahimi static int ssl_cache_pick_writing_slot(mbedtls_ssl_cache_context *cache,
131*62c56f98SSadaf Ebrahimi                                        unsigned char const *session_id,
132*62c56f98SSadaf Ebrahimi                                        size_t session_id_len,
133*62c56f98SSadaf Ebrahimi                                        mbedtls_ssl_cache_entry **dst)
134*62c56f98SSadaf Ebrahimi {
135*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
136*62c56f98SSadaf Ebrahimi     mbedtls_time_t t = mbedtls_time(NULL), oldest = 0;
137*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_HAVE_TIME */
138*62c56f98SSadaf Ebrahimi 
139*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_entry *old = NULL;
140*62c56f98SSadaf Ebrahimi     int count = 0;
141*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_entry *cur, *last;
142*62c56f98SSadaf Ebrahimi 
143*62c56f98SSadaf Ebrahimi     /* Check 1: Is there already an entry with the given session ID?
144*62c56f98SSadaf Ebrahimi      *
145*62c56f98SSadaf Ebrahimi      * If yes, overwrite it.
146*62c56f98SSadaf Ebrahimi      *
147*62c56f98SSadaf Ebrahimi      * If not, `count` will hold the size of the session cache
148*62c56f98SSadaf Ebrahimi      * at the end of this loop, and `last` will point to the last
149*62c56f98SSadaf Ebrahimi      * entry, both of which will be used later. */
150*62c56f98SSadaf Ebrahimi 
151*62c56f98SSadaf Ebrahimi     last = NULL;
152*62c56f98SSadaf Ebrahimi     for (cur = cache->chain; cur != NULL; cur = cur->next) {
153*62c56f98SSadaf Ebrahimi         count++;
154*62c56f98SSadaf Ebrahimi         if (session_id_len == cur->session_id_len &&
155*62c56f98SSadaf Ebrahimi             memcmp(session_id, cur->session_id, cur->session_id_len) == 0) {
156*62c56f98SSadaf Ebrahimi             goto found;
157*62c56f98SSadaf Ebrahimi         }
158*62c56f98SSadaf Ebrahimi         last = cur;
159*62c56f98SSadaf Ebrahimi     }
160*62c56f98SSadaf Ebrahimi 
161*62c56f98SSadaf Ebrahimi     /* Check 2: Is there an outdated entry in the cache?
162*62c56f98SSadaf Ebrahimi      *
163*62c56f98SSadaf Ebrahimi      * If so, overwrite it.
164*62c56f98SSadaf Ebrahimi      *
165*62c56f98SSadaf Ebrahimi      * If not, remember the oldest entry in `old` for later.
166*62c56f98SSadaf Ebrahimi      */
167*62c56f98SSadaf Ebrahimi 
168*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
169*62c56f98SSadaf Ebrahimi     for (cur = cache->chain; cur != NULL; cur = cur->next) {
170*62c56f98SSadaf Ebrahimi         if (cache->timeout != 0 &&
171*62c56f98SSadaf Ebrahimi             (int) (t - cur->timestamp) > cache->timeout) {
172*62c56f98SSadaf Ebrahimi             goto found;
173*62c56f98SSadaf Ebrahimi         }
174*62c56f98SSadaf Ebrahimi 
175*62c56f98SSadaf Ebrahimi         if (oldest == 0 || cur->timestamp < oldest) {
176*62c56f98SSadaf Ebrahimi             oldest = cur->timestamp;
177*62c56f98SSadaf Ebrahimi             old = cur;
178*62c56f98SSadaf Ebrahimi         }
179*62c56f98SSadaf Ebrahimi     }
180*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_HAVE_TIME */
181*62c56f98SSadaf Ebrahimi 
182*62c56f98SSadaf Ebrahimi     /* Check 3: Is there free space in the cache? */
183*62c56f98SSadaf Ebrahimi 
184*62c56f98SSadaf Ebrahimi     if (count < cache->max_entries) {
185*62c56f98SSadaf Ebrahimi         /* Create new entry */
186*62c56f98SSadaf Ebrahimi         cur = mbedtls_calloc(1, sizeof(mbedtls_ssl_cache_entry));
187*62c56f98SSadaf Ebrahimi         if (cur == NULL) {
188*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_ALLOC_FAILED;
189*62c56f98SSadaf Ebrahimi         }
190*62c56f98SSadaf Ebrahimi 
191*62c56f98SSadaf Ebrahimi         /* Append to the end of the linked list. */
192*62c56f98SSadaf Ebrahimi         if (last == NULL) {
193*62c56f98SSadaf Ebrahimi             cache->chain = cur;
194*62c56f98SSadaf Ebrahimi         } else {
195*62c56f98SSadaf Ebrahimi             last->next = cur;
196*62c56f98SSadaf Ebrahimi         }
197*62c56f98SSadaf Ebrahimi 
198*62c56f98SSadaf Ebrahimi         goto found;
199*62c56f98SSadaf Ebrahimi     }
200*62c56f98SSadaf Ebrahimi 
201*62c56f98SSadaf Ebrahimi     /* Last resort: The cache is full and doesn't contain any outdated
202*62c56f98SSadaf Ebrahimi      * elements. In this case, we evict the oldest one, judged by timestamp
203*62c56f98SSadaf Ebrahimi      * (if present) or cache-order. */
204*62c56f98SSadaf Ebrahimi 
205*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
206*62c56f98SSadaf Ebrahimi     if (old == NULL) {
207*62c56f98SSadaf Ebrahimi         /* This should only happen on an ill-configured cache
208*62c56f98SSadaf Ebrahimi          * with max_entries == 0. */
209*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
210*62c56f98SSadaf Ebrahimi     }
211*62c56f98SSadaf Ebrahimi #else /* MBEDTLS_HAVE_TIME */
212*62c56f98SSadaf Ebrahimi     /* Reuse first entry in chain, but move to last place. */
213*62c56f98SSadaf Ebrahimi     if (cache->chain == NULL) {
214*62c56f98SSadaf Ebrahimi         /* This should never happen */
215*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
216*62c56f98SSadaf Ebrahimi     }
217*62c56f98SSadaf Ebrahimi 
218*62c56f98SSadaf Ebrahimi     old = cache->chain;
219*62c56f98SSadaf Ebrahimi     cache->chain = old->next;
220*62c56f98SSadaf Ebrahimi     old->next = NULL;
221*62c56f98SSadaf Ebrahimi     last->next = old;
222*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_HAVE_TIME */
223*62c56f98SSadaf Ebrahimi 
224*62c56f98SSadaf Ebrahimi     /* Now `old` points to the oldest entry to be overwritten. */
225*62c56f98SSadaf Ebrahimi     cur = old;
226*62c56f98SSadaf Ebrahimi 
227*62c56f98SSadaf Ebrahimi found:
228*62c56f98SSadaf Ebrahimi 
229*62c56f98SSadaf Ebrahimi     /* If we're reusing an entry, free it first. */
230*62c56f98SSadaf Ebrahimi     if (cur->session != NULL) {
231*62c56f98SSadaf Ebrahimi         /* `ssl_cache_entry_zeroize` would break the chain,
232*62c56f98SSadaf Ebrahimi          * so we reuse `old` to record `next` temporarily. */
233*62c56f98SSadaf Ebrahimi         old = cur->next;
234*62c56f98SSadaf Ebrahimi         ssl_cache_entry_zeroize(cur);
235*62c56f98SSadaf Ebrahimi         cur->next = old;
236*62c56f98SSadaf Ebrahimi     }
237*62c56f98SSadaf Ebrahimi 
238*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
239*62c56f98SSadaf Ebrahimi     cur->timestamp = t;
240*62c56f98SSadaf Ebrahimi #endif
241*62c56f98SSadaf Ebrahimi 
242*62c56f98SSadaf Ebrahimi     *dst = cur;
243*62c56f98SSadaf Ebrahimi     return 0;
244*62c56f98SSadaf Ebrahimi }
245*62c56f98SSadaf Ebrahimi 
mbedtls_ssl_cache_set(void * data,unsigned char const * session_id,size_t session_id_len,const mbedtls_ssl_session * session)246*62c56f98SSadaf Ebrahimi int mbedtls_ssl_cache_set(void *data,
247*62c56f98SSadaf Ebrahimi                           unsigned char const *session_id,
248*62c56f98SSadaf Ebrahimi                           size_t session_id_len,
249*62c56f98SSadaf Ebrahimi                           const mbedtls_ssl_session *session)
250*62c56f98SSadaf Ebrahimi {
251*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
252*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
253*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_entry *cur;
254*62c56f98SSadaf Ebrahimi 
255*62c56f98SSadaf Ebrahimi     size_t session_serialized_len = 0;
256*62c56f98SSadaf Ebrahimi     unsigned char *session_serialized = NULL;
257*62c56f98SSadaf Ebrahimi 
258*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
259*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) {
260*62c56f98SSadaf Ebrahimi         return ret;
261*62c56f98SSadaf Ebrahimi     }
262*62c56f98SSadaf Ebrahimi #endif
263*62c56f98SSadaf Ebrahimi 
264*62c56f98SSadaf Ebrahimi     ret = ssl_cache_pick_writing_slot(cache,
265*62c56f98SSadaf Ebrahimi                                       session_id, session_id_len,
266*62c56f98SSadaf Ebrahimi                                       &cur);
267*62c56f98SSadaf Ebrahimi     if (ret != 0) {
268*62c56f98SSadaf Ebrahimi         goto exit;
269*62c56f98SSadaf Ebrahimi     }
270*62c56f98SSadaf Ebrahimi 
271*62c56f98SSadaf Ebrahimi     /* Check how much space we need to serialize the session
272*62c56f98SSadaf Ebrahimi      * and allocate a sufficiently large buffer. */
273*62c56f98SSadaf Ebrahimi     ret = mbedtls_ssl_session_save(session, NULL, 0, &session_serialized_len);
274*62c56f98SSadaf Ebrahimi     if (ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) {
275*62c56f98SSadaf Ebrahimi         goto exit;
276*62c56f98SSadaf Ebrahimi     }
277*62c56f98SSadaf Ebrahimi 
278*62c56f98SSadaf Ebrahimi     session_serialized = mbedtls_calloc(1, session_serialized_len);
279*62c56f98SSadaf Ebrahimi     if (session_serialized == NULL) {
280*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
281*62c56f98SSadaf Ebrahimi         goto exit;
282*62c56f98SSadaf Ebrahimi     }
283*62c56f98SSadaf Ebrahimi 
284*62c56f98SSadaf Ebrahimi     /* Now serialize the session into the allocated buffer. */
285*62c56f98SSadaf Ebrahimi     ret = mbedtls_ssl_session_save(session,
286*62c56f98SSadaf Ebrahimi                                    session_serialized,
287*62c56f98SSadaf Ebrahimi                                    session_serialized_len,
288*62c56f98SSadaf Ebrahimi                                    &session_serialized_len);
289*62c56f98SSadaf Ebrahimi     if (ret != 0) {
290*62c56f98SSadaf Ebrahimi         goto exit;
291*62c56f98SSadaf Ebrahimi     }
292*62c56f98SSadaf Ebrahimi 
293*62c56f98SSadaf Ebrahimi     if (session_id_len > sizeof(cur->session_id)) {
294*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
295*62c56f98SSadaf Ebrahimi         goto exit;
296*62c56f98SSadaf Ebrahimi     }
297*62c56f98SSadaf Ebrahimi     cur->session_id_len = session_id_len;
298*62c56f98SSadaf Ebrahimi     memcpy(cur->session_id, session_id, session_id_len);
299*62c56f98SSadaf Ebrahimi 
300*62c56f98SSadaf Ebrahimi     cur->session = session_serialized;
301*62c56f98SSadaf Ebrahimi     cur->session_len = session_serialized_len;
302*62c56f98SSadaf Ebrahimi     session_serialized = NULL;
303*62c56f98SSadaf Ebrahimi 
304*62c56f98SSadaf Ebrahimi     ret = 0;
305*62c56f98SSadaf Ebrahimi 
306*62c56f98SSadaf Ebrahimi exit:
307*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
308*62c56f98SSadaf Ebrahimi     if (mbedtls_mutex_unlock(&cache->mutex) != 0) {
309*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
310*62c56f98SSadaf Ebrahimi     }
311*62c56f98SSadaf Ebrahimi #endif
312*62c56f98SSadaf Ebrahimi 
313*62c56f98SSadaf Ebrahimi     if (session_serialized != NULL) {
314*62c56f98SSadaf Ebrahimi         mbedtls_zeroize_and_free(session_serialized, session_serialized_len);
315*62c56f98SSadaf Ebrahimi         session_serialized = NULL;
316*62c56f98SSadaf Ebrahimi     }
317*62c56f98SSadaf Ebrahimi 
318*62c56f98SSadaf Ebrahimi     return ret;
319*62c56f98SSadaf Ebrahimi }
320*62c56f98SSadaf Ebrahimi 
mbedtls_ssl_cache_remove(void * data,unsigned char const * session_id,size_t session_id_len)321*62c56f98SSadaf Ebrahimi int mbedtls_ssl_cache_remove(void *data,
322*62c56f98SSadaf Ebrahimi                              unsigned char const *session_id,
323*62c56f98SSadaf Ebrahimi                              size_t session_id_len)
324*62c56f98SSadaf Ebrahimi {
325*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
326*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
327*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_entry *entry;
328*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_entry *prev;
329*62c56f98SSadaf Ebrahimi 
330*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
331*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) {
332*62c56f98SSadaf Ebrahimi         return ret;
333*62c56f98SSadaf Ebrahimi     }
334*62c56f98SSadaf Ebrahimi #endif
335*62c56f98SSadaf Ebrahimi 
336*62c56f98SSadaf Ebrahimi     ret = ssl_cache_find_entry(cache, session_id, session_id_len, &entry);
337*62c56f98SSadaf Ebrahimi     /* No valid entry found, exit with success */
338*62c56f98SSadaf Ebrahimi     if (ret != 0) {
339*62c56f98SSadaf Ebrahimi         ret = 0;
340*62c56f98SSadaf Ebrahimi         goto exit;
341*62c56f98SSadaf Ebrahimi     }
342*62c56f98SSadaf Ebrahimi 
343*62c56f98SSadaf Ebrahimi     /* Now we remove the entry from the chain */
344*62c56f98SSadaf Ebrahimi     if (entry == cache->chain) {
345*62c56f98SSadaf Ebrahimi         cache->chain = entry->next;
346*62c56f98SSadaf Ebrahimi         goto free;
347*62c56f98SSadaf Ebrahimi     }
348*62c56f98SSadaf Ebrahimi     for (prev = cache->chain; prev->next != NULL; prev = prev->next) {
349*62c56f98SSadaf Ebrahimi         if (prev->next == entry) {
350*62c56f98SSadaf Ebrahimi             prev->next = entry->next;
351*62c56f98SSadaf Ebrahimi             break;
352*62c56f98SSadaf Ebrahimi         }
353*62c56f98SSadaf Ebrahimi     }
354*62c56f98SSadaf Ebrahimi 
355*62c56f98SSadaf Ebrahimi free:
356*62c56f98SSadaf Ebrahimi     ssl_cache_entry_zeroize(entry);
357*62c56f98SSadaf Ebrahimi     mbedtls_free(entry);
358*62c56f98SSadaf Ebrahimi     ret = 0;
359*62c56f98SSadaf Ebrahimi 
360*62c56f98SSadaf Ebrahimi exit:
361*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
362*62c56f98SSadaf Ebrahimi     if (mbedtls_mutex_unlock(&cache->mutex) != 0) {
363*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
364*62c56f98SSadaf Ebrahimi     }
365*62c56f98SSadaf Ebrahimi #endif
366*62c56f98SSadaf Ebrahimi 
367*62c56f98SSadaf Ebrahimi     return ret;
368*62c56f98SSadaf Ebrahimi }
369*62c56f98SSadaf Ebrahimi 
370*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
mbedtls_ssl_cache_set_timeout(mbedtls_ssl_cache_context * cache,int timeout)371*62c56f98SSadaf Ebrahimi void mbedtls_ssl_cache_set_timeout(mbedtls_ssl_cache_context *cache, int timeout)
372*62c56f98SSadaf Ebrahimi {
373*62c56f98SSadaf Ebrahimi     if (timeout < 0) {
374*62c56f98SSadaf Ebrahimi         timeout = 0;
375*62c56f98SSadaf Ebrahimi     }
376*62c56f98SSadaf Ebrahimi 
377*62c56f98SSadaf Ebrahimi     cache->timeout = timeout;
378*62c56f98SSadaf Ebrahimi }
379*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_HAVE_TIME */
380*62c56f98SSadaf Ebrahimi 
mbedtls_ssl_cache_set_max_entries(mbedtls_ssl_cache_context * cache,int max)381*62c56f98SSadaf Ebrahimi void mbedtls_ssl_cache_set_max_entries(mbedtls_ssl_cache_context *cache, int max)
382*62c56f98SSadaf Ebrahimi {
383*62c56f98SSadaf Ebrahimi     if (max < 0) {
384*62c56f98SSadaf Ebrahimi         max = 0;
385*62c56f98SSadaf Ebrahimi     }
386*62c56f98SSadaf Ebrahimi 
387*62c56f98SSadaf Ebrahimi     cache->max_entries = max;
388*62c56f98SSadaf Ebrahimi }
389*62c56f98SSadaf Ebrahimi 
mbedtls_ssl_cache_free(mbedtls_ssl_cache_context * cache)390*62c56f98SSadaf Ebrahimi void mbedtls_ssl_cache_free(mbedtls_ssl_cache_context *cache)
391*62c56f98SSadaf Ebrahimi {
392*62c56f98SSadaf Ebrahimi     mbedtls_ssl_cache_entry *cur, *prv;
393*62c56f98SSadaf Ebrahimi 
394*62c56f98SSadaf Ebrahimi     cur = cache->chain;
395*62c56f98SSadaf Ebrahimi 
396*62c56f98SSadaf Ebrahimi     while (cur != NULL) {
397*62c56f98SSadaf Ebrahimi         prv = cur;
398*62c56f98SSadaf Ebrahimi         cur = cur->next;
399*62c56f98SSadaf Ebrahimi 
400*62c56f98SSadaf Ebrahimi         ssl_cache_entry_zeroize(prv);
401*62c56f98SSadaf Ebrahimi         mbedtls_free(prv);
402*62c56f98SSadaf Ebrahimi     }
403*62c56f98SSadaf Ebrahimi 
404*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C)
405*62c56f98SSadaf Ebrahimi     mbedtls_mutex_free(&cache->mutex);
406*62c56f98SSadaf Ebrahimi #endif
407*62c56f98SSadaf Ebrahimi     cache->chain = NULL;
408*62c56f98SSadaf Ebrahimi }
409*62c56f98SSadaf Ebrahimi 
410*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_CACHE_C */
411