Fix buffer overreads in mbedtls_pem_read_buffer()

This commit is contained in:
Andres AG 2016-10-24 11:23:36 +01:00
parent cef21e4cd9
commit 7df03916e1
2 changed files with 14 additions and 9 deletions

View file

@ -14,6 +14,9 @@ Bugfix
in RFC 6347 Section 4.3.1. This could cause the execution of the in RFC 6347 Section 4.3.1. This could cause the execution of the
renegotiation routines at unexpected times when the protocol is DTLS. Found renegotiation routines at unexpected times when the protocol is DTLS. Found
by wariua. #687 by wariua. #687
* Fixed multiple buffer overreads in mbedtls_pem_read_buffer() when parsing
the input string in pem format to extract the different components. Found
by Eyal Itkin.
= mbed TLS 2.4.1 branch released 2016-12-13 = mbed TLS 2.4.1 branch released 2016-12-13

View file

@ -249,7 +249,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
enc = 0; enc = 0;
if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
{ {
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
@ -262,22 +262,22 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
#if defined(MBEDTLS_DES_C) #if defined(MBEDTLS_DES_C)
if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
{ {
enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC;
s1 += 23; s1 += 23;
if( pem_get_iv( s1, pem_iv, 8 ) != 0 ) if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8 ) != 0 )
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
s1 += 16; s1 += 16;
} }
else if( memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
{ {
enc_alg = MBEDTLS_CIPHER_DES_CBC; enc_alg = MBEDTLS_CIPHER_DES_CBC;
s1 += 18; s1 += 18;
if( pem_get_iv( s1, pem_iv, 8) != 0 ) if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8) != 0 )
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
s1 += 16; s1 += 16;
@ -285,9 +285,11 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
#endif /* MBEDTLS_DES_C */ #endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_AES_C)
if( memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 )
{ {
if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) if( s2 - s1 < 22 )
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
enc_alg = MBEDTLS_CIPHER_AES_128_CBC; enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
enc_alg = MBEDTLS_CIPHER_AES_192_CBC; enc_alg = MBEDTLS_CIPHER_AES_192_CBC;
@ -297,7 +299,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
s1 += 22; s1 += 22;
if( pem_get_iv( s1, pem_iv, 16 ) != 0 ) if( s2 - s1 < 32 || pem_get_iv( s1, pem_iv, 16 ) != 0 )
return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
s1 += 32; s1 += 32;
@ -316,7 +318,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
} }
if( s1 == s2 ) if( s1 >= s2 )
return( MBEDTLS_ERR_PEM_INVALID_DATA ); return( MBEDTLS_ERR_PEM_INVALID_DATA );
ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 ); ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 );