mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-26 10:05:46 +01:00
Merge pull request #297 from gilles-peskine-arm/asn1_get_int-undefined_shift
Fix int overflow in mbedtls_asn1_get_int
This commit is contained in:
commit
3cdb3da3a0
@ -149,16 +149,26 @@ int mbedtls_asn1_get_int( unsigned char **p,
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( len == 0 || ( **p & 0x80 ) != 0 )
|
||||
/* len==0 is malformed (0 must be represented as 020100). */
|
||||
if( len == 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
/* This is a cryptography library. Reject negative integers. */
|
||||
if( ( **p & 0x80 ) != 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
|
||||
/* Skip leading zeros. */
|
||||
while( len > 0 && **p == 0 )
|
||||
{
|
||||
++( *p );
|
||||
--len;
|
||||
}
|
||||
|
||||
/* Reject integers that don't fit in an int. This code assumes that
|
||||
* the int type has no padding bit. */
|
||||
if( len > sizeof( int ) )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
if( len == sizeof( int ) && ( **p & 0x80 ) != 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
|
||||
*val = 0;
|
||||
while( len-- > 0 )
|
||||
|
@ -164,8 +164,7 @@ Not BOOLEAN
|
||||
get_boolean:"020101":0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
|
||||
|
||||
Empty INTEGER
|
||||
depends_on:SUPPORT_NEGATIVE_INTEGERS
|
||||
get_integer:"0200":"":MBEDTLS_ERR_ASN1_INVALID_LENGTH
|
||||
empty_integer:"0200"
|
||||
|
||||
INTEGER 0
|
||||
get_integer:"020100":"0":0
|
||||
@ -173,27 +172,15 @@ get_integer:"020100":"0":0
|
||||
INTEGER 0, extra leading 0
|
||||
get_integer:"02020000":"0":0
|
||||
|
||||
INTEGER -0
|
||||
depends_on:SUPPORT_NEGATIVE_INTEGERS
|
||||
get_integer:"020180":"0":0
|
||||
|
||||
INTEGER 1
|
||||
get_integer:"020101":"1":0:
|
||||
|
||||
INTEGER 1, extra leading 0
|
||||
get_integer:"02020001":"1":0:
|
||||
|
||||
INTEGER -1
|
||||
depends_on:SUPPORT_NEGATIVE_INTEGERS
|
||||
get_integer:"020181":"-1":0
|
||||
|
||||
INTEGER 0x7f
|
||||
get_integer:"02017f":"7f":0
|
||||
|
||||
INTEGER -0x7f
|
||||
depends_on:SUPPORT_NEGATIVE_INTEGERS
|
||||
get_integer:"0201ff":"-7f":0
|
||||
|
||||
INTEGER 0x80
|
||||
get_integer:"02020080":"80":0
|
||||
|
||||
@ -212,9 +199,30 @@ get_integer:"020412345678":"12345678":0
|
||||
INTEGER 0x12345678, extra leading 0
|
||||
get_integer:"02050012345678":"12345678":0
|
||||
|
||||
INTEGER 0x7fffffff
|
||||
get_integer:"02047fffffff":"7fffffff":0
|
||||
|
||||
INTEGER 0x7fffffff, extra leading 0
|
||||
get_integer:"0205007fffffff":"7fffffff":0
|
||||
|
||||
INTEGER 0x80000000
|
||||
get_integer:"02050080000000":"80000000":0
|
||||
|
||||
INTEGER 0xffffffff
|
||||
get_integer:"020500ffffffff":"ffffffff":0
|
||||
|
||||
INTEGER 0x100000000
|
||||
get_integer:"02050100000000":"0100000000":0
|
||||
|
||||
INTEGER 0x123456789abcdef0
|
||||
get_integer:"0208123456789abcdef0":"123456789abcdef0":0
|
||||
|
||||
INTEGER 0xfedcab9876543210
|
||||
get_integer:"020900fedcab9876543210":"fedcab9876543210":0
|
||||
|
||||
INTEGER 0x1fedcab9876543210
|
||||
get_integer:"020901fedcab9876543210":"1fedcab9876543210":0
|
||||
|
||||
INTEGER with 127 value octets
|
||||
get_integer:"027f0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":0
|
||||
|
||||
@ -227,6 +235,51 @@ get_integer:"0281800123456789abcdef0123456789abcdef0123456789abcdef0123456789abc
|
||||
INTEGER with 128 value octets (leading 0 in length)
|
||||
get_integer:"028200800123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":0
|
||||
|
||||
INTEGER -1
|
||||
get_integer:"0201ff":"-1":0
|
||||
|
||||
INTEGER -1, extra leading ff
|
||||
get_integer:"0202ffff":"-1":0
|
||||
|
||||
INTEGER -0x7f
|
||||
get_integer:"020181":"-7f":0
|
||||
|
||||
INTEGER -0x80
|
||||
get_integer:"020180":"-80":0
|
||||
|
||||
INTEGER -0x81
|
||||
get_integer:"0202ff7f":"-81":0
|
||||
|
||||
INTEGER -0xff
|
||||
get_integer:"0202ff01":"-ff":0
|
||||
|
||||
INTEGER -0x100
|
||||
get_integer:"0202ff00":"-100":0
|
||||
|
||||
INTEGER -0x7fffffff
|
||||
get_integer:"020480000001":"-7fffffff":0
|
||||
|
||||
INTEGER -0x80000000
|
||||
get_integer:"020480000000":"-80000000":0
|
||||
|
||||
INTEGER -0x80000001
|
||||
get_integer:"0205ff7fffffff":"-80000001":0
|
||||
|
||||
INTEGER -0xffffffff
|
||||
get_integer:"0205ff00000001":"-ffffffff":0
|
||||
|
||||
INTEGER -0x100000000
|
||||
get_integer:"0205ff00000000":"-100000000":0
|
||||
|
||||
INTEGER -0x123456789abcdef0
|
||||
get_integer:"0208edcba98765432110":"-123456789abcdef0":0
|
||||
|
||||
INTEGER -0xfedcba9876543210
|
||||
get_integer:"0209ff0123456789abcdf0":"-fedcba9876543210":0
|
||||
|
||||
INTEGER -0x1fedcab9876543210
|
||||
get_integer:"0209fe0123546789abcdf0":"-1fedcab9876543210":0
|
||||
|
||||
Not INTEGER
|
||||
get_integer:"010101":"":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
|
||||
|
||||
|
@ -59,6 +59,10 @@ static int nested_parse( unsigned char **const p,
|
||||
*p = start;
|
||||
ret = mbedtls_asn1_get_mpi( p, end, &mpi );
|
||||
mbedtls_mpi_free( &mpi );
|
||||
#else
|
||||
*p = start + 1;
|
||||
ret = mbedtls_asn1_get_len( p, end, &len );
|
||||
*p += len;
|
||||
#endif
|
||||
/* If we're sure that the number fits in an int, also
|
||||
* call mbedtls_asn1_get_int(). */
|
||||
@ -246,6 +250,41 @@ void get_boolean( const data_t *input,
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void empty_integer( const data_t *input )
|
||||
{
|
||||
unsigned char *p;
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
mbedtls_mpi actual_mpi;
|
||||
#endif
|
||||
int val;
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
mbedtls_mpi_init( & actual_mpi );
|
||||
#endif
|
||||
|
||||
/* An INTEGER with no content is not valid. */
|
||||
p = input->x;
|
||||
TEST_EQUAL( mbedtls_asn1_get_int( &p, input->x + input->len, &val ),
|
||||
MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
/* INTEGERs are sometimes abused as bitstrings, so the library accepts
|
||||
* an INTEGER with empty content and gives it the value 0. */
|
||||
p = input->x;
|
||||
TEST_EQUAL( mbedtls_asn1_get_mpi( &p, input->x + input->len, &actual_mpi ),
|
||||
0 );
|
||||
TEST_EQUAL( mbedtls_mpi_cmp_int( &actual_mpi, 0 ), 0 );
|
||||
#endif
|
||||
|
||||
exit:
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
mbedtls_mpi_free( &actual_mpi );
|
||||
#endif
|
||||
/*empty cleanup in some configurations*/ ;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void get_integer( const data_t *input,
|
||||
const char *expected_hex, int expected_result )
|
||||
@ -254,16 +293,18 @@ void get_integer( const data_t *input,
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
mbedtls_mpi expected_mpi;
|
||||
mbedtls_mpi actual_mpi;
|
||||
mbedtls_mpi complement;
|
||||
int expected_result_for_mpi = expected_result;
|
||||
#endif
|
||||
long expected_value;
|
||||
int expected_result_for_int = expected_result;
|
||||
int expected_result_for_mpi = expected_result;
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
mbedtls_mpi_init( &expected_mpi );
|
||||
mbedtls_mpi_init( &actual_mpi );
|
||||
mbedtls_mpi_init( &complement );
|
||||
#endif
|
||||
|
||||
errno = 0;
|
||||
@ -275,6 +316,16 @@ void get_integer( const data_t *input,
|
||||
#endif
|
||||
) )
|
||||
{
|
||||
/* The library returns the dubious error code INVALID_LENGTH
|
||||
* for integers that are out of range. */
|
||||
expected_result_for_int = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
if( expected_result == 0 && expected_value < 0 )
|
||||
{
|
||||
/* The library does not support negative INTEGERs and
|
||||
* returns the dubious error code INVALID_LENGTH.
|
||||
* Test that we preserve the historical behavior. If we
|
||||
* decide to change the behavior, we'll also change this test. */
|
||||
expected_result_for_int = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
@ -300,7 +351,34 @@ void get_integer( const data_t *input,
|
||||
TEST_EQUAL( ret, expected_result_for_mpi );
|
||||
if( ret == 0 )
|
||||
{
|
||||
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &actual_mpi , &expected_mpi ) == 0 );
|
||||
if( expected_value >= 0 )
|
||||
{
|
||||
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &actual_mpi,
|
||||
&expected_mpi ) == 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The library ignores the sign bit in ASN.1 INTEGERs
|
||||
* (which makes sense insofar as INTEGERs are sometimes
|
||||
* abused as bit strings), so the result of parsing them
|
||||
* is a positive integer such that expected_mpi +
|
||||
* actual_mpi = 2^n where n is the length of the content
|
||||
* of the INTEGER. (Leading ff octets don't matter for the
|
||||
* expected value, but they matter for the actual value.)
|
||||
* Test that we don't change from this behavior. If we
|
||||
* decide to fix the library to change the behavior on
|
||||
* negative INTEGERs, we'll fix this test code. */
|
||||
unsigned char *q = input->x + 1;
|
||||
size_t len;
|
||||
TEST_ASSERT( mbedtls_asn1_get_len( &q, input->x + input->len,
|
||||
&len ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_lset( &complement, 1 ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_shift_l( &complement, len * 8 ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_add_mpi( &complement, &complement,
|
||||
&expected_mpi ) == 0 );
|
||||
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &complement,
|
||||
&actual_mpi ) == 0 );
|
||||
}
|
||||
TEST_ASSERT( p == input->x + input->len );
|
||||
}
|
||||
#endif
|
||||
@ -309,7 +387,9 @@ exit:
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
mbedtls_mpi_free( &expected_mpi );
|
||||
mbedtls_mpi_free( &actual_mpi );
|
||||
mbedtls_mpi_free( &complement );
|
||||
#endif
|
||||
/*empty cleanup in some configurations*/ ;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user