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