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