Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
tls_cache.c
Go to the documentation of this file.
00001 /** 00002 * @file tls_cache.c 00003 * @brief Session cache management 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneSSL Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL TLS_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include <string.h> 00034 #include "tls.h" 00035 #include "tls_cache.h" 00036 #include "debug.h" 00037 00038 //Check SSL library configuration 00039 #if (TLS_SUPPORT == ENABLED) 00040 00041 00042 /** 00043 * @brief Session cache initialization 00044 * @param[in] size Maximum number of cache entries 00045 * @return Handle referencing the fully initialized session cache 00046 **/ 00047 00048 TlsCache *tlsInitCache(uint_t size) 00049 { 00050 size_t n; 00051 TlsCache *cache; 00052 00053 //Make sure the parameter is acceptable 00054 if(size < 1) 00055 return NULL; 00056 00057 //Size of the memory required 00058 n = sizeof(TlsCache) + size * sizeof(TlsSession); 00059 00060 //Allocate a memory buffer to hold the session cache 00061 cache = tlsAllocMem(n); 00062 //Failed to allocate memory? 00063 if(cache == NULL) 00064 return NULL; 00065 00066 //Clear memory 00067 memset(cache, 0, n); 00068 00069 //Create a mutex to prevent simultaneous access to the cache 00070 if(!osCreateMutex(&cache->mutex)) 00071 { 00072 //Clean up side effects 00073 tlsFreeMem(cache); 00074 //Report an error 00075 return NULL; 00076 } 00077 00078 //Save the maximum number of cache entries 00079 cache->size = size; 00080 00081 //Return a pointer to the newly created cache 00082 return cache; 00083 } 00084 00085 00086 /** 00087 * @brief Search the session cache for a given session ID 00088 * @param[in] cache Pointer to the session cache 00089 * @param[in] id Expected session ID 00090 * @param[in] length Length of the session ID 00091 * @return A pointer to the matching session is returned. NULL is returned 00092 * if the specified ID could not be found in the session cache 00093 **/ 00094 00095 TlsSession *tlsFindCache(TlsCache *cache, const uint8_t *id, size_t length) 00096 { 00097 uint_t i; 00098 systime_t time; 00099 TlsSession *session; 00100 00101 //Check whether session caching is supported 00102 if(cache == NULL) 00103 return NULL; 00104 //Ensure the session ID is valid 00105 if(id == NULL || length == 0) 00106 return NULL; 00107 00108 //Get current time 00109 time = osGetSystemTime(); 00110 00111 //Acquire exclusive access to the session cache 00112 osAcquireMutex(&cache->mutex); 00113 00114 //Flush expired entries 00115 for(i = 0; i < cache->size; i++) 00116 { 00117 //Point to the current entry 00118 session = &cache->sessions[i]; 00119 00120 //Skip unused entries 00121 if(session->idLength) 00122 { 00123 //Outdated entry? 00124 if((time - session->timestamp) >= TLS_SESSION_CACHE_LIFETIME) 00125 { 00126 //This session is no more valid and should be removed from the cache 00127 memset(session, 0, sizeof(TlsSession)); 00128 } 00129 } 00130 } 00131 00132 //Search the cache for the specified session ID 00133 for(i = 0; i < cache->size; i++) 00134 { 00135 //Point to the current entry 00136 session = &cache->sessions[i]; 00137 00138 //Check whether the current identifier matches the specified session ID 00139 if(session->idLength == length && !memcmp(session->id, id, length)) 00140 { 00141 //Release exclusive access to the session cache 00142 osReleaseMutex(&cache->mutex); 00143 //Return session parameters 00144 return session; 00145 } 00146 } 00147 00148 //Release exclusive access to the session cache 00149 osReleaseMutex(&cache->mutex); 00150 //No matching entry in session cache 00151 return NULL; 00152 } 00153 00154 00155 /** 00156 * @brief Save current session in cache 00157 * @param[in] context TLS context 00158 * @return Error code 00159 **/ 00160 00161 error_t tlsSaveToCache(TlsContext *context) 00162 { 00163 error_t error; 00164 uint_t i; 00165 TlsSession *session; 00166 TlsSession *firstFreeEntry; 00167 TlsSession *oldestEntry; 00168 00169 //Check parameters 00170 if(context == NULL) 00171 return ERROR_INVALID_PARAMETER; 00172 //Check whether session caching is supported 00173 if(context->cache == NULL) 00174 return ERROR_FAILURE; 00175 //Ensure the session ID is valid 00176 if(context->sessionIdLen == 0) 00177 return NO_ERROR; 00178 00179 //Acquire exclusive access to the session cache 00180 osAcquireMutex(&context->cache->mutex); 00181 00182 //Keep track of the first free entry 00183 firstFreeEntry = NULL; 00184 //Keep track of the oldest entry 00185 oldestEntry = NULL; 00186 00187 //Search the cache for the specified session ID 00188 for(i = 0; i < context->cache->size; i++) 00189 { 00190 //Point to the current entry 00191 session = &context->cache->sessions[i]; 00192 00193 //If the session ID already exists, we are done 00194 if(session->idLength == context->sessionIdLen && 00195 !memcmp(session->id, context->sessionId, session->idLength)) 00196 { 00197 //Do not write to session cache 00198 firstFreeEntry = NULL; 00199 oldestEntry = NULL; 00200 //Exit immediately 00201 break; 00202 } 00203 00204 //Check whether current entry is free 00205 if(!session->idLength) 00206 { 00207 //Keep track of the first free entry 00208 if(!firstFreeEntry) 00209 firstFreeEntry = session; 00210 } 00211 else 00212 { 00213 //Keep track of the oldest entry in the table 00214 if(!oldestEntry || timeCompare(session->timestamp, oldestEntry->timestamp) < 0) 00215 oldestEntry = session; 00216 } 00217 } 00218 00219 //Add current session to cache if necessary 00220 if(firstFreeEntry != NULL) 00221 error = tlsSaveSession(context, firstFreeEntry); 00222 else if(oldestEntry != NULL) 00223 error = tlsSaveSession(context, oldestEntry); 00224 else 00225 error = NO_ERROR; 00226 00227 //Release exclusive access to the session cache 00228 osReleaseMutex(&context->cache->mutex); 00229 //Return status code 00230 return error; 00231 } 00232 00233 00234 /** 00235 * @brief Remove current session from cache 00236 * @param[in] context TLS context 00237 * @return Error code 00238 **/ 00239 00240 error_t tlsRemoveFromCache(TlsContext *context) 00241 { 00242 uint_t i; 00243 TlsSession *session; 00244 00245 //Check parameters 00246 if(context == NULL) 00247 return ERROR_INVALID_PARAMETER; 00248 //Check whether session caching is supported 00249 if(context->cache == NULL) 00250 return ERROR_FAILURE; 00251 00252 //Ensure the session ID is valid 00253 if(context->sessionIdLen == 0) 00254 return NO_ERROR; 00255 00256 //Acquire exclusive access to the session cache 00257 osAcquireMutex(&context->cache->mutex); 00258 00259 //Search the cache for the specified session ID 00260 for(i = 0; i < context->cache->size; i++) 00261 { 00262 //Point to the current entry 00263 session = &context->cache->sessions[i]; 00264 00265 //Check whether the current identifier matches the specified session ID 00266 if(session->idLength == context->sessionIdLen && 00267 !memcmp(session->id, context->sessionId, session->idLength)) 00268 { 00269 //Drop current entry 00270 memset(session, 0, sizeof(TlsSession)); 00271 } 00272 } 00273 00274 //Release exclusive access to the session cache 00275 osReleaseMutex(&context->cache->mutex); 00276 //Successful processing 00277 return NO_ERROR; 00278 } 00279 00280 00281 /** 00282 * @brief Properly dispose a session cache 00283 * @param[in] cache Pointer to the session cache to be released 00284 **/ 00285 00286 void tlsFreeCache(TlsCache *cache) 00287 { 00288 size_t n; 00289 00290 //Invalid session cache? 00291 if(cache == NULL) 00292 return; 00293 00294 //Release previously allocated resources 00295 osDeleteMutex(&cache->mutex); 00296 00297 //Compute the number of bytes allocated for the session cache 00298 n = sizeof(TlsCache) + cache->size * sizeof(TlsSession); 00299 00300 //Clear the session cache before freeing memory 00301 memset(cache, 0, n); 00302 tlsFreeMem(cache); 00303 } 00304 00305 #endif 00306
Generated on Tue Jul 12 2022 17:10:17 by
