blob: 8c260f7670b542cacd1455b1eff83b8197db714a [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{
Chris Jones9634bb12021-01-20 15:56:42 +000018 mbedtls_test_set_step( data->size );
Gilles Peskine61940532022-06-15 21:17:25 +020019 mbedtls_free( data->output );
20 data->output = NULL;
Gilles Peskine3a032c32019-03-01 18:13:36 +010021 ASSERT_ALLOC( data->output, data->size == 0 ? 1 : data->size );
22 data->end = data->output + data->size;
23 data->p = data->end;
24 data->start = data->end - data->size;
25 return( 1 );
26exit:
27 return( 0 );
28}
29
30int generic_write_finish_step( generic_write_data_t *data,
31 const data_t *expected, int ret )
32{
33 int ok = 0;
34
35 if( data->size < expected->len )
36 {
37 TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
38 }
39 else
40 {
41 TEST_EQUAL( ret, data->end - data->p );
42 TEST_ASSERT( data->p >= data->start );
43 TEST_ASSERT( data->p <= data->end );
44 ASSERT_COMPARE( data->p, (size_t)( data->end - data->p ),
45 expected->x, expected->len );
46 }
47 ok = 1;
48
49exit:
Gilles Peskine3a032c32019-03-01 18:13:36 +010050 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
Gilles Peskine2c2730a2022-06-10 20:15:44 +020066 for( data.size = 0; data.size <= expected->len + 1; data.size++ )
Gilles Peskine9311cf52019-03-01 20:05:05 +010067 {
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;
Gilles Peskine61940532022-06-15 21:17:25 +020073 /* There's no parsing function for NULL. */
Gilles Peskine9311cf52019-03-01 20:05:05 +010074 }
75
76exit:
77 mbedtls_free( data.output );
78}
79/* END_CASE */
80
81/* BEGIN_CASE */
Gilles Peskine3a032c32019-03-01 18:13:36 +010082void mbedtls_asn1_write_bool( int val, data_t *expected )
83{
84 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
85 int ret;
86
Gilles Peskine2c2730a2022-06-10 20:15:44 +020087 for( data.size = 0; data.size <= expected->len + 1; data.size++ )
Gilles Peskine3a032c32019-03-01 18:13:36 +010088 {
89 if( ! generic_write_start_step( &data ) )
90 goto exit;
91 ret = mbedtls_asn1_write_bool( &data.p, data.start, val );
92 if( ! generic_write_finish_step( &data, expected, ret ) )
93 goto exit;
Gilles Peskine61940532022-06-15 21:17:25 +020094#if defined(MBEDTLS_ASN1_PARSE_C)
95 if( ret >= 0 )
96 {
97 int read = 0xdeadbeef;
98 TEST_EQUAL( mbedtls_asn1_get_bool( &data.p, data.end, &read ), 0 );
99 TEST_EQUAL( val, read );
100 }
101#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskine3a032c32019-03-01 18:13:36 +0100102 }
103
104exit:
105 mbedtls_free( data.output );
106}
107/* END_CASE */
108
109/* BEGIN_CASE */
110void mbedtls_asn1_write_int( int val, data_t *expected )
111{
112 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
113 int ret;
114
Gilles Peskine2c2730a2022-06-10 20:15:44 +0200115 for( data.size = 0; data.size <= expected->len + 1; data.size++ )
Gilles Peskine3a032c32019-03-01 18:13:36 +0100116 {
117 if( ! generic_write_start_step( &data ) )
118 goto exit;
119 ret = mbedtls_asn1_write_int( &data.p, data.start, val );
120 if( ! generic_write_finish_step( &data, expected, ret ) )
121 goto exit;
Gilles Peskine61940532022-06-15 21:17:25 +0200122#if defined(MBEDTLS_ASN1_PARSE_C)
123 if( ret >= 0 )
124 {
125 int read = 0xdeadbeef;
126 TEST_EQUAL( mbedtls_asn1_get_int( &data.p, data.end, &read ), 0 );
127 TEST_EQUAL( val, read );
128 }
129#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskine3a032c32019-03-01 18:13:36 +0100130 }
131
132exit:
133 mbedtls_free( data.output );
134}
135/* END_CASE */
136
Mykhailo Sopiha6af7bf92019-10-31 15:55:16 +0200137
138/* BEGIN_CASE */
139void mbedtls_asn1_write_enum( int val, data_t *expected )
140{
141 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
142 int ret;
143
Gilles Peskine2c2730a2022-06-10 20:15:44 +0200144 for( data.size = 0; data.size <= expected->len + 1; data.size++ )
Mykhailo Sopiha6af7bf92019-10-31 15:55:16 +0200145 {
146 if( ! generic_write_start_step( &data ) )
147 goto exit;
148 ret = mbedtls_asn1_write_enum( &data.p, data.start, val );
149 if( ! generic_write_finish_step( &data, expected, ret ) )
150 goto exit;
Gilles Peskine61940532022-06-15 21:17:25 +0200151#if defined(MBEDTLS_ASN1_PARSE_C)
152 if( ret >= 0 )
153 {
154 int read = 0xdeadbeef;
155 TEST_EQUAL( mbedtls_asn1_get_enum( &data.p, data.end, &read ), 0 );
156 TEST_EQUAL( val, read );
157 }
158#endif /* MBEDTLS_ASN1_PARSE_C */
Mykhailo Sopiha6af7bf92019-10-31 15:55:16 +0200159 }
160
161exit:
162 mbedtls_free( data.output );
163}
164/* END_CASE */
165
Gilles Peskine3a032c32019-03-01 18:13:36 +0100166/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
167void mbedtls_asn1_write_mpi( data_t *val, data_t *expected )
168{
169 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
Gilles Peskine61940532022-06-15 21:17:25 +0200170 mbedtls_mpi mpi, read;
Gilles Peskine3a032c32019-03-01 18:13:36 +0100171 int ret;
172
173 mbedtls_mpi_init( &mpi );
Gilles Peskine61940532022-06-15 21:17:25 +0200174 mbedtls_mpi_init( &read );
Gilles Peskine3a032c32019-03-01 18:13:36 +0100175 TEST_ASSERT( mbedtls_mpi_read_binary( &mpi, val->x, val->len ) == 0 );
176
Gilles Peskine2c2730a2022-06-10 20:15:44 +0200177 for( data.size = 0; data.size <= expected->len + 1; data.size++ )
Gilles Peskine3a032c32019-03-01 18:13:36 +0100178 {
179 if( ! generic_write_start_step( &data ) )
180 goto exit;
181 ret = mbedtls_asn1_write_mpi( &data.p, data.start, &mpi );
182 if( ! generic_write_finish_step( &data, expected, ret ) )
183 goto exit;
Gilles Peskine61940532022-06-15 21:17:25 +0200184#if defined(MBEDTLS_ASN1_PARSE_C)
185 if( ret >= 0 )
186 {
187 TEST_EQUAL( mbedtls_asn1_get_mpi( &data.p, data.end, &read ), 0 );
188 TEST_EQUAL( 0, mbedtls_mpi_cmp_mpi( &mpi, &read ) );
189 }
190#endif /* MBEDTLS_ASN1_PARSE_C */
191 /* Skip some intermediate lengths, they're boring. */
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100192 if( expected->len > 10 && data.size == 8 )
193 data.size = expected->len - 2;
Gilles Peskine3a032c32019-03-01 18:13:36 +0100194 }
195
196exit:
197 mbedtls_mpi_free( &mpi );
Gilles Peskine61940532022-06-15 21:17:25 +0200198 mbedtls_mpi_free( &read );
Gilles Peskine3a032c32019-03-01 18:13:36 +0100199 mbedtls_free( data.output );
200}
201/* END_CASE */
202
203/* BEGIN_CASE */
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100204void mbedtls_asn1_write_string( int tag, data_t *content, data_t *expected )
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200205{
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100206 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200207 int ret;
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200208
Gilles Peskine2c2730a2022-06-10 20:15:44 +0200209 for( data.size = 0; data.size <= expected->len + 1; data.size++ )
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200210 {
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100211 if( ! generic_write_start_step( &data ) )
212 goto exit;
213 switch( tag )
214 {
215 case MBEDTLS_ASN1_OCTET_STRING:
216 ret = mbedtls_asn1_write_octet_string(
217 &data.p, data.start, content->x, content->len );
218 break;
Gilles Peskine9311cf52019-03-01 20:05:05 +0100219 case MBEDTLS_ASN1_OID:
220 ret = mbedtls_asn1_write_oid(
221 &data.p, data.start,
222 (const char *) content->x, content->len );
223 break;
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100224 case MBEDTLS_ASN1_UTF8_STRING:
225 ret = mbedtls_asn1_write_utf8_string(
226 &data.p, data.start,
227 (const char *) content->x, content->len );
228 break;
229 case MBEDTLS_ASN1_PRINTABLE_STRING:
230 ret = mbedtls_asn1_write_printable_string(
231 &data.p, data.start,
232 (const char *) content->x, content->len );
233 break;
234 case MBEDTLS_ASN1_IA5_STRING:
235 ret = mbedtls_asn1_write_ia5_string(
236 &data.p, data.start,
237 (const char *) content->x, content->len );
238 break;
239 default:
240 ret = mbedtls_asn1_write_tagged_string(
241 &data.p, data.start, tag,
242 (const char *) content->x, content->len );
243 }
244 if( ! generic_write_finish_step( &data, expected, ret ) )
245 goto exit;
Gilles Peskine61940532022-06-15 21:17:25 +0200246 /* There's no parsing function for octet or character strings. */
247 /* Skip some intermediate lengths, they're boring. */
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100248 if( expected->len > 10 && data.size == 8 )
249 data.size = expected->len - 2;
Manuel Pégourié-Gonnard36178ff2014-05-29 14:26:03 +0200250 }
251
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100252exit:
253 mbedtls_free( data.output );
Manuel Pégourié-Gonnardc22bb492014-05-29 17:16:45 +0200254}
255/* END_CASE */
Paul Bakkere325db92016-07-14 10:27:36 +0100256
Gilles Peskine9311cf52019-03-01 20:05:05 +0100257/* BEGIN_CASE */
258void mbedtls_asn1_write_algorithm_identifier( data_t *oid,
259 int par_len,
260 data_t *expected )
261{
262 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
263 int ret;
Gilles Peskine61940532022-06-15 21:17:25 +0200264#if defined(MBEDTLS_ASN1_PARSE_C)
265 unsigned char *buf_complete = NULL;
266#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskine9311cf52019-03-01 20:05:05 +0100267
Gilles Peskine2c2730a2022-06-10 20:15:44 +0200268 for( data.size = 0; data.size <= expected->len + 1; data.size++ )
Gilles Peskine9311cf52019-03-01 20:05:05 +0100269 {
270 if( ! generic_write_start_step( &data ) )
271 goto exit;
272 ret = mbedtls_asn1_write_algorithm_identifier(
273 &data.p, data.start,
274 (const char *) oid->x, oid->len, par_len );
275 /* If params_len != 0, mbedtls_asn1_write_algorithm_identifier()
276 * assumes that the parameters are already present in the buffer
277 * and returns a length that accounts for this, but our test
278 * data omits the parameters. */
279 if( ret >= 0 )
280 ret -= par_len;
281 if( ! generic_write_finish_step( &data, expected, ret ) )
282 goto exit;
Gilles Peskine61940532022-06-15 21:17:25 +0200283
284#if defined(MBEDTLS_ASN1_PARSE_C)
285 /* Only do a parse-back test if the parameters aren't too large for
286 * a small-heap environment. The boundary is somewhat arbitrary. */
287 if( ret >= 0 && par_len <= 1234 )
288 {
289 mbedtls_asn1_buf alg = {0, 0, NULL};
290 mbedtls_asn1_buf params = {0, 0, NULL};
291 /* The writing function doesn't write the parameters unless
292 * they're null: it only takes their length as input. But the
293 * parsing function requires the parameters to be present.
294 * Thus make up parameters. */
295 size_t data_len = data.end - data.p;
296 size_t len_complete = data_len + par_len;
297 unsigned char expected_params_tag;
298 size_t expected_params_len;
299 ASSERT_ALLOC( buf_complete, len_complete );
300 unsigned char *end_complete = buf_complete + len_complete;
301 memcpy( buf_complete, data.p, data_len );
302 if( par_len == 0 )
303 {
304 /* mbedtls_asn1_write_algorithm_identifier() wrote a NULL */
305 expected_params_tag = 0x05;
306 expected_params_len = 0;
307 }
308 else if( par_len >= 2 && par_len < 2 + 128 )
309 {
310 /* Write an OCTET STRING with a short length encoding */
311 expected_params_tag = buf_complete[data_len] = 0x04;
312 expected_params_len = par_len - 2;
313 buf_complete[data_len + 1] = (unsigned char) expected_params_len;
314 }
315 else if( par_len >= 4 + 128 && par_len < 3 + 256 * 256 )
316 {
317 /* Write an OCTET STRING with a two-byte length encoding */
318 expected_params_tag = buf_complete[data_len] = 0x04;
319 expected_params_len = par_len - 4;
320 buf_complete[data_len + 1] = 0x82;
321 buf_complete[data_len + 2] = (unsigned char) ( expected_params_len >> 8 );
322 buf_complete[data_len + 3] = (unsigned char) ( expected_params_len );
323 }
324 else
325 {
326 TEST_ASSERT( ! "Bad test data: invalid length of ASN.1 element" );
327 }
328 unsigned char *p = buf_complete;
329 TEST_EQUAL( mbedtls_asn1_get_alg( &p, end_complete,
330 &alg, &params ), 0 );
331 TEST_EQUAL( alg.tag, MBEDTLS_ASN1_OID );
332 ASSERT_COMPARE( alg.p, alg.len, oid->x, oid->len );
333 TEST_EQUAL( params.tag, expected_params_tag );
334 TEST_EQUAL( params.len, expected_params_len );
335 mbedtls_free( buf_complete );
336 buf_complete = NULL;
337 }
338#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskine9311cf52019-03-01 20:05:05 +0100339 }
340
341exit:
342 mbedtls_free( data.output );
Gilles Peskine61940532022-06-15 21:17:25 +0200343#if defined(MBEDTLS_ASN1_PARSE_C)
344 mbedtls_free( buf_complete );
345#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskine9311cf52019-03-01 20:05:05 +0100346}
347/* END_CASE */
348
Gilles Peskine91d8d022019-03-01 19:34:24 +0100349/* BEGIN_CASE depends_on:MBEDTLS_ASN1_PARSE_C */
Azim Khan5fcca462018-06-29 11:05:32 +0100350void mbedtls_asn1_write_len( int len, data_t * asn1, int buf_len,
Azim Khand30ca132017-06-09 04:32:58 +0100351 int result )
Paul Bakkere325db92016-07-14 10:27:36 +0100352{
353 int ret;
354 unsigned char buf[150];
Paul Bakkere325db92016-07-14 10:27:36 +0100355 unsigned char *p;
Azim Khan90791702017-05-30 00:57:11 +0100356 size_t i;
357 size_t read_len;
Paul Bakkere325db92016-07-14 10:27:36 +0100358
359 memset( buf, GUARD_VAL, sizeof( buf ) );
Paul Bakkere325db92016-07-14 10:27:36 +0100360
Paul Bakker58bfb832016-07-14 11:02:31 +0100361 p = buf + GUARD_LEN + buf_len;
Paul Bakkere325db92016-07-14 10:27:36 +0100362
363 ret = mbedtls_asn1_write_len( &p, buf + GUARD_LEN, (size_t) len );
364
365 TEST_ASSERT( ret == result );
366
367 /* Check for buffer overwrite on both sides */
368 for( i = 0; i < GUARD_LEN; i++ )
369 {
370 TEST_ASSERT( buf[i] == GUARD_VAL );
Paul Bakker58bfb832016-07-14 11:02:31 +0100371 TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
Paul Bakkere325db92016-07-14 10:27:36 +0100372 }
373
374 if( result >= 0 )
375 {
Azim Khand30ca132017-06-09 04:32:58 +0100376 TEST_ASSERT( p + asn1->len == buf + GUARD_LEN + buf_len );
Paul Bakkere325db92016-07-14 10:27:36 +0100377
Azim Khand30ca132017-06-09 04:32:58 +0100378 TEST_ASSERT( memcmp( p, asn1->x, asn1->len ) == 0 );
Paul Bakker5e8b77c2016-07-14 11:14:54 +0100379
380 /* Read back with mbedtls_asn1_get_len() to check */
381 ret = mbedtls_asn1_get_len( &p, buf + GUARD_LEN + buf_len, &read_len );
382
383 if( len == 0 )
384 {
385 TEST_ASSERT( ret == 0 );
386 }
387 else
388 {
389 /* Return will be MBEDTLS_ERR_ASN1_OUT_OF_DATA because the rest of
390 * the buffer is missing
391 */
392 TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA );
393 }
394 TEST_ASSERT( read_len == (size_t) len );
395 TEST_ASSERT( p == buf + GUARD_LEN + buf_len );
Paul Bakkere325db92016-07-14 10:27:36 +0100396 }
397}
398/* END_CASE */
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100399
400/* BEGIN_CASE */
401void test_asn1_write_bitstrings( data_t *bitstring, int bits,
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100402 data_t *expected, int is_named )
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100403{
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100404 generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 };
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100405 int ret;
Mateusz Starzyk4e300d02021-01-27 15:37:12 +0100406 int ( *func )( unsigned char **p, const unsigned char *start,
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100407 const unsigned char *buf, size_t bits ) =
408 ( is_named ? mbedtls_asn1_write_named_bitstring :
409 mbedtls_asn1_write_bitstring );
Gilles Peskine61940532022-06-15 21:17:25 +0200410#if defined(MBEDTLS_ASN1_PARSE_C)
411 unsigned char *masked_bitstring = NULL;
412#endif /* MBEDTLS_ASN1_PARSE_C */
413
414 /* The API expects `bitstring->x` to contain `bits` bits. */
415 size_t byte_length = ( bits + 7 ) / 8;
416 TEST_ASSERT( bitstring->len >= byte_length );
417
418#if defined(MBEDTLS_ASN1_PARSE_C)
419 ASSERT_ALLOC( masked_bitstring, byte_length );
420 memcpy( masked_bitstring, bitstring->x, byte_length );
421 if( bits % 8 != 0 )
422 masked_bitstring[byte_length - 1] &= ~( 0xff >> ( bits % 8 ) );
423 size_t value_bits = bits;
424 if( is_named )
425 {
426 /* In a named bit string, all trailing 0 bits are removed. */
427 while( byte_length > 0 && masked_bitstring[byte_length - 1] == 0 )
428 --byte_length;
429 value_bits = 8 * byte_length;
430 if( byte_length > 0 )
431 {
432 unsigned char last_byte = masked_bitstring[byte_length - 1];
433 for( unsigned b = 1; b < 0xff && ( last_byte & b ) == 0; b <<= 1 )
434 --value_bits;
435 }
436 }
437#endif /* MBEDTLS_ASN1_PARSE_C */
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100438
Gilles Peskine2c2730a2022-06-10 20:15:44 +0200439 for( data.size = 0; data.size <= expected->len + 1; data.size++ )
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100440 {
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100441 if( ! generic_write_start_step( &data ) )
442 goto exit;
443 ret = ( *func )( &data.p, data.start, bitstring->x, bits );
444 if( ! generic_write_finish_step( &data, expected, ret ) )
445 goto exit;
Gilles Peskine61940532022-06-15 21:17:25 +0200446#if defined(MBEDTLS_ASN1_PARSE_C)
447 if( ret >= 0 )
448 {
449 mbedtls_asn1_bitstring read = {0, 0, NULL};
450 TEST_EQUAL( mbedtls_asn1_get_bitstring( &data.p, data.end,
451 &read ), 0 );
452 ASSERT_COMPARE( read.p, read.len,
453 masked_bitstring, byte_length );
454 TEST_EQUAL( read.unused_bits, 8 * byte_length - value_bits );
455 }
456#endif /* MBEDTLS_ASN1_PARSE_C */
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100457 }
458
Gilles Peskine3f37dca2019-03-01 19:30:20 +0100459exit:
460 mbedtls_free( data.output );
Gilles Peskine61940532022-06-15 21:17:25 +0200461#if defined(MBEDTLS_ASN1_PARSE_C)
462 mbedtls_free( masked_bitstring );
463#endif /* MBEDTLS_ASN1_PARSE_C */
Andres Amaya Garcia5d261632018-09-26 10:51:16 +0100464}
465/* END_CASE */
Gilles Peskinea9023032019-03-01 23:26:05 +0100466
467/* BEGIN_CASE */
468void store_named_data_find( data_t *oid0, data_t *oid1,
469 data_t *oid2, data_t *oid3,
470 data_t *needle, int from, int position )
471{
472 data_t *oid[4] = {oid0, oid1, oid2, oid3};
473 mbedtls_asn1_named_data nd[] ={
474 { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
475 { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
476 { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
477 { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 },
478 };
479 mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
480 size_t i;
481 mbedtls_asn1_named_data *head = NULL;
482 mbedtls_asn1_named_data *found = NULL;
483
484 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
485 pointers[i] = &nd[i];
486 pointers[ARRAY_LENGTH( nd )] = NULL;
487 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
488 {
489 ASSERT_ALLOC( nd[i].oid.p, oid[i]->len );
490 memcpy( nd[i].oid.p, oid[i]->x, oid[i]->len );
491 nd[i].oid.len = oid[i]->len;
492 nd[i].next = pointers[i+1];
493 }
494
495 head = pointers[from];
496 found = mbedtls_asn1_store_named_data( &head,
497 (const char *) needle->x,
498 needle->len,
499 NULL, 0 );
500
501 /* In any case, the existing list structure must be unchanged. */
502 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
503 TEST_ASSERT( nd[i].next == pointers[i+1] );
504
505 if( position >= 0 )
506 {
507 /* position should have been found and modified. */
508 TEST_ASSERT( head == pointers[from] );
509 TEST_ASSERT( found == pointers[position] );
510 }
511 else
512 {
513 /* A new entry should have been created. */
514 TEST_ASSERT( found == head );
515 TEST_ASSERT( head->next == pointers[from] );
516 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
517 TEST_ASSERT( found != &nd[i] );
518 }
519
520exit:
521 if( found != NULL && found == head && found != pointers[from] )
522 {
523 mbedtls_free( found->oid.p );
524 mbedtls_free( found );
525 }
526 for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
527 mbedtls_free( nd[i].oid.p );
528}
529/* END_CASE */
530
531/* BEGIN_CASE */
532void store_named_data_val_found( int old_len, int new_len )
533{
534 mbedtls_asn1_named_data nd =
535 { {0x06, 3, (unsigned char *) "OID"}, {0, 0, NULL}, NULL, 0 };
536 mbedtls_asn1_named_data *head = &nd;
537 mbedtls_asn1_named_data *found = NULL;
538 unsigned char *old_val = NULL;
539 unsigned char *new_val = (unsigned char *) "new value";
540
541 if( old_len != 0 )
542 {
543 ASSERT_ALLOC( nd.val.p, (size_t) old_len );
544 old_val = nd.val.p;
545 nd.val.len = old_len;
546 memset( old_val, 'x', old_len );
547 }
548 if( new_len <= 0 )
549 {
550 new_len = - new_len;
551 new_val = NULL;
552 }
553
554 found = mbedtls_asn1_store_named_data( &head, "OID", 3,
555 new_val, new_len );
556 TEST_ASSERT( head == &nd );
557 TEST_ASSERT( found == head );
558
559 if( new_val != NULL)
560 ASSERT_COMPARE( found->val.p, found->val.len,
561 new_val, (size_t) new_len );
562 if( new_len == 0)
563 TEST_ASSERT( found->val.p == NULL );
564 else if( new_len == old_len )
565 TEST_ASSERT( found->val.p == old_val );
566 else
567 TEST_ASSERT( found->val.p != old_val );
568
569exit:
570 mbedtls_free( nd.val.p );
571}
572/* END_CASE */
573
574/* BEGIN_CASE */
Werner Lewise59a5312022-05-04 09:44:50 +0100575void store_named_data_val_new( int new_len, int set_new_val )
Gilles Peskinea9023032019-03-01 23:26:05 +0100576{
577 mbedtls_asn1_named_data *head = NULL;
578 mbedtls_asn1_named_data *found = NULL;
579 const unsigned char *oid = (unsigned char *) "OID";
580 size_t oid_len = strlen( (const char *) oid );
581 const unsigned char *new_val = (unsigned char *) "new value";
582
Werner Lewise59a5312022-05-04 09:44:50 +0100583 if( set_new_val == 0 )
Gilles Peskinea9023032019-03-01 23:26:05 +0100584 new_val = NULL;
Gilles Peskinea9023032019-03-01 23:26:05 +0100585
586 found = mbedtls_asn1_store_named_data( &head,
587 (const char *) oid, oid_len,
588 new_val, (size_t) new_len );
589 TEST_ASSERT( found != NULL );
590 TEST_ASSERT( found == head );
591 TEST_ASSERT( found->oid.p != oid );
592 ASSERT_COMPARE( found->oid.p, found->oid.len, oid, oid_len );
593 if( new_len == 0 )
594 TEST_ASSERT( found->val.p == NULL );
595 else if( new_val == NULL )
596 TEST_ASSERT( found->val.p != NULL );
597 else
598 {
599 TEST_ASSERT( found->val.p != new_val );
600 ASSERT_COMPARE( found->val.p, found->val.len,
601 new_val, (size_t) new_len );
602 }
603
604exit:
605 if( found != NULL )
606 {
607 mbedtls_free( found->oid.p );
608 mbedtls_free( found->val.p );
609 }
610 mbedtls_free( found );
611}
612/* END_CASE */