mbedtls/tests/suites/test_suite_asn1write.function
Chris Jones 9634bb10d9 Move helper testing functions to tests/src/helpers.c
Moves the functions `test_fail`, `test_set_step`, `test_skip` and the struct
`test_info` from `tests/suites/helpers.function` to `tests/src/helpers.*`.
This is done to open these functions up to the API where they can be used by
other functions in the 'src' test infrastructure module.

As the functions are now contained within the src folder of the testing
infrastructure, the `mbedtls_` prefix has been added to the functions.

Signed-off-by: Chris Jones <christopher.jones@arm.com>
2021-01-20 15:56:42 +00:00

474 lines
14 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 )
{
mbedtls_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_null( 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_null( &data.p, data.start );
if( ! generic_write_finish_step( &data, expected, ret ) )
goto exit;
}
exit:
mbedtls_free( data.output );
}
/* END_CASE */
/* 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 */
void mbedtls_asn1_write_enum( 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_enum( &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;
if( expected->len > 10 && data.size == 8 )
data.size = expected->len - 2;
}
exit:
mbedtls_mpi_free( &mpi );
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_asn1_write_string( int tag, data_t *content, 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;
switch( tag )
{
case MBEDTLS_ASN1_OCTET_STRING:
ret = mbedtls_asn1_write_octet_string(
&data.p, data.start, content->x, content->len );
break;
case MBEDTLS_ASN1_OID:
ret = mbedtls_asn1_write_oid(
&data.p, data.start,
(const char *) content->x, content->len );
break;
case MBEDTLS_ASN1_UTF8_STRING:
ret = mbedtls_asn1_write_utf8_string(
&data.p, data.start,
(const char *) content->x, content->len );
break;
case MBEDTLS_ASN1_PRINTABLE_STRING:
ret = mbedtls_asn1_write_printable_string(
&data.p, data.start,
(const char *) content->x, content->len );
break;
case MBEDTLS_ASN1_IA5_STRING:
ret = mbedtls_asn1_write_ia5_string(
&data.p, data.start,
(const char *) content->x, content->len );
break;
default:
ret = mbedtls_asn1_write_tagged_string(
&data.p, data.start, tag,
(const char *) content->x, content->len );
}
if( ! generic_write_finish_step( &data, expected, ret ) )
goto exit;
if( expected->len > 10 && data.size == 8 )
data.size = expected->len - 2;
}
exit:
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_asn1_write_algorithm_identifier( data_t *oid,
int par_len,
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_algorithm_identifier(
&data.p, data.start,
(const char *) oid->x, oid->len, par_len );
/* If params_len != 0, mbedtls_asn1_write_algorithm_identifier()
* assumes that the parameters are already present in the buffer
* and returns a length that accounts for this, but our test
* data omits the parameters. */
if( ret >= 0 )
ret -= par_len;
if( ! generic_write_finish_step( &data, expected, ret ) )
goto exit;
}
exit:
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ASN1_PARSE_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, int is_named )
{
generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
int ret;
int ( *func )( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits ) =
( is_named ? mbedtls_asn1_write_named_bitstring :
mbedtls_asn1_write_bitstring );
for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
if( ! generic_write_start_step( &data ) )
goto exit;
ret = ( *func )( &data.p, data.start, bitstring->x, bits );
if( ! generic_write_finish_step( &data, expected, ret ) )
goto exit;
}
exit:
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE */
void store_named_data_find( data_t *oid0, data_t *oid1,
data_t *oid2, data_t *oid3,
data_t *needle, int from, int position )
{
data_t *oid[4] = {oid0, oid1, oid2, oid3};
mbedtls_asn1_named_data nd[] ={
{ {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
{ {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
{ {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
{ {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
};
mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
size_t i;
mbedtls_asn1_named_data *head = NULL;
mbedtls_asn1_named_data *found = NULL;
for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
pointers[i] = &nd[i];
pointers[ARRAY_LENGTH( nd )] = NULL;
for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
{
ASSERT_ALLOC( nd[i].oid.p, oid[i]->len );
memcpy( nd[i].oid.p, oid[i]->x, oid[i]->len );
nd[i].oid.len = oid[i]->len;
nd[i].next = pointers[i+1];
}
head = pointers[from];
found = mbedtls_asn1_store_named_data( &head,
(const char *) needle->x,
needle->len,
NULL, 0 );
/* In any case, the existing list structure must be unchanged. */
for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
TEST_ASSERT( nd[i].next == pointers[i+1] );
if( position >= 0 )
{
/* position should have been found and modified. */
TEST_ASSERT( head == pointers[from] );
TEST_ASSERT( found == pointers[position] );
}
else
{
/* A new entry should have been created. */
TEST_ASSERT( found == head );
TEST_ASSERT( head->next == pointers[from] );
for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
TEST_ASSERT( found != &nd[i] );
}
exit:
if( found != NULL && found == head && found != pointers[from] )
{
mbedtls_free( found->oid.p );
mbedtls_free( found );
}
for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
mbedtls_free( nd[i].oid.p );
}
/* END_CASE */
/* BEGIN_CASE */
void store_named_data_val_found( int old_len, int new_len )
{
mbedtls_asn1_named_data nd =
{ {0x06, 3, (unsigned char *) "OID"}, {0, 0, NULL}, NULL, 0 };
mbedtls_asn1_named_data *head = &nd;
mbedtls_asn1_named_data *found = NULL;
unsigned char *old_val = NULL;
unsigned char *new_val = (unsigned char *) "new value";
if( old_len != 0 )
{
ASSERT_ALLOC( nd.val.p, (size_t) old_len );
old_val = nd.val.p;
nd.val.len = old_len;
memset( old_val, 'x', old_len );
}
if( new_len <= 0 )
{
new_len = - new_len;
new_val = NULL;
}
found = mbedtls_asn1_store_named_data( &head, "OID", 3,
new_val, new_len );
TEST_ASSERT( head == &nd );
TEST_ASSERT( found == head );
if( new_val != NULL)
ASSERT_COMPARE( found->val.p, found->val.len,
new_val, (size_t) new_len );
if( new_len == 0)
TEST_ASSERT( found->val.p == NULL );
else if( new_len == old_len )
TEST_ASSERT( found->val.p == old_val );
else
TEST_ASSERT( found->val.p != old_val );
exit:
mbedtls_free( nd.val.p );
}
/* END_CASE */
/* BEGIN_CASE */
void store_named_data_val_new( int new_len )
{
mbedtls_asn1_named_data *head = NULL;
mbedtls_asn1_named_data *found = NULL;
const unsigned char *oid = (unsigned char *) "OID";
size_t oid_len = strlen( (const char *) oid );
const unsigned char *new_val = (unsigned char *) "new value";
if( new_len <= 0 )
new_val = NULL;
if( new_len < 0 )
new_len = - new_len;
found = mbedtls_asn1_store_named_data( &head,
(const char *) oid, oid_len,
new_val, (size_t) new_len );
TEST_ASSERT( found != NULL );
TEST_ASSERT( found == head );
TEST_ASSERT( found->oid.p != oid );
ASSERT_COMPARE( found->oid.p, found->oid.len, oid, oid_len );
if( new_len == 0 )
TEST_ASSERT( found->val.p == NULL );
else if( new_val == NULL )
TEST_ASSERT( found->val.p != NULL );
else
{
TEST_ASSERT( found->val.p != new_val );
ASSERT_COMPARE( found->val.p, found->val.len,
new_val, (size_t) new_len );
}
exit:
if( found != NULL )
{
mbedtls_free( found->oid.p );
mbedtls_free( found->val.p );
}
mbedtls_free( found );
}
/* END_CASE */