Externals: Update mbedtls to 2.4.1

The latest version has tons of security fixes (which is expected for a
library such as mbedtls).

Updating also allows getting rid of a few deprecation warnings.
This commit is contained in:
Léo Lam
2017-01-28 16:03:21 +01:00
parent 0e961776e6
commit b8dd3e690f
104 changed files with 6445 additions and 1270 deletions

View File

@ -27,24 +27,24 @@
#if defined(MBEDTLS_SSL_CLI_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h"
#include <string.h>
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#include <stdint.h>
#if defined(MBEDTLS_HAVE_TIME)
#include <time.h>
#include "mbedtls/platform_time.h"
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -60,6 +60,7 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t hostname_len;
*olen = 0;
@ -72,6 +73,12 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
hostname_len = strlen( ssl->hostname );
if( end < p || (size_t)( end - p ) < hostname_len + 9 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
/*
* struct {
* NameType name_type;
@ -115,6 +122,7 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
@ -123,6 +131,12 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
/*
* Secure renegotiation
*/
@ -149,6 +163,7 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t sig_alg_len = 0;
const int *md;
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
@ -162,9 +177,27 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
{
#if defined(MBEDTLS_ECDSA_C)
sig_alg_len += 2;
#endif
#if defined(MBEDTLS_RSA_C)
sig_alg_len += 2;
#endif
}
if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
/*
* Prepare signature_algorithms extension (TLS 1.2)
*/
sig_alg_len = 0;
for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
{
#if defined(MBEDTLS_ECDSA_C)
@ -208,12 +241,14 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
unsigned char *elliptic_curve_list = p + 6;
size_t elliptic_curve_len = 0;
const mbedtls_ecp_curve_info *info;
@ -235,7 +270,31 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
{
#endif
if( info == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) );
return;
}
elliptic_curve_len += 2;
}
if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
elliptic_curve_len = 0;
#if defined(MBEDTLS_ECP_C)
for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
{
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
#else
for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
{
#endif
elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
}
@ -260,12 +319,18 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
size_t *olen )
{
unsigned char *p = buf;
((void) ssl);
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
if( end < p || (size_t)( end - p ) < 6 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
@ -277,7 +342,86 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
*olen = 6;
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
{
int ret;
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t kkpp_len;
*olen = 0;
/* Skip costly extension if we can't use EC J-PAKE anyway */
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
return;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
if( end - p < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
/*
* We may need to send ClientHello multiple times for Hello verification.
* We don't want to compute fresh values every time (both for performance
* and consistency reasons), so cache the extension content.
*/
if( ssl->handshake->ecjpake_cache == NULL ||
ssl->handshake->ecjpake_cache_len == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
return;
}
ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
if( ssl->handshake->ecjpake_cache == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
return;
}
memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
ssl->handshake->ecjpake_cache_len = kkpp_len;
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
kkpp_len = ssl->handshake->ecjpake_cache_len;
if( (size_t)( end - p - 2 ) < kkpp_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
}
*p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
*olen = kkpp_len + 4;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
@ -285,14 +429,22 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
*olen = 0;
return;
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
if( end < p || (size_t)( end - p ) < 5 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
@ -310,15 +462,23 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
{
*olen = 0;
return;
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
if( end < p || (size_t)( end - p ) < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
@ -334,17 +494,25 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{
*olen = 0;
return;
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
"extension" ) );
if( end < p || (size_t)( end - p ) < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
@ -360,17 +528,25 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{
*olen = 0;
return;
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
"extension" ) );
if( end < p || (size_t)( end - p ) < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
@ -386,16 +562,24 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t tlen = ssl->session_negotiate->ticket_len;
*olen = 0;
if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
{
*olen = 0;
return;
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
if( end < p || (size_t)( end - p ) < 4 + tlen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
@ -404,8 +588,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
*olen = 4;
if( ssl->session_negotiate->ticket == NULL ||
ssl->session_negotiate->ticket_len == 0 )
if( ssl->session_negotiate->ticket == NULL || tlen == 0 )
{
return;
}
@ -423,16 +606,28 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen )
{
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t alpnlen = 0;
const char **cur;
*olen = 0;
if( ssl->conf->alpn_list == NULL )
{
*olen = 0;
return;
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1;
if( end < p || (size_t)( end - p ) < 6 + alpnlen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
@ -474,7 +669,7 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
int ret;
unsigned char *p = ssl->handshake->randbytes;
#if defined(MBEDTLS_HAVE_TIME)
time_t t;
mbedtls_time_t t;
#endif
/*
@ -489,7 +684,7 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
#endif
#if defined(MBEDTLS_HAVE_TIME)
t = time( NULL );
t = mbedtls_time( NULL );
*p++ = (unsigned char)( t >> 24 );
*p++ = (unsigned char)( t >> 16 );
*p++ = (unsigned char)( t >> 8 );
@ -680,8 +875,14 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
continue;
#endif
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %2d",
ciphersuites[i] ) );
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
continue;
#endif
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
ciphersuites[i] ) );
n++;
*p++ = (unsigned char)( ciphersuites[i] >> 8 );
@ -771,7 +972,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
@ -779,6 +981,11 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
@ -799,13 +1006,13 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
#if defined(MBEDTLS_SSL_ALPN)
ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_ALPN)
ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
#endif
@ -986,7 +1193,8 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@ -1007,7 +1215,12 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
p[0] == MBEDTLS_ECP_PF_COMPRESSED )
{
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
ssl->handshake->ecdh_ctx.point_format = p[0];
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl->handshake->ecjpake_ctx.point_format = p[0];
#endif
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
return( 0 );
}
@ -1019,7 +1232,38 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
int ret;
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
return( 0 );
}
/* If we got here, we no longer need our cached extension */
mbedtls_free( ssl->handshake->ecjpake_cache );
ssl->handshake->ecjpake_cache = NULL;
ssl->handshake->ecjpake_cache_len = 0;
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
buf, len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
return( ret );
}
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN)
static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
@ -1111,6 +1355,15 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
cookie_len = *p++;
MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "cookie length does not match incoming message size" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
mbedtls_free( ssl->handshake->verify_cookie );
ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
@ -1348,7 +1601,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
ssl->state++;
ssl->handshake->resume = 0;
#if defined(MBEDTLS_HAVE_TIME)
ssl->session_negotiate->start = time( NULL );
ssl->session_negotiate->start = mbedtls_time( NULL );
#endif
ssl->session_negotiate->ciphersuite = i;
ssl->session_negotiate->compression = comp;
@ -1369,7 +1622,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->handshake->resume ? "a" : "no" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", i ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
@ -1384,6 +1637,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
i = 0;
while( 1 )
{
@ -1507,7 +1762,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
@ -1518,7 +1774,21 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
}
break;
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) );
if( ( ret = ssl_parse_ecjpake_kkpp( ssl,
ext + 4, ext_size ) ) != 0 )
{
return( ret );
}
break;
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN)
case MBEDTLS_TLS_EXT_ALPN:
@ -1725,8 +1995,11 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
// TODO: Retrieve PSK identity hint and callback to app
//
/*
* Note: we currently ignore the PKS identity hint, as we only allow one
* PSK to be provisionned on the client. This could be changed later if
* someone needs that feature.
*/
*p += len;
ret = 0;
@ -1813,7 +2086,9 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED)
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end,
@ -1838,7 +2113,7 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
*/
if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used unsupported "
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported "
"HashAlgorithm %d", *(p)[0] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@ -1848,7 +2123,7 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
*/
if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used unsupported "
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported "
"SignatureAlgorithm %d", (*p)[1] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@ -1858,7 +2133,7 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
*/
if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used HashAlgorithm "
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm "
"that was not offered" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@ -1869,7 +2144,9 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
@ -2037,6 +2314,19 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@ -2230,7 +2520,9 @@ exit:
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
@ -2241,7 +2533,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ssl->state++;
@ -2255,8 +2548,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
int ret;
unsigned char *buf, *p;
size_t n = 0, m = 0;
unsigned char *buf;
size_t n = 0;
size_t cert_type_len = 0, dn_len = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
@ -2265,7 +2558,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ssl->state++;
@ -2303,9 +2597,6 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
ssl->record_read = 0;
// TODO: handshake_failure alert for an anonymous server to request
// client authentication
/*
* struct {
* ClientCertificateType certificate_types<1..2^8-1>;
@ -2313,11 +2604,26 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
* supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
* DistinguishedName certificate_authorities<0..2^16-1>;
* } CertificateRequest;
*
* Since we only support a single certificate on clients, let's just
* ignore all the information that's supposed to help us pick a
* certificate.
*
* We could check that our certificate matches the request, and bail out
* if it doesn't, but it's simpler to just send the certificate anyway,
* and give the server the opportunity to decide if it should terminate
* the connection when it doesn't like our certificate.
*
* Same goes for the hash in TLS 1.2's signature_algorithms: at this
* point we only have one hash available (see comments in
* write_certificate_verify), so let's just use what we have.
*
* However, we still minimally parse the message to check it is at least
* superficially sane.
*/
buf = ssl->in_msg;
// Retrieve cert types
//
/* certificate_types */
cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
n = cert_type_len;
@ -2327,45 +2633,23 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
}
p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1;
while( cert_type_len > 0 )
{
#if defined(MBEDTLS_RSA_C)
if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN &&
mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
{
ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
break;
}
else
#endif
#if defined(MBEDTLS_ECDSA_C)
if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN &&
mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
{
ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
break;
}
else
#endif
{
; /* Unsupported cert type, ignore */
}
cert_type_len--;
p++;
}
/* supported_signature_algorithms */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
/* Ignored, see comments about hash in write_certificate_verify */
// TODO: should check the signature part against our pk_key though
size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
#if defined(MBEDTLS_DEBUG_C)
unsigned char* sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
size_t i;
m += 2;
n += sig_alg_len;
for( i = 0; i < sig_alg_len; i += 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d,%d", sig_alg[i], sig_alg[i + 1] ) );
}
#endif
n += 2 + sig_alg_len;
if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
{
@ -2375,13 +2659,12 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
/* Ignore certificate_authorities, we only have one cert anyway */
// TODO: should not send cert if no CA matches
dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 )
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) );
/* certificate_authorities */
dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
n += dn_len;
if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + n )
if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
@ -2394,7 +2677,9 @@ exit:
}
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
@ -2645,6 +2930,31 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret );
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
i = 4;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret );
}
ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
return( ret );
}
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
{
((void) ciphersuite_info);
@ -2671,7 +2981,9 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
@ -2689,7 +3001,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
@ -2721,7 +3034,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
@ -2849,7 +3163,10 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
}
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )