• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/asn1write.h"
3
4#define GUARD_LEN 4
5#define GUARD_VAL 0x2a
6
7typedef struct
8{
9    unsigned char *output;
10    unsigned char *start;
11    unsigned char *end;
12    unsigned char *p;
13    size_t size;
14} generic_write_data_t;
15
16int generic_write_start_step( generic_write_data_t *data )
17{
18    mbedtls_test_set_step( data->size );
19    ASSERT_ALLOC( data->output, data->size == 0 ? 1 : data->size );
20    data->end = data->output + data->size;
21    data->p = data->end;
22    data->start = data->end - data->size;
23    return( 1 );
24exit:
25    return( 0 );
26}
27
28int generic_write_finish_step( generic_write_data_t *data,
29                               const data_t *expected, int ret )
30{
31    int ok = 0;
32
33    if( data->size < expected->len )
34    {
35        TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
36    }
37    else
38    {
39        TEST_EQUAL( ret, data->end - data->p );
40        TEST_ASSERT( data->p >= data->start );
41        TEST_ASSERT( data->p <= data->end );
42        ASSERT_COMPARE( data->p, (size_t)( data->end - data->p ),
43                        expected->x, expected->len );
44    }
45    ok = 1;
46
47exit:
48    mbedtls_free( data->output );
49    data->output = NULL;
50    return( ok );
51}
52
53/* END_HEADER */
54
55/* BEGIN_DEPENDENCIES
56 * depends_on:MBEDTLS_ASN1_WRITE_C
57 * END_DEPENDENCIES
58 */
59
60/* BEGIN_CASE */
61void mbedtls_asn1_write_null( data_t *expected )
62{
63    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
64    int ret;
65
66    for( data.size = 0; data.size < expected->len + 1; data.size++ )
67    {
68        if( ! generic_write_start_step( &data ) )
69            goto exit;
70        ret = mbedtls_asn1_write_null( &data.p, data.start );
71        if( ! generic_write_finish_step( &data, expected, ret ) )
72            goto exit;
73    }
74
75exit:
76    mbedtls_free( data.output );
77}
78/* END_CASE */
79
80/* BEGIN_CASE */
81void mbedtls_asn1_write_bool( int val, data_t *expected )
82{
83    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
84    int ret;
85
86    for( data.size = 0; data.size < expected->len + 1; data.size++ )
87    {
88        if( ! generic_write_start_step( &data ) )
89            goto exit;
90        ret = mbedtls_asn1_write_bool( &data.p, data.start, val );
91        if( ! generic_write_finish_step( &data, expected, ret ) )
92            goto exit;
93    }
94
95exit:
96    mbedtls_free( data.output );
97}
98/* END_CASE */
99
100/* BEGIN_CASE */
101void mbedtls_asn1_write_int( int val, data_t *expected )
102{
103    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
104    int ret;
105
106    for( data.size = 0; data.size < expected->len + 1; data.size++ )
107    {
108        if( ! generic_write_start_step( &data ) )
109            goto exit;
110        ret = mbedtls_asn1_write_int( &data.p, data.start, val );
111        if( ! generic_write_finish_step( &data, expected, ret ) )
112            goto exit;
113    }
114
115exit:
116    mbedtls_free( data.output );
117}
118/* END_CASE */
119
120
121/* BEGIN_CASE */
122void mbedtls_asn1_write_enum( int val, data_t *expected )
123{
124    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
125    int ret;
126
127    for( data.size = 0; data.size < expected->len + 1; data.size++ )
128    {
129        if( ! generic_write_start_step( &data ) )
130            goto exit;
131        ret = mbedtls_asn1_write_enum( &data.p, data.start, val );
132        if( ! generic_write_finish_step( &data, expected, ret ) )
133            goto exit;
134    }
135
136exit:
137    mbedtls_free( data.output );
138}
139/* END_CASE */
140
141/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
142void mbedtls_asn1_write_mpi( data_t *val, data_t *expected )
143{
144    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
145    mbedtls_mpi mpi;
146    int ret;
147
148    mbedtls_mpi_init( &mpi );
149    TEST_ASSERT( mbedtls_mpi_read_binary( &mpi, val->x, val->len ) == 0 );
150
151    for( data.size = 0; data.size < expected->len + 1; data.size++ )
152    {
153        if( ! generic_write_start_step( &data ) )
154            goto exit;
155        ret = mbedtls_asn1_write_mpi( &data.p, data.start, &mpi );
156        if( ! generic_write_finish_step( &data, expected, ret ) )
157            goto exit;
158        if( expected->len > 10 && data.size == 8 )
159            data.size = expected->len - 2;
160    }
161
162exit:
163    mbedtls_mpi_free( &mpi );
164    mbedtls_free( data.output );
165}
166/* END_CASE */
167
168/* BEGIN_CASE */
169void mbedtls_asn1_write_string( int tag, data_t *content, data_t *expected )
170{
171    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
172    int ret;
173
174    for( data.size = 0; data.size < expected->len + 1; data.size++ )
175    {
176        if( ! generic_write_start_step( &data ) )
177            goto exit;
178        switch( tag )
179        {
180            case MBEDTLS_ASN1_OCTET_STRING:
181                ret = mbedtls_asn1_write_octet_string(
182                    &data.p, data.start, content->x, content->len );
183                break;
184            case MBEDTLS_ASN1_OID:
185                ret = mbedtls_asn1_write_oid(
186                    &data.p, data.start,
187                    (const char *) content->x, content->len );
188                break;
189            case MBEDTLS_ASN1_UTF8_STRING:
190                ret = mbedtls_asn1_write_utf8_string(
191                    &data.p, data.start,
192                    (const char *) content->x, content->len );
193                break;
194            case MBEDTLS_ASN1_PRINTABLE_STRING:
195                ret = mbedtls_asn1_write_printable_string(
196                    &data.p, data.start,
197                    (const char *) content->x, content->len );
198                break;
199            case MBEDTLS_ASN1_IA5_STRING:
200                ret = mbedtls_asn1_write_ia5_string(
201                    &data.p, data.start,
202                    (const char *) content->x, content->len );
203                break;
204            default:
205                ret = mbedtls_asn1_write_tagged_string(
206                    &data.p, data.start, tag,
207                    (const char *) content->x, content->len );
208        }
209        if( ! generic_write_finish_step( &data, expected, ret ) )
210            goto exit;
211        if( expected->len > 10 && data.size == 8 )
212            data.size = expected->len - 2;
213    }
214
215exit:
216    mbedtls_free( data.output );
217}
218/* END_CASE */
219
220/* BEGIN_CASE */
221void mbedtls_asn1_write_algorithm_identifier( data_t *oid,
222                                              int par_len,
223                                              data_t *expected )
224{
225    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
226    int ret;
227
228    for( data.size = 0; data.size < expected->len + 1; data.size++ )
229    {
230        if( ! generic_write_start_step( &data ) )
231            goto exit;
232        ret = mbedtls_asn1_write_algorithm_identifier(
233            &data.p, data.start,
234            (const char *) oid->x, oid->len, par_len );
235        /* If params_len != 0, mbedtls_asn1_write_algorithm_identifier()
236         * assumes that the parameters are already present in the buffer
237         * and returns a length that accounts for this, but our test
238         * data omits the parameters. */
239        if( ret >= 0 )
240            ret -= par_len;
241        if( ! generic_write_finish_step( &data, expected, ret ) )
242            goto exit;
243    }
244
245exit:
246    mbedtls_free( data.output );
247}
248/* END_CASE */
249
250/* BEGIN_CASE depends_on:MBEDTLS_ASN1_PARSE_C */
251void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
252                             int result )
253{
254    int ret;
255    unsigned char buf[150];
256    unsigned char *p;
257    size_t i;
258    size_t read_len;
259
260    memset( buf, GUARD_VAL, sizeof( buf ) );
261
262    p = buf + GUARD_LEN + buf_len;
263
264    ret = mbedtls_asn1_write_len( &p, buf + GUARD_LEN, (size_t) len );
265
266    TEST_ASSERT( ret == result );
267
268    /* Check for buffer overwrite on both sides */
269    for( i = 0; i < GUARD_LEN; i++ )
270    {
271        TEST_ASSERT( buf[i] == GUARD_VAL );
272        TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
273    }
274
275    if( result >= 0 )
276    {
277        TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );
278
279        TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );
280
281        /* Read back with mbedtls_asn1_get_len() to check */
282        ret = mbedtls_asn1_get_len( &p, buf + GUARD_LEN + buf_len, &read_len );
283
284        if( len == 0 )
285        {
286            TEST_ASSERT( ret == 0 );
287        }
288        else
289        {
290            /* Return will be MBEDTLS_ERR_ASN1_OUT_OF_DATA because the rest of
291             * the buffer is missing
292             */
293            TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA );
294        }
295        TEST_ASSERT( read_len == (size_t) len );
296        TEST_ASSERT( p == buf + GUARD_LEN + buf_len );
297    }
298}
299/* END_CASE */
300
301/* BEGIN_CASE */
302void test_asn1_write_bitstrings( data_t *bitstring, int bits,
303                                 data_t *expected, int is_named )
304{
305    generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
306    int ret;
307    int ( *func )( unsigned char **p, const unsigned char *start,
308                   const unsigned char *buf, size_t bits ) =
309        ( is_named ? mbedtls_asn1_write_named_bitstring :
310          mbedtls_asn1_write_bitstring );
311
312    for( data.size = 0; data.size < expected->len + 1; data.size++ )
313    {
314        if( ! generic_write_start_step( &data ) )
315            goto exit;
316        ret = ( *func )( &data.p, data.start, bitstring->x, bits );
317        if( ! generic_write_finish_step( &data, expected, ret ) )
318            goto exit;
319    }
320
321exit:
322    mbedtls_free( data.output );
323}
324/* END_CASE */
325
326/* BEGIN_CASE */
327void store_named_data_find( data_t *oid0, data_t *oid1,
328                            data_t *oid2, data_t *oid3,
329                            data_t *needle, int from, int position )
330{
331    data_t *oid[4] = {oid0, oid1, oid2, oid3};
332    mbedtls_asn1_named_data nd[] ={
333        { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
334        { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
335        { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
336        { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
337    };
338    mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
339    size_t i;
340    mbedtls_asn1_named_data *head = NULL;
341    mbedtls_asn1_named_data *found = NULL;
342
343    for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
344        pointers[i] = &nd[i];
345    pointers[ARRAY_LENGTH( nd )] = NULL;
346    for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
347    {
348        ASSERT_ALLOC( nd[i].oid.p, oid[i]->len );
349        memcpy( nd[i].oid.p, oid[i]->x, oid[i]->len );
350        nd[i].oid.len = oid[i]->len;
351        nd[i].next = pointers[i+1];
352    }
353
354    head = pointers[from];
355    found = mbedtls_asn1_store_named_data( &head,
356                                           (const char *) needle->x,
357                                           needle->len,
358                                           NULL, 0 );
359
360    /* In any case, the existing list structure must be unchanged. */
361    for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
362        TEST_ASSERT( nd[i].next == pointers[i+1] );
363
364    if( position >= 0 )
365    {
366        /* position should have been found and modified. */
367        TEST_ASSERT( head == pointers[from] );
368        TEST_ASSERT( found == pointers[position] );
369    }
370    else
371    {
372        /* A new entry should have been created. */
373        TEST_ASSERT( found == head );
374        TEST_ASSERT( head->next == pointers[from] );
375        for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
376            TEST_ASSERT( found != &nd[i] );
377    }
378
379exit:
380    if( found != NULL && found == head && found != pointers[from] )
381    {
382        mbedtls_free( found->oid.p );
383        mbedtls_free( found );
384    }
385    for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
386        mbedtls_free( nd[i].oid.p );
387}
388/* END_CASE */
389
390/* BEGIN_CASE */
391void store_named_data_val_found( int old_len, int new_len )
392{
393    mbedtls_asn1_named_data nd =
394        { {0x06, 3, (unsigned char *) "OID"}, {0, 0, NULL}, NULL, 0 };
395    mbedtls_asn1_named_data *head = &nd;
396    mbedtls_asn1_named_data *found = NULL;
397    unsigned char *old_val = NULL;
398    unsigned char *new_val = (unsigned char *) "new value";
399
400    if( old_len != 0 )
401    {
402        ASSERT_ALLOC( nd.val.p, (size_t) old_len );
403        old_val = nd.val.p;
404        nd.val.len = old_len;
405        memset( old_val, 'x', old_len );
406    }
407    if( new_len <= 0 )
408    {
409        new_len = - new_len;
410        new_val = NULL;
411    }
412
413    found = mbedtls_asn1_store_named_data( &head, "OID", 3,
414                                           new_val, new_len );
415    TEST_ASSERT( head == &nd );
416    TEST_ASSERT( found == head );
417
418    if( new_val != NULL)
419        ASSERT_COMPARE( found->val.p, found->val.len,
420                        new_val, (size_t) new_len );
421    if( new_len == 0)
422        TEST_ASSERT( found->val.p == NULL );
423    else if( new_len == old_len )
424        TEST_ASSERT( found->val.p == old_val );
425    else
426        TEST_ASSERT( found->val.p != old_val );
427
428exit:
429    mbedtls_free( nd.val.p );
430}
431/* END_CASE */
432
433/* BEGIN_CASE */
434void store_named_data_val_new( int new_len )
435{
436    mbedtls_asn1_named_data *head = NULL;
437    mbedtls_asn1_named_data *found = NULL;
438    const unsigned char *oid = (unsigned char *) "OID";
439    size_t oid_len = strlen( (const char *) oid );
440    const unsigned char *new_val = (unsigned char *) "new value";
441
442    if( new_len <= 0 )
443        new_val = NULL;
444    if( new_len < 0 )
445        new_len = - new_len;
446
447    found = mbedtls_asn1_store_named_data( &head,
448                                           (const char *) oid, oid_len,
449                                           new_val, (size_t) new_len );
450    TEST_ASSERT( found != NULL );
451    TEST_ASSERT( found == head );
452    TEST_ASSERT( found->oid.p != oid );
453    ASSERT_COMPARE( found->oid.p, found->oid.len, oid, oid_len );
454    if( new_len == 0 )
455        TEST_ASSERT( found->val.p == NULL );
456    else if( new_val == NULL )
457        TEST_ASSERT( found->val.p != NULL );
458    else
459    {
460        TEST_ASSERT( found->val.p != new_val );
461        ASSERT_COMPARE( found->val.p, found->val.len,
462                        new_val, (size_t) new_len );
463    }
464
465exit:
466    if( found != NULL )
467    {
468        mbedtls_free( found->oid.p );
469        mbedtls_free( found->val.p );
470    }
471    mbedtls_free( found );
472}
473/* END_CASE */
474