mbedtls/tests/suites/test_suite_asn1write.function
Gilles Peskine 3a032c36c1 Add test cases for BOOLEANs and INTEGERs
Omit negative integers and MPIs that would result in values that look
like negative INTEGERs, since the library doesn't respect the
specifications there, but fixing it has a serious risk of breaking
interoperability when ASN.1 is used in X.509 and other
cryptography-related applications.
2019-09-11 15:46:44 +02:00

287 lines
7.3 KiB
Plaintext

/* BEGIN_HEADER */
#include "mbedtls/asn1write.h"
#define GUARD_LEN 4
#define GUARD_VAL 0x2a
typedef struct
{
unsigned char *output;
unsigned char *start;
unsigned char *end;
unsigned char *p;
size_t size;
} generic_write_data_t;
int generic_write_start_step( generic_write_data_t *data )
{
test_set_step( data->size );
ASSERT_ALLOC( data->output, data->size == 0 ? 1 : data->size );
data->end = data->output + data->size;
data->p = data->end;
data->start = data->end - data->size;
return( 1 );
exit:
return( 0 );
}
int generic_write_finish_step( generic_write_data_t *data,
const data_t *expected, int ret )
{
int ok = 0;
if( data->size < expected->len )
{
TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
}
else
{
TEST_EQUAL( ret, data->end - data->p );
TEST_ASSERT( data->p >= data->start );
TEST_ASSERT( data->p <= data->end );
ASSERT_COMPARE( data->p, (size_t)( data->end - data->p ),
expected->x, expected->len );
}
ok = 1;
exit:
mbedtls_free( data->output );
data->output = NULL;
return( ok );
}
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_ASN1_WRITE_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
void mbedtls_asn1_write_bool( int val, data_t *expected )
{
generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
int ret;
for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
if( ! generic_write_start_step( &data ) )
goto exit;
ret = mbedtls_asn1_write_bool( &data.p, data.start, val );
if( ! generic_write_finish_step( &data, expected, ret ) )
goto exit;
}
exit:
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_asn1_write_int( int val, data_t *expected )
{
generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
int ret;
for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
if( ! generic_write_start_step( &data ) )
goto exit;
ret = mbedtls_asn1_write_int( &data.p, data.start, val );
if( ! generic_write_finish_step( &data, expected, ret ) )
goto exit;
}
exit:
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
void mbedtls_asn1_write_mpi( data_t *val, data_t *expected )
{
generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
mbedtls_mpi mpi;
int ret;
mbedtls_mpi_init( &mpi );
TEST_ASSERT( mbedtls_mpi_read_binary( &mpi, val->x, val->len ) == 0 );
for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
if( ! generic_write_start_step( &data ) )
goto exit;
ret = mbedtls_asn1_write_mpi( &data.p, data.start, &mpi );
if( ! generic_write_finish_step( &data, expected, ret ) )
goto exit;
}
exit:
mbedtls_mpi_free( &mpi );
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_asn1_write_octet_string( data_t * str, data_t * asn1,
int buf_len, int result )
{
int ret;
unsigned char buf[150];
size_t i;
unsigned char *p;
memset( buf, GUARD_VAL, sizeof( buf ) );
p = buf + GUARD_LEN + buf_len;
ret = mbedtls_asn1_write_octet_string( &p, buf + GUARD_LEN, str->x, str->len );
/* Check for buffer overwrite on both sides */
for( i = 0; i < GUARD_LEN; i++ )
{
TEST_ASSERT( buf[i] == GUARD_VAL );
TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
}
if( result >= 0 )
{
TEST_ASSERT( (size_t) ret == asn1->len );
TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );
TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );
}
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_asn1_write_ia5_string( char * str, data_t * asn1,
int buf_len, int result )
{
int ret;
unsigned char buf[150];
size_t str_len;
size_t i;
unsigned char *p;
memset( buf, GUARD_VAL, sizeof( buf ) );
str_len = strlen( str );
p = buf + GUARD_LEN + buf_len;
ret = mbedtls_asn1_write_ia5_string( &p, buf + GUARD_LEN, str, str_len );
/* Check for buffer overwrite on both sides */
for( i = 0; i < GUARD_LEN; i++ )
{
TEST_ASSERT( buf[i] == GUARD_VAL );
TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
}
if( result >= 0 )
{
TEST_ASSERT( (size_t) ret == asn1->len );
TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );
TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );
}
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ASN1PARSE_C */
void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
int result )
{
int ret;
unsigned char buf[150];
unsigned char *p;
size_t i;
size_t read_len;
memset( buf, GUARD_VAL, sizeof( buf ) );
p = buf + GUARD_LEN + buf_len;
ret = mbedtls_asn1_write_len( &p, buf + GUARD_LEN, (size_t) len );
TEST_ASSERT( ret == result );
/* Check for buffer overwrite on both sides */
for( i = 0; i < GUARD_LEN; i++ )
{
TEST_ASSERT( buf[i] == GUARD_VAL );
TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
}
if( result >= 0 )
{
TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );
TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );
/* Read back with mbedtls_asn1_get_len() to check */
ret = mbedtls_asn1_get_len( &p, buf + GUARD_LEN + buf_len, &read_len );
if( len == 0 )
{
TEST_ASSERT( ret == 0 );
}
else
{
/* Return will be MBEDTLS_ERR_ASN1_OUT_OF_DATA because the rest of
* the buffer is missing
*/
TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA );
}
TEST_ASSERT( read_len == (size_t) len );
TEST_ASSERT( p == buf + GUARD_LEN + buf_len );
}
}
/* END_CASE */
/* BEGIN_CASE */
void test_asn1_write_bitstrings( data_t *bitstring, int bits,
data_t *expected_asn1, int result,
int is_named )
{
int ret;
size_t i;
unsigned char buf[150];
unsigned char *p;
memset( buf, GUARD_VAL, sizeof( buf ) );
p = buf + GUARD_LEN + expected_asn1->len;
if ( is_named == 0 )
{
ret = mbedtls_asn1_write_bitstring( &p,
buf,
(unsigned char *)bitstring->x,
(size_t) bits );
}
else
{
ret = mbedtls_asn1_write_named_bitstring( &p,
buf,
(unsigned char *)bitstring->x,
(size_t) bits );
}
TEST_ASSERT( ret == result );
/* Check for buffer overwrite on both sides */
for( i = 0; i < GUARD_LEN; i++ )
{
TEST_ASSERT( buf[i] == GUARD_VAL );
TEST_ASSERT( buf[GUARD_LEN + expected_asn1->len + i] == GUARD_VAL );
}
if ( result >= 0 )
{
TEST_ASSERT( memcmp( p, expected_asn1->x, expected_asn1->len ) == 0 );
}
}
/* END_CASE */