/* BEGIN_HEADER */
#include "mbedtls/asn1write.h"

#define GUARD_LEN 4
#define GUARD_VAL 0x2a

typedef struct
{
    unsigned char *output;
    unsigned char *start;
    unsigned char *end;
    unsigned char *p;
    size_t size;
} generic_write_data_t;

int generic_write_start_step( generic_write_data_t *data )
{
    test_set_step( data->size );
    ASSERT_ALLOC( data->output, data->size == 0 ? 1 : data->size );
    data->end = data->output + data->size;
    data->p = data->end;
    data->start = data->end - data->size;
    return( 1 );
exit:
    return( 0 );
}

int generic_write_finish_step( generic_write_data_t *data,
                               const data_t *expected, int ret )
{
    int ok = 0;

    if( data->size < expected->len )
    {
        TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
    }
    else
    {
        TEST_EQUAL( ret, data->end - data->p );
        TEST_ASSERT( data->p >= data->start );
        TEST_ASSERT( data->p <= data->end );
        ASSERT_COMPARE( data->p, (size_t)( data->end - data->p ),
                        expected->x, expected->len );
    }
    ok = 1;

exit:
    mbedtls_free( data->output );
    data->output = NULL;
    return( ok );
}

/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_ASN1_WRITE_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void mbedtls_asn1_write_null( data_t *expected )
{
    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
    int ret;

    for( data.size = 0; data.size < expected->len + 1; data.size++ )
    {
        if( ! generic_write_start_step( &data ) )
            goto exit;
        ret = mbedtls_asn1_write_null( &data.p, data.start );
        if( ! generic_write_finish_step( &data, expected, ret ) )
            goto exit;
    }

exit:
    mbedtls_free( data.output );
}
/* END_CASE */

/* BEGIN_CASE */
void mbedtls_asn1_write_bool( int val, data_t *expected )
{
    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
    int ret;

    for( data.size = 0; data.size < expected->len + 1; data.size++ )
    {
        if( ! generic_write_start_step( &data ) )
            goto exit;
        ret = mbedtls_asn1_write_bool( &data.p, data.start, val );
        if( ! generic_write_finish_step( &data, expected, ret ) )
            goto exit;
    }

exit:
    mbedtls_free( data.output );
}
/* END_CASE */

/* BEGIN_CASE */
void mbedtls_asn1_write_int( int val, data_t *expected )
{
    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
    int ret;

    for( data.size = 0; data.size < expected->len + 1; data.size++ )
    {
        if( ! generic_write_start_step( &data ) )
            goto exit;
        ret = mbedtls_asn1_write_int( &data.p, data.start, val );
        if( ! generic_write_finish_step( &data, expected, ret ) )
            goto exit;
    }

exit:
    mbedtls_free( data.output );
}
/* END_CASE */


/* BEGIN_CASE */
void mbedtls_asn1_write_enum( int val, data_t *expected )
{
    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
    int ret;

    for( data.size = 0; data.size < expected->len + 1; data.size++ )
    {
        if( ! generic_write_start_step( &data ) )
            goto exit;
        ret = mbedtls_asn1_write_enum( &data.p, data.start, val );
        if( ! generic_write_finish_step( &data, expected, ret ) )
            goto exit;
    }

exit:
    mbedtls_free( data.output );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
void mbedtls_asn1_write_mpi( data_t *val, data_t *expected )
{
    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
    mbedtls_mpi mpi;
    int ret;

    mbedtls_mpi_init( &mpi );
    TEST_ASSERT( mbedtls_mpi_read_binary( &mpi, val->x, val->len ) == 0 );

    for( data.size = 0; data.size < expected->len + 1; data.size++ )
    {
        if( ! generic_write_start_step( &data ) )
            goto exit;
        ret = mbedtls_asn1_write_mpi( &data.p, data.start, &mpi );
        if( ! generic_write_finish_step( &data, expected, ret ) )
            goto exit;
        if( expected->len > 10 && data.size == 8 )
            data.size = expected->len - 2;
    }

exit:
    mbedtls_mpi_free( &mpi );
    mbedtls_free( data.output );
}
/* END_CASE */

/* BEGIN_CASE */
void mbedtls_asn1_write_string( int tag, data_t *content, data_t *expected )
{
    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
    int ret;

    for( data.size = 0; data.size < expected->len + 1; data.size++ )
    {
        if( ! generic_write_start_step( &data ) )
            goto exit;
        switch( tag )
        {
            case MBEDTLS_ASN1_OCTET_STRING:
                ret = mbedtls_asn1_write_octet_string(
                    &data.p, data.start, content->x, content->len );
                break;
            case MBEDTLS_ASN1_OID:
                ret = mbedtls_asn1_write_oid(
                    &data.p, data.start,
                    (const char *) content->x, content->len );
                break;
            case MBEDTLS_ASN1_UTF8_STRING:
                ret = mbedtls_asn1_write_utf8_string(
                    &data.p, data.start,
                    (const char *) content->x, content->len );
                break;
            case MBEDTLS_ASN1_PRINTABLE_STRING:
                ret = mbedtls_asn1_write_printable_string(
                    &data.p, data.start,
                    (const char *) content->x, content->len );
                break;
            case MBEDTLS_ASN1_IA5_STRING:
                ret = mbedtls_asn1_write_ia5_string(
                    &data.p, data.start,
                    (const char *) content->x, content->len );
                break;
            default:
                ret = mbedtls_asn1_write_tagged_string(
                    &data.p, data.start, tag,
                    (const char *) content->x, content->len );
        }
        if( ! generic_write_finish_step( &data, expected, ret ) )
            goto exit;
        if( expected->len > 10 && data.size == 8 )
            data.size = expected->len - 2;
    }

exit:
    mbedtls_free( data.output );
}
/* END_CASE */

/* BEGIN_CASE */
void mbedtls_asn1_write_algorithm_identifier( data_t *oid,
                                              int par_len,
                                              data_t *expected )
{
    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
    int ret;

    for( data.size = 0; data.size < expected->len + 1; data.size++ )
    {
        if( ! generic_write_start_step( &data ) )
            goto exit;
        ret = mbedtls_asn1_write_algorithm_identifier(
            &data.p, data.start,
            (const char *) oid->x, oid->len, par_len );
        /* If params_len != 0, mbedtls_asn1_write_algorithm_identifier()
         * assumes that the parameters are already present in the buffer
         * and returns a length that accounts for this, but our test
         * data omits the parameters. */
        if( ret >= 0 )
            ret -= par_len;
        if( ! generic_write_finish_step( &data, expected, ret ) )
            goto exit;
    }

exit:
    mbedtls_free( data.output );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_ASN1_PARSE_C */
void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
                             int result )
{
    int ret;
    unsigned char buf[150];
    unsigned char *p;
    size_t i;
    size_t read_len;

    memset( buf, GUARD_VAL, sizeof( buf ) );

    p = buf + GUARD_LEN + buf_len;

    ret = mbedtls_asn1_write_len( &p, buf + GUARD_LEN, (size_t) len );

    TEST_ASSERT( ret == result );

    /* Check for buffer overwrite on both sides */
    for( i = 0; i < GUARD_LEN; i++ )
    {
        TEST_ASSERT( buf[i] == GUARD_VAL );
        TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
    }

    if( result >= 0 )
    {
        TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );

        TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );

        /* Read back with mbedtls_asn1_get_len() to check */
        ret = mbedtls_asn1_get_len( &p, buf + GUARD_LEN + buf_len, &read_len );

        if( len == 0 )
        {
            TEST_ASSERT( ret == 0 );
        }
        else
        {
            /* Return will be MBEDTLS_ERR_ASN1_OUT_OF_DATA because the rest of
             * the buffer is missing
             */
            TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA );
        }
        TEST_ASSERT( read_len == (size_t) len );
        TEST_ASSERT( p == buf + GUARD_LEN + buf_len );
    }
}
/* END_CASE */

/* BEGIN_CASE */
void test_asn1_write_bitstrings( data_t *bitstring, int bits,
                                 data_t *expected, int is_named )
{
    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
    int ret;
    int ( *func )( unsigned char **p, unsigned char *start,
                   const unsigned char *buf, size_t bits ) =
        ( is_named ? mbedtls_asn1_write_named_bitstring :
          mbedtls_asn1_write_bitstring );

    for( data.size = 0; data.size < expected->len + 1; data.size++ )
    {
        if( ! generic_write_start_step( &data ) )
            goto exit;
        ret = ( *func )( &data.p, data.start, bitstring->x, bits );
        if( ! generic_write_finish_step( &data, expected, ret ) )
            goto exit;
    }

exit:
    mbedtls_free( data.output );
}
/* END_CASE */

/* BEGIN_CASE */
void store_named_data_find( data_t *oid0, data_t *oid1,
                            data_t *oid2, data_t *oid3,
                            data_t *needle, int from, int position )
{
    data_t *oid[4] = {oid0, oid1, oid2, oid3};
    mbedtls_asn1_named_data nd[] ={
        { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
        { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
        { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
        { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
    };
    mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
    size_t i;
    mbedtls_asn1_named_data *head = NULL;
    mbedtls_asn1_named_data *found = NULL;

    for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
        pointers[i] = &nd[i];
    pointers[ARRAY_LENGTH( nd )] = NULL;
    for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
    {
        ASSERT_ALLOC( nd[i].oid.p, oid[i]->len );
        memcpy( nd[i].oid.p, oid[i]->x, oid[i]->len );
        nd[i].oid.len = oid[i]->len;
        nd[i].next = pointers[i+1];
    }

    head = pointers[from];
    found = mbedtls_asn1_store_named_data( &head,
                                           (const char *) needle->x,
                                           needle->len,
                                           NULL, 0 );

    /* In any case, the existing list structure must be unchanged. */
    for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
        TEST_ASSERT( nd[i].next == pointers[i+1] );

    if( position >= 0 )
    {
        /* position should have been found and modified. */
        TEST_ASSERT( head == pointers[from] );
        TEST_ASSERT( found == pointers[position] );
    }
    else
    {
        /* A new entry should have been created. */
        TEST_ASSERT( found == head );
        TEST_ASSERT( head->next == pointers[from] );
        for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
            TEST_ASSERT( found != &nd[i] );
    }

exit:
    if( found != NULL && found == head && found != pointers[from] )
    {
        mbedtls_free( found->oid.p );
        mbedtls_free( found );
    }
    for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
        mbedtls_free( nd[i].oid.p );
}
/* END_CASE */

/* BEGIN_CASE */
void store_named_data_val_found( int old_len, int new_len )
{
    mbedtls_asn1_named_data nd =
        { {0x06, 3, (unsigned char *) "OID"}, {0, 0, NULL}, NULL, 0 };
    mbedtls_asn1_named_data *head = &nd;
    mbedtls_asn1_named_data *found = NULL;
    unsigned char *old_val = NULL;
    unsigned char *new_val = (unsigned char *) "new value";

    if( old_len != 0 )
    {
        ASSERT_ALLOC( nd.val.p, (size_t) old_len );
        old_val = nd.val.p;
        nd.val.len = old_len;
        memset( old_val, 'x', old_len );
    }
    if( new_len <= 0 )
    {
        new_len = - new_len;
        new_val = NULL;
    }

    found = mbedtls_asn1_store_named_data( &head, "OID", 3,
                                           new_val, new_len );
    TEST_ASSERT( head == &nd );
    TEST_ASSERT( found == head );

    if( new_val != NULL)
        ASSERT_COMPARE( found->val.p, found->val.len,
                        new_val, (size_t) new_len );
    if( new_len == 0)
        TEST_ASSERT( found->val.p == NULL );
    else if( new_len == old_len )
        TEST_ASSERT( found->val.p == old_val );
    else
        TEST_ASSERT( found->val.p != old_val );

exit:
    mbedtls_free( nd.val.p );
}
/* END_CASE */

/* BEGIN_CASE */
void store_named_data_val_new( int new_len )
{
    mbedtls_asn1_named_data *head = NULL;
    mbedtls_asn1_named_data *found = NULL;
    const unsigned char *oid = (unsigned char *) "OID";
    size_t oid_len = strlen( (const char *) oid );
    const unsigned char *new_val = (unsigned char *) "new value";

    if( new_len <= 0 )
        new_val = NULL;
    if( new_len < 0 )
        new_len = - new_len;

    found = mbedtls_asn1_store_named_data( &head,
                                           (const char *) oid, oid_len,
                                           new_val, (size_t) new_len );
    TEST_ASSERT( found != NULL );
    TEST_ASSERT( found == head );
    TEST_ASSERT( found->oid.p != oid );
    ASSERT_COMPARE( found->oid.p, found->oid.len, oid, oid_len );
    if( new_len == 0 )
        TEST_ASSERT( found->val.p == NULL );
    else if( new_val == NULL )
        TEST_ASSERT( found->val.p != NULL );
    else
    {
        TEST_ASSERT( found->val.p != new_val );
        ASSERT_COMPARE( found->val.p, found->val.len,
                        new_val, (size_t) new_len );
    }

exit:
    if( found != NULL )
    {
        mbedtls_free( found->oid.p );
        mbedtls_free( found->val.p );
    }
    mbedtls_free( found );
}
/* END_CASE */
