mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-04-16 08:42:50 +00:00
move session_save/load_tls12
Signed-off-by: Jerry Yu <jerry.h.yu@arm.com>
This commit is contained in:
parent
d9d91da7c7
commit
4f9e3efbeb
@ -2533,177 +2533,6 @@ static unsigned char ssl_serialized_session_header[] = {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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
|
|
||||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
|
||||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
|
||||||
size_t cert_len;
|
|
||||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Time
|
|
||||||
*/
|
|
||||||
#if defined(MBEDTLS_HAVE_TIME)
|
|
||||||
used += 8;
|
|
||||||
|
|
||||||
if( used <= buf_len )
|
|
||||||
{
|
|
||||||
start = (uint64_t) session->start;
|
|
||||||
|
|
||||||
MBEDTLS_PUT_UINT64_BE( start, p, 0 );
|
|
||||||
p += 8;
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_HAVE_TIME */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Basic mandatory fields
|
|
||||||
*/
|
|
||||||
used += 2 /* ciphersuite */
|
|
||||||
+ 1 /* compression */
|
|
||||||
+ 1 /* id_len */
|
|
||||||
+ sizeof( session->id )
|
|
||||||
+ sizeof( session->master )
|
|
||||||
+ 4; /* verify_result */
|
|
||||||
|
|
||||||
if( used <= buf_len )
|
|
||||||
{
|
|
||||||
MBEDTLS_PUT_UINT16_BE( session->ciphersuite, p, 0 );
|
|
||||||
p += 2;
|
|
||||||
|
|
||||||
*p++ = MBEDTLS_BYTE_0( session->compression );
|
|
||||||
|
|
||||||
*p++ = MBEDTLS_BYTE_0( session->id_len );
|
|
||||||
memcpy( p, session->id, 32 );
|
|
||||||
p += 32;
|
|
||||||
|
|
||||||
memcpy( p, session->master, 48 );
|
|
||||||
p += 48;
|
|
||||||
|
|
||||||
MBEDTLS_PUT_UINT32_BE( session->verify_result, p, 0 );
|
|
||||||
p += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Peer's end-entity certificate
|
|
||||||
*/
|
|
||||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
|
||||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
|
||||||
if( session->peer_cert == NULL )
|
|
||||||
cert_len = 0;
|
|
||||||
else
|
|
||||||
cert_len = session->peer_cert->raw.len;
|
|
||||||
|
|
||||||
used += 3 + cert_len;
|
|
||||||
|
|
||||||
if( used <= buf_len )
|
|
||||||
{
|
|
||||||
*p++ = MBEDTLS_BYTE_2( cert_len );
|
|
||||||
*p++ = MBEDTLS_BYTE_1( cert_len );
|
|
||||||
*p++ = MBEDTLS_BYTE_0( cert_len );
|
|
||||||
|
|
||||||
if( session->peer_cert != NULL )
|
|
||||||
{
|
|
||||||
memcpy( p, session->peer_cert->raw.p, cert_len );
|
|
||||||
p += cert_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
|
||||||
if( session->peer_cert_digest != NULL )
|
|
||||||
{
|
|
||||||
used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
|
|
||||||
if( used <= buf_len )
|
|
||||||
{
|
|
||||||
*p++ = (unsigned char) session->peer_cert_digest_type;
|
|
||||||
*p++ = (unsigned char) session->peer_cert_digest_len;
|
|
||||||
memcpy( p, session->peer_cert_digest,
|
|
||||||
session->peer_cert_digest_len );
|
|
||||||
p += session->peer_cert_digest_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
used += 2;
|
|
||||||
if( used <= buf_len )
|
|
||||||
{
|
|
||||||
*p++ = (unsigned char) MBEDTLS_MD_NONE;
|
|
||||||
*p++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Session ticket if any, plus associated data
|
|
||||||
*/
|
|
||||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
|
||||||
used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
|
|
||||||
|
|
||||||
if( used <= buf_len )
|
|
||||||
{
|
|
||||||
*p++ = MBEDTLS_BYTE_2( session->ticket_len );
|
|
||||||
*p++ = MBEDTLS_BYTE_1( session->ticket_len );
|
|
||||||
*p++ = MBEDTLS_BYTE_0( session->ticket_len );
|
|
||||||
|
|
||||||
if( session->ticket != NULL )
|
|
||||||
{
|
|
||||||
memcpy( p, session->ticket, session->ticket_len );
|
|
||||||
p += session->ticket_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
MBEDTLS_PUT_UINT32_BE( session->ticket_lifetime, p, 0 );
|
|
||||||
p += 4;
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Misc extension-related info
|
|
||||||
*/
|
|
||||||
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
|
|
||||||
used += 1;
|
|
||||||
|
|
||||||
if( used <= buf_len )
|
|
||||||
*p++ = session->mfl_code;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
|
|
||||||
used += 1;
|
|
||||||
|
|
||||||
if( used <= buf_len )
|
|
||||||
*p++ = MBEDTLS_BYTE_0( session->encrypt_then_mac );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return( used );
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
|
||||||
|
|
||||||
static int ssl_session_save( const mbedtls_ssl_session *session,
|
static int ssl_session_save( const mbedtls_ssl_session *session,
|
||||||
unsigned char omit_header,
|
unsigned char omit_header,
|
||||||
unsigned char *buf,
|
unsigned char *buf,
|
||||||
@ -2771,212 +2600,7 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
|
|||||||
{
|
{
|
||||||
return( ssl_session_save( session, 0, buf, buf_len, olen ) );
|
return( ssl_session_save( session, 0, buf, buf_len, olen ) );
|
||||||
}
|
}
|
||||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
|
||||||
/*
|
|
||||||
* Deserialize session, see mbedtls_ssl_session_save() for format.
|
|
||||||
*
|
|
||||||
* 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_tls12( mbedtls_ssl_session *session,
|
|
||||||
const unsigned char *buf,
|
|
||||||
size_t len )
|
|
||||||
{
|
|
||||||
#if defined(MBEDTLS_HAVE_TIME)
|
|
||||||
uint64_t start;
|
|
||||||
#endif
|
|
||||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
|
||||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
|
||||||
size_t cert_len;
|
|
||||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
|
||||||
|
|
||||||
const unsigned char *p = buf;
|
|
||||||
const unsigned char * const end = buf + len;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Time
|
|
||||||
*/
|
|
||||||
#if defined(MBEDTLS_HAVE_TIME)
|
|
||||||
if( 8 > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
start = ( (uint64_t) p[0] << 56 ) |
|
|
||||||
( (uint64_t) p[1] << 48 ) |
|
|
||||||
( (uint64_t) p[2] << 40 ) |
|
|
||||||
( (uint64_t) p[3] << 32 ) |
|
|
||||||
( (uint64_t) p[4] << 24 ) |
|
|
||||||
( (uint64_t) p[5] << 16 ) |
|
|
||||||
( (uint64_t) p[6] << 8 ) |
|
|
||||||
( (uint64_t) p[7] );
|
|
||||||
p += 8;
|
|
||||||
|
|
||||||
session->start = (time_t) start;
|
|
||||||
#endif /* MBEDTLS_HAVE_TIME */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Basic mandatory fields
|
|
||||||
*/
|
|
||||||
if( 2 + 1 + 1 + 32 + 48 + 4 > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->ciphersuite = ( p[0] << 8 ) | p[1];
|
|
||||||
p += 2;
|
|
||||||
|
|
||||||
session->compression = *p++;
|
|
||||||
|
|
||||||
session->id_len = *p++;
|
|
||||||
memcpy( session->id, p, 32 );
|
|
||||||
p += 32;
|
|
||||||
|
|
||||||
memcpy( session->master, p, 48 );
|
|
||||||
p += 48;
|
|
||||||
|
|
||||||
session->verify_result = ( (uint32_t) p[0] << 24 ) |
|
|
||||||
( (uint32_t) p[1] << 16 ) |
|
|
||||||
( (uint32_t) p[2] << 8 ) |
|
|
||||||
( (uint32_t) p[3] );
|
|
||||||
p += 4;
|
|
||||||
|
|
||||||
/* Immediately clear invalid pointer values that have been read, in case
|
|
||||||
* we exit early before we replaced them with valid ones. */
|
|
||||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
|
||||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
|
||||||
session->peer_cert = NULL;
|
|
||||||
#else
|
|
||||||
session->peer_cert_digest = NULL;
|
|
||||||
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
|
||||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
|
||||||
session->ticket = NULL;
|
|
||||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Peer certificate
|
|
||||||
*/
|
|
||||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
|
||||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
|
||||||
/* Deserialize CRT from the end of the ticket. */
|
|
||||||
if( 3 > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
|
|
||||||
p += 3;
|
|
||||||
|
|
||||||
if( cert_len != 0 )
|
|
||||||
{
|
|
||||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
|
||||||
|
|
||||||
if( cert_len > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
|
|
||||||
|
|
||||||
if( session->peer_cert == NULL )
|
|
||||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
|
||||||
|
|
||||||
mbedtls_x509_crt_init( session->peer_cert );
|
|
||||||
|
|
||||||
if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
|
|
||||||
p, cert_len ) ) != 0 )
|
|
||||||
{
|
|
||||||
mbedtls_x509_crt_free( session->peer_cert );
|
|
||||||
mbedtls_free( session->peer_cert );
|
|
||||||
session->peer_cert = NULL;
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
p += cert_len;
|
|
||||||
}
|
|
||||||
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
|
||||||
/* Deserialize CRT digest from the end of the ticket. */
|
|
||||||
if( 2 > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
|
|
||||||
session->peer_cert_digest_len = (size_t) *p++;
|
|
||||||
|
|
||||||
if( session->peer_cert_digest_len != 0 )
|
|
||||||
{
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type( session->peer_cert_digest_type );
|
|
||||||
if( md_info == NULL )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
if( session->peer_cert_digest_len != mbedtls_md_get_size( md_info ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
if( session->peer_cert_digest_len > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->peer_cert_digest =
|
|
||||||
mbedtls_calloc( 1, session->peer_cert_digest_len );
|
|
||||||
if( session->peer_cert_digest == NULL )
|
|
||||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
|
||||||
|
|
||||||
memcpy( session->peer_cert_digest, p,
|
|
||||||
session->peer_cert_digest_len );
|
|
||||||
p += session->peer_cert_digest_len;
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Session ticket and associated data
|
|
||||||
*/
|
|
||||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
|
||||||
if( 3 > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->ticket_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
|
|
||||||
p += 3;
|
|
||||||
|
|
||||||
if( session->ticket_len != 0 )
|
|
||||||
{
|
|
||||||
if( session->ticket_len > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->ticket = mbedtls_calloc( 1, session->ticket_len );
|
|
||||||
if( session->ticket == NULL )
|
|
||||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
|
||||||
|
|
||||||
memcpy( session->ticket, p, session->ticket_len );
|
|
||||||
p += session->ticket_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( 4 > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->ticket_lifetime = ( (uint32_t) p[0] << 24 ) |
|
|
||||||
( (uint32_t) p[1] << 16 ) |
|
|
||||||
( (uint32_t) p[2] << 8 ) |
|
|
||||||
( (uint32_t) p[3] );
|
|
||||||
p += 4;
|
|
||||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Misc extension-related info
|
|
||||||
*/
|
|
||||||
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
|
|
||||||
if( 1 > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->mfl_code = *p++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
|
|
||||||
if( 1 > (size_t)( end - p ) )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
session->encrypt_then_mac = *p++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Done, should have consumed entire buffer */
|
|
||||||
if( p != end )
|
|
||||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
#endif /*MBEDTLS_SSL_PROTO_TLS1_2 */
|
|
||||||
static int ssl_session_load( mbedtls_ssl_session *session,
|
static int ssl_session_load( mbedtls_ssl_session *session,
|
||||||
unsigned char omit_header,
|
unsigned char omit_header,
|
||||||
const unsigned char *buf,
|
const unsigned char *buf,
|
||||||
@ -7942,6 +7566,379 @@ void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
|
|||||||
|
|
||||||
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||||
|
size_t cert_len;
|
||||||
|
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||||
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_HAVE_TIME)
|
||||||
|
used += 8;
|
||||||
|
|
||||||
|
if( used <= buf_len )
|
||||||
|
{
|
||||||
|
start = (uint64_t) session->start;
|
||||||
|
|
||||||
|
MBEDTLS_PUT_UINT64_BE( start, p, 0 );
|
||||||
|
p += 8;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_HAVE_TIME */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic mandatory fields
|
||||||
|
*/
|
||||||
|
used += 2 /* ciphersuite */
|
||||||
|
+ 1 /* compression */
|
||||||
|
+ 1 /* id_len */
|
||||||
|
+ sizeof( session->id )
|
||||||
|
+ sizeof( session->master )
|
||||||
|
+ 4; /* verify_result */
|
||||||
|
|
||||||
|
if( used <= buf_len )
|
||||||
|
{
|
||||||
|
MBEDTLS_PUT_UINT16_BE( session->ciphersuite, p, 0 );
|
||||||
|
p += 2;
|
||||||
|
|
||||||
|
*p++ = MBEDTLS_BYTE_0( session->compression );
|
||||||
|
|
||||||
|
*p++ = MBEDTLS_BYTE_0( session->id_len );
|
||||||
|
memcpy( p, session->id, 32 );
|
||||||
|
p += 32;
|
||||||
|
|
||||||
|
memcpy( p, session->master, 48 );
|
||||||
|
p += 48;
|
||||||
|
|
||||||
|
MBEDTLS_PUT_UINT32_BE( session->verify_result, p, 0 );
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Peer's end-entity certificate
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||||
|
if( session->peer_cert == NULL )
|
||||||
|
cert_len = 0;
|
||||||
|
else
|
||||||
|
cert_len = session->peer_cert->raw.len;
|
||||||
|
|
||||||
|
used += 3 + cert_len;
|
||||||
|
|
||||||
|
if( used <= buf_len )
|
||||||
|
{
|
||||||
|
*p++ = MBEDTLS_BYTE_2( cert_len );
|
||||||
|
*p++ = MBEDTLS_BYTE_1( cert_len );
|
||||||
|
*p++ = MBEDTLS_BYTE_0( cert_len );
|
||||||
|
|
||||||
|
if( session->peer_cert != NULL )
|
||||||
|
{
|
||||||
|
memcpy( p, session->peer_cert->raw.p, cert_len );
|
||||||
|
p += cert_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||||
|
if( session->peer_cert_digest != NULL )
|
||||||
|
{
|
||||||
|
used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
|
||||||
|
if( used <= buf_len )
|
||||||
|
{
|
||||||
|
*p++ = (unsigned char) session->peer_cert_digest_type;
|
||||||
|
*p++ = (unsigned char) session->peer_cert_digest_len;
|
||||||
|
memcpy( p, session->peer_cert_digest,
|
||||||
|
session->peer_cert_digest_len );
|
||||||
|
p += session->peer_cert_digest_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
used += 2;
|
||||||
|
if( used <= buf_len )
|
||||||
|
{
|
||||||
|
*p++ = (unsigned char) MBEDTLS_MD_NONE;
|
||||||
|
*p++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||||
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Session ticket if any, plus associated data
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||||
|
used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
|
||||||
|
|
||||||
|
if( used <= buf_len )
|
||||||
|
{
|
||||||
|
*p++ = MBEDTLS_BYTE_2( session->ticket_len );
|
||||||
|
*p++ = MBEDTLS_BYTE_1( session->ticket_len );
|
||||||
|
*p++ = MBEDTLS_BYTE_0( session->ticket_len );
|
||||||
|
|
||||||
|
if( session->ticket != NULL )
|
||||||
|
{
|
||||||
|
memcpy( p, session->ticket, session->ticket_len );
|
||||||
|
p += session->ticket_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
MBEDTLS_PUT_UINT32_BE( session->ticket_lifetime, p, 0 );
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Misc extension-related info
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
|
||||||
|
used += 1;
|
||||||
|
|
||||||
|
if( used <= buf_len )
|
||||||
|
*p++ = session->mfl_code;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
|
||||||
|
used += 1;
|
||||||
|
|
||||||
|
if( used <= buf_len )
|
||||||
|
*p++ = MBEDTLS_BYTE_0( session->encrypt_then_mac );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return( used );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deserialize session, see mbedtls_ssl_session_save() for format.
|
||||||
|
*
|
||||||
|
* 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_tls12( mbedtls_ssl_session *session,
|
||||||
|
const unsigned char *buf,
|
||||||
|
size_t len )
|
||||||
|
{
|
||||||
|
#if defined(MBEDTLS_HAVE_TIME)
|
||||||
|
uint64_t start;
|
||||||
|
#endif
|
||||||
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||||
|
size_t cert_len;
|
||||||
|
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||||
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||||
|
|
||||||
|
const unsigned char *p = buf;
|
||||||
|
const unsigned char * const end = buf + len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_HAVE_TIME)
|
||||||
|
if( 8 > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
start = ( (uint64_t) p[0] << 56 ) |
|
||||||
|
( (uint64_t) p[1] << 48 ) |
|
||||||
|
( (uint64_t) p[2] << 40 ) |
|
||||||
|
( (uint64_t) p[3] << 32 ) |
|
||||||
|
( (uint64_t) p[4] << 24 ) |
|
||||||
|
( (uint64_t) p[5] << 16 ) |
|
||||||
|
( (uint64_t) p[6] << 8 ) |
|
||||||
|
( (uint64_t) p[7] );
|
||||||
|
p += 8;
|
||||||
|
|
||||||
|
session->start = (time_t) start;
|
||||||
|
#endif /* MBEDTLS_HAVE_TIME */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic mandatory fields
|
||||||
|
*/
|
||||||
|
if( 2 + 1 + 1 + 32 + 48 + 4 > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->ciphersuite = ( p[0] << 8 ) | p[1];
|
||||||
|
p += 2;
|
||||||
|
|
||||||
|
session->compression = *p++;
|
||||||
|
|
||||||
|
session->id_len = *p++;
|
||||||
|
memcpy( session->id, p, 32 );
|
||||||
|
p += 32;
|
||||||
|
|
||||||
|
memcpy( session->master, p, 48 );
|
||||||
|
p += 48;
|
||||||
|
|
||||||
|
session->verify_result = ( (uint32_t) p[0] << 24 ) |
|
||||||
|
( (uint32_t) p[1] << 16 ) |
|
||||||
|
( (uint32_t) p[2] << 8 ) |
|
||||||
|
( (uint32_t) p[3] );
|
||||||
|
p += 4;
|
||||||
|
|
||||||
|
/* Immediately clear invalid pointer values that have been read, in case
|
||||||
|
* we exit early before we replaced them with valid ones. */
|
||||||
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||||
|
session->peer_cert = NULL;
|
||||||
|
#else
|
||||||
|
session->peer_cert_digest = NULL;
|
||||||
|
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||||
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||||
|
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||||
|
session->ticket = NULL;
|
||||||
|
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Peer certificate
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||||
|
/* Deserialize CRT from the end of the ticket. */
|
||||||
|
if( 3 > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
|
||||||
|
p += 3;
|
||||||
|
|
||||||
|
if( cert_len != 0 )
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
if( cert_len > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
|
||||||
|
|
||||||
|
if( session->peer_cert == NULL )
|
||||||
|
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||||
|
|
||||||
|
mbedtls_x509_crt_init( session->peer_cert );
|
||||||
|
|
||||||
|
if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
|
||||||
|
p, cert_len ) ) != 0 )
|
||||||
|
{
|
||||||
|
mbedtls_x509_crt_free( session->peer_cert );
|
||||||
|
mbedtls_free( session->peer_cert );
|
||||||
|
session->peer_cert = NULL;
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
p += cert_len;
|
||||||
|
}
|
||||||
|
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||||
|
/* Deserialize CRT digest from the end of the ticket. */
|
||||||
|
if( 2 > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
|
||||||
|
session->peer_cert_digest_len = (size_t) *p++;
|
||||||
|
|
||||||
|
if( session->peer_cert_digest_len != 0 )
|
||||||
|
{
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type( session->peer_cert_digest_type );
|
||||||
|
if( md_info == NULL )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
if( session->peer_cert_digest_len != mbedtls_md_get_size( md_info ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
if( session->peer_cert_digest_len > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->peer_cert_digest =
|
||||||
|
mbedtls_calloc( 1, session->peer_cert_digest_len );
|
||||||
|
if( session->peer_cert_digest == NULL )
|
||||||
|
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||||
|
|
||||||
|
memcpy( session->peer_cert_digest, p,
|
||||||
|
session->peer_cert_digest_len );
|
||||||
|
p += session->peer_cert_digest_len;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||||
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Session ticket and associated data
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||||
|
if( 3 > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->ticket_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
|
||||||
|
p += 3;
|
||||||
|
|
||||||
|
if( session->ticket_len != 0 )
|
||||||
|
{
|
||||||
|
if( session->ticket_len > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->ticket = mbedtls_calloc( 1, session->ticket_len );
|
||||||
|
if( session->ticket == NULL )
|
||||||
|
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||||
|
|
||||||
|
memcpy( session->ticket, p, session->ticket_len );
|
||||||
|
p += session->ticket_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( 4 > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->ticket_lifetime = ( (uint32_t) p[0] << 24 ) |
|
||||||
|
( (uint32_t) p[1] << 16 ) |
|
||||||
|
( (uint32_t) p[2] << 8 ) |
|
||||||
|
( (uint32_t) p[3] );
|
||||||
|
p += 4;
|
||||||
|
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Misc extension-related info
|
||||||
|
*/
|
||||||
|
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
|
||||||
|
if( 1 > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->mfl_code = *p++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
|
||||||
|
if( 1 > (size_t)( end - p ) )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
session->encrypt_then_mac = *p++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Done, should have consumed entire buffer */
|
||||||
|
if( p != end )
|
||||||
|
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||||
|
|
||||||
#endif /* MBEDTLS_SSL_TLS_C */
|
#endif /* MBEDTLS_SSL_TLS_C */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user