test_suite_asn1parse.function 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. /* BEGIN_HEADER */
  2. #include <errno.h>
  3. #include <stdlib.h>
  4. #include <limits.h>
  5. #include "mbedtls/bignum.h"
  6. #include "mbedtls/asn1.h"
  7. #if defined(MBEDTLS_ASN1_WRITE_C)
  8. #include "mbedtls/asn1write.h"
  9. #endif
  10. /* Used internally to report an error that indicates a bug in a parsing function. */
  11. #define ERR_PARSE_INCONSISTENCY INT_MAX
  12. /* Use this magic value in some tests to indicate that the expected result
  13. * should not be checked. */
  14. #define UNPREDICTABLE_RESULT 0x5552
  15. static int nested_parse( unsigned char **const p,
  16. const unsigned char *const end )
  17. {
  18. int ret;
  19. size_t len = 0;
  20. size_t len2 = 0;
  21. unsigned char *const start = *p;
  22. unsigned char *content_start;
  23. unsigned char tag;
  24. /* First get the length, skipping over the tag. */
  25. content_start = start + 1;
  26. ret = mbedtls_asn1_get_len( &content_start, end, &len );
  27. TEST_ASSERT( content_start <= end );
  28. if( ret != 0 )
  29. return( ret );
  30. /* Since we have a valid element start (tag and length), retrieve and
  31. * check the tag. */
  32. tag = start[0];
  33. TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len2, tag ^ 1 ),
  34. MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  35. *p = start;
  36. TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len2, tag ), 0 );
  37. TEST_EQUAL( len, len2 );
  38. TEST_ASSERT( *p == content_start );
  39. *p = content_start;
  40. switch( tag & 0x1f )
  41. {
  42. case MBEDTLS_ASN1_BOOLEAN:
  43. {
  44. int val = -257;
  45. *p = start;
  46. ret = mbedtls_asn1_get_bool( p, end, &val );
  47. if( ret == 0 )
  48. TEST_ASSERT( val == 0 || val == 1 );
  49. break;
  50. }
  51. case MBEDTLS_ASN1_INTEGER:
  52. {
  53. #if defined(MBEDTLS_BIGNUM_C)
  54. mbedtls_mpi mpi;
  55. mbedtls_mpi_init( &mpi );
  56. *p = start;
  57. ret = mbedtls_asn1_get_mpi( p, end, &mpi );
  58. mbedtls_mpi_free( &mpi );
  59. #else
  60. *p = start + 1;
  61. ret = mbedtls_asn1_get_len( p, end, &len );
  62. *p += len;
  63. #endif
  64. /* If we're sure that the number fits in an int, also
  65. * call mbedtls_asn1_get_int(). */
  66. if( ret == 0 && len < sizeof( int ) )
  67. {
  68. int val = -257;
  69. unsigned char *q = start;
  70. ret = mbedtls_asn1_get_int( &q, end, &val );
  71. TEST_ASSERT( *p == q );
  72. }
  73. break;
  74. }
  75. case MBEDTLS_ASN1_BIT_STRING:
  76. {
  77. mbedtls_asn1_bitstring bs;
  78. *p = start;
  79. ret = mbedtls_asn1_get_bitstring( p, end, &bs );
  80. break;
  81. }
  82. case MBEDTLS_ASN1_SEQUENCE:
  83. {
  84. while( *p <= end && *p < content_start + len && ret == 0 )
  85. ret = nested_parse( p, content_start + len );
  86. break;
  87. }
  88. case MBEDTLS_ASN1_OCTET_STRING:
  89. case MBEDTLS_ASN1_NULL:
  90. case MBEDTLS_ASN1_OID:
  91. case MBEDTLS_ASN1_UTF8_STRING:
  92. case MBEDTLS_ASN1_SET:
  93. case MBEDTLS_ASN1_PRINTABLE_STRING:
  94. case MBEDTLS_ASN1_T61_STRING:
  95. case MBEDTLS_ASN1_IA5_STRING:
  96. case MBEDTLS_ASN1_UTC_TIME:
  97. case MBEDTLS_ASN1_GENERALIZED_TIME:
  98. case MBEDTLS_ASN1_UNIVERSAL_STRING:
  99. case MBEDTLS_ASN1_BMP_STRING:
  100. default:
  101. /* No further testing implemented for this tag. */
  102. *p += len;
  103. return( 0 );
  104. }
  105. TEST_ASSERT( *p <= end );
  106. return( ret );
  107. exit:
  108. return( ERR_PARSE_INCONSISTENCY );
  109. }
  110. int get_len_step( const data_t *input, size_t buffer_size,
  111. size_t actual_length )
  112. {
  113. unsigned char *buf = NULL;
  114. unsigned char *p = NULL;
  115. unsigned char *end;
  116. size_t parsed_length;
  117. int ret;
  118. mbedtls_test_set_step( buffer_size );
  119. /* Allocate a new buffer of exactly the length to parse each time.
  120. * This gives memory sanitizers a chance to catch buffer overreads. */
  121. if( buffer_size == 0 )
  122. {
  123. ASSERT_ALLOC( buf, 1 );
  124. end = buf + 1;
  125. p = end;
  126. }
  127. else
  128. {
  129. ASSERT_ALLOC_WEAK( buf, buffer_size );
  130. if( buffer_size > input->len )
  131. {
  132. memcpy( buf, input->x, input->len );
  133. memset( buf + input->len, 'A', buffer_size - input->len );
  134. }
  135. else
  136. {
  137. memcpy( buf, input->x, buffer_size );
  138. }
  139. p = buf;
  140. end = buf + buffer_size;
  141. }
  142. ret = mbedtls_asn1_get_len( &p, end, &parsed_length );
  143. if( buffer_size >= input->len + actual_length )
  144. {
  145. TEST_EQUAL( ret, 0 );
  146. TEST_ASSERT( p == buf + input->len );
  147. TEST_EQUAL( parsed_length, actual_length );
  148. }
  149. else
  150. {
  151. TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_OUT_OF_DATA );
  152. }
  153. mbedtls_free( buf );
  154. return( 1 );
  155. exit:
  156. mbedtls_free( buf );
  157. return( 0 );
  158. }
  159. typedef struct
  160. {
  161. const unsigned char *input_start;
  162. const char *description;
  163. } traverse_state_t;
  164. /* Value returned by traverse_callback if description runs out. */
  165. #define RET_TRAVERSE_STOP 1
  166. /* Value returned by traverse_callback if description has an invalid format
  167. * (see traverse_sequence_of). */
  168. #define RET_TRAVERSE_ERROR 2
  169. static int traverse_callback( void *ctx, int tag,
  170. unsigned char *content, size_t len )
  171. {
  172. traverse_state_t *state = ctx;
  173. size_t offset;
  174. const char *rest = state->description;
  175. unsigned long n;
  176. TEST_ASSERT( content > state->input_start );
  177. offset = content - state->input_start;
  178. mbedtls_test_set_step( offset );
  179. if( *rest == 0 )
  180. return( RET_TRAVERSE_STOP );
  181. n = strtoul( rest, (char **) &rest, 0 );
  182. TEST_EQUAL( n, offset );
  183. TEST_EQUAL( *rest, ',' );
  184. ++rest;
  185. n = strtoul( rest, (char **) &rest, 0 );
  186. TEST_EQUAL( n, (unsigned) tag );
  187. TEST_EQUAL( *rest, ',' );
  188. ++rest;
  189. n = strtoul( rest, (char **) &rest, 0 );
  190. TEST_EQUAL( n, len );
  191. if( *rest == ',' )
  192. ++rest;
  193. state->description = rest;
  194. return( 0 );
  195. exit:
  196. return( RET_TRAVERSE_ERROR );
  197. }
  198. /* END_HEADER */
  199. /* BEGIN_DEPENDENCIES
  200. * depends_on:MBEDTLS_ASN1_PARSE_C
  201. * END_DEPENDENCIES
  202. */
  203. /* BEGIN_CASE */
  204. void parse_prefixes( const data_t *input,
  205. int full_result,
  206. int overfull_result )
  207. {
  208. /* full_result: expected result from parsing the given string. */
  209. /* overfull_result: expected_result from parsing the given string plus
  210. * some trailing garbage. This may be UNPREDICTABLE_RESULT to accept
  211. * any result: use this for invalid inputs that may or may not become
  212. * valid depending on what the trailing garbage is. */
  213. unsigned char *buf = NULL;
  214. unsigned char *p = NULL;
  215. size_t buffer_size;
  216. int ret;
  217. /* Test every prefix of the input, except the empty string.
  218. * The first byte of the string is the tag. Without a tag byte,
  219. * we wouldn't know what to parse the input as.
  220. * Also test the input followed by an extra byte.
  221. */
  222. for( buffer_size = 1; buffer_size <= input->len + 1; buffer_size++ )
  223. {
  224. mbedtls_test_set_step( buffer_size );
  225. /* Allocate a new buffer of exactly the length to parse each time.
  226. * This gives memory sanitizers a chance to catch buffer overreads. */
  227. ASSERT_ALLOC( buf, buffer_size );
  228. memcpy( buf, input->x, buffer_size );
  229. p = buf;
  230. ret = nested_parse( &p, buf + buffer_size );
  231. if( ret == ERR_PARSE_INCONSISTENCY )
  232. goto exit;
  233. if( buffer_size < input->len )
  234. {
  235. TEST_EQUAL( ret, MBEDTLS_ERR_ASN1_OUT_OF_DATA );
  236. }
  237. else if( buffer_size == input->len )
  238. {
  239. TEST_EQUAL( ret, full_result );
  240. }
  241. else /* ( buffer_size > input->len ) */
  242. {
  243. if( overfull_result != UNPREDICTABLE_RESULT )
  244. TEST_EQUAL( ret, overfull_result );
  245. }
  246. if( ret == 0 )
  247. TEST_ASSERT( p == buf + input->len );
  248. mbedtls_free( buf );
  249. buf = NULL;
  250. }
  251. exit:
  252. mbedtls_free( buf );
  253. }
  254. /* END_CASE */
  255. /* BEGIN_CASE */
  256. void get_len( const data_t *input, int actual_length_arg )
  257. {
  258. size_t actual_length = actual_length_arg;
  259. size_t buffer_size;
  260. /* Test prefixes of a buffer containing the given length string
  261. * followed by `actual_length` bytes of payload. To save a bit of
  262. * time, we skip some "boring" prefixes: we don't test prefixes where
  263. * the payload is truncated more than one byte away from either end,
  264. * and we only test the empty string on a 1-byte input.
  265. */
  266. for( buffer_size = 1; buffer_size <= input->len + 1; buffer_size++ )
  267. {
  268. if( ! get_len_step( input, buffer_size, actual_length ) )
  269. goto exit;
  270. }
  271. if( ! get_len_step( input, input->len + actual_length - 1, actual_length ) )
  272. goto exit;
  273. if( ! get_len_step( input, input->len + actual_length, actual_length ) )
  274. goto exit;
  275. }
  276. /* END_CASE */
  277. /* BEGIN_CASE */
  278. void get_boolean( const data_t *input,
  279. int expected_value, int expected_result )
  280. {
  281. unsigned char *p = input->x;
  282. int val;
  283. int ret;
  284. ret = mbedtls_asn1_get_bool( &p, input->x + input->len, &val );
  285. TEST_EQUAL( ret, expected_result );
  286. if( expected_result == 0 )
  287. {
  288. TEST_EQUAL( val, expected_value );
  289. TEST_ASSERT( p == input->x + input->len );
  290. }
  291. }
  292. /* END_CASE */
  293. /* BEGIN_CASE */
  294. void empty_integer( const data_t *input )
  295. {
  296. unsigned char *p;
  297. #if defined(MBEDTLS_BIGNUM_C)
  298. mbedtls_mpi actual_mpi;
  299. #endif
  300. int val;
  301. #if defined(MBEDTLS_BIGNUM_C)
  302. mbedtls_mpi_init( & actual_mpi );
  303. #endif
  304. /* An INTEGER with no content is not valid. */
  305. p = input->x;
  306. TEST_EQUAL( mbedtls_asn1_get_int( &p, input->x + input->len, &val ),
  307. MBEDTLS_ERR_ASN1_INVALID_LENGTH );
  308. #if defined(MBEDTLS_BIGNUM_C)
  309. /* INTEGERs are sometimes abused as bitstrings, so the library accepts
  310. * an INTEGER with empty content and gives it the value 0. */
  311. p = input->x;
  312. TEST_EQUAL( mbedtls_asn1_get_mpi( &p, input->x + input->len, &actual_mpi ),
  313. 0 );
  314. TEST_EQUAL( mbedtls_mpi_cmp_int( &actual_mpi, 0 ), 0 );
  315. #endif
  316. exit:
  317. #if defined(MBEDTLS_BIGNUM_C)
  318. mbedtls_mpi_free( &actual_mpi );
  319. #endif
  320. /*empty cleanup in some configurations*/ ;
  321. }
  322. /* END_CASE */
  323. /* BEGIN_CASE */
  324. void get_integer( const data_t *input,
  325. const char *expected_hex, int expected_result )
  326. {
  327. unsigned char *p;
  328. #if defined(MBEDTLS_BIGNUM_C)
  329. mbedtls_mpi expected_mpi;
  330. mbedtls_mpi actual_mpi;
  331. mbedtls_mpi complement;
  332. int expected_result_for_mpi = expected_result;
  333. #endif
  334. long expected_value;
  335. int expected_result_for_int = expected_result;
  336. int val;
  337. int ret;
  338. #if defined(MBEDTLS_BIGNUM_C)
  339. mbedtls_mpi_init( &expected_mpi );
  340. mbedtls_mpi_init( &actual_mpi );
  341. mbedtls_mpi_init( &complement );
  342. #endif
  343. errno = 0;
  344. expected_value = strtol( expected_hex, NULL, 16 );
  345. if( expected_result == 0 &&
  346. ( errno == ERANGE
  347. #if LONG_MAX > INT_MAX
  348. || expected_value > INT_MAX || expected_value < INT_MIN
  349. #endif
  350. ) )
  351. {
  352. /* The library returns the dubious error code INVALID_LENGTH
  353. * for integers that are out of range. */
  354. expected_result_for_int = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  355. }
  356. if( expected_result == 0 && expected_value < 0 )
  357. {
  358. /* The library does not support negative INTEGERs and
  359. * returns the dubious error code INVALID_LENGTH.
  360. * Test that we preserve the historical behavior. If we
  361. * decide to change the behavior, we'll also change this test. */
  362. expected_result_for_int = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  363. }
  364. p = input->x;
  365. ret = mbedtls_asn1_get_int( &p, input->x + input->len, &val );
  366. TEST_EQUAL( ret, expected_result_for_int );
  367. if( ret == 0 )
  368. {
  369. TEST_EQUAL( val, expected_value );
  370. TEST_ASSERT( p == input->x + input->len );
  371. }
  372. #if defined(MBEDTLS_BIGNUM_C)
  373. ret = mbedtls_test_read_mpi( &expected_mpi, 16, expected_hex );
  374. TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
  375. if( ret == MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
  376. {
  377. /* The data overflows the maximum MPI size. */
  378. expected_result_for_mpi = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  379. }
  380. p = input->x;
  381. ret = mbedtls_asn1_get_mpi( &p, input->x + input->len, &actual_mpi );
  382. TEST_EQUAL( ret, expected_result_for_mpi );
  383. if( ret == 0 )
  384. {
  385. if( expected_value >= 0 )
  386. {
  387. TEST_ASSERT( mbedtls_mpi_cmp_mpi( &actual_mpi,
  388. &expected_mpi ) == 0 );
  389. }
  390. else
  391. {
  392. /* The library ignores the sign bit in ASN.1 INTEGERs
  393. * (which makes sense insofar as INTEGERs are sometimes
  394. * abused as bit strings), so the result of parsing them
  395. * is a positive integer such that expected_mpi +
  396. * actual_mpi = 2^n where n is the length of the content
  397. * of the INTEGER. (Leading ff octets don't matter for the
  398. * expected value, but they matter for the actual value.)
  399. * Test that we don't change from this behavior. If we
  400. * decide to fix the library to change the behavior on
  401. * negative INTEGERs, we'll fix this test code. */
  402. unsigned char *q = input->x + 1;
  403. size_t len;
  404. TEST_ASSERT( mbedtls_asn1_get_len( &q, input->x + input->len,
  405. &len ) == 0 );
  406. TEST_ASSERT( mbedtls_mpi_lset( &complement, 1 ) == 0 );
  407. TEST_ASSERT( mbedtls_mpi_shift_l( &complement, len * 8 ) == 0 );
  408. TEST_ASSERT( mbedtls_mpi_add_mpi( &complement, &complement,
  409. &expected_mpi ) == 0 );
  410. TEST_ASSERT( mbedtls_mpi_cmp_mpi( &complement,
  411. &actual_mpi ) == 0 );
  412. }
  413. TEST_ASSERT( p == input->x + input->len );
  414. }
  415. #endif
  416. exit:
  417. #if defined(MBEDTLS_BIGNUM_C)
  418. mbedtls_mpi_free( &expected_mpi );
  419. mbedtls_mpi_free( &actual_mpi );
  420. mbedtls_mpi_free( &complement );
  421. #endif
  422. /*empty cleanup in some configurations*/ ;
  423. }
  424. /* END_CASE */
  425. /* BEGIN_CASE */
  426. void get_enum( const data_t *input,
  427. const char *expected_hex, int expected_result )
  428. {
  429. unsigned char *p;
  430. long expected_value;
  431. int expected_result_for_enum = expected_result;
  432. int val;
  433. int ret;
  434. errno = 0;
  435. expected_value = strtol( expected_hex, NULL, 16 );
  436. if( expected_result == 0 &&
  437. ( errno == ERANGE
  438. #if LONG_MAX > INT_MAX
  439. || expected_value > INT_MAX || expected_value < INT_MIN
  440. #endif
  441. ) )
  442. {
  443. /* The library returns the dubious error code INVALID_LENGTH
  444. * for integers that are out of range. */
  445. expected_result_for_enum = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  446. }
  447. if( expected_result == 0 && expected_value < 0 )
  448. {
  449. /* The library does not support negative INTEGERs and
  450. * returns the dubious error code INVALID_LENGTH.
  451. * Test that we preserve the historical behavior. If we
  452. * decide to change the behavior, we'll also change this test. */
  453. expected_result_for_enum = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  454. }
  455. p = input->x;
  456. ret = mbedtls_asn1_get_enum( &p, input->x + input->len, &val );
  457. TEST_EQUAL( ret, expected_result_for_enum );
  458. if( ret == 0 )
  459. {
  460. TEST_EQUAL( val, expected_value );
  461. TEST_ASSERT( p == input->x + input->len );
  462. }
  463. }
  464. /* END_CASE */
  465. /* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */
  466. void get_mpi_too_large( )
  467. {
  468. unsigned char *buf = NULL;
  469. unsigned char *p;
  470. mbedtls_mpi actual_mpi;
  471. size_t too_many_octets =
  472. MBEDTLS_MPI_MAX_LIMBS * sizeof(mbedtls_mpi_uint) + 1;
  473. size_t size = too_many_octets + 6;
  474. mbedtls_mpi_init( &actual_mpi );
  475. ASSERT_ALLOC( buf, size );
  476. buf[0] = 0x02; /* tag: INTEGER */
  477. buf[1] = 0x84; /* 4-octet length */
  478. buf[2] = ( too_many_octets >> 24 ) & 0xff;
  479. buf[3] = ( too_many_octets >> 16 ) & 0xff;
  480. buf[4] = ( too_many_octets >> 8 ) & 0xff;
  481. buf[5] = too_many_octets & 0xff;
  482. buf[6] = 0x01; /* most significant octet */
  483. p = buf;
  484. TEST_EQUAL( mbedtls_asn1_get_mpi( &p, buf + size, &actual_mpi ),
  485. MBEDTLS_ERR_MPI_ALLOC_FAILED );
  486. exit:
  487. mbedtls_mpi_free( &actual_mpi );
  488. mbedtls_free( buf );
  489. }
  490. /* END_CASE */
  491. /* BEGIN_CASE */
  492. void get_bitstring( const data_t *input,
  493. int expected_length, int expected_unused_bits,
  494. int expected_result, int expected_result_null )
  495. {
  496. mbedtls_asn1_bitstring bs = { 0xdead, 0x21, NULL };
  497. unsigned char *p = input->x;
  498. TEST_EQUAL( mbedtls_asn1_get_bitstring( &p, input->x + input->len, &bs ),
  499. expected_result );
  500. if( expected_result == 0 )
  501. {
  502. TEST_EQUAL( bs.len, (size_t) expected_length );
  503. TEST_EQUAL( bs.unused_bits, expected_unused_bits );
  504. TEST_ASSERT( bs.p != NULL );
  505. TEST_EQUAL( bs.p - input->x + bs.len, input->len );
  506. TEST_ASSERT( p == input->x + input->len );
  507. }
  508. p = input->x;
  509. TEST_EQUAL( mbedtls_asn1_get_bitstring_null( &p, input->x + input->len,
  510. &bs.len ),
  511. expected_result_null );
  512. if( expected_result_null == 0 )
  513. {
  514. TEST_EQUAL( bs.len, (size_t) expected_length );
  515. if( expected_result == 0 )
  516. TEST_ASSERT( p == input->x + input->len - bs.len );
  517. }
  518. }
  519. /* END_CASE */
  520. /* BEGIN_CASE */
  521. void get_sequence_of( const data_t *input, int tag,
  522. const char *description,
  523. int expected_result )
  524. {
  525. /* The description string is a comma-separated list of integers.
  526. * For each element in the SEQUENCE in input, description contains
  527. * two integers: the offset of the element (offset from the start
  528. * of input to the tag of the element) and the length of the
  529. * element's contents.
  530. * "offset1,length1,..." */
  531. mbedtls_asn1_sequence head = { { 0, 0, NULL }, NULL };
  532. mbedtls_asn1_sequence *cur;
  533. unsigned char *p = input->x;
  534. const char *rest = description;
  535. unsigned long n;
  536. unsigned int step = 0;
  537. TEST_EQUAL( mbedtls_asn1_get_sequence_of( &p, input->x + input->len,
  538. &head, tag ),
  539. expected_result );
  540. if( expected_result == 0 )
  541. {
  542. TEST_ASSERT( p == input->x + input->len );
  543. if( ! *rest )
  544. {
  545. TEST_EQUAL( head.buf.tag, 0 );
  546. TEST_ASSERT( head.buf.p == NULL );
  547. TEST_EQUAL( head.buf.len, 0 );
  548. TEST_ASSERT( head.next == NULL );
  549. }
  550. else
  551. {
  552. cur = &head;
  553. while( *rest )
  554. {
  555. mbedtls_test_set_step( step );
  556. TEST_ASSERT( cur != NULL );
  557. TEST_EQUAL( cur->buf.tag, tag );
  558. n = strtoul( rest, (char **) &rest, 0 );
  559. TEST_EQUAL( n, (size_t)( cur->buf.p - input->x ) );
  560. ++rest;
  561. n = strtoul( rest, (char **) &rest, 0 );
  562. TEST_EQUAL( n, cur->buf.len );
  563. if( *rest )
  564. ++rest;
  565. cur = cur->next;
  566. ++step;
  567. }
  568. TEST_ASSERT( cur == NULL );
  569. }
  570. }
  571. exit:
  572. mbedtls_asn1_sequence_free( head.next );
  573. }
  574. /* END_CASE */
  575. /* BEGIN_CASE */
  576. void traverse_sequence_of( const data_t *input,
  577. int tag_must_mask, int tag_must_val,
  578. int tag_may_mask, int tag_may_val,
  579. const char *description,
  580. int expected_result )
  581. {
  582. /* The description string is a comma-separated list of integers.
  583. * For each element in the SEQUENCE in input, description contains
  584. * three integers: the offset of the element's content (offset from
  585. * the start of input to the content of the element), the element's tag,
  586. * and the length of the element's contents.
  587. * "offset1,tag1,length1,..." */
  588. unsigned char *p = input->x;
  589. traverse_state_t traverse_state = {input->x, description};
  590. int ret;
  591. ret = mbedtls_asn1_traverse_sequence_of( &p, input->x + input->len,
  592. (uint8_t) tag_must_mask, (uint8_t) tag_must_val,
  593. (uint8_t) tag_may_mask, (uint8_t) tag_may_val,
  594. traverse_callback, &traverse_state );
  595. if( ret == RET_TRAVERSE_ERROR )
  596. goto exit;
  597. TEST_EQUAL( ret, expected_result );
  598. TEST_EQUAL( *traverse_state.description, 0 );
  599. }
  600. /* END_CASE */
  601. /* BEGIN_CASE */
  602. void get_alg( const data_t *input,
  603. int oid_offset, int oid_length,
  604. int params_tag, int params_offset, int params_length,
  605. int total_length,
  606. int expected_result )
  607. {
  608. mbedtls_asn1_buf oid = { -1, 0, NULL };
  609. mbedtls_asn1_buf params = { -1, 0, NULL };
  610. unsigned char *p = input->x;
  611. int ret;
  612. TEST_EQUAL( mbedtls_asn1_get_alg( &p, input->x + input->len,
  613. &oid, &params ),
  614. expected_result );
  615. if( expected_result == 0 )
  616. {
  617. TEST_EQUAL( oid.tag, MBEDTLS_ASN1_OID );
  618. TEST_EQUAL( oid.p - input->x, oid_offset );
  619. TEST_EQUAL( oid.len, (size_t) oid_length );
  620. TEST_EQUAL( params.tag, params_tag );
  621. if( params_offset != 0 )
  622. TEST_EQUAL( params.p - input->x, params_offset );
  623. else
  624. TEST_ASSERT( params.p == NULL );
  625. TEST_EQUAL( params.len, (size_t) params_length );
  626. TEST_EQUAL( p - input->x, total_length );
  627. }
  628. ret = mbedtls_asn1_get_alg_null( &p, input->x + input->len, &oid );
  629. if( expected_result == 0 && params_offset == 0 )
  630. {
  631. TEST_EQUAL( oid.tag, MBEDTLS_ASN1_OID );
  632. TEST_EQUAL( oid.p - input->x, oid_offset );
  633. TEST_EQUAL( oid.len, (size_t) oid_length );
  634. TEST_EQUAL( p - input->x, total_length );
  635. }
  636. else
  637. TEST_ASSERT( ret != 0 );
  638. }
  639. /* END_CASE */
  640. /* BEGIN_CASE */
  641. void find_named_data( data_t *oid0, data_t *oid1, data_t *oid2, data_t *oid3,
  642. data_t *needle, int from, int position )
  643. {
  644. mbedtls_asn1_named_data nd[] ={
  645. { {0x06, oid0->len, oid0->x}, {0, 0, NULL}, NULL, 0 },
  646. { {0x06, oid1->len, oid1->x}, {0, 0, NULL}, NULL, 0 },
  647. { {0x06, oid2->len, oid2->x}, {0, 0, NULL}, NULL, 0 },
  648. { {0x06, oid3->len, oid3->x}, {0, 0, NULL}, NULL, 0 },
  649. };
  650. mbedtls_asn1_named_data *pointers[ARRAY_LENGTH( nd ) + 1];
  651. size_t i;
  652. mbedtls_asn1_named_data *found;
  653. for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
  654. pointers[i] = &nd[i];
  655. pointers[ARRAY_LENGTH( nd )] = NULL;
  656. for( i = 0; i < ARRAY_LENGTH( nd ); i++ )
  657. nd[i].next = pointers[i+1];
  658. found = mbedtls_asn1_find_named_data( pointers[from],
  659. (const char *) needle->x,
  660. needle->len );
  661. TEST_ASSERT( found == pointers[position] );
  662. }
  663. /* END_CASE */
  664. /* BEGIN_CASE */
  665. void free_named_data_null( )
  666. {
  667. mbedtls_asn1_free_named_data( NULL );
  668. goto exit; /* Silence unused label warning */
  669. }
  670. /* END_CASE */
  671. /* BEGIN_CASE */
  672. void free_named_data( int with_oid, int with_val, int with_next )
  673. {
  674. mbedtls_asn1_named_data next =
  675. { {0x06, 0, NULL}, {0, 0xcafe, NULL}, NULL, 0 };
  676. mbedtls_asn1_named_data head =
  677. { {0x06, 0, NULL}, {0, 0, NULL}, NULL, 0 };
  678. if( with_oid )
  679. ASSERT_ALLOC( head.oid.p, 1 );
  680. if( with_val )
  681. ASSERT_ALLOC( head.val.p, 1 );
  682. if( with_next )
  683. head.next = &next;
  684. mbedtls_asn1_free_named_data( &head );
  685. TEST_ASSERT( head.oid.p == NULL );
  686. TEST_ASSERT( head.val.p == NULL );
  687. TEST_ASSERT( head.next == NULL );
  688. TEST_ASSERT( next.val.len == 0xcafe );
  689. exit:
  690. mbedtls_free( head.oid.p );
  691. mbedtls_free( head.val.p );
  692. }
  693. /* END_CASE */
  694. /* BEGIN_CASE */
  695. void free_named_data_list( int length )
  696. {
  697. mbedtls_asn1_named_data *head = NULL;
  698. int i;
  699. for( i = 0; i < length; i++ )
  700. {
  701. mbedtls_asn1_named_data *new = NULL;
  702. ASSERT_ALLOC( new, sizeof( mbedtls_asn1_named_data ) );
  703. new->next = head;
  704. head = new;
  705. }
  706. mbedtls_asn1_free_named_data_list( &head );
  707. TEST_ASSERT( head == NULL );
  708. /* Most of the point of the test is that it doesn't leak memory.
  709. * So this test is only really useful under a memory leak detection
  710. * framework. */
  711. exit:
  712. mbedtls_asn1_free_named_data_list( &head );
  713. }
  714. /* END_CASE */