Merge pull request #4806 from hanno-arm/ssl_session_serialization_version
Store TLS version in SSL session structure
This commit is contained in:
commit
8bb9b80d18
@ -927,6 +927,11 @@ struct mbedtls_ssl_session
|
||||
|
||||
unsigned char MBEDTLS_PRIVATE(exported);
|
||||
|
||||
/* This field is temporarily duplicated with mbedtls_ssl_context.minor_ver.
|
||||
* Once runtime negotiation of TLS 1.2 and TLS 1.3 is implemented, it needs
|
||||
* to be studied whether one of them can be removed. */
|
||||
unsigned char MBEDTLS_PRIVATE(minor_ver); /*!< The TLS version used in the session. */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
mbedtls_x509_crt *MBEDTLS_PRIVATE(peer_cert); /*!< peer X.509 cert chain */
|
||||
@ -1245,6 +1250,10 @@ struct mbedtls_ssl_context
|
||||
#endif /* MBEDTLS_SSL_RENEGOTIATION */
|
||||
|
||||
int MBEDTLS_PRIVATE(major_ver); /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */
|
||||
|
||||
/* This field is temporarily duplicated with mbedtls_ssl_context.minor_ver.
|
||||
* Once runtime negotiation of TLS 1.2 and TLS 1.3 is implemented, it needs
|
||||
* to be studied whether one of them can be removed. */
|
||||
int MBEDTLS_PRIVATE(minor_ver); /*!< one of MBEDTLS_SSL_MINOR_VERSION_x macros */
|
||||
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
|
||||
|
||||
|
@ -2024,6 +2024,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
|
||||
mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
|
||||
ssl->conf->transport, buf + 0 );
|
||||
ssl->session_negotiate->minor_ver = ssl->minor_ver;
|
||||
|
||||
if( ssl->major_ver < ssl->conf->min_major_ver ||
|
||||
ssl->minor_ver < ssl->conf->min_minor_ver ||
|
||||
|
@ -1392,6 +1392,7 @@ read_record_header:
|
||||
|
||||
mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
|
||||
ssl->conf->transport, buf );
|
||||
ssl->session_negotiate->minor_ver = ssl->minor_ver;
|
||||
|
||||
ssl->handshake->max_major_ver = ssl->major_ver;
|
||||
ssl->handshake->max_minor_ver = ssl->minor_ver;
|
||||
|
@ -655,7 +655,6 @@ typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
|
||||
* - [in] ciphersuite
|
||||
* - [in] master
|
||||
* - [in] encrypt_then_mac
|
||||
* - [in] trunc_hmac
|
||||
* - [in] compression
|
||||
* - [in] tls_prf: pointer to PRF to use for key derivation
|
||||
* - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
|
||||
@ -4488,8 +4487,6 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_MFL 0
|
||||
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
|
||||
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 0
|
||||
|
||||
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_ETM 1
|
||||
#else
|
||||
@ -4506,9 +4503,8 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT 4
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 5
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 6
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 4
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 5
|
||||
|
||||
#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \
|
||||
( (uint16_t) ( \
|
||||
@ -4516,7 +4512,6 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
|
||||
( SSL_SERIALIZED_SESSION_CONFIG_CRT << SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT ) | \
|
||||
( SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET << SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT ) | \
|
||||
( SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT ) | \
|
||||
( SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC << SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT ) | \
|
||||
( SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT ) | \
|
||||
( SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT ) ) )
|
||||
|
||||
@ -4532,44 +4527,61 @@ static unsigned char ssl_serialized_session_header[] = {
|
||||
* Serialize a session in the following format:
|
||||
* (in the presentation language of TLS, RFC 8446 section 3)
|
||||
*
|
||||
* opaque mbedtls_version[3]; // major, minor, patch
|
||||
* opaque session_format[2]; // version-specific 16-bit field determining
|
||||
* // the format of the remaining
|
||||
* // serialized data.
|
||||
* struct {
|
||||
*
|
||||
* Note: When updating the format, remember to keep
|
||||
* these version+format bytes.
|
||||
* opaque mbedtls_version[3]; // library version: major, minor, patch
|
||||
* opaque session_format[2]; // library-version specific 16-bit field
|
||||
* // determining the format of the remaining
|
||||
* // serialized data.
|
||||
*
|
||||
* // In this version, `session_format` determines
|
||||
* // the setting of those compile-time
|
||||
* // configuration options which influence
|
||||
* // the structure of mbedtls_ssl_session.
|
||||
* uint64 start_time;
|
||||
* uint8 ciphersuite[2]; // defined by the standard
|
||||
* uint8 compression; // 0 or 1
|
||||
* uint8 session_id_len; // at most 32
|
||||
* opaque session_id[32];
|
||||
* opaque master[48]; // fixed length in the standard
|
||||
* uint32 verify_result;
|
||||
* opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
|
||||
* opaque ticket<0..2^24-1>; // length 0 means no ticket
|
||||
* uint32 ticket_lifetime;
|
||||
* uint8 mfl_code; // up to 255 according to standard
|
||||
* uint8 trunc_hmac; // 0 or 1
|
||||
* uint8 encrypt_then_mac; // 0 or 1
|
||||
* Note: When updating the format, remember to keep
|
||||
* these version+format bytes.
|
||||
*
|
||||
* // In this version, `session_format` determines
|
||||
* // the setting of those compile-time
|
||||
* // configuration options which influence
|
||||
* // the structure of mbedtls_ssl_session.
|
||||
*
|
||||
* uint8_t minor_ver; // Protocol-version. Possible values:
|
||||
* // - TLS 1.2 (MBEDTLS_SSL_MINOR_VERSION_3)
|
||||
*
|
||||
* select (serialized_session.minor_ver) {
|
||||
*
|
||||
* case MBEDTLS_SSL_MINOR_VERSION_3: // TLS 1.2
|
||||
* serialized_session_tls12 data;
|
||||
*
|
||||
* };
|
||||
*
|
||||
* } serialized_session;
|
||||
*
|
||||
* The order is the same as in the definition of the structure, except
|
||||
* verify_result is put before peer_cert so that all mandatory fields come
|
||||
* together in one block.
|
||||
*/
|
||||
static int ssl_session_save( const mbedtls_ssl_session *session,
|
||||
unsigned char omit_header,
|
||||
unsigned char *buf,
|
||||
size_t buf_len,
|
||||
size_t *olen )
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
/* Serialization of TLS 1.2 sessions:
|
||||
*
|
||||
* struct {
|
||||
* uint64 start_time;
|
||||
* uint8 ciphersuite[2]; // defined by the standard
|
||||
* uint8 compression; // 0 or 1
|
||||
* uint8 session_id_len; // at most 32
|
||||
* opaque session_id[32];
|
||||
* opaque master[48]; // fixed length in the standard
|
||||
* uint32 verify_result;
|
||||
* opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
|
||||
* opaque ticket<0..2^24-1>; // length 0 means no ticket
|
||||
* uint32 ticket_lifetime;
|
||||
* uint8 mfl_code; // up to 255 according to standard
|
||||
* uint8 encrypt_then_mac; // 0 or 1
|
||||
* } serialized_session_tls12;
|
||||
*
|
||||
*/
|
||||
static size_t ssl_session_save_tls12( const mbedtls_ssl_session *session,
|
||||
unsigned char *buf,
|
||||
size_t buf_len )
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
size_t used = 0;
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
uint64_t start;
|
||||
#endif
|
||||
@ -4579,23 +4591,6 @@ static int ssl_session_save( const mbedtls_ssl_session *session,
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
|
||||
if( !omit_header )
|
||||
{
|
||||
/*
|
||||
* Add version identifier
|
||||
*/
|
||||
|
||||
used += sizeof( ssl_serialized_session_header );
|
||||
|
||||
if( used <= buf_len )
|
||||
{
|
||||
memcpy( p, ssl_serialized_session_header,
|
||||
sizeof( ssl_serialized_session_header ) );
|
||||
p += sizeof( ssl_serialized_session_header );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Time
|
||||
*/
|
||||
@ -4738,9 +4733,61 @@ static int ssl_session_save( const mbedtls_ssl_session *session,
|
||||
*p++ = (unsigned char)( ( session->encrypt_then_mac ) & 0xFF );
|
||||
#endif
|
||||
|
||||
/* Done */
|
||||
*olen = used;
|
||||
return( used );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
static int ssl_session_save( const mbedtls_ssl_session *session,
|
||||
unsigned char omit_header,
|
||||
unsigned char *buf,
|
||||
size_t buf_len,
|
||||
size_t *olen )
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
size_t used = 0;
|
||||
|
||||
if( !omit_header )
|
||||
{
|
||||
/*
|
||||
* Add Mbed TLS version identifier
|
||||
*/
|
||||
|
||||
used += sizeof( ssl_serialized_session_header );
|
||||
|
||||
if( used <= buf_len )
|
||||
{
|
||||
memcpy( p, ssl_serialized_session_header,
|
||||
sizeof( ssl_serialized_session_header ) );
|
||||
p += sizeof( ssl_serialized_session_header );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS version identifier
|
||||
*/
|
||||
used += 1;
|
||||
if( used <= buf_len )
|
||||
{
|
||||
*p++ = session->minor_ver;
|
||||
}
|
||||
|
||||
/* Forward to version-specific serialization routine. */
|
||||
switch( session->minor_ver )
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
case MBEDTLS_SSL_MINOR_VERSION_3:
|
||||
{
|
||||
size_t remaining_len = used <= buf_len ? buf_len - used : 0;
|
||||
used += ssl_session_save_tls12( session, p, remaining_len );
|
||||
break;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
default:
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
*olen = used;
|
||||
if( used > buf_len )
|
||||
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
|
||||
|
||||
@ -4764,13 +4811,10 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
|
||||
* This internal version is wrapped by a public function that cleans up in
|
||||
* case of error, and has an extra option omit_header.
|
||||
*/
|
||||
static int ssl_session_load( mbedtls_ssl_session *session,
|
||||
unsigned char omit_header,
|
||||
const unsigned char *buf,
|
||||
size_t len )
|
||||
static int ssl_session_load_tls12( mbedtls_ssl_session *session,
|
||||
const unsigned char *buf,
|
||||
size_t len )
|
||||
{
|
||||
const unsigned char *p = buf;
|
||||
const unsigned char * const end = buf + len;
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
uint64_t start;
|
||||
#endif
|
||||
@ -4780,22 +4824,8 @@ static int ssl_session_load( mbedtls_ssl_session *session,
|
||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
if( !omit_header )
|
||||
{
|
||||
/*
|
||||
* Check version identifier
|
||||
*/
|
||||
|
||||
if( (size_t)( end - p ) < sizeof( ssl_serialized_session_header ) )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
||||
if( memcmp( p, ssl_serialized_session_header,
|
||||
sizeof( ssl_serialized_session_header ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_SSL_VERSION_MISMATCH );
|
||||
}
|
||||
p += sizeof( ssl_serialized_session_header );
|
||||
}
|
||||
const unsigned char *p = buf;
|
||||
const unsigned char * const end = buf + len;
|
||||
|
||||
/*
|
||||
* Time
|
||||
@ -4980,6 +5010,54 @@ static int ssl_session_load( mbedtls_ssl_session *session,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int ssl_session_load( mbedtls_ssl_session *session,
|
||||
unsigned char omit_header,
|
||||
const unsigned char *buf,
|
||||
size_t len )
|
||||
{
|
||||
const unsigned char *p = buf;
|
||||
const unsigned char * const end = buf + len;
|
||||
|
||||
if( !omit_header )
|
||||
{
|
||||
/*
|
||||
* Check Mbed TLS version identifier
|
||||
*/
|
||||
|
||||
if( (size_t)( end - p ) < sizeof( ssl_serialized_session_header ) )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
||||
if( memcmp( p, ssl_serialized_session_header,
|
||||
sizeof( ssl_serialized_session_header ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_SSL_VERSION_MISMATCH );
|
||||
}
|
||||
p += sizeof( ssl_serialized_session_header );
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS version identifier
|
||||
*/
|
||||
if( 1 > (size_t)( end - p ) )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
session->minor_ver = *p++;
|
||||
|
||||
/* Dispatch according to TLS version. */
|
||||
switch( session->minor_ver )
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
case MBEDTLS_SSL_MINOR_VERSION_3: /* TLS 1.2 */
|
||||
{
|
||||
size_t remaining_len = ( end - p );
|
||||
return( ssl_session_load_tls12( session, p, remaining_len ) );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
default:
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Deserialize session: public wrapper for error cleaning
|
||||
*/
|
||||
|
@ -1435,13 +1435,14 @@ cleanup:
|
||||
* Populate a session structure for serialization tests.
|
||||
* Choose dummy values, mostly non-0 to distinguish from the init default.
|
||||
*/
|
||||
static int ssl_populate_session( mbedtls_ssl_session *session,
|
||||
int ticket_len,
|
||||
const char *crt_file )
|
||||
static int ssl_populate_session_tls12( mbedtls_ssl_session *session,
|
||||
int ticket_len,
|
||||
const char *crt_file )
|
||||
{
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
session->start = mbedtls_time( NULL ) - 42;
|
||||
#endif
|
||||
session->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
|
||||
session->ciphersuite = 0xabcd;
|
||||
session->compression = 1;
|
||||
session->id_len = sizeof( session->id );
|
||||
@ -1449,7 +1450,7 @@ static int ssl_populate_session( mbedtls_ssl_session *session,
|
||||
memset( session->master, 17, sizeof( session->master ) );
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_FS_IO)
|
||||
if( strlen( crt_file ) != 0 )
|
||||
if( crt_file != NULL && strlen( crt_file ) != 0 )
|
||||
{
|
||||
mbedtls_x509_crt tmp_crt;
|
||||
int ret;
|
||||
@ -4005,7 +4006,7 @@ void ssl_serialize_session_save_load( int ticket_len, char *crt_file )
|
||||
mbedtls_ssl_session_init( &restored );
|
||||
|
||||
/* Prepare a dummy session to work on */
|
||||
TEST_ASSERT( ssl_populate_session( &original, ticket_len, crt_file ) == 0 );
|
||||
TEST_ASSERT( ssl_populate_session_tls12( &original, ticket_len, crt_file ) == 0 );
|
||||
|
||||
/* Serialize it */
|
||||
TEST_ASSERT( mbedtls_ssl_session_save( &original, NULL, 0, &len )
|
||||
@ -4023,6 +4024,7 @@ void ssl_serialize_session_save_load( int ticket_len, char *crt_file )
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
TEST_ASSERT( original.start == restored.start );
|
||||
#endif
|
||||
TEST_ASSERT( original.minor_ver == restored.minor_ver );
|
||||
TEST_ASSERT( original.ciphersuite == restored.ciphersuite );
|
||||
TEST_ASSERT( original.compression == restored.compression );
|
||||
TEST_ASSERT( original.id_len == restored.id_len );
|
||||
@ -4101,7 +4103,7 @@ void ssl_serialize_session_load_save( int ticket_len, char *crt_file )
|
||||
mbedtls_ssl_session_init( &session );
|
||||
|
||||
/* Prepare a dummy session to work on */
|
||||
TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
|
||||
TEST_ASSERT( ssl_populate_session_tls12( &session, ticket_len, crt_file ) == 0 );
|
||||
|
||||
/* Get desired buffer size for serializing */
|
||||
TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &len0 )
|
||||
@ -4151,7 +4153,7 @@ void ssl_serialize_session_save_buf_size( int ticket_len, char *crt_file )
|
||||
mbedtls_ssl_session_init( &session );
|
||||
|
||||
/* Prepare dummy session and get serialized size */
|
||||
TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
|
||||
TEST_ASSERT( ssl_populate_session_tls12( &session, ticket_len, crt_file ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &good_len )
|
||||
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
|
||||
|
||||
@ -4187,7 +4189,7 @@ void ssl_serialize_session_load_buf_size( int ticket_len, char *crt_file )
|
||||
mbedtls_ssl_session_init( &session );
|
||||
|
||||
/* Prepare serialized session data */
|
||||
TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
|
||||
TEST_ASSERT( ssl_populate_session_tls12( &session, ticket_len, crt_file ) == 0 );
|
||||
TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &good_len )
|
||||
== MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
|
||||
TEST_ASSERT( ( good_buf = mbedtls_calloc( 1, good_len ) ) != NULL );
|
||||
@ -4232,6 +4234,7 @@ void ssl_session_serialize_version_check( int corrupt_major,
|
||||
corrupt_config == 1 };
|
||||
|
||||
mbedtls_ssl_session_init( &session );
|
||||
ssl_populate_session_tls12( &session, 0, NULL );
|
||||
|
||||
/* Infer length of serialized session. */
|
||||
TEST_ASSERT( mbedtls_ssl_session_save( &session,
|
||||
|
Loading…
Reference in New Issue
Block a user