Skip to content

ASN.1 tests without x509 #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 164 additions & 69 deletions include/mbedtls/asn1.h

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions include/mbedtls/asn1write.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param X The MPI to write.
* It must be non-negative.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
Expand Down Expand Up @@ -184,6 +185,7 @@ int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start,
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param val The integer value to write.
* It must be non-negative.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
Expand Down Expand Up @@ -232,7 +234,7 @@ int mbedtls_asn1_write_printable_string( unsigned char **p,

/**
* \brief Write a UTF8 string in ASN.1 format using the UTF8String
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
* string encoding tag (#MBEDTLS_ASN1_UTF8_STRING).
*
* \note This function works backwards in data buffer.
*
Expand Down Expand Up @@ -332,9 +334,13 @@ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
* through (will be updated in case of a new entry).
* \param oid The OID to look for.
* \param oid_len The size of the OID.
* \param val The data to store (can be \c NULL if you want to fill
* it by hand).
* \param val The associated data to store. If this is \c NULL,
* no data is copied to the new or existing buffer.
* \param val_len The minimum length of the data buffer needed.
* If this is 0, do not allocate a buffer for the associated
* data.
* If the OID was already present, enlarge, shrink or free
* the existing buffer to fit \p val_len.
*
* \return A pointer to the new / existing entry on success.
* \return \c NULL if if there was a memory allocation error.
Expand Down
18 changes: 15 additions & 3 deletions library/asn1parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,18 @@ 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 || len > sizeof( int ) || ( **p & 0x80 ) != 0 )
if( len == 0 || ( **p & 0x80 ) != 0 )
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );

*val = 0;
while( len > 0 && **p == 0 )
{
++( *p );
--len;
}
if( len > sizeof( int ) )
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );

*val = 0;
while( len-- > 0 )
{
*val = ( *val << 8 ) | **p;
Expand Down Expand Up @@ -223,8 +230,13 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end
if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
return( ret );

if( (*len)-- < 2 || *(*p)++ != 0 )
if( *len == 0 )
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
--( *len );

if( **p != 0 )
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
++( *p );

return( 0 );
}
Expand Down
37 changes: 24 additions & 13 deletions library/asn1write.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,17 +236,20 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
int ret;
size_t len = 0;

if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );

len += 1;
*--(*p) = val;

if( val > 0 && **p & 0x80 )
do
{
if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
len += 1;
*--(*p) = val & 0xff;
val >>= 8;
}
while( val > 0 );

if( **p & 0x80 )
{
if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
Expand Down Expand Up @@ -429,18 +432,26 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
memcpy( cur->oid.p, oid, oid_len );

cur->val.len = val_len;
cur->val.p = mbedtls_calloc( 1, val_len );
if( cur->val.p == NULL )
if( val_len != 0 )
{
mbedtls_free( cur->oid.p );
mbedtls_free( cur );
return( NULL );
cur->val.p = mbedtls_calloc( 1, val_len );
if( cur->val.p == NULL )
{
mbedtls_free( cur->oid.p );
mbedtls_free( cur );
return( NULL );
}
}

cur->next = *head;
*head = cur;
}
else if( cur->val.len < val_len )
else if( val_len == 0 )
{
mbedtls_free( cur->val.p );
cur->val.p = NULL;
}
else if( cur->val.len != val_len )
{
/*
* Enlarge existing value buffer if needed
Expand Down
2 changes: 1 addition & 1 deletion library/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid" );
if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ add_test_suite(aes aes.rest)
add_test_suite(aes aes.xts)
add_test_suite(arc4)
add_test_suite(aria)
add_test_suite(asn1parse)
add_test_suite(asn1write)
add_test_suite(base64)
add_test_suite(blowfish)
Expand Down
34 changes: 34 additions & 0 deletions tests/suites/helpers.function
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,26 @@ typedef enum
} \
while( 0 )

/** Allocate memory dynamically. Exit the test if this fails, but do
* not mark the test as failed.
*
* This macro behaves like #ASSERT_ALLOC, except that if the allocation
* fails, it jumps to the \c exit label without calling test_fail().
*/
#define ASSERT_ALLOC_WEAK( pointer, length ) \
do \
{ \
TEST_ASSERT( ( pointer ) == NULL ); \
if( ( length ) != 0 ) \
{ \
( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
( length ) ); \
if( ( pointer ) == NULL ) \
goto exit; \
} \
} \
while( 0 )

/** Compare two buffers and fail the test case if they differ.
*
* This macro expands to an instruction, not an expression.
Expand Down Expand Up @@ -393,6 +413,7 @@ static struct
const char *test;
const char *filename;
int line_no;
unsigned long step;
}
test_info;

Expand Down Expand Up @@ -423,6 +444,19 @@ jmp_buf jmp_tmp;
/*----------------------------------------------------------------------------*/
/* Helper Functions */

/** Set the test step number for failure reports.
*
* Call this function to display "step NNN" in addition to the line number
* and file name if a test fails. Typically the "step number" is the index
* of a for loop but it can be whatever you want.
*
* \param step The step number to report.
*/
void test_set_step( unsigned long step )
{
test_info.step = step;
}

void test_fail( const char *test, int line_no, const char* filename )
{
test_info.result = TEST_RESULT_FAILED;
Expand Down
13 changes: 10 additions & 3 deletions tests/suites/host_test.function
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ int execute_tests( int argc , const char ** argv )
{
test_info.result = TEST_RESULT_SUCCESS;
test_info.paramfail_test_state = PARAMFAIL_TESTSTATE_IDLE;
test_info.step = (unsigned long)( -1 );

#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
/* Suppress all output from the library unless we're verbose
Expand Down Expand Up @@ -624,9 +625,15 @@ int execute_tests( int argc , const char ** argv )
{
total_errors++;
mbedtls_fprintf( stdout, "FAILED\n" );
mbedtls_fprintf( stdout, " %s\n at line %d, %s\n",
test_info.test, test_info.line_no,
test_info.filename );
mbedtls_fprintf( stdout, " %s\n at ",
test_info.test );
if( test_info.step != (unsigned long)( -1 ) )
{
mbedtls_fprintf( stdout, "step %lu, ",
test_info.step );
}
mbedtls_fprintf( stdout, "line %d, %s",
test_info.line_no, test_info.filename );
}
fflush( stdout );
}
Expand Down
1 change: 1 addition & 0 deletions tests/suites/target_test.function
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ int execute_tests( int args, const char ** argv )
{
ret = 0;
test_info.result = TEST_RESULT_SUCCESS;
test_info.step = (unsigned long)( -1 );
data_len = 0;

data = receive_data( &data_len );
Expand Down
Loading