mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
ssl_cache.c
00001 /* 00002 * SSL session cache implementation 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 /* 00023 * These session callbacks use a simple chained list 00024 * to store and retrieve the session information. 00025 */ 00026 00027 #if !defined(POLARSSL_CONFIG_FILE) 00028 #include "polarssl/config.h" 00029 #else 00030 #include POLARSSL_CONFIG_FILE 00031 #endif 00032 00033 #if defined(POLARSSL_SSL_CACHE_C) 00034 00035 #include "polarssl/ssl_cache.h" 00036 00037 #include <string.h> 00038 00039 #if defined(POLARSSL_PLATFORM_C) 00040 #include "polarssl/platform.h" 00041 #else 00042 #include <stdlib.h> 00043 #define polarssl_malloc malloc 00044 #define polarssl_free free 00045 #endif 00046 00047 void ssl_cache_init( ssl_cache_context *cache ) 00048 { 00049 memset( cache, 0, sizeof( ssl_cache_context ) ); 00050 00051 cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT; 00052 cache->max_entries = SSL_CACHE_DEFAULT_MAX_ENTRIES; 00053 00054 #if defined(POLARSSL_THREADING_C) 00055 polarssl_mutex_init( &cache->mutex ); 00056 #endif 00057 } 00058 00059 int ssl_cache_get( void *data, ssl_session *session ) 00060 { 00061 int ret = 1; 00062 #if defined(POLARSSL_HAVE_TIME) 00063 time_t t = time( NULL ); 00064 #endif 00065 ssl_cache_context *cache = (ssl_cache_context *) data; 00066 ssl_cache_entry *cur, *entry; 00067 00068 #if defined(POLARSSL_THREADING_C) 00069 if( polarssl_mutex_lock( &cache->mutex ) != 0 ) 00070 return( 1 ); 00071 #endif 00072 00073 cur = cache->chain ; 00074 entry = NULL; 00075 00076 while( cur != NULL ) 00077 { 00078 entry = cur; 00079 cur = cur->next ; 00080 00081 #if defined(POLARSSL_HAVE_TIME) 00082 if( cache->timeout != 0 && 00083 (int) ( t - entry->timestamp ) > cache->timeout ) 00084 continue; 00085 #endif 00086 00087 if( session->ciphersuite != entry->session .ciphersuite || 00088 session->compression != entry->session .compression || 00089 session->length != entry->session .length ) 00090 continue; 00091 00092 if( memcmp( session->id, entry->session .id, 00093 entry->session .length ) != 0 ) 00094 continue; 00095 00096 memcpy( session->master, entry->session .master, 48 ); 00097 00098 session->verify_result = entry->session .verify_result; 00099 00100 #if defined(POLARSSL_X509_CRT_PARSE_C) 00101 /* 00102 * Restore peer certificate (without rest of the original chain) 00103 */ 00104 if( entry->peer_cert .p != NULL ) 00105 { 00106 if( ( session->peer_cert = polarssl_malloc( 00107 sizeof(x509_crt) ) ) == NULL ) 00108 { 00109 ret = 1; 00110 goto exit; 00111 } 00112 00113 x509_crt_init( session->peer_cert ); 00114 if( x509_crt_parse( session->peer_cert, entry->peer_cert .p, 00115 entry->peer_cert .len ) != 0 ) 00116 { 00117 polarssl_free( session->peer_cert ); 00118 session->peer_cert = NULL; 00119 ret = 1; 00120 goto exit; 00121 } 00122 } 00123 #endif /* POLARSSL_X509_CRT_PARSE_C */ 00124 00125 ret = 0; 00126 goto exit; 00127 } 00128 00129 exit: 00130 #if defined(POLARSSL_THREADING_C) 00131 if( polarssl_mutex_unlock( &cache->mutex ) != 0 ) 00132 ret = 1; 00133 #endif 00134 00135 return( ret ); 00136 } 00137 00138 int ssl_cache_set( void *data, const ssl_session *session ) 00139 { 00140 int ret = 1; 00141 #if defined(POLARSSL_HAVE_TIME) 00142 time_t t = time( NULL ), oldest = 0; 00143 ssl_cache_entry *old = NULL; 00144 #endif 00145 ssl_cache_context *cache = (ssl_cache_context *) data; 00146 ssl_cache_entry *cur, *prv; 00147 int count = 0; 00148 00149 #if defined(POLARSSL_THREADING_C) 00150 if( ( ret = polarssl_mutex_lock( &cache->mutex ) ) != 0 ) 00151 return( ret ); 00152 #endif 00153 00154 cur = cache->chain ; 00155 prv = NULL; 00156 00157 while( cur != NULL ) 00158 { 00159 count++; 00160 00161 #if defined(POLARSSL_HAVE_TIME) 00162 if( cache->timeout != 0 && 00163 (int) ( t - cur->timestamp ) > cache->timeout ) 00164 { 00165 cur->timestamp = t; 00166 break; /* expired, reuse this slot, update timestamp */ 00167 } 00168 #endif 00169 00170 if( memcmp( session->id, cur->session .id, cur->session .length ) == 0 ) 00171 break; /* client reconnected, keep timestamp for session id */ 00172 00173 #if defined(POLARSSL_HAVE_TIME) 00174 if( oldest == 0 || cur->timestamp < oldest ) 00175 { 00176 oldest = cur->timestamp ; 00177 old = cur; 00178 } 00179 #endif 00180 00181 prv = cur; 00182 cur = cur->next ; 00183 } 00184 00185 if( cur == NULL ) 00186 { 00187 #if defined(POLARSSL_HAVE_TIME) 00188 /* 00189 * Reuse oldest entry if max_entries reached 00190 */ 00191 if( count >= cache->max_entries ) 00192 { 00193 if( old == NULL ) 00194 { 00195 ret = 1; 00196 goto exit; 00197 } 00198 00199 cur = old; 00200 } 00201 #else /* POLARSSL_HAVE_TIME */ 00202 /* 00203 * Reuse first entry in chain if max_entries reached, 00204 * but move to last place 00205 */ 00206 if( count >= cache->max_entries ) 00207 { 00208 if( cache->chain == NULL ) 00209 { 00210 ret = 1; 00211 goto exit; 00212 } 00213 00214 cur = cache->chain ; 00215 cache->chain = cur->next ; 00216 cur->next = NULL; 00217 prv->next = cur; 00218 } 00219 #endif /* POLARSSL_HAVE_TIME */ 00220 else 00221 { 00222 /* 00223 * max_entries not reached, create new entry 00224 */ 00225 cur = polarssl_malloc( sizeof(ssl_cache_entry) ); 00226 if( cur == NULL ) 00227 { 00228 ret = 1; 00229 goto exit; 00230 } 00231 00232 memset( cur, 0, sizeof(ssl_cache_entry) ); 00233 00234 if( prv == NULL ) 00235 cache->chain = cur; 00236 else 00237 prv->next = cur; 00238 } 00239 00240 #if defined(POLARSSL_HAVE_TIME) 00241 cur->timestamp = t; 00242 #endif 00243 } 00244 00245 memcpy( &cur->session , session, sizeof( ssl_session ) ); 00246 00247 #if defined(POLARSSL_X509_CRT_PARSE_C) 00248 /* 00249 * If we're reusing an entry, free its certificate first 00250 */ 00251 if( cur->peer_cert .p != NULL ) 00252 { 00253 polarssl_free( cur->peer_cert .p ); 00254 memset( &cur->peer_cert , 0, sizeof(x509_buf) ); 00255 } 00256 00257 /* 00258 * Store peer certificate 00259 */ 00260 if( session->peer_cert != NULL ) 00261 { 00262 cur->peer_cert .p = polarssl_malloc( session->peer_cert->raw.len ); 00263 if( cur->peer_cert .p == NULL ) 00264 { 00265 ret = 1; 00266 goto exit; 00267 } 00268 00269 memcpy( cur->peer_cert .p, session->peer_cert->raw.p, 00270 session->peer_cert->raw.len ); 00271 cur->peer_cert .len = session->peer_cert->raw.len; 00272 00273 cur->session .peer_cert = NULL; 00274 } 00275 #endif /* POLARSSL_X509_CRT_PARSE_C */ 00276 00277 ret = 0; 00278 00279 exit: 00280 #if defined(POLARSSL_THREADING_C) 00281 if( polarssl_mutex_unlock( &cache->mutex ) != 0 ) 00282 ret = 1; 00283 #endif 00284 00285 return( ret ); 00286 } 00287 00288 #if defined(POLARSSL_HAVE_TIME) 00289 void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout ) 00290 { 00291 if( timeout < 0 ) timeout = 0; 00292 00293 cache->timeout = timeout; 00294 } 00295 #endif /* POLARSSL_HAVE_TIME */ 00296 00297 void ssl_cache_set_max_entries( ssl_cache_context *cache, int max ) 00298 { 00299 if( max < 0 ) max = 0; 00300 00301 cache->max_entries = max; 00302 } 00303 00304 void ssl_cache_free( ssl_cache_context *cache ) 00305 { 00306 ssl_cache_entry *cur, *prv; 00307 00308 cur = cache->chain ; 00309 00310 while( cur != NULL ) 00311 { 00312 prv = cur; 00313 cur = cur->next ; 00314 00315 ssl_session_free( &prv->session ); 00316 00317 #if defined(POLARSSL_X509_CRT_PARSE_C) 00318 polarssl_free( prv->peer_cert .p ); 00319 #endif /* POLARSSL_X509_CRT_PARSE_C */ 00320 00321 polarssl_free( prv ); 00322 } 00323 00324 #if defined(POLARSSL_THREADING_C) 00325 polarssl_mutex_free( &cache->mutex ); 00326 #endif 00327 } 00328 00329 #endif /* POLARSSL_SSL_CACHE_C */ 00330
Generated on Tue Jul 12 2022 13:50:38 by 1.7.2