Merge pull request #4529 from hanno-arm/ssl_session_cache_fix_backport_2x

Backport 2.x: Add session ID as an explicit parameter to SSL session cache API
This commit is contained in:
Janos Follath 2021-05-21 08:49:11 +01:00 committed by GitHub
commit d76f7ba2e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 22 deletions

View file

@ -0,0 +1,5 @@
Changes
* When using session cache based session resumption on the server,
double-check that custom session cache implementations return
sessions which are consistent with the negotiated ciphersuite
and compression method.

View file

@ -78,14 +78,12 @@ int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
continue; continue;
#endif #endif
if( session->ciphersuite != entry->session.ciphersuite || if( session->id_len != entry->session.id_len ||
session->compression != entry->session.compression || memcmp( session->id, entry->session.id,
session->id_len != entry->session.id_len )
continue;
if( memcmp( session->id, entry->session.id,
entry->session.id_len ) != 0 ) entry->session.id_len ) != 0 )
{
continue; continue;
}
ret = mbedtls_ssl_session_copy( session, &entry->session ); ret = mbedtls_ssl_session_copy( session, &entry->session );
if( ret != 0 ) if( ret != 0 )

View file

@ -2765,6 +2765,55 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
} }
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
static void ssl_handle_id_based_session_resumption( mbedtls_ssl_context *ssl )
{
int ret;
mbedtls_ssl_session session_tmp;
mbedtls_ssl_session * const session = ssl->session_negotiate;
/* Resume is 0 by default, see ssl_handshake_init().
* It may be already set to 1 by ssl_parse_session_ticket_ext(). */
if( ssl->handshake->resume == 1 )
return;
if( session->id_len == 0 )
return;
if( ssl->conf->f_get_cache == NULL )
return;
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
return;
#endif
mbedtls_ssl_session_init( &session_tmp );
session_tmp.id_len = session->id_len;
memcpy( session_tmp.id, session->id, session->id_len );
ret = ssl->conf->f_get_cache( ssl->conf->p_cache,
&session_tmp );
if( ret != 0 )
goto exit;
if( session->ciphersuite != session_tmp.ciphersuite ||
session->compression != session_tmp.compression )
{
/* Mismatch between cached and negotiated session */
goto exit;
}
/* Move semantics */
mbedtls_ssl_session_free( session );
*session = session_tmp;
memset( &session_tmp, 0, sizeof( session_tmp ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
ssl->handshake->resume = 1;
exit:
mbedtls_ssl_session_free( &session_tmp );
}
static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
{ {
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
@ -2835,22 +2884,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
/* ssl_handle_id_based_session_resumption( ssl );
* Resume is 0 by default, see ssl_handshake_init().
* It may be already set to 1 by ssl_parse_session_ticket_ext().
* If not, try looking up session ID in our cache.
*/
if( ssl->handshake->resume == 0 &&
#if defined(MBEDTLS_SSL_RENEGOTIATION)
ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE &&
#endif
ssl->session_negotiate->id_len != 0 &&
ssl->conf->f_get_cache != NULL &&
ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
ssl->handshake->resume = 1;
}
if( ssl->handshake->resume == 0 ) if( ssl->handshake->resume == 0 )
{ {