00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "polarssl/config.h"
00031
00032 #if defined(POLARSSL_SSL_CACHE_C)
00033
00034 #include "polarssl/ssl_cache.h"
00035
00036 #if defined(POLARSSL_MEMORY_C)
00037 #include "polarssl/memory.h"
00038 #else
00039 #define polarssl_malloc malloc
00040 #define polarssl_free free
00041 #endif
00042
00043 #include <stdlib.h>
00044
00045 void ssl_cache_init( ssl_cache_context *cache )
00046 {
00047 memset( cache, 0, sizeof( ssl_cache_context ) );
00048
00049 cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT;
00050 cache->max_entries = SSL_CACHE_DEFAULT_MAX_ENTRIES;
00051
00052 #if defined(POLARSSL_THREADING_C)
00053 polarssl_mutex_init( &cache->mutex );
00054 #endif
00055 }
00056
00057 int ssl_cache_get( void *data, ssl_session *session )
00058 {
00059 int ret = 1;
00060 #if defined(POLARSSL_HAVE_TIME)
00061 time_t t = time( NULL );
00062 #endif
00063 ssl_cache_context *cache = (ssl_cache_context *) data;
00064 ssl_cache_entry *cur, *entry;
00065
00066 #if defined(POLARSSL_THREADING_C)
00067 if( polarssl_mutex_lock( &cache->mutex ) != 0 )
00068 return( 1 );
00069 #endif
00070
00071 cur = cache->chain;
00072 entry = NULL;
00073
00074 while( cur != NULL )
00075 {
00076 entry = cur;
00077 cur = cur->next;
00078
00079 #if defined(POLARSSL_HAVE_TIME)
00080 if( cache->timeout != 0 &&
00081 (int) ( t - entry->timestamp ) > cache->timeout )
00082 continue;
00083 #endif
00084
00085 if( session->ciphersuite != entry->session.ciphersuite ||
00086 session->compression != entry->session.compression ||
00087 session->length != entry->session.length )
00088 continue;
00089
00090 if( memcmp( session->id, entry->session.id,
00091 entry->session.length ) != 0 )
00092 continue;
00093
00094 memcpy( session->master, entry->session.master, 48 );
00095
00096 session->verify_result = entry->session.verify_result;
00097
00098 #if defined(POLARSSL_X509_CRT_PARSE_C)
00099
00100
00101
00102 if( entry->peer_cert.p != NULL )
00103 {
00104 session->peer_cert = (x509_crt *) polarssl_malloc( sizeof(x509_crt) );
00105 if( session->peer_cert == NULL )
00106 {
00107 ret = 1;
00108 goto exit;
00109 }
00110
00111 x509_crt_init( session->peer_cert );
00112 if( x509_crt_parse( session->peer_cert, entry->peer_cert.p,
00113 entry->peer_cert.len ) != 0 )
00114 {
00115 polarssl_free( session->peer_cert );
00116 session->peer_cert = NULL;
00117 ret = 1;
00118 goto exit;
00119 }
00120 }
00121 #endif
00122
00123 ret = 0;
00124 goto exit;
00125 }
00126
00127 exit:
00128 #if defined(POLARSSL_THREADING_C)
00129 if( polarssl_mutex_unlock( &cache->mutex ) != 0 )
00130 ret = 1;
00131 #endif
00132
00133 return( ret );
00134 }
00135
00136 int ssl_cache_set( void *data, const ssl_session *session )
00137 {
00138 int ret = 1;
00139 #if defined(POLARSSL_HAVE_TIME)
00140 time_t t = time( NULL ), oldest = 0;
00141 ssl_cache_entry *old = NULL;
00142 #endif
00143 ssl_cache_context *cache = (ssl_cache_context *) data;
00144 ssl_cache_entry *cur, *prv;
00145 int count = 0;
00146
00147 #if defined(POLARSSL_THREADING_C)
00148 if( ( ret = polarssl_mutex_lock( &cache->mutex ) ) != 0 )
00149 return( ret );
00150 #endif
00151
00152 cur = cache->chain;
00153 prv = NULL;
00154
00155 while( cur != NULL )
00156 {
00157 count++;
00158
00159 #if defined(POLARSSL_HAVE_TIME)
00160 if( cache->timeout != 0 &&
00161 (int) ( t - cur->timestamp ) > cache->timeout )
00162 {
00163 cur->timestamp = t;
00164 break;
00165 }
00166 #endif
00167
00168 if( memcmp( session->id, cur->session.id, cur->session.length ) == 0 )
00169 break;
00170
00171 #if defined(POLARSSL_HAVE_TIME)
00172 if( oldest == 0 || cur->timestamp < oldest )
00173 {
00174 oldest = cur->timestamp;
00175 old = cur;
00176 }
00177 #endif
00178
00179 prv = cur;
00180 cur = cur->next;
00181 }
00182
00183 if( cur == NULL )
00184 {
00185 #if defined(POLARSSL_HAVE_TIME)
00186
00187
00188
00189 if( old != NULL && count >= cache->max_entries )
00190 {
00191 cur = old;
00192 memset( &cur->session, 0, sizeof(ssl_session) );
00193 #if defined(POLARSSL_X509_CRT_PARSE_C)
00194 if( cur->peer_cert.p != NULL )
00195 {
00196 polarssl_free( cur->peer_cert.p );
00197 memset( &cur->peer_cert, 0, sizeof(x509_buf) );
00198 }
00199 #endif
00200 }
00201 #else
00202
00203
00204
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
00217 #if defined(POLARSSL_X509_CRT_PARSE_C)
00218 if( cur->peer_cert.p != NULL )
00219 {
00220 polarssl_free( cur->peer_cert.p );
00221 memset( &cur->peer_cert, 0, sizeof(x509_buf) );
00222 }
00223 #endif
00224
00225 memset( cur, 0, sizeof(ssl_cache_entry) );
00226 prv->next = cur;
00227 }
00228 #endif
00229 else
00230 {
00231 cur = (ssl_cache_entry *) polarssl_malloc( sizeof(ssl_cache_entry) );
00232 if( cur == NULL )
00233 {
00234 ret = 1;
00235 goto exit;
00236 }
00237
00238 memset( cur, 0, sizeof(ssl_cache_entry) );
00239
00240 if( prv == NULL )
00241 cache->chain = cur;
00242 else
00243 prv->next = cur;
00244 }
00245
00246 #if defined(POLARSSL_HAVE_TIME)
00247 cur->timestamp = t;
00248 #endif
00249 }
00250
00251 memcpy( &cur->session, session, sizeof( ssl_session ) );
00252
00253 #if defined(POLARSSL_X509_CRT_PARSE_C)
00254
00255
00256
00257 if( session->peer_cert != NULL )
00258 {
00259 cur->peer_cert.p = (unsigned char *) polarssl_malloc( 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
00273
00274 ret = 0;
00275
00276 exit:
00277 #if defined(POLARSSL_THREADING_C)
00278 if( polarssl_mutex_unlock( &cache->mutex ) != 0 )
00279 ret = 1;
00280 #endif
00281
00282 return( ret );
00283 }
00284
00285 #if defined(POLARSSL_HAVE_TIME)
00286 void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout )
00287 {
00288 if( timeout < 0 ) timeout = 0;
00289
00290 cache->timeout = timeout;
00291 }
00292 #endif
00293
00294 void ssl_cache_set_max_entries( ssl_cache_context *cache, int max )
00295 {
00296 if( max < 0 ) max = 0;
00297
00298 cache->max_entries = max;
00299 }
00300
00301 void ssl_cache_free( ssl_cache_context *cache )
00302 {
00303 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 ssl_session_free( &prv->session );
00313
00314 #if defined(POLARSSL_X509_CRT_PARSE_C)
00315 if( prv->peer_cert.p != NULL )
00316 polarssl_free( prv->peer_cert.p );
00317 #endif
00318
00319 polarssl_free( prv );
00320 }
00321
00322 #if defined(POLARSSL_THREADING_C)
00323 polarssl_mutex_free( &cache->mutex );
00324 #endif
00325 }
00326
00327 #endif