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

#define GUARD_LEN 4
#define GUARD_VAL 0x2a
/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_ASN1_WRITE_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void mbedtls_asn1_write_octet_string( data_t * str, data_t * asn1,
                                      int buf_len, int result )
{
    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++ )
    {
        TEST_ASSERT( buf[i] == GUARD_VAL );
        TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
    }

    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 );
    }
}
/* END_CASE */

/* BEGIN_CASE */
void mbedtls_asn1_write_ia5_string( char * str, data_t * asn1,
                                    int buf_len, int result )
{
    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++ )
    {
        TEST_ASSERT( buf[i] == GUARD_VAL );
        TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
    }

    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 );
    }
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_ASN1PARSE_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 */
