blob: b69f6b5c3a6e046099a84477920970495decdda8 [file] [log] [blame]
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/asn1write.h"
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +02003
4#define GUARD_LEN 4
5#define GUARD_VAL 0x2a
Gilles Peskine3a032c32019-03-01 18:13:36 +01006
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 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
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +020053/* END_HEADER */
54
55/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056 * depends_on:MBEDTLS_ASN1_WRITE_C
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +020057 * END_DEPENDENCIES
58 */
59
60/* BEGIN_CASE */
Gilles Peskine9311cf52019-03-01 20:05:05 +010061void 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 */
Gilles Peskine3a032c32019-03-01 18:13:36 +010081void 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/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
121void mbedtls_asn1_write_mpi( data_t *val, data_t *expected )
122{
123 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
124 mbedtls_mpi mpi;
125 int ret;
126
127 mbedtls_mpi_init( &mpi );
128 TEST_ASSERT( mbedtls_mpi_read_binary( &mpi, val->x, val->len ) == 0 );
129
130 for( data.size = 0; data.size < expected->len + 1; data.size++ )
131 {
132 if( ! generic_write_start_step( &data ) )
133 goto exit;
134 ret = mbedtls_asn1_write_mpi( &data.p, data.start, &mpi );
135 if( ! generic_write_finish_step( &data, expected, ret ) )
136 goto exit;
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100137 if( expected->len > 10 && data.size == 8 )
138 data.size = expected->len - 2;
Gilles Peskine3a032c32019-03-01 18:13:36 +0100139 }
140
141exit:
142 mbedtls_mpi_free( &mpi );
143 mbedtls_free( data.output );
144}
145/* END_CASE */
146
147/* BEGIN_CASE */
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100148void mbedtls_asn1_write_string( int tag, data_t *content, data_t *expected )
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200149{
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100150 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200151 int ret;
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200152
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100153 for( data.size = 0; data.size < expected->len + 1; data.size++ )
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200154 {
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100155 if( ! generic_write_start_step( &data ) )
156 goto exit;
157 switch( tag )
158 {
159 case MBEDTLS_ASN1_OCTET_STRING:
160 ret = mbedtls_asn1_write_octet_string(
161 &data.p, data.start, content->x, content->len );
162 break;
Gilles Peskine9311cf52019-03-01 20:05:05 +0100163 case MBEDTLS_ASN1_OID:
164 ret = mbedtls_asn1_write_oid(
165 &data.p, data.start,
166 (const char *) content->x, content->len );
167 break;
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100168 case MBEDTLS_ASN1_UTF8_STRING:
169 ret = mbedtls_asn1_write_utf8_string(
170 &data.p, data.start,
171 (const char *) content->x, content->len );
172 break;
173 case MBEDTLS_ASN1_PRINTABLE_STRING:
174 ret = mbedtls_asn1_write_printable_string(
175 &data.p, data.start,
176 (const char *) content->x, content->len );
177 break;
178 case MBEDTLS_ASN1_IA5_STRING:
179 ret = mbedtls_asn1_write_ia5_string(
180 &data.p, data.start,
181 (const char *) content->x, content->len );
182 break;
183 default:
184 ret = mbedtls_asn1_write_tagged_string(
185 &data.p, data.start, tag,
186 (const char *) content->x, content->len );
187 }
188 if( ! generic_write_finish_step( &data, expected, ret ) )
189 goto exit;
190 if( expected->len > 10 && data.size == 8 )
191 data.size = expected->len - 2;
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200192 }
193
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100194exit:
195 mbedtls_free( data.output );
Manuel Pégourié-Gonnardc22bb492014-05-29 17:16:45 +0200196}
197/* END_CASE */
Paul Bakkere325db92016-07-14 10:27:36 +0100198
Gilles Peskine9311cf52019-03-01 20:05:05 +0100199/* BEGIN_CASE */
200void mbedtls_asn1_write_algorithm_identifier( data_t *oid,
201 int par_len,
202 data_t *expected )
203{
204 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
205 int ret;
206
207 for( data.size = 0; data.size < expected->len + 1; data.size++ )
208 {
209 if( ! generic_write_start_step( &data ) )
210 goto exit;
211 ret = mbedtls_asn1_write_algorithm_identifier(
212 &data.p, data.start,
213 (const char *) oid->x, oid->len, par_len );
214 /* If params_len != 0, mbedtls_asn1_write_algorithm_identifier()
215 * assumes that the parameters are already present in the buffer
216 * and returns a length that accounts for this, but our test
217 * data omits the parameters. */
218 if( ret >= 0 )
219 ret -= par_len;
220 if( ! generic_write_finish_step( &data, expected, ret ) )
221 goto exit;
222 }
223
224exit:
225 mbedtls_free( data.output );
226}
227/* END_CASE */
228
Gilles Peskine91d8d022019-03-01 19:34:24 +0100229/* BEGIN_CASE depends_on:MBEDTLS_ASN1_PARSE_C */
Azim Khan5fcca462018-06-29 11:05:32 +0100230void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
Azim Khand30ca132017-06-09 04:32:58 +0100231 int result )
Paul Bakkere325db92016-07-14 10:27:36 +0100232{
233 int ret;
234 unsigned char buf[150];
Paul Bakkere325db92016-07-14 10:27:36 +0100235 unsigned char *p;
Azim Khan90791702017-05-30 00:57:11 +0100236 size_t i;
237 size_t read_len;
Paul Bakkere325db92016-07-14 10:27:36 +0100238
239 memset( buf, GUARD_VAL, sizeof( buf ) );
Paul Bakkere325db92016-07-14 10:27:36 +0100240
Paul Bakker58bfb832016-07-14 11:02:31 +0100241 p = buf + GUARD_LEN + buf_len;
Paul Bakkere325db92016-07-14 10:27:36 +0100242
243 ret = mbedtls_asn1_write_len( &p, buf + GUARD_LEN, (size_t) len );
244
245 TEST_ASSERT( ret == result );
246
247 /* Check for buffer overwrite on both sides */
248 for( i = 0; i < GUARD_LEN; i++ )
249 {
250 TEST_ASSERT( buf[i] == GUARD_VAL );
Paul Bakker58bfb832016-07-14 11:02:31 +0100251 TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
Paul Bakkere325db92016-07-14 10:27:36 +0100252 }
253
254 if( result >= 0 )
255 {
Azim Khand30ca132017-06-09 04:32:58 +0100256 TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );
Paul Bakkere325db92016-07-14 10:27:36 +0100257
Azim Khand30ca132017-06-09 04:32:58 +0100258 TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );
Paul Bakker5e8b77c2016-07-14 11:14:54 +0100259
260 /* Read back with mbedtls_asn1_get_len() to check */
261 ret = mbedtls_asn1_get_len( &p, buf + GUARD_LEN + buf_len, &read_len );
262
263 if( len == 0 )
264 {
265 TEST_ASSERT( ret == 0 );
266 }
267 else
268 {
269 /* Return will be MBEDTLS_ERR_ASN1_OUT_OF_DATA because the rest of
270 * the buffer is missing
271 */
272 TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA );
273 }
274 TEST_ASSERT( read_len == (size_t) len );
275 TEST_ASSERT( p == buf + GUARD_LEN + buf_len );
Paul Bakkere325db92016-07-14 10:27:36 +0100276 }
277}
278/* END_CASE */
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100279
280/* BEGIN_CASE */
281void test_asn1_write_bitstrings( data_t *bitstring, int bits,
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100282 data_t *expected, int is_named )
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100283{
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100284 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100285 int ret;
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100286 int ( *func )( unsigned char **p, unsigned char *start,
287 const unsigned char *buf, size_t bits ) =
288 ( is_named ? mbedtls_asn1_write_named_bitstring :
289 mbedtls_asn1_write_bitstring );
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100290
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100291 for( data.size = 0; data.size < expected->len + 1; data.size++ )
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100292 {
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100293 if( ! generic_write_start_step( &data ) )
294 goto exit;
295 ret = ( *func )( &data.p, data.start, bitstring->x, bits );
296 if( ! generic_write_finish_step( &data, expected, ret ) )
297 goto exit;
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100298 }
299
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100300exit:
301 mbedtls_free( data.output );
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100302}
303/* END_CASE */
Gilles Peskinea9023032019-03-01 23:26:05 +0100304
305/* BEGIN_CASE */
306void store_named_data_find( data_t *oid0, data_t *oid1,
307 data_t *oid2, data_t *oid3,
308 data_t *needle, int from, int position )
309{
310 data_t *oid[4] = {oid0, oid1, oid2, oid3};
311 mbedtls_asn1_named_data nd[] ={
312 { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
313 { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
314 { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
315 { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
316 };
317 mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
318 size_t i;
319 mbedtls_asn1_named_data *head = NULL;
320 mbedtls_asn1_named_data *found = NULL;
321
322 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
323 pointers[i] = &nd[i];
324 pointers[ARRAY_LENGTH( nd )] = NULL;
325 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
326 {
327 ASSERT_ALLOC( nd[i].oid.p, oid[i]->len );
328 memcpy( nd[i].oid.p, oid[i]->x, oid[i]->len );
329 nd[i].oid.len = oid[i]->len;
330 nd[i].next = pointers[i+1];
331 }
332
333 head = pointers[from];
334 found = mbedtls_asn1_store_named_data( &head,
335 (const char *) needle->x,
336 needle->len,
337 NULL, 0 );
338
339 /* In any case, the existing list structure must be unchanged. */
340 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
341 TEST_ASSERT( nd[i].next == pointers[i+1] );
342
343 if( position >= 0 )
344 {
345 /* position should have been found and modified. */
346 TEST_ASSERT( head == pointers[from] );
347 TEST_ASSERT( found == pointers[position] );
348 }
349 else
350 {
351 /* A new entry should have been created. */
352 TEST_ASSERT( found == head );
353 TEST_ASSERT( head->next == pointers[from] );
354 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
355 TEST_ASSERT( found != &nd[i] );
356 }
357
358exit:
359 if( found != NULL && found == head && found != pointers[from] )
360 {
361 mbedtls_free( found->oid.p );
362 mbedtls_free( found );
363 }
364 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
365 mbedtls_free( nd[i].oid.p );
366}
367/* END_CASE */
368
369/* BEGIN_CASE */
370void store_named_data_val_found( int old_len, int new_len )
371{
372 mbedtls_asn1_named_data nd =
373 { {0x06, 3, (unsigned char *) "OID"}, {0, 0, NULL}, NULL, 0 };
374 mbedtls_asn1_named_data *head = &nd;
375 mbedtls_asn1_named_data *found = NULL;
376 unsigned char *old_val = NULL;
377 unsigned char *new_val = (unsigned char *) "new value";
378
379 if( old_len != 0 )
380 {
381 ASSERT_ALLOC( nd.val.p, (size_t) old_len );
382 old_val = nd.val.p;
383 nd.val.len = old_len;
384 memset( old_val, 'x', old_len );
385 }
386 if( new_len <= 0 )
387 {
388 new_len = - new_len;
389 new_val = NULL;
390 }
391
392 found = mbedtls_asn1_store_named_data( &head, "OID", 3,
393 new_val, new_len );
394 TEST_ASSERT( head == &nd );
395 TEST_ASSERT( found == head );
396
397 if( new_val != NULL)
398 ASSERT_COMPARE( found->val.p, found->val.len,
399 new_val, (size_t) new_len );
400 if( new_len == 0)
401 TEST_ASSERT( found->val.p == NULL );
402 else if( new_len == old_len )
403 TEST_ASSERT( found->val.p == old_val );
404 else
405 TEST_ASSERT( found->val.p != old_val );
406
407exit:
408 mbedtls_free( nd.val.p );
409}
410/* END_CASE */
411
412/* BEGIN_CASE */
413void store_named_data_val_new( int new_len )
414{
415 mbedtls_asn1_named_data *head = NULL;
416 mbedtls_asn1_named_data *found = NULL;
417 const unsigned char *oid = (unsigned char *) "OID";
418 size_t oid_len = strlen( (const char *) oid );
419 const unsigned char *new_val = (unsigned char *) "new value";
420
421 if( new_len <= 0 )
422 new_val = NULL;
423 if( new_len < 0 )
424 new_len = - new_len;
425
426 found = mbedtls_asn1_store_named_data( &head,
427 (const char *) oid, oid_len,
428 new_val, (size_t) new_len );
429 TEST_ASSERT( found != NULL );
430 TEST_ASSERT( found == head );
431 TEST_ASSERT( found->oid.p != oid );
432 ASSERT_COMPARE( found->oid.p, found->oid.len, oid, oid_len );
433 if( new_len == 0 )
434 TEST_ASSERT( found->val.p == NULL );
435 else if( new_val == NULL )
436 TEST_ASSERT( found->val.p != NULL );
437 else
438 {
439 TEST_ASSERT( found->val.p != new_val );
440 ASSERT_COMPARE( found->val.p, found->val.len,
441 new_val, (size_t) new_len );
442 }
443
444exit:
445 if( found != NULL )
446 {
447 mbedtls_free( found->oid.p );
448 mbedtls_free( found->val.p );
449 }
450 mbedtls_free( found );
451}
452/* END_CASE */