diff --git a/library/ssl_cache.c b/library/ssl_cache.c index 216b192739..3fdab5b48e 100644 --- a/library/ssl_cache.c +++ b/library/ssl_cache.c @@ -50,84 +50,98 @@ void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ) #endif } +static int ssl_cache_find_entry( mbedtls_ssl_cache_context *cache, + unsigned char const *session_id, + size_t session_id_len, + mbedtls_ssl_cache_entry **dst ) +{ + int ret = 1; +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_time_t t = mbedtls_time( NULL ); +#endif + mbedtls_ssl_cache_entry *cur; + + for( cur = cache->chain; cur != NULL; cur = cur->next ) + { +#if defined(MBEDTLS_HAVE_TIME) + if( cache->timeout != 0 && + (int) ( t - cur->timestamp ) > cache->timeout ) + continue; +#endif + + if( session_id_len != cur->session.id_len || + memcmp( session_id, cur->session.id, + cur->session.id_len ) != 0 ) + { + continue; + } + + break; + } + + if( cur != NULL ) + { + *dst = cur; + ret = 0; + } + + return( ret ); +} + + int mbedtls_ssl_cache_get( void *data, unsigned char const *session_id, size_t session_id_len, mbedtls_ssl_session *session ) { int ret = 1; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t = mbedtls_time( NULL ); -#endif mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; - mbedtls_ssl_cache_entry *cur, *entry; + mbedtls_ssl_cache_entry *entry; #if defined(MBEDTLS_THREADING_C) if( mbedtls_mutex_lock( &cache->mutex ) != 0 ) return( 1 ); #endif - cur = cache->chain; - entry = NULL; + ret = ssl_cache_find_entry( cache, session_id, session_id_len, &entry ); + if( ret != 0 ) + goto exit; - while( cur != NULL ) + ret = mbedtls_ssl_session_copy( session, &entry->session ); + if( ret != 0 ) + goto exit; + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ + defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + /* + * Restore peer certificate (without rest of the original chain) + */ + if( entry->peer_cert.p != NULL ) { - entry = cur; - cur = cur->next; + /* `session->peer_cert` is NULL after the call to + * mbedtls_ssl_session_copy(), because cache entries + * have the `peer_cert` field set to NULL. */ -#if defined(MBEDTLS_HAVE_TIME) - if( cache->timeout != 0 && - (int) ( t - entry->timestamp ) > cache->timeout ) - continue; -#endif - - if( session_id_len != entry->session.id_len || - memcmp( session_id, entry->session.id, - entry->session.id_len ) != 0 ) - { - continue; - } - - ret = mbedtls_ssl_session_copy( session, &entry->session ); - if( ret != 0 ) + if( ( session->peer_cert = mbedtls_calloc( 1, + sizeof(mbedtls_x509_crt) ) ) == NULL ) { ret = 1; goto exit; } -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* - * Restore peer certificate (without rest of the original chain) - */ - if( entry->peer_cert.p != NULL ) + mbedtls_x509_crt_init( session->peer_cert ); + if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p, + entry->peer_cert.len ) != 0 ) { - /* `session->peer_cert` is NULL after the call to - * mbedtls_ssl_session_copy(), because cache entries - * have the `peer_cert` field set to NULL. */ - - if( ( session->peer_cert = mbedtls_calloc( 1, - sizeof(mbedtls_x509_crt) ) ) == NULL ) - { - ret = 1; - goto exit; - } - - mbedtls_x509_crt_init( session->peer_cert ); - if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p, - entry->peer_cert.len ) != 0 ) - { - mbedtls_free( session->peer_cert ); - session->peer_cert = NULL; - ret = 1; - goto exit; - } + mbedtls_free( session->peer_cert ); + session->peer_cert = NULL; + ret = 1; + goto exit; } + } #endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - ret = 0; - goto exit; - } + ret = 0; exit: #if defined(MBEDTLS_THREADING_C)