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:
@ -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
|
||||
*/
|
||||
|
Reference in New Issue
Block a user