Fix possible buffer overflow with PSK

This commit is contained in:
Manuel Pégourié-Gonnard 2014-03-25 16:28:12 +01:00 committed by Paul Bakker
parent fdddac90a6
commit b2bf5a1bbb
3 changed files with 14 additions and 2 deletions

View file

@ -25,10 +25,11 @@ Changes
Security Security
* Forbid change of server certificate during renegotiation to prevent * Forbid change of server certificate during renegotiation to prevent
"triple handshake" attack when authentication mode is optional (the "triple handshake" attack when authentication mode is 'optional' (the
attack was already impossible when authentication is required). attack was already impossible when authentication is required).
* Check notBefore timestamp of certificates and CRLs from the future. * Check notBefore timestamp of certificates and CRLs from the future.
* Forbid sequence number wrapping * Forbid sequence number wrapping
* Fix possible buffer overflow with overlong PSK
Bugfix Bugfix
* ecp_gen_keypair() does more tries to prevent failure because of * ecp_gen_keypair() does more tries to prevent failure because of

View file

@ -2455,7 +2455,7 @@ static int ssl_parse_encrypted_pms( ssl_context *ssl,
ret = pk_decrypt( ssl_own_key( ssl ), p, len, ret = pk_decrypt( ssl_own_key( ssl ), p, len,
pms, &ssl->handshake->pmslen, pms, &ssl->handshake->pmslen,
sizeof(ssl->handshake->premaster), sizeof( ssl->handshake->premaster ) - pms_offset,
ssl->f_rng, ssl->p_rng ); ssl->f_rng, ssl->p_rng );
if( ret != 0 || ssl->handshake->pmslen != 48 || if( ret != 0 || ssl->handshake->pmslen != 48 ||

View file

@ -916,6 +916,9 @@ int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex )
} }
/* opaque psk<0..2^16-1>; */ /* opaque psk<0..2^16-1>; */
if( end - p < 2 + (int) ssl->psk_len )
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
*(p++) = (unsigned char)( ssl->psk_len >> 8 ); *(p++) = (unsigned char)( ssl->psk_len >> 8 );
*(p++) = (unsigned char)( ssl->psk_len ); *(p++) = (unsigned char)( ssl->psk_len );
memcpy( p, ssl->psk, ssl->psk_len ); memcpy( p, ssl->psk, ssl->psk_len );
@ -3784,6 +3787,14 @@ int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
if( psk == NULL || psk_identity == NULL ) if( psk == NULL || psk_identity == NULL )
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
/*
* The length will be check later anyway, but in case it is obviously
* too large, better abort now. The PMS is as follows:
* other_len (2 bytes) + other + psk_len (2 bytes) + psk
*/
if( psk_len + 4 > POLARSSL_PREMASTER_SIZE )
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
if( ssl->psk != NULL ) if( ssl->psk != NULL )
{ {
polarssl_free( ssl->psk ); polarssl_free( ssl->psk );