Merge pull request #75 from gilles-peskine-arm/asn1-tests-without-x509

ASN.1 tests without x509
This commit is contained in:
Jaeden Amero 2019-10-04 12:30:01 +01:00 committed by GitHub
commit 9ab7c07f1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 1849 additions and 227 deletions

View File

@ -52,7 +52,7 @@
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. */
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
@ -176,119 +176,203 @@ mbedtls_asn1_named_data;
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len The variable that will receive the value
* \param p On entry, \c *p points to the first byte of the length,
* i.e. immediately after the tag.
* On successful completion, \c *p points to the first byte
* after the length, i.e. the first byte of the content.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param len On successful completion, \c *len contains the length
* read from the ASN.1 input.
*
* \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
* end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
* unparseable.
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
* would end beyond \p end.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len );
const unsigned char *end,
size_t *len );
/**
* \brief Get the tag and length of the tag. Check for the requested tag.
* \brief Get the tag and length of the element.
* Check for the requested tag.
* Updates the pointer to immediately behind the tag and length.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len The variable that will receive the length
* \param tag The expected tag
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* after the length, i.e. the first byte of the content.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param len On successful completion, \c *len contains the length
* read from the ASN.1 input.
* \param tag The expected tag.
*
* \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
* not match requested tag, or another specific ASN.1 error code.
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start
* with the requested tag.
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
* would end beyond \p end.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag );
const unsigned char *end,
size_t *len, int tag );
/**
* \brief Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param val The variable that will receive the value
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the ASN.1 element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param val On success, the parsed value (\c 0 or \c 1).
*
* \return 0 if successful or a specific ASN.1 error code.
* \return 0 if successful.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 BOOLEAN.
*/
int mbedtls_asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val );
const unsigned char *end,
int *val );
/**
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param val The variable that will receive the value
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the ASN.1 element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param val On success, the parsed value.
*
* \return 0 if successful or a specific ASN.1 error code.
* \return 0 if successful.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 INTEGER.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
* not fit in an \c int.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 INTEGER.
*/
int mbedtls_asn1_get_int( unsigned char **p,
const unsigned char *end,
int *val );
const unsigned char *end,
int *val );
/**
* \brief Retrieve a bitstring ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param bs The variable that will receive the value
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p is equal to \p end.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param bs On success, ::mbedtls_asn1_bitstring information about
* the parsed value.
*
* \return 0 if successful or a specific ASN.1 error code.
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
* extra data after a valid BIT STRING.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
mbedtls_asn1_bitstring *bs);
mbedtls_asn1_bitstring *bs );
/**
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
* value.
* Updates the pointer to the beginning of the bit/octet string.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len Length of the actual bit/octect string in bytes
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* of the content of the BIT STRING.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param len On success, \c *len is the length of the content in bytes.
*
* \return 0 if successful or a specific ASN.1 error code.
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with
* a valid BIT STRING with a nonzero number of unused bits.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
size_t *len );
int mbedtls_asn1_get_bitstring_null( unsigned char **p,
const unsigned char *end,
size_t *len );
/**
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
* Updated the pointer to immediately behind the full sequence tag.
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
* Updates the pointer to immediately behind the full sequence tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param cur First variable in the chain to fill
* \param tag Type of sequence
* \note On error, this function may return a partial list in \p cur.
* You must set `cur->next = NULL` before calling this function!
* Otherwise it is impossible to distinguish a previously non-null
* pointer from a pointer to an object allocated by this function.
*
* \return 0 if successful or a specific ASN.1 error code.
* \note If the sequence is empty, this function does not modify
* \c *cur. If the sequence is valid and non-empty, this
* function sets `cur->buf.tag` to \p tag. This allows
* callers to distinguish between an empty sequence and
* a one-element sequence.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p is equal to \p end.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param cur A ::mbedtls_asn1_sequence which this function fills.
* When this function returns, \c *cur is the head of a linked
* list. Each node in this list is allocated with
* mbedtls_calloc() apart from \p cur itself, and should
* therefore be freed with mbedtls_free().
* The list describes the content of the sequence.
* The head of the list (i.e. \c *cur itself) describes the
* first element, `*cur->next` describes the second element, etc.
* For each element, `buf.tag == tag`, `buf.len` is the length
* of the content of the content of the element, and `buf.p`
* points to the first byte of the content (i.e. immediately
* past the length of the element).
* Note that list elements may be allocated even on error.
* \param tag Each element of the sequence must have this tag.
*
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
* extra data after a valid SEQUENCE OF \p tag.
* \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_sequence *cur,
int tag);
const unsigned char *end,
mbedtls_asn1_sequence *cur,
int tag );
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Retrieve a MPI value from an integer ASN.1 tag.
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param X The MPI that will receive the value
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the ASN.1 element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param X On success, the parsed value.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
* \return 0 if successful.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 INTEGER.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
* not fit in an \c int.
* \return An MPI error code if the parsed value is too large.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 INTEGER.
*/
int mbedtls_asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X );
const unsigned char *end,
mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
@ -296,10 +380,14 @@ int mbedtls_asn1_get_mpi( unsigned char **p,
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param alg The buffer to receive the OID
* \param params The buffer to receive the params (if any)
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the AlgorithmIdentifier element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param alg The buffer to receive the OID.
* \param params The buffer to receive the parameters.
* This is zeroized if there are no parameters.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
@ -313,9 +401,12 @@ int mbedtls_asn1_get_alg( unsigned char **p,
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param alg The buffer to receive the OID
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the AlgorithmIdentifier element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param alg The buffer to receive the OID.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
@ -339,15 +430,19 @@ mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *
/**
* \brief Free a mbedtls_asn1_named_data entry
*
* \param entry The named data entry to free
* \param entry The named data entry to free.
* This function calls mbedtls_free() on
* `entry->oid.p` and `entry->val.p`.
*/
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
/**
* \brief Free all entries in a mbedtls_asn1_named_data list
* Head will be set to NULL
* \brief Free all entries in a mbedtls_asn1_named_data list.
*
* \param head Pointer to the head of the list of named data entries to free
* \param head Pointer to the head of the list of named data entries to free.
* This function calls mbedtls_asn1_free_named_data() and
* mbedtls_free() on each list element and
* sets \c *head to \c NULL.
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );

View File

@ -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.
@ -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.
@ -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.
*
@ -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.

View File

@ -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 );
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;
@ -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 );
}

View File

@ -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;
}
@ -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

View File

@ -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) )

View File

@ -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)

View File

@ -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.
@ -393,6 +413,7 @@ static struct
const char *test;
const char *filename;
int line_no;
unsigned long step;
}
test_info;
@ -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;

View File

@ -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
@ -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 );
}

View File

@ -376,6 +376,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 );

View File

@ -0,0 +1,438 @@
Empty length
parse_prefixes:"04":0:MBEDTLS_ERR_ASN1_INVALID_LENGTH
Prefixes of OCTET STRING, length=0
parse_prefixes:"04007e":2:0
Prefixes of OCTET STRING, length=0 (0 length bytes)
parse_prefixes:"04807e":2:MBEDTLS_ERR_ASN1_INVALID_LENGTH
Prefixes of OCTET STRING, length=1
parse_prefixes:"0401417e":3:0
Prefixes of OCTET STRING, length=2
parse_prefixes:"040241427e":4:0
Prefixes of BOOLEAN, length=0
parse_prefixes:"01007e":2:MBEDTLS_ERR_ASN1_INVALID_LENGTH
Prefixes of BOOLEAN, length=1
parse_prefixes:"0101007e":3:0
Prefixes of BOOLEAN, length=2
parse_prefixes:"010200007e":4:MBEDTLS_ERR_ASN1_INVALID_LENGTH
Prefixes of INTEGER, length=1
parse_prefixes:"0201417e":3:0
Prefixes of INTEGER, length=2
parse_prefixes:"020241427e":4:0
Prefixes of INTEGER, length=5
parse_prefixes:"020541424344457e":7:0
Prefixes of empty BIT STRING
parse_prefixes:"03007e":2:MBEDTLS_ERR_ASN1_OUT_OF_DATA
Prefixes of BIT STRING, unused_bits=0, payload_length=0
parse_prefixes:"030100":3:0
Prefixes of BIT STRING, unused_bits=0, payload_length=1
parse_prefixes:"0302002a":4:0
Prefixes of BIT STRING, unused_bits=1, payload_length=1
parse_prefixes:"0302012a":4:0
Prefixes of empty SEQUENCE
parse_prefixes:"30007e":2:0
Prefixes of SEQUENCE of BOOLEAN, INTEGER, INTEGER
parse_prefixes:"300b01010102012a02031234567e":13:0
Prefixes of SEQUENCE of (SEQUENCE of INTEGER, INTEGER), INTEGER
parse_prefixes:"300b30060201410201420201617e":13:0
length=0 (short form)
get_len:"00":0
length=0 (1 length byte)
get_len:"8100":0
length=0 (2 length bytes)
get_len:"820000":0
length=1 (short form)
get_len:"01":1
length=1 (1 length byte)
get_len:"8101":1
length=1 (2 length bytes)
get_len:"820001":1
length=1 (3 length bytes)
get_len:"83000001":1
length=1 (4 length bytes)
get_len:"8400000001":1
length=2 (short form)
get_len:"02":2
length=2 (1 length byte)
get_len:"8102":2
length=2 (2 length bytes)
get_len:"820002":2
length=2 (3 length bytes)
get_len:"83000002":2
length=2 (4 length bytes)
get_len:"8400000002":2
length=127 (short form)
get_len:"7f":127
length=128 (1 length byte)
get_len:"8180":128
length=128 (2 length bytes)
get_len:"820080":128
length=255 (1 length byte)
get_len:"81ff":255
length=255 (2 length bytes)
get_len:"8200ff":255
length=256 (2 length bytes)
get_len:"820100":256
length=256 (3 length bytes)
get_len:"83000100":256
length=258 (2 length bytes)
get_len:"820102":258
length=258 (3 length bytes)
get_len:"83000102":258
length=65535 (2 length bytes)
get_len:"82ffff":65535
length=65535 (3 length bytes)
get_len:"8300ffff":65535
length=65535 (4 length bytes)
get_len:"840000ffff":65535
length=65536 (3 length bytes)
get_len:"83010000":65536
length=65536 (4 length bytes)
get_len:"8400010000":65536
length=16777215 (3 length bytes)
get_len:"83ffffff":16777215
length=16777215 (4 length bytes)
get_len:"8400ffffff":16777215
length=16777216 (4 length bytes)
get_len:"8401000000":16777216
length=16909060 (4 length bytes)
get_len:"8401020304":16909060
BOOLEAN FALSE
get_boolean:"010100":0:0
BOOLEAN TRUE (1)
get_boolean:"010101":1:0
BOOLEAN TRUE (2)
get_boolean:"010101":1:0
BOOLEAN TRUE (128)
get_boolean:"010180":1:0
BOOLEAN TRUE (255)
get_boolean:"0101ff":1:0
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
INTEGER 0
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
INTEGER 0x80, extra leading 0
get_integer:"0203000080":"80":0
INTEGER 0xff
get_integer:"020200ff":"ff":0
INTEGER 0x7fff
get_integer:"02027fff":"7fff":0
INTEGER 0x12345678
get_integer:"020412345678":"12345678":0
INTEGER 0x12345678, extra leading 0
get_integer:"02050012345678":"12345678":0
INTEGER 0x123456789abcdef0
get_integer:"0208123456789abcdef0":"123456789abcdef0":0
INTEGER with 127 value octets
get_integer:"027f0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":0
INTEGER with 127 value octets (long length encoding)
get_integer:"02817f0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd":0
INTEGER with 128 value octets
get_integer:"0281800123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":0
INTEGER with 128 value octets (leading 0 in length)
get_integer:"028200800123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":0
Not INTEGER
get_integer:"010101":"":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
INTEGER too large for mpi
get_mpi_too_large:
BIT STRING: empty
get_bitstring:"0300":0:0:MBEDTLS_ERR_ASN1_OUT_OF_DATA:MBEDTLS_ERR_ASN1_INVALID_DATA
BIT STRING: octets=0, unused_bits=0
get_bitstring:"030100":0:0:0:0
BIT STRING: octets=0, unused_bits=7
get_bitstring:"030107":0:7:0:MBEDTLS_ERR_ASN1_INVALID_DATA
BIT STRING: octets=0, unused_bits=8
get_bitstring:"030108":0:0:MBEDTLS_ERR_ASN1_INVALID_LENGTH:MBEDTLS_ERR_ASN1_INVALID_DATA
BIT STRING: octets=1, unused_bits=0
get_bitstring:"03020041":1:0:0:0
BIT STRING: octets=1, unused_bits=7
get_bitstring:"03020741":1:7:0:MBEDTLS_ERR_ASN1_INVALID_DATA
BIT STRING: octets=1, unused_bits=8
get_bitstring:"03020841":1:8:MBEDTLS_ERR_ASN1_INVALID_LENGTH:MBEDTLS_ERR_ASN1_INVALID_DATA
BIT STRING: octets=2, unused_bits=0
get_bitstring:"0303004142":2:0:0:0
BIT STRING: octets=2, unused_bits=7
get_bitstring:"0303074142":2:7:0:MBEDTLS_ERR_ASN1_INVALID_DATA
BIT STRING: octets=2, unused_bits=8
get_bitstring:"0303084142":2:8:MBEDTLS_ERR_ASN1_INVALID_LENGTH:MBEDTLS_ERR_ASN1_INVALID_DATA
BIT STRING with trailing garbage, unused_bits=0
get_bitstring:"030200417e":1:0:MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:0
BIT STRING with trailing garbage, unused_bits=7
get_bitstring:"030207417e":1:7:MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:MBEDTLS_ERR_ASN1_INVALID_DATA
BIT STRING with trailing garbage, unused_bits=8
get_bitstring:"030208417e":1:8:MBEDTLS_ERR_ASN1_INVALID_LENGTH:MBEDTLS_ERR_ASN1_INVALID_DATA
Not BIT STRING
get_bitstring:"04020100":0:0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
SEQUENCE OF 0 OCTET STRING
get_sequence_of:"3000":0x04:"":0
SEQUENCE OF 0 OCTET STRING plus trailing garbage
get_sequence_of:"30007e":0x04:"":MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
SEQUENCE of 1 OCTET STRING truncated after tag
get_sequence_of:"300104":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 1 OCTET STRING truncated in length #1
get_sequence_of:"30020481":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 1 OCTET STRING truncated in length #2
get_sequence_of:"3003048201":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 1 OCTET STRING truncated in content #1
get_sequence_of:"30020401":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 1 OCTET STRING truncated in content #2
get_sequence_of:"3003040241":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 1 OCTET STRING truncated in content #3
get_sequence_of:"300404034142":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 1 OCTET STRING (0)
get_sequence_of:"30020400":0x04:"4,0":0
SEQUENCE of 1 OCTET STRING (1)
get_sequence_of:"3003040141":0x04:"4,1":0
SEQUENCE of 1 OCTET STRING (126)
get_sequence_of:"308180047e414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141":0x04:"5,126":0
SEQUENCE of 2 OCTET STRINGs, second truncated after tag
get_sequence_of:"30050402414104":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 2 OCTET STRINGs, second truncated in length #1
get_sequence_of:"3006040241410481":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 2 OCTET STRINGs, second truncated in length #2
get_sequence_of:"300704024141048201":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 2 OCTET STRINGs, second truncated in content #1
get_sequence_of:"3006040241410401":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 2 OCTET STRINGs, second truncated in content #2
get_sequence_of:"300704024141040241":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 2 OCTET STRINGs, second truncated in content #3
get_sequence_of:"30080402414104034142":0x04:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA
SEQUENCE of 2 OCTET STRINGs (2, 0)
get_sequence_of:"3006040241410400":0x04:"4,2,8,0":0
SEQUENCE of 2 OCTET STRINGs (2, 1)
get_sequence_of:"300704024141040142":0x04:"4,2,8,1":0
SEQUENCE of 2 OCTET STRINGs (0, 2)
get_sequence_of:"3006040004024141":0x04:"4,0,6,2":0
SEQUENCE of 2 OCTET STRINGs (1, 2)
get_sequence_of:"300704014104024242":0x04:"4,1,7,2":0
Not a SEQUENCE (not CONSTRUCTED)
get_sequence_of:"1000":0x04:"":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
Not a SEQUENCE (not SEQUENCE)
get_sequence_of:"3100":0x04:"":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
AlgorithmIdentifier, no params
get_alg:"300506034f4944":4:3:0:0:0:7:0
AlgorithmIdentifier, no params, trailing garbage
get_alg:"300506034f49447e":4:3:0:0:0:7:0
AlgorithmIdentifier, null params
get_alg:"300706034f49440500":4:3:0x05:9:0:9:0
AlgorithmIdentifier, null params, trailing garbage
get_alg:"300706034f494405007e":4:3:0x05:9:0:9:0
AlgorithmIdentifier, OCTET STRING params
get_alg:"300c06034f494404056162636465":4:3:0x04:9:5:14:0
AlgorithmIdentifier, truncated before OID
get_alg:"3000":4:3:0:0:0:2:MBEDTLS_ERR_ASN1_OUT_OF_DATA
AlgorithmIdentifier, truncated in OID after tag
get_alg:"300106":0:0:0:0:0:3:MBEDTLS_ERR_ASN1_OUT_OF_DATA
AlgorithmIdentifier, truncated in OID after length
get_alg:"30020603":4:3:0:0:0:4:MBEDTLS_ERR_ASN1_OUT_OF_DATA
AlgorithmIdentifier, truncated inside OID content
get_alg:"300406034f49":4:3:0:0:0:6:MBEDTLS_ERR_ASN1_OUT_OF_DATA
AlgorithmIdentifier, truncated in params after tag
get_alg:"300606034f494404":4:3:0x04:0:0:8:MBEDTLS_ERR_ASN1_OUT_OF_DATA
AlgorithmIdentifier, truncated in params after length
get_alg:"300706034f49440405":4:3:0x04:9:0:9:MBEDTLS_ERR_ASN1_OUT_OF_DATA
AlgorithmIdentifier, truncated inside params content
get_alg:"300806034f4944040561":4:3:0x04:9:5:10:MBEDTLS_ERR_ASN1_OUT_OF_DATA
Not an AlgorithmIdentifier (not a SEQUENCE)
get_alg:"310506034f4944":0:0:0:0:0:0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
Not an AlgorithmIdentifier (empty SEQUENCE)
get_alg:"3000":0:0:0:0:0:0:MBEDTLS_ERR_ASN1_OUT_OF_DATA
Not an AlgorithmIdentifier (not an OID)
get_alg:"3006050006034f4944":0:0:0:0:0:0:MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
Not an AlgorithmIdentifier (too many elements)
get_alg:"300f06034f494406034f494406034f4944":0:0:0:0:0:0:MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
Find named data: not found
find_named_data:"414141":"424242":"434343":"444444":"7f7f7f":0:4
Find named data: empty haystack
find_named_data:"414141":"424242":"434343":"444444":"7f7f7f":4:4
Find named data: first
find_named_data:"414141":"424242":"434343":"444444":"414141":0:0
Find named data: last
find_named_data:"414141":"424242":"434343":"444444":"444444":0:3
Find named data: skip suffix
find_named_data:"41414141":"414141":"434343":"444444":"414141":0:1
Find named data: skip prefix
find_named_data:"4141":"414141":"434343":"444444":"414141":0:1
Find named data: first match
find_named_data:"414141":"414141":"434343":"444444":"414141":0:0
Free named data: null pointer
free_named_data_null:
Free named data: all null
free_named_data:0:0:0
Free named data: with oid
free_named_data:1:0:0
Free named data: with val
free_named_data:0:1:0
Free named data: with next
free_named_data:0:0:1
Free named data list (empty)
free_named_data_list:0
Free named data list (1)
free_named_data_list:1
Free named data list (2)
free_named_data_list:2

View File

@ -0,0 +1,562 @@
/* BEGIN_HEADER */
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include "mbedtls/bignum.h"
#include "mbedtls/asn1.h"
#if defined(MBEDTLS_ASN1_WRITE_C)
#include "mbedtls/asn1write.h"
#endif
#define ERR_PARSE_INCONSISTENCY INT_MAX
static int nested_parse( unsigned char **const p,
const unsigned char *const end )
{
int ret;
size_t len = 0;
size_t len2 = 0;
unsigned char *const start = *p;
unsigned char *content_start;
unsigned char tag;
/* First get the length, skipping over the tag. */
content_start = start + 1;
ret = mbedtls_asn1_get_len( &content_start, end, &len );
TEST_ASSERT( content_start <= end );
if( ret != 0 )
return( ret );
/* Since we have a valid element start (tag and length), retrieve and
* check the tag. */
tag = start[0];
TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len2, tag ^ 1 ),
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
*p = start;
TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len2, tag ), 0 );
TEST_EQUAL( len, len2 );
TEST_ASSERT( *p == content_start );
*p = content_start;
switch( tag & 0x1f )
{
case MBEDTLS_ASN1_BOOLEAN:
{
int val = -257;
*p = start;
ret = mbedtls_asn1_get_bool( p, end, &val );
if( ret == 0 )
TEST_ASSERT( val == 0 || val == 1 );
break;
}
case MBEDTLS_ASN1_INTEGER:
{
#if defined(MBEDTLS_BIGNUM_C)
mbedtls_mpi mpi;
mbedtls_mpi_init( &mpi );
*p = start;
ret = mbedtls_asn1_get_mpi( p, end, &mpi );
mbedtls_mpi_free( &mpi );
#endif
/* If we're sure that the number fits in an int, also
* call mbedtls_asn1_get_int(). */
if( ret == 0 && len < sizeof( int ) )
{
int val = -257;
unsigned char *q = start;
ret = mbedtls_asn1_get_int( &q, end, &val );
TEST_ASSERT( *p == q );
}
break;
}
case MBEDTLS_ASN1_BIT_STRING:
{
mbedtls_asn1_bitstring bs;
*p = start;
ret = mbedtls_asn1_get_bitstring( p, end, &bs );
break;
}
case MBEDTLS_ASN1_SEQUENCE:
{
while( *p <= end && *p < content_start + len && ret == 0 )
ret = nested_parse( p, content_start + len );
break;
}
case MBEDTLS_ASN1_OCTET_STRING:
case MBEDTLS_ASN1_NULL:
case MBEDTLS_ASN1_OID:
case MBEDTLS_ASN1_UTF8_STRING:
case MBEDTLS_ASN1_SET:
case MBEDTLS_ASN1_PRINTABLE_STRING:
case MBEDTLS_ASN1_T61_STRING:
case MBEDTLS_ASN1_IA5_STRING:
case MBEDTLS_ASN1_UTC_TIME:
case MBEDTLS_ASN1_GENERALIZED_TIME:
case MBEDTLS_ASN1_UNIVERSAL_STRING:
case MBEDTLS_ASN1_BMP_STRING:
default:
/* No further testing implemented for this tag. */
*p += len;
return( 0 );
}
TEST_ASSERT( *p <= end );
return( ret );
exit:
return( ERR_PARSE_INCONSISTENCY );
}
int get_len_step( const data_t *input, size_t buffer_size,
size_t actual_length )
{
unsigned char *buf = NULL;
unsigned char *p = NULL;
size_t parsed_length;
int ret;
test_set_step( buffer_size );
/* Allocate a new buffer of exactly the length to parse each time.
* This gives memory sanitizers a chance to catch buffer overreads. */
if( buffer_size == 0 )
{
ASSERT_ALLOC( buf, 1 );
p = buf + 1;
}
else
{
ASSERT_ALLOC_WEAK( buf, buffer_size );
if( buffer_size > input->len )
{
memcpy( buf, input->x, input->len );
memset( buf + input->len, 'A', buffer_size - input->len );
}
else
{
memcpy( buf, input->x, buffer_size );
}
p = buf;
}
ret = mbedtls_asn1_get_len( &p, buf + buffer_size, &parsed_length );
if( buffer_size >= input->len + actual_length )
{
TEST_EQUAL( ret, 0 );
TEST_ASSERT( p == buf + input->len );
TEST_EQUAL( parsed_length, actual_length );
}
else
{
TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_OUT_OF_DATA );
}
mbedtls_free( buf );
return( 1 );
exit:
mbedtls_free( buf );
return( 0 );
}
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_ASN1_PARSE_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
void parse_prefixes( const data_t *input,
int actual_length_arg,
int last_result )
{
size_t actual_length = actual_length_arg;
unsigned char *buf = NULL;
unsigned char *p = NULL;
size_t buffer_size;
int ret;
for( buffer_size = 1; buffer_size <= input->len; buffer_size++ )
{
test_set_step( buffer_size );
/* Allocate a new buffer of exactly the length to parse each time.
* This gives memory sanitizers a chance to catch buffer overreads. */
ASSERT_ALLOC( buf, buffer_size );
memcpy( buf, input->x, buffer_size );
p = buf;
ret = nested_parse( &p, buf + buffer_size );
if( ret == ERR_PARSE_INCONSISTENCY )
goto exit;
if( actual_length > 0 && buffer_size >= actual_length )
{
TEST_EQUAL( ret, last_result );
if( ret == 0 )
TEST_ASSERT( p == buf + actual_length );
}
else
{
TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_OUT_OF_DATA );
}
mbedtls_free( buf );
buf = NULL;
}
exit:
mbedtls_free( buf );
}
/* END_CASE */
/* BEGIN_CASE */
void get_len( const data_t *input, int actual_length_arg )
{
size_t actual_length = actual_length_arg;
size_t buffer_size;
for( buffer_size = 1; buffer_size <= input->len + 1; buffer_size++ )
{
if( ! get_len_step( input, buffer_size, actual_length ) )
goto exit;
}
if( ! get_len_step( input, input->len + actual_length - 1, actual_length ) )
goto exit;
if( ! get_len_step( input, input->len + actual_length, actual_length ) )
goto exit;
}
/* END_CASE */
/* BEGIN_CASE */
void get_boolean( const data_t *input,
int expected_value, int expected_result )
{
unsigned char *p = input->x;
int val;
int ret;
ret = mbedtls_asn1_get_bool( &p, input->x + input->len, &val );
TEST_EQUAL( ret, expected_result );
if( expected_result == 0 )
{
TEST_EQUAL( val, expected_value );
TEST_ASSERT( p == input->x + input->len );
}
}
/* END_CASE */
/* BEGIN_CASE */
void get_integer( const data_t *input,
const char *expected_hex, int expected_result )
{
unsigned char *p;
#if defined(MBEDTLS_BIGNUM_C)
mbedtls_mpi expected_mpi;
mbedtls_mpi actual_mpi;
#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 );
#endif
errno = 0;
expected_value = strtol( expected_hex, NULL, 16 );
if( expected_result == 0 &&
( errno == ERANGE
#if LONG_MAX > INT_MAX
|| expected_value > INT_MAX || expected_value < INT_MIN
#endif
) )
{
expected_result_for_int = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
}
p = input->x;
ret = mbedtls_asn1_get_int( &p, input->x + input->len, &val );
TEST_EQUAL( ret, expected_result_for_int );
if( ret == 0 )
{
TEST_EQUAL( val, expected_value );
TEST_ASSERT( p == input->x + input->len );
}
#if defined(MBEDTLS_BIGNUM_C)
ret = mbedtls_mpi_read_string( &expected_mpi, 16, expected_hex );
TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( ret == MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
{
/* The data overflows the maximum MPI size. */
expected_result_for_mpi = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
p = input->x;
ret = mbedtls_asn1_get_mpi( &p, input->x + input->len, &actual_mpi );
TEST_EQUAL( ret, expected_result_for_mpi );
if( ret == 0 )
{
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &actual_mpi , &expected_mpi ) == 0 );
TEST_ASSERT( p == input->x + input->len );
}
#endif
exit:
#if defined(MBEDTLS_BIGNUM_C)
mbedtls_mpi_free( &expected_mpi );
mbedtls_mpi_free( &actual_mpi );
#endif
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
void get_mpi_too_large( )
{
unsigned char *buf = NULL;
unsigned char *p;
mbedtls_mpi actual_mpi;
size_t too_many_octets =
MBEDTLS_MPI_MAX_LIMBS * sizeof(mbedtls_mpi_uint) + 1;
size_t size = too_many_octets + 6;
mbedtls_mpi_init( &actual_mpi );
ASSERT_ALLOC( buf, size );
buf[0] = 0x02; /* tag: INTEGER */
buf[1] = 0x84; /* 4-octet length */
buf[2] = ( too_many_octets >> 24 ) & 0xff;
buf[3] = ( too_many_octets >> 16 ) & 0xff;
buf[4] = ( too_many_octets >> 8 ) & 0xff;
buf[5] = too_many_octets & 0xff;
buf[6] = 0x01; /* most significant octet */
p = buf;
TEST_EQUAL( mbedtls_asn1_get_mpi( &p, buf + size, &actual_mpi ),
MBEDTLS_ERR_MPI_ALLOC_FAILED );
exit:
mbedtls_mpi_free( &actual_mpi );
mbedtls_free( buf );
}
/* END_CASE */
/* BEGIN_CASE */
void get_bitstring( const data_t *input,
int expected_length, int expected_unused_bits,
int expected_result, int expected_result_null )
{
mbedtls_asn1_bitstring bs = { 0xdead, 0x21, NULL };
unsigned char *p = input->x;
TEST_EQUAL( mbedtls_asn1_get_bitstring( &p, input->x + input->len, &bs ),
expected_result );
if( expected_result == 0 )
{
TEST_EQUAL( bs.len, (size_t) expected_length );
TEST_EQUAL( bs.unused_bits, expected_unused_bits );
TEST_ASSERT( bs.p != NULL );
TEST_EQUAL( bs.p - input->x + bs.len, input->len );
TEST_ASSERT( p == input->x + input->len );
}
p = input->x;
TEST_EQUAL( mbedtls_asn1_get_bitstring_null( &p, input->x + input->len,
&bs.len ),
expected_result_null );
if( expected_result_null == 0 )
{
TEST_EQUAL( bs.len, (size_t) expected_length );
if( expected_result == 0 )
TEST_ASSERT( p == input->x + input->len - bs.len );
}
}
/* END_CASE */
/* BEGIN_CASE */
void get_sequence_of( const data_t *input, int tag,
const char *description,
int expected_result )
{
mbedtls_asn1_sequence head = { { 0, 0, NULL }, NULL };
mbedtls_asn1_sequence *cur, *next;
unsigned char *p = input->x;
const char *rest = description;
unsigned long n;
TEST_EQUAL( mbedtls_asn1_get_sequence_of( &p, input->x + input->len,
&head, tag ),
expected_result );
if( expected_result == 0 )
{
TEST_ASSERT( p == input->x + input->len );
if( ! *rest )
{
TEST_EQUAL( head.buf.tag, 0 );
TEST_ASSERT( head.buf.p == NULL );
TEST_EQUAL( head.buf.len, 0 );
TEST_ASSERT( head.next == NULL );
}
else
{
cur = &head;
while( *rest )
{
++test_info.step;
TEST_ASSERT( cur != NULL );
TEST_EQUAL( cur->buf.tag, tag );
n = strtoul( rest, (char **) &rest, 0 );
TEST_EQUAL( n, (size_t)( cur->buf.p - input->x ) );
++rest;
n = strtoul( rest, (char **) &rest, 0 );
TEST_EQUAL( n, cur->buf.len );
if( *rest )
++rest;
cur = cur->next;
}
TEST_ASSERT( cur == NULL );
}
}
exit:
cur = head.next;
while( cur != NULL )
{
next = cur->next;
mbedtls_free( cur );
cur = next;
}
}
/* END_CASE */
/* BEGIN_CASE */
void get_alg( const data_t *input,
int oid_offset, int oid_length,
int params_tag, int params_offset, int params_length,
int total_length,
int expected_result )
{
mbedtls_asn1_buf oid = { -1, 0, NULL };
mbedtls_asn1_buf params = { -1, 0, NULL };
unsigned char *p = input->x;
int ret;
TEST_EQUAL( mbedtls_asn1_get_alg( &p, input->x + input->len,
&oid, &params ),
expected_result );
if( expected_result == 0 )
{
TEST_EQUAL( oid.tag, MBEDTLS_ASN1_OID );
TEST_EQUAL( oid.p - input->x, oid_offset );
TEST_EQUAL( oid.len, (size_t) oid_length );
TEST_EQUAL( params.tag, params_tag );
if( params_offset != 0 )
TEST_EQUAL( params.p - input->x, params_offset );
else
TEST_ASSERT( params.p == NULL );
TEST_EQUAL( params.len, (size_t) params_length );
TEST_EQUAL( p - input->x, total_length );
}
ret = mbedtls_asn1_get_alg_null( &p, input->x + input->len, &oid );
if( expected_result == 0 && params_offset == 0 )
{
TEST_EQUAL( oid.tag, MBEDTLS_ASN1_OID );
TEST_EQUAL( oid.p - input->x, oid_offset );
TEST_EQUAL( oid.len, (size_t) oid_length );
TEST_EQUAL( p - input->x, total_length );
}
else
TEST_ASSERT( ret != 0 );
}
/* END_CASE */
/* BEGIN_CASE */
void find_named_data( data_t *oid0, data_t *oid1, data_t *oid2, data_t *oid3,
data_t *needle, int from, int position )
{
mbedtls_asn1_named_data nd[] ={
{ {0x06, oid0->len, oid0->x}, {0, 0, NULL}, NULL, 0 },
{ {0x06, oid1->len, oid1->x}, {0, 0, NULL}, NULL, 0 },
{ {0x06, oid2->len, oid2->x}, {0, 0, NULL}, NULL, 0 },
{ {0x06, oid3->len, oid3->x}, {0, 0, NULL}, NULL, 0 },
};
mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
size_t i;
mbedtls_asn1_named_data *found;
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++ )
nd[i].next = pointers[i+1];
found = mbedtls_asn1_find_named_data( pointers[from],
(const char *) needle->x,
needle->len );
TEST_ASSERT( found == pointers[position] );
}
/* END_CASE */
/* BEGIN_CASE */
void free_named_data_null( )
{
mbedtls_asn1_free_named_data( NULL );
goto exit; /* Silence unused label warning */
}
/* END_CASE */
/* BEGIN_CASE */
void free_named_data( int with_oid, int with_val, int with_next )
{
mbedtls_asn1_named_data next =
{ {0x06, 0, NULL}, {0, 0xcafe, NULL}, NULL, 0 };
mbedtls_asn1_named_data head =
{ {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 };
if( with_oid )
ASSERT_ALLOC( head.oid.p, 1 );
if( with_val )
ASSERT_ALLOC( head.val.p, 1 );
if( with_next )
head.next = &next;
mbedtls_asn1_free_named_data( &head );
TEST_ASSERT( head.oid.p == NULL );
TEST_ASSERT( head.val.p == NULL );
TEST_ASSERT( head.next == NULL );
TEST_ASSERT( next.val.len == 0xcafe );
exit:
mbedtls_free( head.oid.p );
mbedtls_free( head.val.p );
}
/* END_CASE */
/* BEGIN_CASE */
void free_named_data_list( int length )
{
mbedtls_asn1_named_data *head = NULL;
int i;
for( i = 0; i < length; i++ )
{
mbedtls_asn1_named_data *new = NULL;
ASSERT_ALLOC( new, sizeof( mbedtls_asn1_named_data ) );
new->next = head;
head = new;
}
mbedtls_asn1_free_named_data_list( &head );
TEST_ASSERT( head == NULL );
/* Most of the point of the test is that it doesn't leak memory.
* So this test is only really useful under a memory leak detection
* framework. */
exit:
mbedtls_asn1_free_named_data_list( &head );
}
/* END_CASE */

View File

@ -1,53 +1,182 @@
ASN.1 Write Octet String #0 (Empty string)
mbedtls_asn1_write_octet_string:"":"0400":2:2
ASN.1 Write NULL
mbedtls_asn1_write_null:"0500"
ASN.1 Write Octet String #1 (Large buffer)
mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":10:5
ASN.1 Write BOOLEAN FALSE
mbedtls_asn1_write_bool:0:"010100"
ASN.1 Write Octet String #2 (Buffer just fits)
mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":5:5
ASN.1 Write BOOLEAN TRUE
mbedtls_asn1_write_bool:1:"0101ff"
ASN.1 Write Octet String #3 (Buffer too small for tag)
mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":4:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 0
mbedtls_asn1_write_int:0:"020100"
ASN.1 Write Octet String #4 (Buffer too small for len)
mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":3:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 1
mbedtls_asn1_write_int:1:"020101"
ASN.1 Write Octet String #5 (Buffer too small for string)
mbedtls_asn1_write_octet_string:"AABBCC":"0403AABBCC":2:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 127
mbedtls_asn1_write_int:0x7f:"02017f"
ASN.1 Write Octet String #6 (l = 128, large buffer)
mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"048180000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":140:131
ASN.1 Write int 128
mbedtls_asn1_write_int:0x80:"02020080"
ASN.1 Write Octet String #7 (l = 128, buffer just fits)
mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"048180000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":131:131
ASN.1 Write int 255
mbedtls_asn1_write_int:0xff:"020200ff"
ASN.1 Write Octet String #8 (l = 128, buffer too small for tag)
mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":130:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 256
mbedtls_asn1_write_int:0x100:"02020100"
ASN.1 Write Octet String #9 (l = 128, buffer too small for len)
mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":129:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 32767
mbedtls_asn1_write_int:0x7fff:"02027fff"
ASN.1 Write Octet String #9 (l = 128, buffer too small for string)
mbedtls_asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":127:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 32768
mbedtls_asn1_write_int:0x8000:"0203008000"
ASN.1 Write IA5 String #0 (Empty string)
mbedtls_asn1_write_ia5_string:"":"1600":2:2
ASN.1 Write int 65535
mbedtls_asn1_write_int:0xffff:"020300ffff"
ASN.1 Write IA5 String #1 (Large buffer)
mbedtls_asn1_write_ia5_string:"ABC":"1603414243":10:5
ASN.1 Write int 65536
mbedtls_asn1_write_int:0x10000:"0203010000"
ASN.1 Write IA5 String #2 (Buffer just fits)
mbedtls_asn1_write_ia5_string:"ABC":"1603414243":5:5
ASN.1 Write int 8388607
mbedtls_asn1_write_int:0x7fffff:"02037fffff"
ASN.1 Write IA5 String #3 (Buffer too small for tag)
mbedtls_asn1_write_ia5_string:"ABC":"":4:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 8388608
mbedtls_asn1_write_int:0x800000:"020400800000"
ASN.1 Write IA5 String #4 (Buffer too small for len)
mbedtls_asn1_write_ia5_string:"ABC":"":3:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 0x12345678
mbedtls_asn1_write_int:0x12345678:"020412345678"
ASN.1 Write IA5 String #5 (Buffer too small for string)
mbedtls_asn1_write_ia5_string:"ABC":"":2:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write int 2147483647
mbedtls_asn1_write_int:0x7fffffff:"02047fffffff"
#ASN.1 Write mpi 0
#mbedtls_asn1_write_mpi:"00":"020100"
ASN.1 Write mpi 1
mbedtls_asn1_write_mpi:"01":"020101"
ASN.1 Write mpi 0x7f
mbedtls_asn1_write_mpi:"7f":"02017f"
#ASN.1 Write mpi 0x80
#mbedtls_asn1_write_mpi:"7f":"02020080"
#ASN.1 Write mpi 0xff
#mbedtls_asn1_write_mpi:"7f":"020200ff"
ASN.1 Write mpi 0x100
mbedtls_asn1_write_mpi:"0100":"02020100"
ASN.1 Write mpi, 127*8-1 bits
mbedtls_asn1_write_mpi:"7f7b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8":"027f7f7b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8"
#ASN.1 Write mpi, 127*8 bits
#mbedtls_asn1_write_mpi:"e77b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8":"028180e77b16e05c1537de7c41cef1a0985d6a3ced98aec28e091874cbad6b5e40a5c956258f18861c28bed8ba808259339ee34b2e509c4080149474d5d5b86093f90c475a6443fc87e1a293d4151be625d652f1c32a00a018bba10c8a2ae5b2b0ee4be64e053dce9d07ec7919526c9dfcf2ec9fc3db485caa8e5a68a2cd0a427de8"
ASN.1 Write mpi, 127*8+1 bits
mbedtls_asn1_write_mpi:"108446d68934cc1af23c4cd909884d4bd737a1890e12f5ef8bf3d807d72feffa63c0bf2633345f8b8418d144617c871a7a0277ac0150eed4b3db7f9dff21114cd0d7f282400f03c931cb00c367550e374a1ed3762a1801ca714cfc8d5aac69707ca81e0661400ed0014d97cba48f94d835dd681fc3053c51958afbf7583cf49c":"028180108446d68934cc1af23c4cd909884d4bd737a1890e12f5ef8bf3d807d72feffa63c0bf2633345f8b8418d144617c871a7a0277ac0150eed4b3db7f9dff21114cd0d7f282400f03c931cb00c367550e374a1ed3762a1801ca714cfc8d5aac69707ca81e0661400ed0014d97cba48f94d835dd681fc3053c51958afbf7583cf49c"
ASN.1 Write mpi, 255*8-1 bits
mbedtls_asn1_write_mpi:"7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c":"0281ff7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c"
#ASN.1 Write mpi, 255*8 bits
#mbedtls_asn1_write_mpi:"fbd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c":"0282010000fbd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c"
ASN.1 Write mpi, 256*8-1 bits
mbedtls_asn1_write_mpi:"7bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c89":"028201007bd1913fcfb652896209ad3e62f5d04a8dfc71eb1698543c52200bd7bbf3c11dd9ff57c299a2f4da172b3d5bd7e29affddf8859be7d50a45537a0df15b17af603d18803fd17134847cba78d83e64bf9fee58364d6124add0541da7bad331cd35fb48186a74bc502ddb967602401c0db02b19e5d38f09e8618fa7f6a1a3f738629baffdc63d9d70d396007d943fd64ae696e5b7e88f2c6d6ec322b461dbddd36efa91d990343b66419cf4832a22dc9ad13021185a1bf007989a50ba3bfd1152b8db899482d3ed498d1b9fae243a3cdae9530d8b29fdb684f70cdc0c9b8527265312603b405e67d59d4b1d654ddc3b7fd5515acb32440dc80903c8474a2c136c89"
ASN.1 Write OCTET STRING: length=0
mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"":"0400"
ASN.1 Write OCTET STRING: length=1
mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"41":"040141"
ASN.1 Write OCTET STRING: length=2
mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"4142":"04024142"
ASN.1 Write OCTET STRING: length=127
mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"99a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"047f99a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
ASN.1 Write OCTET STRING: length=128
mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"0481800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
ASN.1 Write OCTET STRING: length=255
mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"633ed2cb0a2915dc4438a4c063017eb336cd9571d2a0585522c5073ca22a30ca7b8c9bd167d89ba1827bc6fb5d6ef6dcc52ee6eecc47e84ee0dd18fa3ebbdb6edfc679f037160d48d46a0d7e571335b24a28c8fd29b7f4a93d013b74e522bc1f5f605096bb99d438814b77b54d6dde608417b0a0ce9a8cb507fbeb95e9926b4bb6eec725599493d4b156ef3a5fd701426456029111c20f1d03c5d8999d2c042277ef91c5114a6c06218c1ba28d41ef08e4870d0cef260cba9de16d7d11ed5889b88fb93073746ebb158a4246cdb8a4ce403a5d1d598a0d11548f22070f833c1344d15e7a1445c133d19b8295b7c071bf2227178938031249d22d21c6f8e53d":"0481ff633ed2cb0a2915dc4438a4c063017eb336cd9571d2a0585522c5073ca22a30ca7b8c9bd167d89ba1827bc6fb5d6ef6dcc52ee6eecc47e84ee0dd18fa3ebbdb6edfc679f037160d48d46a0d7e571335b24a28c8fd29b7f4a93d013b74e522bc1f5f605096bb99d438814b77b54d6dde608417b0a0ce9a8cb507fbeb95e9926b4bb6eec725599493d4b156ef3a5fd701426456029111c20f1d03c5d8999d2c042277ef91c5114a6c06218c1ba28d41ef08e4870d0cef260cba9de16d7d11ed5889b88fb93073746ebb158a4246cdb8a4ce403a5d1d598a0d11548f22070f833c1344d15e7a1445c133d19b8295b7c071bf2227178938031249d22d21c6f8e53d"
ASN.1 Write OCTET STRING: length=256
mbedtls_asn1_write_string:MBEDTLS_ASN1_OCTET_STRING:"5a633ed2cb0a2915dc4438a4c063017eb336cd9571d2a0585522c5073ca22a30ca7b8c9bd167d89ba1827bc6fb5d6ef6dcc52ee6eecc47e84ee0dd18fa3ebbdb6edfc679f037160d48d46a0d7e571335b24a28c8fd29b7f4a93d013b74e522bc1f5f605096bb99d438814b77b54d6dde608417b0a0ce9a8cb507fbeb95e9926b4bb6eec725599493d4b156ef3a5fd701426456029111c20f1d03c5d8999d2c042277ef91c5114a6c06218c1ba28d41ef08e4870d0cef260cba9de16d7d11ed5889b88fb93073746ebb158a4246cdb8a4ce403a5d1d598a0d11548f22070f833c1344d15e7a1445c133d19b8295b7c071bf2227178938031249d22d21c6f8e53d":"048201005a633ed2cb0a2915dc4438a4c063017eb336cd9571d2a0585522c5073ca22a30ca7b8c9bd167d89ba1827bc6fb5d6ef6dcc52ee6eecc47e84ee0dd18fa3ebbdb6edfc679f037160d48d46a0d7e571335b24a28c8fd29b7f4a93d013b74e522bc1f5f605096bb99d438814b77b54d6dde608417b0a0ce9a8cb507fbeb95e9926b4bb6eec725599493d4b156ef3a5fd701426456029111c20f1d03c5d8999d2c042277ef91c5114a6c06218c1ba28d41ef08e4870d0cef260cba9de16d7d11ed5889b88fb93073746ebb158a4246cdb8a4ce403a5d1d598a0d11548f22070f833c1344d15e7a1445c133d19b8295b7c071bf2227178938031249d22d21c6f8e53d"
ASN.1 Write UTF8 STRING: length=0
mbedtls_asn1_write_string:MBEDTLS_ASN1_UTF8_STRING:"":"0c00"
ASN.1 Write UTF8 STRING: length=1
mbedtls_asn1_write_string:MBEDTLS_ASN1_UTF8_STRING:"41":"0c0141"
ASN.1 Write UTF8 STRING: length=128
mbedtls_asn1_write_string:MBEDTLS_ASN1_UTF8_STRING:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"0c81800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
ASN.1 Write PRINTABLE STRING: length=0
mbedtls_asn1_write_string:MBEDTLS_ASN1_PRINTABLE_STRING:"":"1300"
ASN.1 Write PRINTABLE STRING: length=1
mbedtls_asn1_write_string:MBEDTLS_ASN1_PRINTABLE_STRING:"41":"130141"
ASN.1 Write PRINTABLE STRING: length=128
mbedtls_asn1_write_string:MBEDTLS_ASN1_PRINTABLE_STRING:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"1381800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
ASN.1 Write IA5 STRING: length=0
mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING:"":"1600"
ASN.1 Write IA5 STRING: length=1
mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING:"41":"160141"
ASN.1 Write IA5 STRING: length=128
mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"1681800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
ASN.1 Write tagged string: length=0
mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING | MBEDTLS_ASN1_CONTEXT_SPECIFIC:"":"9600"
ASN.1 Write tagged string: length=1
mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING | MBEDTLS_ASN1_CONTEXT_SPECIFIC:"41":"960141"
ASN.1 Write tagged string: length=128
mbedtls_asn1_write_string:MBEDTLS_ASN1_IA5_STRING | MBEDTLS_ASN1_CONTEXT_SPECIFIC:"0199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38":"9681800199a66790856f7199641f55cadabb660aaed6aa0d9ef8cef4417118c6e8c6e15becbaa21c63faf48726e92357a38b3079a0b9d60be7457ec6552f900dd032577167c91e829927343c3a769b362db4de0ad2ffb8f13cc2eeca9e52dc557118baa88b857477595622bc301a1ae2150030d652c4a482cf88d0ded85d6731ff2d38"
ASN.1 Write OID: length=0
mbedtls_asn1_write_string:MBEDTLS_ASN1_OID:"":"0600"
ASN.1 Write OID: length=1
mbedtls_asn1_write_string:MBEDTLS_ASN1_OID:"41":"060141"
ASN.1 Write AlgorithmIdentifier, null parameters
mbedtls_asn1_write_algorithm_identifier:"4f4944":8:"300d06034f4944"
ASN.1 Write AlgorithmIdentifier, parameters (8 bytes)
mbedtls_asn1_write_algorithm_identifier:"4f4944":8:"300d06034f4944"
ASN.1 Write AlgorithmIdentifier, total length=0x7f
mbedtls_asn1_write_algorithm_identifier:"4f4944":0x7a:"307f06034f4944"
ASN.1 Write AlgorithmIdentifier, total length=0x80
mbedtls_asn1_write_algorithm_identifier:"4f4944":0x7b:"30818006034f4944"
ASN.1 Write AlgorithmIdentifier, total length=0xff
mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfa:"3081ff06034f4944"
ASN.1 Write AlgorithmIdentifier, total length=0x100
mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfb:"3082010006034f4944"
ASN.1 Write AlgorithmIdentifier, total length=0xffff
mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfffa:"3082ffff06034f4944"
ASN.1 Write AlgorithmIdentifier, total length=0x10000
mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfffb:"308301000006034f4944"
ASN.1 Write AlgorithmIdentifier, total length=0xffffff
mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfffffa:"3083ffffff06034f4944"
ASN.1 Write AlgorithmIdentifier, total length=0x1000000
mbedtls_asn1_write_algorithm_identifier:"4f4944":0xfffffb:"30840100000006034f4944"
ASN.1 Write / Read Length #0 (Len = 0, short form)
mbedtls_asn1_write_len:0:"00":1:1
@ -92,73 +221,121 @@ ASN.1 Write / Read Length #12 (Len = 16909060, buffer too small)
mbedtls_asn1_write_len:16909060:"8401020304":4:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
ASN.1 Write Named Bitstring / Unused bits #0
test_asn1_write_bitstrings:"FF":8:"030200FF":4:1
test_asn1_write_bitstrings:"FF":8:"030200FF":1
ASN.1 Write Named Bitstring / Unused bits #1
test_asn1_write_bitstrings:"FE":8:"030201FE":4:1
test_asn1_write_bitstrings:"FE":8:"030201FE":1
ASN.1 Write Named Bitstring / Unused bits #2
test_asn1_write_bitstrings:"FC":7:"030202FC":4:1
test_asn1_write_bitstrings:"FC":7:"030202FC":1
ASN.1 Write Named Bitstring / Unused bits #3
test_asn1_write_bitstrings:"F8":8:"030203F8":4:1
test_asn1_write_bitstrings:"F8":8:"030203F8":1
ASN.1 Write Named Bitstring / Unused bits #4
test_asn1_write_bitstrings:"F0":6:"030204F0":4:1
test_asn1_write_bitstrings:"F0":6:"030204F0":1
ASN.1 Write Named Bitstring / Unused bits #5
test_asn1_write_bitstrings:"E0":6:"030205E0":4:1
test_asn1_write_bitstrings:"E0":6:"030205E0":1
ASN.1 Write Named Bitstring / Unused bits #6
test_asn1_write_bitstrings:"C0":8:"030206C0":4:1
test_asn1_write_bitstrings:"C0":8:"030206C0":1
ASN.1 Write Named Bitstring / Unused bits #7
test_asn1_write_bitstrings:"80":8:"03020780":4:1
test_asn1_write_bitstrings:"80":8:"03020780":1
ASN.1 Write Named Bitstring / Empty bitstring
test_asn1_write_bitstrings:"00":7:"030100":3:1
test_asn1_write_bitstrings:"00":7:"030100":1
ASN.1 Write Named Bitstring / Empty bitstring (bits = 16)
test_asn1_write_bitstrings:"0000":16:"030100":3:1
test_asn1_write_bitstrings:"0000":16:"030100":1
ASN.1 Write Named Bitstring / Empty bitstring (bits = 24)
test_asn1_write_bitstrings:"FFFFFF":0:"030100":3:1
test_asn1_write_bitstrings:"FFFFFF":0:"030100":1
ASN.1 Write Named Bitstring / 15 trailing bits all unset
test_asn1_write_bitstrings:"F88000":24:"030307F880":5:1
test_asn1_write_bitstrings:"F88000":24:"030307F880":1
ASN.1 Write Named Bitstring / 15 trailing bits all set
test_asn1_write_bitstrings:"F8FFFF":9:"030307F880":5:1
test_asn1_write_bitstrings:"F8FFFF":9:"030307F880":1
ASN.1 Write Bitstring / Unused bits #0
test_asn1_write_bitstrings:"FF":8:"030200FF":4:0
test_asn1_write_bitstrings:"FF":8:"030200FF":0
ASN.1 Write Bitstring / Unused bits #1
test_asn1_write_bitstrings:"FF":7:"030201FE":4:0
test_asn1_write_bitstrings:"FF":7:"030201FE":0
ASN.1 Write Bitstring / Unused bits #2
test_asn1_write_bitstrings:"FF":6:"030202FC":4:0
test_asn1_write_bitstrings:"FF":6:"030202FC":0
ASN.1 Write Bitstring / Unused bits #3
test_asn1_write_bitstrings:"FF":5:"030203F8":4:0
test_asn1_write_bitstrings:"FF":5:"030203F8":0
ASN.1 Write Bitstring / Unused bits #4
test_asn1_write_bitstrings:"FF":4:"030204F0":4:0
test_asn1_write_bitstrings:"FF":4:"030204F0":0
ASN.1 Write Bitstring / Unused bits #5
test_asn1_write_bitstrings:"FF":3:"030205E0":4:0
test_asn1_write_bitstrings:"FF":3:"030205E0":0
ASN.1 Write Bitstring / Unused bits #6
test_asn1_write_bitstrings:"FF":2:"030206C0":4:0
test_asn1_write_bitstrings:"FF":2:"030206C0":0
ASN.1 Write Bitstring / Unused bits #7
test_asn1_write_bitstrings:"FF":1:"03020780":4:0
test_asn1_write_bitstrings:"FF":1:"03020780":0
ASN.1 Write Bitstring / 1 trailing bit (bits 15)
test_asn1_write_bitstrings:"0003":15:"0303010002":5:0
test_asn1_write_bitstrings:"0003":15:"0303010002":0
ASN.1 Write Bitstring / 0 bits
test_asn1_write_bitstrings:"":0:"030100":3:0
test_asn1_write_bitstrings:"":0:"030100":0
ASN.1 Write Bitstring / long string all bits unset except trailing bits
test_asn1_write_bitstrings:"000000000007":45:"030703000000000000":9:0
test_asn1_write_bitstrings:"000000000007":45:"030703000000000000":0
Store named data: not found
store_named_data_find:"414141":"424242":"434343":"444444":"7f7f7f":0:-1
Store named data: empty haystack
store_named_data_find:"414141":"424242":"434343":"444444":"7f7f7f":4:-1
Store named data: first
store_named_data_find:"414141":"424242":"434343":"444444":"414141":0:0
Store named data: last
store_named_data_find:"414141":"424242":"434343":"444444":"444444":0:3
Store named data: skip suffix
store_named_data_find:"41414141":"414141":"434343":"444444":"414141":0:1
Store named data: skip prefix
store_named_data_find:"4141":"414141":"434343":"444444":"414141":0:1
Store named data: first match
store_named_data_find:"414141":"414141":"434343":"444444":"414141":0:0
Store named data: found, null to zero
store_named_data_val_found:0:0
Store named data: found, null to data
store_named_data_val_found:0:9
Store named data: found, data to zero
store_named_data_val_found:9:0
Store named data: found, smaller data
store_named_data_val_found:9:2
Store named data: found, same-size data
store_named_data_val_found:9:9
Store named data: found, larger data
store_named_data_val_found:4:9
Store named data: new, val_len=0
store_named_data_val_new:0
Store named data: new, val_len=4
store_named_data_val_new:4
Store named data: new, val_len=4, val=NULL
store_named_data_val_new:-4

View File

@ -3,6 +3,53 @@
#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
@ -11,74 +58,175 @@
*/
/* BEGIN_CASE */
void mbedtls_asn1_write_octet_string( data_t * str, data_t * asn1,
int buf_len, int result )
void mbedtls_asn1_write_null( data_t *expected )
{
generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
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++ )
for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
TEST_ASSERT( buf[i] == GUARD_VAL );
TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
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;
}
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 );
}
exit:
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_asn1_write_ia5_string( char * str, data_t * asn1,
int buf_len, int result )
void mbedtls_asn1_write_bool( int val, data_t *expected )
{
generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
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++ )
for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
TEST_ASSERT( buf[i] == GUARD_VAL );
TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
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;
}
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 );
}
exit:
mbedtls_free( data.output );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ASN1PARSE_C */
/* 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;
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 )
{
@ -131,44 +279,174 @@ void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
/* BEGIN_CASE */
void test_asn1_write_bitstrings( data_t *bitstring, int bits,
data_t *expected_asn1, int result,
int is_named )
data_t *expected, int is_named )
{
generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
int ret;
size_t i;
unsigned char buf[150];
unsigned char *p;
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 );
memset( buf, GUARD_VAL, sizeof( buf ) );
p = buf + GUARD_LEN + expected_asn1->len;
if ( is_named == 0 )
for( data.size = 0; data.size < expected->len + 1; data.size++ )
{
ret = mbedtls_asn1_write_bitstring( &p,
buf,
(unsigned char *)bitstring->x,
(size_t) bits );
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
{
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 );
/* 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] );
}
if ( result >= 0 )
exit:
if( found != NULL && found == head && found != pointers[from] )
{
TEST_ASSERT( memcmp( p, expected_asn1->x, expected_asn1->len ) == 0 );
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 */