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