From 4f9e3efbeb68d2768ea3391440f9ef2b681791fa Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Thu, 17 Feb 2022 14:58:27 +0800 Subject: [PATCH] move session_save/load_tls12 Signed-off-by: Jerry Yu --- library/ssl_tls.c | 749 +++++++++++++++++++++++----------------------- 1 file changed, 373 insertions(+), 376 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 53f5038ee..2de330a1a 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -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, unsigned char omit_header, 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 ) ); } -#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, unsigned char omit_header, 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 */ +/* 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_TLS_C */