ssl_cache.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*
  2. * SSL session cache implementation
  3. *
  4. * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * This file is part of mbed TLS (https://tls.mbed.org)
  20. */
  21. /*
  22. * These session callbacks use a simple chained list
  23. * to store and retrieve the session information.
  24. */
  25. #if !defined(MBEDTLS_CONFIG_FILE)
  26. #include "mbedtls/config.h"
  27. #else
  28. #include MBEDTLS_CONFIG_FILE
  29. #endif
  30. #if defined(MBEDTLS_SSL_CACHE_C)
  31. #if defined(MBEDTLS_PLATFORM_C)
  32. #include "mbedtls/platform.h"
  33. #else
  34. #include <stdlib.h>
  35. #define mbedtls_calloc calloc
  36. #define mbedtls_free free
  37. #endif
  38. #include "mbedtls/ssl_cache.h"
  39. #include <string.h>
  40. void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache )
  41. {
  42. memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) );
  43. cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT;
  44. cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES;
  45. #if defined(MBEDTLS_THREADING_C)
  46. mbedtls_mutex_init( &cache->mutex );
  47. #endif
  48. }
  49. int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
  50. {
  51. int ret = 1;
  52. #if defined(MBEDTLS_HAVE_TIME)
  53. mbedtls_time_t t = mbedtls_time( NULL );
  54. #endif
  55. mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
  56. mbedtls_ssl_cache_entry *cur, *entry;
  57. #if defined(MBEDTLS_THREADING_C)
  58. if( mbedtls_mutex_lock( &cache->mutex ) != 0 )
  59. return( 1 );
  60. #endif
  61. cur = cache->chain;
  62. entry = NULL;
  63. while( cur != NULL )
  64. {
  65. entry = cur;
  66. cur = cur->next;
  67. #if defined(MBEDTLS_HAVE_TIME)
  68. if( cache->timeout != 0 &&
  69. (int) ( t - entry->timestamp ) > cache->timeout )
  70. continue;
  71. #endif
  72. if( session->ciphersuite != entry->session.ciphersuite ||
  73. session->compression != entry->session.compression ||
  74. session->id_len != entry->session.id_len )
  75. continue;
  76. if( memcmp( session->id, entry->session.id,
  77. entry->session.id_len ) != 0 )
  78. continue;
  79. memcpy( session->master, entry->session.master, 48 );
  80. session->verify_result = entry->session.verify_result;
  81. #if defined(MBEDTLS_X509_CRT_PARSE_C)
  82. /*
  83. * Restore peer certificate (without rest of the original chain)
  84. */
  85. if( entry->peer_cert.p != NULL )
  86. {
  87. if( ( session->peer_cert = mbedtls_calloc( 1,
  88. sizeof(mbedtls_x509_crt) ) ) == NULL )
  89. {
  90. ret = 1;
  91. goto exit;
  92. }
  93. mbedtls_x509_crt_init( session->peer_cert );
  94. if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p,
  95. entry->peer_cert.len ) != 0 )
  96. {
  97. mbedtls_free( session->peer_cert );
  98. session->peer_cert = NULL;
  99. ret = 1;
  100. goto exit;
  101. }
  102. }
  103. #endif /* MBEDTLS_X509_CRT_PARSE_C */
  104. ret = 0;
  105. goto exit;
  106. }
  107. exit:
  108. #if defined(MBEDTLS_THREADING_C)
  109. if( mbedtls_mutex_unlock( &cache->mutex ) != 0 )
  110. ret = 1;
  111. #endif
  112. return( ret );
  113. }
  114. int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
  115. {
  116. int ret = 1;
  117. #if defined(MBEDTLS_HAVE_TIME)
  118. mbedtls_time_t t = mbedtls_time( NULL ), oldest = 0;
  119. mbedtls_ssl_cache_entry *old = NULL;
  120. #endif
  121. mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
  122. mbedtls_ssl_cache_entry *cur, *prv;
  123. int count = 0;
  124. #if defined(MBEDTLS_THREADING_C)
  125. if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 )
  126. return( ret );
  127. #endif
  128. cur = cache->chain;
  129. prv = NULL;
  130. while( cur != NULL )
  131. {
  132. count++;
  133. #if defined(MBEDTLS_HAVE_TIME)
  134. if( cache->timeout != 0 &&
  135. (int) ( t - cur->timestamp ) > cache->timeout )
  136. {
  137. cur->timestamp = t;
  138. break; /* expired, reuse this slot, update timestamp */
  139. }
  140. #endif
  141. if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 )
  142. break; /* client reconnected, keep timestamp for session id */
  143. #if defined(MBEDTLS_HAVE_TIME)
  144. if( oldest == 0 || cur->timestamp < oldest )
  145. {
  146. oldest = cur->timestamp;
  147. old = cur;
  148. }
  149. #endif
  150. prv = cur;
  151. cur = cur->next;
  152. }
  153. if( cur == NULL )
  154. {
  155. #if defined(MBEDTLS_HAVE_TIME)
  156. /*
  157. * Reuse oldest entry if max_entries reached
  158. */
  159. if( count >= cache->max_entries )
  160. {
  161. if( old == NULL )
  162. {
  163. ret = 1;
  164. goto exit;
  165. }
  166. cur = old;
  167. }
  168. #else /* MBEDTLS_HAVE_TIME */
  169. /*
  170. * Reuse first entry in chain if max_entries reached,
  171. * but move to last place
  172. */
  173. if( count >= cache->max_entries )
  174. {
  175. if( cache->chain == NULL )
  176. {
  177. ret = 1;
  178. goto exit;
  179. }
  180. cur = cache->chain;
  181. cache->chain = cur->next;
  182. cur->next = NULL;
  183. prv->next = cur;
  184. }
  185. #endif /* MBEDTLS_HAVE_TIME */
  186. else
  187. {
  188. /*
  189. * max_entries not reached, create new entry
  190. */
  191. cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) );
  192. if( cur == NULL )
  193. {
  194. ret = 1;
  195. goto exit;
  196. }
  197. if( prv == NULL )
  198. cache->chain = cur;
  199. else
  200. prv->next = cur;
  201. }
  202. #if defined(MBEDTLS_HAVE_TIME)
  203. cur->timestamp = t;
  204. #endif
  205. }
  206. memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) );
  207. #if defined(MBEDTLS_X509_CRT_PARSE_C)
  208. /*
  209. * If we're reusing an entry, free its certificate first
  210. */
  211. if( cur->peer_cert.p != NULL )
  212. {
  213. mbedtls_free( cur->peer_cert.p );
  214. memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) );
  215. }
  216. /*
  217. * Store peer certificate
  218. */
  219. if( session->peer_cert != NULL )
  220. {
  221. cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len );
  222. if( cur->peer_cert.p == NULL )
  223. {
  224. ret = 1;
  225. goto exit;
  226. }
  227. memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
  228. session->peer_cert->raw.len );
  229. cur->peer_cert.len = session->peer_cert->raw.len;
  230. cur->session.peer_cert = NULL;
  231. }
  232. #endif /* MBEDTLS_X509_CRT_PARSE_C */
  233. ret = 0;
  234. exit:
  235. #if defined(MBEDTLS_THREADING_C)
  236. if( mbedtls_mutex_unlock( &cache->mutex ) != 0 )
  237. ret = 1;
  238. #endif
  239. return( ret );
  240. }
  241. #if defined(MBEDTLS_HAVE_TIME)
  242. void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout )
  243. {
  244. if( timeout < 0 ) timeout = 0;
  245. cache->timeout = timeout;
  246. }
  247. #endif /* MBEDTLS_HAVE_TIME */
  248. void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max )
  249. {
  250. if( max < 0 ) max = 0;
  251. cache->max_entries = max;
  252. }
  253. void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
  254. {
  255. mbedtls_ssl_cache_entry *cur, *prv;
  256. cur = cache->chain;
  257. while( cur != NULL )
  258. {
  259. prv = cur;
  260. cur = cur->next;
  261. mbedtls_ssl_session_free( &prv->session );
  262. #if defined(MBEDTLS_X509_CRT_PARSE_C)
  263. mbedtls_free( prv->peer_cert.p );
  264. #endif /* MBEDTLS_X509_CRT_PARSE_C */
  265. mbedtls_free( prv );
  266. }
  267. #if defined(MBEDTLS_THREADING_C)
  268. mbedtls_mutex_free( &cache->mutex );
  269. #endif
  270. }
  271. #endif /* MBEDTLS_SSL_CACHE_C */