Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbedtls by
ssl_cache.c
00001 /* 00002 * SSL session cache implementation 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 /* 00022 * These session callbacks use a simple chained list 00023 * to store and retrieve the session information. 00024 */ 00025 00026 #if !defined(MBEDTLS_CONFIG_FILE) 00027 #include "mbedtls/config.h" 00028 #else 00029 #include MBEDTLS_CONFIG_FILE 00030 #endif 00031 00032 #if defined(MBEDTLS_SSL_CACHE_C) 00033 00034 #if defined(MBEDTLS_PLATFORM_C) 00035 #include "mbedtls/platform.h" 00036 #else 00037 #include <stdlib.h> 00038 #define mbedtls_calloc calloc 00039 #define mbedtls_free free 00040 #endif 00041 00042 #include "mbedtls/ssl_cache.h" 00043 00044 #include <string.h> 00045 00046 void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ) 00047 { 00048 memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) ); 00049 00050 cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT; 00051 cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES; 00052 00053 #if defined(MBEDTLS_THREADING_C) 00054 mbedtls_mutex_init( &cache->mutex ); 00055 #endif 00056 } 00057 00058 int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ) 00059 { 00060 int ret = 1; 00061 #if defined(MBEDTLS_HAVE_TIME) 00062 mbedtls_time_t t = mbedtls_time( NULL ); 00063 #endif 00064 mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; 00065 mbedtls_ssl_cache_entry *cur, *entry; 00066 00067 #if defined(MBEDTLS_THREADING_C) 00068 if( mbedtls_mutex_lock( &cache->mutex ) != 0 ) 00069 return( 1 ); 00070 #endif 00071 00072 cur = cache->chain ; 00073 entry = NULL; 00074 00075 while( cur != NULL ) 00076 { 00077 entry = cur; 00078 cur = cur->next ; 00079 00080 #if defined(MBEDTLS_HAVE_TIME) 00081 if( cache->timeout != 0 && 00082 (int) ( t - entry->timestamp ) > cache->timeout ) 00083 continue; 00084 #endif 00085 00086 if( session->ciphersuite != entry->session .ciphersuite || 00087 session->compression != entry->session .compression || 00088 session->id_len != entry->session .id_len ) 00089 continue; 00090 00091 if( memcmp( session->id, entry->session .id, 00092 entry->session .id_len ) != 0 ) 00093 continue; 00094 00095 memcpy( session->master, entry->session .master, 48 ); 00096 00097 session->verify_result = entry->session .verify_result; 00098 00099 #if defined(MBEDTLS_X509_CRT_PARSE_C) 00100 /* 00101 * Restore peer certificate (without rest of the original chain) 00102 */ 00103 if( entry->peer_cert .p != NULL ) 00104 { 00105 if( ( session->peer_cert = mbedtls_calloc( 1, 00106 sizeof(mbedtls_x509_crt) ) ) == NULL ) 00107 { 00108 ret = 1; 00109 goto exit; 00110 } 00111 00112 mbedtls_x509_crt_init( session->peer_cert ); 00113 if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert .p, 00114 entry->peer_cert .len ) != 0 ) 00115 { 00116 mbedtls_free( session->peer_cert ); 00117 session->peer_cert = NULL; 00118 ret = 1; 00119 goto exit; 00120 } 00121 } 00122 #endif /* MBEDTLS_X509_CRT_PARSE_C */ 00123 00124 ret = 0; 00125 goto exit; 00126 } 00127 00128 exit: 00129 #if defined(MBEDTLS_THREADING_C) 00130 if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) 00131 ret = 1; 00132 #endif 00133 00134 return( ret ); 00135 } 00136 00137 int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ) 00138 { 00139 int ret = 1; 00140 #if defined(MBEDTLS_HAVE_TIME) 00141 mbedtls_time_t t = mbedtls_time( NULL ), oldest = 0; 00142 mbedtls_ssl_cache_entry *old = NULL; 00143 #endif 00144 mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; 00145 mbedtls_ssl_cache_entry *cur, *prv; 00146 int count = 0; 00147 00148 #if defined(MBEDTLS_THREADING_C) 00149 if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 ) 00150 return( ret ); 00151 #endif 00152 00153 cur = cache->chain ; 00154 prv = NULL; 00155 00156 while( cur != NULL ) 00157 { 00158 count++; 00159 00160 #if defined(MBEDTLS_HAVE_TIME) 00161 if( cache->timeout != 0 && 00162 (int) ( t - cur->timestamp ) > cache->timeout ) 00163 { 00164 cur->timestamp = t; 00165 break; /* expired, reuse this slot, update timestamp */ 00166 } 00167 #endif 00168 00169 if( memcmp( session->id, cur->session .id, cur->session .id_len ) == 0 ) 00170 break; /* client reconnected, keep timestamp for session id */ 00171 00172 #if defined(MBEDTLS_HAVE_TIME) 00173 if( oldest == 0 || cur->timestamp < oldest ) 00174 { 00175 oldest = cur->timestamp ; 00176 old = cur; 00177 } 00178 #endif 00179 00180 prv = cur; 00181 cur = cur->next ; 00182 } 00183 00184 if( cur == NULL ) 00185 { 00186 #if defined(MBEDTLS_HAVE_TIME) 00187 /* 00188 * Reuse oldest entry if max_entries reached 00189 */ 00190 if( count >= cache->max_entries ) 00191 { 00192 if( old == NULL ) 00193 { 00194 ret = 1; 00195 goto exit; 00196 } 00197 00198 cur = old; 00199 } 00200 #else /* MBEDTLS_HAVE_TIME */ 00201 /* 00202 * Reuse first entry in chain if max_entries reached, 00203 * but move to last place 00204 */ 00205 if( count >= cache->max_entries ) 00206 { 00207 if( cache->chain == NULL ) 00208 { 00209 ret = 1; 00210 goto exit; 00211 } 00212 00213 cur = cache->chain ; 00214 cache->chain = cur->next ; 00215 cur->next = NULL; 00216 prv->next = cur; 00217 } 00218 #endif /* MBEDTLS_HAVE_TIME */ 00219 else 00220 { 00221 /* 00222 * max_entries not reached, create new entry 00223 */ 00224 cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) ); 00225 if( cur == NULL ) 00226 { 00227 ret = 1; 00228 goto exit; 00229 } 00230 00231 if( prv == NULL ) 00232 cache->chain = cur; 00233 else 00234 prv->next = cur; 00235 } 00236 00237 #if defined(MBEDTLS_HAVE_TIME) 00238 cur->timestamp = t; 00239 #endif 00240 } 00241 00242 memcpy( &cur->session , session, sizeof( mbedtls_ssl_session ) ); 00243 00244 #if defined(MBEDTLS_X509_CRT_PARSE_C) 00245 /* 00246 * If we're reusing an entry, free its certificate first 00247 */ 00248 if( cur->peer_cert .p != NULL ) 00249 { 00250 mbedtls_free( cur->peer_cert .p ); 00251 memset( &cur->peer_cert , 0, sizeof(mbedtls_x509_buf) ); 00252 } 00253 00254 /* 00255 * Store peer certificate 00256 */ 00257 if( session->peer_cert != NULL ) 00258 { 00259 cur->peer_cert .p = mbedtls_calloc( 1, session->peer_cert->raw.len ); 00260 if( cur->peer_cert .p == NULL ) 00261 { 00262 ret = 1; 00263 goto exit; 00264 } 00265 00266 memcpy( cur->peer_cert .p, session->peer_cert->raw.p, 00267 session->peer_cert->raw.len ); 00268 cur->peer_cert .len = session->peer_cert->raw.len; 00269 00270 cur->session .peer_cert = NULL; 00271 } 00272 #endif /* MBEDTLS_X509_CRT_PARSE_C */ 00273 00274 ret = 0; 00275 00276 exit: 00277 #if defined(MBEDTLS_THREADING_C) 00278 if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) 00279 ret = 1; 00280 #endif 00281 00282 return( ret ); 00283 } 00284 00285 #if defined(MBEDTLS_HAVE_TIME) 00286 void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout ) 00287 { 00288 if( timeout < 0 ) timeout = 0; 00289 00290 cache->timeout = timeout; 00291 } 00292 #endif /* MBEDTLS_HAVE_TIME */ 00293 00294 void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max ) 00295 { 00296 if( max < 0 ) max = 0; 00297 00298 cache->max_entries = max; 00299 } 00300 00301 void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ) 00302 { 00303 mbedtls_ssl_cache_entry *cur, *prv; 00304 00305 cur = cache->chain ; 00306 00307 while( cur != NULL ) 00308 { 00309 prv = cur; 00310 cur = cur->next ; 00311 00312 mbedtls_ssl_session_free( &prv->session ); 00313 00314 #if defined(MBEDTLS_X509_CRT_PARSE_C) 00315 mbedtls_free( prv->peer_cert .p ); 00316 #endif /* MBEDTLS_X509_CRT_PARSE_C */ 00317 00318 mbedtls_free( prv ); 00319 } 00320 00321 #if defined(MBEDTLS_THREADING_C) 00322 mbedtls_mutex_free( &cache->mutex ); 00323 #endif 00324 } 00325 00326 #endif /* MBEDTLS_SSL_CACHE_C */
Generated on Tue Jul 12 2022 17:25:42 by
