/* 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

/* Used internally to report an error that indicates a bug in a parsing function. */
#define ERR_PARSE_INCONSISTENCY INT_MAX

/* Use this magic value in some tests to indicate that the expected result
 * should not be checked. */
#define UNPREDICTABLE_RESULT 0x5552

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 );
#else
            *p = start + 1;
            ret = mbedtls_asn1_get_len( p, end, &len );
            *p += len;
#endif
            /* If we're sure that the number fits in an int, also
             * call mbedtls_asn1_get_int(). */
            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;
    unsigned char *end;
    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 );
        end = buf + 1;
        p = end;
    }
    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;
        end = buf + buffer_size;
    }

    ret = mbedtls_asn1_get_len( &p, end, &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 );
}

typedef struct
{
    const unsigned char *input_start;
    const char *description;
} traverse_state_t;

/* Value returned by traverse_callback if description runs out. */
#define RET_TRAVERSE_STOP 1
/* Value returned by traverse_callback if description has an invalid format
 * (see traverse_sequence_of). */
#define RET_TRAVERSE_ERROR 2


static int traverse_callback( void *ctx, int tag,
                              unsigned char *content, size_t len )
{
    traverse_state_t *state = ctx;
    size_t offset;
    const char *rest = state->description;
    unsigned long n;

    TEST_ASSERT( content > state->input_start );
    offset = content - state->input_start;
    test_set_step( offset );

    if( *rest == 0 )
        return( RET_TRAVERSE_STOP );
    n = strtoul( rest, (char **) &rest, 0 );
    TEST_EQUAL( n, offset );
    TEST_EQUAL( *rest, ',' );
    ++rest;
    n = strtoul( rest, (char **) &rest, 0 );
    TEST_EQUAL( n, (unsigned) tag );
    TEST_EQUAL( *rest, ',' );
    ++rest;
    n = strtoul( rest, (char **) &rest, 0 );
    TEST_EQUAL( n, len );
    if( *rest == ',' )
        ++rest;

    state->description = rest;
    return( 0 );

exit:
    return( RET_TRAVERSE_ERROR );
}

/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_ASN1_PARSE_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void parse_prefixes( const data_t *input,
                     int full_result,
                     int overfull_result )
{
    /* full_result: expected result from parsing the given string. */
    /* overfull_result: expected_result from parsing the given string plus
     * some trailing garbage. This may be UNPREDICTABLE_RESULT to accept
     * any result: use this for invalid inputs that may or may not become
     * valid depending on what the trailing garbage is. */

    unsigned char *buf = NULL;
    unsigned char *p = NULL;
    size_t buffer_size;
    int ret;

    /* Test every prefix of the input, except the empty string.
     * The first byte of the string is the tag. Without a tag byte,
     * we wouldn't know what to parse the input as.
     * Also test the input followed by an extra byte.
     */
    for( buffer_size = 1; buffer_size <= input->len + 1; 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( buffer_size < input->len )
        {
            TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_OUT_OF_DATA );
        }
        else if( buffer_size == input->len )
        {
            TEST_EQUAL( ret, full_result );
        }
        else /* ( buffer_size > input->len ) */
        {
            if( overfull_result != UNPREDICTABLE_RESULT )
                TEST_EQUAL( ret, overfull_result );
        }
        if( ret == 0 )
            TEST_ASSERT( p == buf + input->len );

        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;

    /* Test prefixes of a buffer containing the given length string
     * followed by `actual_length` bytes of payload. To save a bit of
     * time, we skip some "boring" prefixes: we don't test prefixes where
     * the payload is truncated more than one byte away from either end,
     * and we only test the empty string on a 1-byte input.
     */
    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 empty_integer( const data_t *input )
{
    unsigned char *p;
#if defined(MBEDTLS_BIGNUM_C)
    mbedtls_mpi actual_mpi;
#endif
    int val;

#if defined(MBEDTLS_BIGNUM_C)
    mbedtls_mpi_init( & actual_mpi );
#endif

    /* An INTEGER with no content is not valid. */
    p = input->x;
    TEST_EQUAL( mbedtls_asn1_get_int( &p, input->x + input->len, &val ),
                MBEDTLS_ERR_ASN1_INVALID_LENGTH );

#if defined(MBEDTLS_BIGNUM_C)
    /* INTEGERs are sometimes abused as bitstrings, so the library accepts
     * an INTEGER with empty content and gives it the value 0. */
    p = input->x;
    TEST_EQUAL( mbedtls_asn1_get_mpi( &p, input->x + input->len, &actual_mpi ),
                0 );
    TEST_EQUAL( mbedtls_mpi_cmp_int( &actual_mpi, 0 ), 0 );
#endif

exit:
#if defined(MBEDTLS_BIGNUM_C)
    mbedtls_mpi_free( &actual_mpi );
#endif
    /*empty cleanup in some configurations*/ ;
}
/* END_CASE */

/* BEGIN_CASE */
void get_integer( const data_t *input,
                  const char *expected_hex, int expected_result )
{
    unsigned char *p;
#if defined(MBEDTLS_BIGNUM_C)
    mbedtls_mpi expected_mpi;
    mbedtls_mpi actual_mpi;
    mbedtls_mpi complement;
    int expected_result_for_mpi = expected_result;
#endif
    long expected_value;
    int expected_result_for_int = expected_result;
    int val;
    int ret;

#if defined(MBEDTLS_BIGNUM_C)
    mbedtls_mpi_init( &expected_mpi );
    mbedtls_mpi_init( &actual_mpi );
    mbedtls_mpi_init( &complement );
#endif

    errno = 0;
    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
            ) )
    {
        /* The library returns the dubious error code INVALID_LENGTH
         * for integers that are out of range. */
        expected_result_for_int = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
    }
    if( expected_result == 0 && expected_value < 0 )
    {
        /* The library does not support negative INTEGERs and
         * returns the dubious error code INVALID_LENGTH.
         * Test that we preserve the historical behavior. If we
         * decide to change the behavior, we'll also change this test. */
        expected_result_for_int = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
    }

    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 )
    {
        if( expected_value >= 0 )
        {
            TEST_ASSERT( mbedtls_mpi_cmp_mpi( &actual_mpi,
                                              &expected_mpi ) == 0 );
        }
        else
        {
            /* The library ignores the sign bit in ASN.1 INTEGERs
             * (which makes sense insofar as INTEGERs are sometimes
             * abused as bit strings), so the result of parsing them
             * is a positive integer such that expected_mpi +
             * actual_mpi = 2^n where n is the length of the content
             * of the INTEGER. (Leading ff octets don't matter for the
             * expected value, but they matter for the actual value.)
             * Test that we don't change from this behavior. If we
             * decide to fix the library to change the behavior on
             * negative INTEGERs, we'll fix this test code. */
            unsigned char *q = input->x + 1;
            size_t len;
            TEST_ASSERT( mbedtls_asn1_get_len( &q, input->x + input->len,
                                               &len ) == 0 );
            TEST_ASSERT( mbedtls_mpi_lset( &complement, 1 ) == 0 );
            TEST_ASSERT( mbedtls_mpi_shift_l( &complement, len * 8 ) == 0 );
            TEST_ASSERT( mbedtls_mpi_add_mpi( &complement, &complement,
                                              &expected_mpi ) == 0 );
            TEST_ASSERT( mbedtls_mpi_cmp_mpi( &complement,
                                              &actual_mpi ) == 0 );
        }
        TEST_ASSERT( p == input->x + input->len );
    }
#endif

exit:
#if defined(MBEDTLS_BIGNUM_C)
    mbedtls_mpi_free( &expected_mpi );
    mbedtls_mpi_free( &actual_mpi );
    mbedtls_mpi_free( &complement );
#endif
    /*empty cleanup in some configurations*/ ;
}
/* END_CASE */

/* BEGIN_CASE */
void get_enum( const data_t *input,
               const char *expected_hex, int expected_result )
{
    unsigned char *p;
    long expected_value;
    int expected_result_for_enum = expected_result;
    int val;
    int ret;

    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
            ) )
    {
        /* The library returns the dubious error code INVALID_LENGTH
         * for integers that are out of range. */
        expected_result_for_enum = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
    }
    if( expected_result == 0 && expected_value < 0 )
    {
        /* The library does not support negative INTEGERs and
         * returns the dubious error code INVALID_LENGTH.
         * Test that we preserve the historical behavior. If we
         * decide to change the behavior, we'll also change this test. */
        expected_result_for_enum = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
    }

    p = input->x;
    ret = mbedtls_asn1_get_enum( &p, input->x + input->len, &val );
    TEST_EQUAL( ret, expected_result_for_enum );
    if( ret == 0 )
    {
        TEST_EQUAL( val, expected_value );
        TEST_ASSERT( p == input->x + input->len );
    }
}
/* 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 )
{
    /* The description string is a comma-separated list of integers.
     * For each element in the SEQUENCE in input, description contains
     * two integers: the offset of the element (offset from the start
     * of input to the tag of the element) and the length of the
     * element's contents.
     * "offset1,length1,..." */

    mbedtls_asn1_sequence head = { { 0, 0, NULL }, NULL };
    mbedtls_asn1_sequence *cur;
    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:
    mbedtls_asn1_sequence_free( head.next );
}
/* END_CASE */

/* BEGIN_CASE */
void traverse_sequence_of( const data_t *input,
                           int tag_must_mask, int tag_must_val,
                           int tag_may_mask, int tag_may_val,
                           const char *description,
                           int expected_result )
{
    /* The description string is a comma-separated list of integers.
     * For each element in the SEQUENCE in input, description contains
     * three integers: the offset of the element's content (offset from
     * the start of input to the content of the element), the element's tag,
     * and the length of the element's contents.
     * "offset1,tag1,length1,..." */

    unsigned char *p = input->x;
    traverse_state_t traverse_state = {input->x, description};
    int ret;

    ret = mbedtls_asn1_traverse_sequence_of( &p, input->x + input->len,
                                             (uint8_t) tag_must_mask, (uint8_t) tag_must_val,
                                             (uint8_t) tag_may_mask, (uint8_t) tag_may_val,
                                             traverse_callback, &traverse_state );
    if( ret == RET_TRAVERSE_ERROR )
        goto exit;
    TEST_EQUAL( ret, expected_result );
    TEST_EQUAL( *traverse_state.description, 0 );
}
/* 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 */
