1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-28 00:21:48 +03:00

Merge pull request #4806 from hanno-arm/ssl_session_serialization_version

Store TLS version in SSL session structure
This commit is contained in:
Gilles Peskine
2021-08-02 12:45:55 +02:00
committed by GitHub
5 changed files with 179 additions and 87 deletions

View File

@ -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
*/