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,6 +27,14 @@
#if defined(MBEDTLS_SSL_SRV_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"
@ -37,16 +45,8 @@
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#if defined(MBEDTLS_HAVE_TIME)
#include <time.h>
#include "mbedtls/platform_time.h"
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -232,7 +232,8 @@ have_sig_alg:
#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 int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@ -305,7 +306,12 @@ static int ssl_parse_supported_point_formats( 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 );
}
@ -316,7 +322,35 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
return( 0 );
}
#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( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
return( 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 );
}
/* Only mark the extension as OK when we're sure it is */
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK;
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
@ -707,6 +741,17 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
}
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake "
"not configured or ext missing" ) );
return( 0 );
}
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) &&
( ssl->handshake->curves == NULL ||
@ -998,7 +1043,6 @@ have_ciphersuite_v2:
ssl->session_negotiate->ciphersuite = ciphersuites[i];
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
/*
* SSLv2 Client Hello relevant renegotiation security checks
@ -1460,180 +1504,200 @@ read_record_header:
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
#endif
/*
* Check the extension length
*/
ext_offset = comp_offset + 1 + comp_len;
if( msg_len > ext_offset )
/* Do not parse the extensions if the protocol is SSLv3 */
#if defined(MBEDTLS_SSL_PROTO_SSL3)
if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) )
{
if( msg_len < ext_offset + 2 )
#endif
/*
* Check the extension length
*/
ext_offset = comp_offset + 1 + comp_len;
if( msg_len > ext_offset )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
if( msg_len < ext_offset + 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
ext_len = ( buf[ext_offset + 0] << 8 )
| ( buf[ext_offset + 1] );
if( ( ext_len > 0 && ext_len < 4 ) ||
msg_len != ext_offset + 2 + ext_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
}
else
ext_len = 0;
ext_len = ( buf[ext_offset + 0] << 8 )
| ( buf[ext_offset + 1] );
ext = buf + ext_offset + 2;
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len );
if( ( ext_len > 0 && ext_len < 4 ) ||
msg_len != ext_offset + 2 + ext_len )
while( ext_len != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
}
else
ext_len = 0;
unsigned int ext_id = ( ( ext[0] << 8 )
| ( ext[1] ) );
unsigned int ext_size = ( ( ext[2] << 8 )
| ( ext[3] ) );
ext = buf + ext_offset + 2;
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len );
while( ext_len != 0 )
{
unsigned int ext_id = ( ( ext[0] << 8 )
| ( ext[1] ) );
unsigned int ext_size = ( ( ext[2] << 8 )
| ( ext[3] ) );
if( ext_size + 4 > ext_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
switch( ext_id )
{
if( ext_size + 4 > ext_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
switch( ext_id )
{
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
case MBEDTLS_TLS_EXT_SERVERNAME:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
if( ssl->conf->f_sni == NULL )
break;
case MBEDTLS_TLS_EXT_SERVERNAME:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
if( ssl->conf->f_sni == NULL )
break;
ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
#if defined(MBEDTLS_SSL_RENEGOTIATION)
renegotiation_info_seen = 1;
renegotiation_info_seen = 1;
#endif
ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
case MBEDTLS_TLS_EXT_SIG_ALG:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
case MBEDTLS_TLS_EXT_SIG_ALG:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
break;
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
break;
#endif
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#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" ) );
ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) );
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) );
ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) );
case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) );
ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
case MBEDTLS_TLS_EXT_SESSION_TICKET:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) );
case MBEDTLS_TLS_EXT_SESSION_TICKET:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) );
ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_ALPN)
case MBEDTLS_TLS_EXT_ALPN:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
case MBEDTLS_TLS_EXT_ALPN:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
default:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
ext_id ) );
}
default:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
ext_id ) );
}
ext_len -= 4 + ext_size;
ext += 4 + ext_size;
ext_len -= 4 + ext_size;
ext += 4 + ext_size;
if( ext_len > 0 && ext_len < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
if( ext_len > 0 && ext_len < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
}
#endif
#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 )
@ -1775,7 +1839,6 @@ have_ciphersuite:
ssl->session_negotiate->ciphersuite = ciphersuites[i];
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
ssl->state++;
@ -1976,7 +2039,8 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#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_point_formats_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
@ -2004,7 +2068,51 @@ 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 computation if not needed */
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
return;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, 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 );
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;
}
*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_ALPN )
static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
@ -2108,7 +2216,7 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_HAVE_TIME)
time_t t;
mbedtls_time_t t;
#endif
int ret;
size_t olen, ext_len = 0, n;
@ -2151,7 +2259,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
buf[4], buf[5] ) );
#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 );
@ -2200,7 +2308,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ssl->state++;
#if defined(MBEDTLS_HAVE_TIME)
ssl->session_negotiate->start = time( NULL );
ssl->session_negotiate->start = mbedtls_time( NULL );
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -2259,6 +2367,12 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X",
ssl->session_negotiate->compression ) );
/* Do not write the extensions if the protocol is SSLv3 */
#if defined(MBEDTLS_SSL_PROTO_SSL3)
if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) )
{
#endif
/*
* First write extensions, then the total length
*/
@ -2290,11 +2404,17 @@ static int ssl_write_server_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_point_formats_ext( ssl, p + 2 + ext_len, &olen );
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_ALPN)
ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
@ -2309,6 +2429,10 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
p += ext_len;
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
}
#endif
ssl->out_msglen = p - buf;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO;
@ -2322,7 +2446,9 @@ static int ssl_write_server_hello( 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_request( mbedtls_ssl_context *ssl )
{
@ -2333,7 +2459,8 @@ static int ssl_write_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 write certificate request" ) );
ssl->state++;
@ -2351,6 +2478,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
size_t dn_size, total_dn_size; /* excluding length bytes */
size_t ct_len, sa_len; /* including length bytes */
unsigned char *buf, *p;
const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
const mbedtls_x509_crt *crt;
int authmode;
@ -2369,6 +2497,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
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_ECJPAKE ||
authmode == MBEDTLS_SSL_VERIFY_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
@ -2425,29 +2554,27 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
*/
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
/*
* Only use current running hash algorithm that is already required
* for requested ciphersuite.
*/
ssl->handshake->verify_sig_alg = MBEDTLS_SSL_HASH_SHA256;
if( ssl->transform_negotiate->ciphersuite_info->mac ==
MBEDTLS_MD_SHA384 )
{
ssl->handshake->verify_sig_alg = MBEDTLS_SSL_HASH_SHA384;
}
const int *cur;
/*
* Supported signature algorithms
*/
for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
{
unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur );
if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) )
continue;
#if defined(MBEDTLS_RSA_C)
p[2 + sa_len++] = ssl->handshake->verify_sig_alg;
p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA;
p[2 + sa_len++] = hash;
p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA;
#endif
#if defined(MBEDTLS_ECDSA_C)
p[2 + sa_len++] = ssl->handshake->verify_sig_alg;
p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA;
p[2 + sa_len++] = hash;
p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA;
#endif
}
p[0] = (unsigned char)( sa_len >> 8 );
p[1] = (unsigned char)( sa_len );
@ -2471,10 +2598,16 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
total_dn_size = 0;
while( crt != NULL && crt->version != 0 )
{
if( p - buf > 4096 )
break;
dn_size = crt->subject_raw.len;
if( end < p ||
(size_t)( end - p ) < dn_size ||
(size_t)( end - p ) < 2 + dn_size )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) );
break;
}
*p++ = (unsigned char)( dn_size >> 8 );
*p++ = (unsigned char)( dn_size );
memcpy( p, crt->subject_raw.p, dn_size );
@ -2500,7 +2633,9 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
}
#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 */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
@ -2539,12 +2674,14 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
unsigned char *p = ssl->out_msg + 4;
unsigned char *dig_signed = p;
size_t dig_signed_len = 0, len;
((void) dig_signed);
((void) dig_signed_len);
((void) len);
#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
@ -2575,12 +2712,32 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
}
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
size_t jlen;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p, &jlen, ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret );
}
p += jlen;
n += jlen;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{
/* TODO: Support identity hints */
/* Note: we don't support identity hints, until someone asks
* for them. */
*(p++) = 0x00;
*(p++) = 0x00;
@ -3326,6 +3483,28 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_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 );
}
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_ECJPAKE_ENABLED */
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@ -3346,7 +3525,9 @@ static int ssl_parse_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_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
@ -3357,7 +3538,8 @@ static int ssl_parse_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 parse certificate verify" ) );
ssl->state++;
@ -3387,6 +3569,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
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_ECJPAKE ||
ssl->session_negotiate->peer_cert == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
@ -3394,17 +3577,28 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( 0 );
}
/* Needs to be done before read_record() to exclude current message */
ssl->handshake->calc_verify( ssl, hash );
/* Read the message without adding it to the checksum */
do {
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret );
return( ret );
}
ret = mbedtls_ssl_handle_message_type( ssl );
} while( MBEDTLS_ERR_SSL_NON_FATAL == ret );
if( 0 != ret )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
return( ret );
}
ssl->state++;
/* Process the message contents */
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY )
{
@ -3451,14 +3645,19 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
/*
* Hash
*/
if( ssl->in_msg[i] != ssl->handshake->verify_sig_alg )
md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] );
if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
" for verify message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
}
md_alg = mbedtls_ssl_md_alg_from_hash( ssl->handshake->verify_sig_alg );
#if !defined(MBEDTLS_MD_SHA1)
if( MBEDTLS_MD_SHA1 == md_alg )
hash_start += 16;
#endif
/* Info from md_alg will be used instead */
hashlen = 0;
@ -3509,6 +3708,9 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
}
/* Calculate hash and verify signature */
ssl->handshake->calc_verify( ssl, hash );
if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
md_alg, hash_start, hashlen,
ssl->in_msg + i, sig_len ) ) != 0 )
@ -3517,13 +3719,18 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
mbedtls_ssl_update_handshake_status( ssl );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) );
return( ret );
}
#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_write_new_session_ticket( mbedtls_ssl_context *ssl )