1*62c56f98SSadaf Ebrahimi/* BEGIN_HEADER */ 2*62c56f98SSadaf Ebrahimi#include "mbedtls/asn1write.h" 3*62c56f98SSadaf Ebrahimi 4*62c56f98SSadaf Ebrahimi#define GUARD_LEN 4 5*62c56f98SSadaf Ebrahimi#define GUARD_VAL 0x2a 6*62c56f98SSadaf Ebrahimi 7*62c56f98SSadaf Ebrahimitypedef struct { 8*62c56f98SSadaf Ebrahimi unsigned char *output; 9*62c56f98SSadaf Ebrahimi unsigned char *start; 10*62c56f98SSadaf Ebrahimi unsigned char *end; 11*62c56f98SSadaf Ebrahimi unsigned char *p; 12*62c56f98SSadaf Ebrahimi size_t size; 13*62c56f98SSadaf Ebrahimi} generic_write_data_t; 14*62c56f98SSadaf Ebrahimi 15*62c56f98SSadaf Ebrahimiint generic_write_start_step(generic_write_data_t *data) 16*62c56f98SSadaf Ebrahimi{ 17*62c56f98SSadaf Ebrahimi mbedtls_test_set_step(data->size); 18*62c56f98SSadaf Ebrahimi mbedtls_free(data->output); 19*62c56f98SSadaf Ebrahimi data->output = NULL; 20*62c56f98SSadaf Ebrahimi TEST_CALLOC(data->output, data->size == 0 ? 1 : data->size); 21*62c56f98SSadaf Ebrahimi data->end = data->output + data->size; 22*62c56f98SSadaf Ebrahimi data->p = data->end; 23*62c56f98SSadaf Ebrahimi data->start = data->end - data->size; 24*62c56f98SSadaf Ebrahimi return 1; 25*62c56f98SSadaf Ebrahimiexit: 26*62c56f98SSadaf Ebrahimi return 0; 27*62c56f98SSadaf Ebrahimi} 28*62c56f98SSadaf Ebrahimi 29*62c56f98SSadaf Ebrahimiint generic_write_finish_step(generic_write_data_t *data, 30*62c56f98SSadaf Ebrahimi const data_t *expected, int ret) 31*62c56f98SSadaf Ebrahimi{ 32*62c56f98SSadaf Ebrahimi int ok = 0; 33*62c56f98SSadaf Ebrahimi 34*62c56f98SSadaf Ebrahimi if (data->size < expected->len) { 35*62c56f98SSadaf Ebrahimi TEST_EQUAL(ret, MBEDTLS_ERR_ASN1_BUF_TOO_SMALL); 36*62c56f98SSadaf Ebrahimi } else { 37*62c56f98SSadaf Ebrahimi TEST_EQUAL(ret, data->end - data->p); 38*62c56f98SSadaf Ebrahimi TEST_ASSERT(data->p >= data->start); 39*62c56f98SSadaf Ebrahimi TEST_ASSERT(data->p <= data->end); 40*62c56f98SSadaf Ebrahimi TEST_MEMORY_COMPARE(data->p, (size_t) (data->end - data->p), 41*62c56f98SSadaf Ebrahimi expected->x, expected->len); 42*62c56f98SSadaf Ebrahimi } 43*62c56f98SSadaf Ebrahimi ok = 1; 44*62c56f98SSadaf Ebrahimi 45*62c56f98SSadaf Ebrahimiexit: 46*62c56f98SSadaf Ebrahimi return ok; 47*62c56f98SSadaf Ebrahimi} 48*62c56f98SSadaf Ebrahimi 49*62c56f98SSadaf Ebrahimi/* END_HEADER */ 50*62c56f98SSadaf Ebrahimi 51*62c56f98SSadaf Ebrahimi/* BEGIN_DEPENDENCIES 52*62c56f98SSadaf Ebrahimi * depends_on:MBEDTLS_ASN1_WRITE_C 53*62c56f98SSadaf Ebrahimi * END_DEPENDENCIES 54*62c56f98SSadaf Ebrahimi */ 55*62c56f98SSadaf Ebrahimi 56*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 57*62c56f98SSadaf Ebrahimivoid mbedtls_asn1_write_null(data_t *expected) 58*62c56f98SSadaf Ebrahimi{ 59*62c56f98SSadaf Ebrahimi generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 }; 60*62c56f98SSadaf Ebrahimi int ret; 61*62c56f98SSadaf Ebrahimi 62*62c56f98SSadaf Ebrahimi for (data.size = 0; data.size <= expected->len + 1; data.size++) { 63*62c56f98SSadaf Ebrahimi if (!generic_write_start_step(&data)) { 64*62c56f98SSadaf Ebrahimi goto exit; 65*62c56f98SSadaf Ebrahimi } 66*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_null(&data.p, data.start); 67*62c56f98SSadaf Ebrahimi if (!generic_write_finish_step(&data, expected, ret)) { 68*62c56f98SSadaf Ebrahimi goto exit; 69*62c56f98SSadaf Ebrahimi } 70*62c56f98SSadaf Ebrahimi /* There's no parsing function for NULL. */ 71*62c56f98SSadaf Ebrahimi } 72*62c56f98SSadaf Ebrahimi 73*62c56f98SSadaf Ebrahimiexit: 74*62c56f98SSadaf Ebrahimi mbedtls_free(data.output); 75*62c56f98SSadaf Ebrahimi} 76*62c56f98SSadaf Ebrahimi/* END_CASE */ 77*62c56f98SSadaf Ebrahimi 78*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 79*62c56f98SSadaf Ebrahimivoid mbedtls_asn1_write_bool(int val, data_t *expected) 80*62c56f98SSadaf Ebrahimi{ 81*62c56f98SSadaf Ebrahimi generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 }; 82*62c56f98SSadaf Ebrahimi int ret; 83*62c56f98SSadaf Ebrahimi 84*62c56f98SSadaf Ebrahimi for (data.size = 0; data.size <= expected->len + 1; data.size++) { 85*62c56f98SSadaf Ebrahimi if (!generic_write_start_step(&data)) { 86*62c56f98SSadaf Ebrahimi goto exit; 87*62c56f98SSadaf Ebrahimi } 88*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_bool(&data.p, data.start, val); 89*62c56f98SSadaf Ebrahimi if (!generic_write_finish_step(&data, expected, ret)) { 90*62c56f98SSadaf Ebrahimi goto exit; 91*62c56f98SSadaf Ebrahimi } 92*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 93*62c56f98SSadaf Ebrahimi if (ret >= 0) { 94*62c56f98SSadaf Ebrahimi int read = 0xdeadbeef; 95*62c56f98SSadaf Ebrahimi TEST_EQUAL(mbedtls_asn1_get_bool(&data.p, data.end, &read), 0); 96*62c56f98SSadaf Ebrahimi TEST_EQUAL(val, read); 97*62c56f98SSadaf Ebrahimi } 98*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 99*62c56f98SSadaf Ebrahimi } 100*62c56f98SSadaf Ebrahimi 101*62c56f98SSadaf Ebrahimiexit: 102*62c56f98SSadaf Ebrahimi mbedtls_free(data.output); 103*62c56f98SSadaf Ebrahimi} 104*62c56f98SSadaf Ebrahimi/* END_CASE */ 105*62c56f98SSadaf Ebrahimi 106*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 107*62c56f98SSadaf Ebrahimivoid mbedtls_asn1_write_int(int val, data_t *expected) 108*62c56f98SSadaf Ebrahimi{ 109*62c56f98SSadaf Ebrahimi generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 }; 110*62c56f98SSadaf Ebrahimi int ret; 111*62c56f98SSadaf Ebrahimi 112*62c56f98SSadaf Ebrahimi for (data.size = 0; data.size <= expected->len + 1; data.size++) { 113*62c56f98SSadaf Ebrahimi if (!generic_write_start_step(&data)) { 114*62c56f98SSadaf Ebrahimi goto exit; 115*62c56f98SSadaf Ebrahimi } 116*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_int(&data.p, data.start, val); 117*62c56f98SSadaf Ebrahimi if (!generic_write_finish_step(&data, expected, ret)) { 118*62c56f98SSadaf Ebrahimi goto exit; 119*62c56f98SSadaf Ebrahimi } 120*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 121*62c56f98SSadaf Ebrahimi if (ret >= 0) { 122*62c56f98SSadaf Ebrahimi int read = 0xdeadbeef; 123*62c56f98SSadaf Ebrahimi TEST_EQUAL(mbedtls_asn1_get_int(&data.p, data.end, &read), 0); 124*62c56f98SSadaf Ebrahimi TEST_EQUAL(val, read); 125*62c56f98SSadaf Ebrahimi } 126*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 127*62c56f98SSadaf Ebrahimi } 128*62c56f98SSadaf Ebrahimi 129*62c56f98SSadaf Ebrahimiexit: 130*62c56f98SSadaf Ebrahimi mbedtls_free(data.output); 131*62c56f98SSadaf Ebrahimi} 132*62c56f98SSadaf Ebrahimi/* END_CASE */ 133*62c56f98SSadaf Ebrahimi 134*62c56f98SSadaf Ebrahimi 135*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 136*62c56f98SSadaf Ebrahimivoid mbedtls_asn1_write_enum(int val, data_t *expected) 137*62c56f98SSadaf Ebrahimi{ 138*62c56f98SSadaf Ebrahimi generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 }; 139*62c56f98SSadaf Ebrahimi int ret; 140*62c56f98SSadaf Ebrahimi 141*62c56f98SSadaf Ebrahimi for (data.size = 0; data.size <= expected->len + 1; data.size++) { 142*62c56f98SSadaf Ebrahimi if (!generic_write_start_step(&data)) { 143*62c56f98SSadaf Ebrahimi goto exit; 144*62c56f98SSadaf Ebrahimi } 145*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_enum(&data.p, data.start, val); 146*62c56f98SSadaf Ebrahimi if (!generic_write_finish_step(&data, expected, ret)) { 147*62c56f98SSadaf Ebrahimi goto exit; 148*62c56f98SSadaf Ebrahimi } 149*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 150*62c56f98SSadaf Ebrahimi if (ret >= 0) { 151*62c56f98SSadaf Ebrahimi int read = 0xdeadbeef; 152*62c56f98SSadaf Ebrahimi TEST_EQUAL(mbedtls_asn1_get_enum(&data.p, data.end, &read), 0); 153*62c56f98SSadaf Ebrahimi TEST_EQUAL(val, read); 154*62c56f98SSadaf Ebrahimi } 155*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 156*62c56f98SSadaf Ebrahimi } 157*62c56f98SSadaf Ebrahimi 158*62c56f98SSadaf Ebrahimiexit: 159*62c56f98SSadaf Ebrahimi mbedtls_free(data.output); 160*62c56f98SSadaf Ebrahimi} 161*62c56f98SSadaf Ebrahimi/* END_CASE */ 162*62c56f98SSadaf Ebrahimi 163*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_BIGNUM_C */ 164*62c56f98SSadaf Ebrahimivoid mbedtls_asn1_write_mpi(data_t *val, data_t *expected) 165*62c56f98SSadaf Ebrahimi{ 166*62c56f98SSadaf Ebrahimi generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 }; 167*62c56f98SSadaf Ebrahimi mbedtls_mpi mpi, read; 168*62c56f98SSadaf Ebrahimi int ret; 169*62c56f98SSadaf Ebrahimi 170*62c56f98SSadaf Ebrahimi mbedtls_mpi_init(&mpi); 171*62c56f98SSadaf Ebrahimi mbedtls_mpi_init(&read); 172*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_mpi_read_binary(&mpi, val->x, val->len) == 0); 173*62c56f98SSadaf Ebrahimi 174*62c56f98SSadaf Ebrahimi for (data.size = 0; data.size <= expected->len + 1; data.size++) { 175*62c56f98SSadaf Ebrahimi if (!generic_write_start_step(&data)) { 176*62c56f98SSadaf Ebrahimi goto exit; 177*62c56f98SSadaf Ebrahimi } 178*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_mpi(&data.p, data.start, &mpi); 179*62c56f98SSadaf Ebrahimi if (!generic_write_finish_step(&data, expected, ret)) { 180*62c56f98SSadaf Ebrahimi goto exit; 181*62c56f98SSadaf Ebrahimi } 182*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 183*62c56f98SSadaf Ebrahimi if (ret >= 0) { 184*62c56f98SSadaf Ebrahimi TEST_EQUAL(mbedtls_asn1_get_mpi(&data.p, data.end, &read), 0); 185*62c56f98SSadaf Ebrahimi TEST_EQUAL(0, mbedtls_mpi_cmp_mpi(&mpi, &read)); 186*62c56f98SSadaf Ebrahimi } 187*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 188*62c56f98SSadaf Ebrahimi /* Skip some intermediate lengths, they're boring. */ 189*62c56f98SSadaf Ebrahimi if (expected->len > 10 && data.size == 8) { 190*62c56f98SSadaf Ebrahimi data.size = expected->len - 2; 191*62c56f98SSadaf Ebrahimi } 192*62c56f98SSadaf Ebrahimi } 193*62c56f98SSadaf Ebrahimi 194*62c56f98SSadaf Ebrahimiexit: 195*62c56f98SSadaf Ebrahimi mbedtls_mpi_free(&mpi); 196*62c56f98SSadaf Ebrahimi mbedtls_mpi_free(&read); 197*62c56f98SSadaf Ebrahimi mbedtls_free(data.output); 198*62c56f98SSadaf Ebrahimi} 199*62c56f98SSadaf Ebrahimi/* END_CASE */ 200*62c56f98SSadaf Ebrahimi 201*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 202*62c56f98SSadaf Ebrahimivoid mbedtls_asn1_write_string(int tag, data_t *content, data_t *expected) 203*62c56f98SSadaf Ebrahimi{ 204*62c56f98SSadaf Ebrahimi generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 }; 205*62c56f98SSadaf Ebrahimi int ret; 206*62c56f98SSadaf Ebrahimi 207*62c56f98SSadaf Ebrahimi for (data.size = 0; data.size <= expected->len + 1; data.size++) { 208*62c56f98SSadaf Ebrahimi if (!generic_write_start_step(&data)) { 209*62c56f98SSadaf Ebrahimi goto exit; 210*62c56f98SSadaf Ebrahimi } 211*62c56f98SSadaf Ebrahimi switch (tag) { 212*62c56f98SSadaf Ebrahimi case MBEDTLS_ASN1_OCTET_STRING: 213*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_octet_string( 214*62c56f98SSadaf Ebrahimi &data.p, data.start, content->x, content->len); 215*62c56f98SSadaf Ebrahimi break; 216*62c56f98SSadaf Ebrahimi case MBEDTLS_ASN1_OID: 217*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_oid( 218*62c56f98SSadaf Ebrahimi &data.p, data.start, 219*62c56f98SSadaf Ebrahimi (const char *) content->x, content->len); 220*62c56f98SSadaf Ebrahimi break; 221*62c56f98SSadaf Ebrahimi case MBEDTLS_ASN1_UTF8_STRING: 222*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_utf8_string( 223*62c56f98SSadaf Ebrahimi &data.p, data.start, 224*62c56f98SSadaf Ebrahimi (const char *) content->x, content->len); 225*62c56f98SSadaf Ebrahimi break; 226*62c56f98SSadaf Ebrahimi case MBEDTLS_ASN1_PRINTABLE_STRING: 227*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_printable_string( 228*62c56f98SSadaf Ebrahimi &data.p, data.start, 229*62c56f98SSadaf Ebrahimi (const char *) content->x, content->len); 230*62c56f98SSadaf Ebrahimi break; 231*62c56f98SSadaf Ebrahimi case MBEDTLS_ASN1_IA5_STRING: 232*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_ia5_string( 233*62c56f98SSadaf Ebrahimi &data.p, data.start, 234*62c56f98SSadaf Ebrahimi (const char *) content->x, content->len); 235*62c56f98SSadaf Ebrahimi break; 236*62c56f98SSadaf Ebrahimi default: 237*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_tagged_string( 238*62c56f98SSadaf Ebrahimi &data.p, data.start, tag, 239*62c56f98SSadaf Ebrahimi (const char *) content->x, content->len); 240*62c56f98SSadaf Ebrahimi } 241*62c56f98SSadaf Ebrahimi if (!generic_write_finish_step(&data, expected, ret)) { 242*62c56f98SSadaf Ebrahimi goto exit; 243*62c56f98SSadaf Ebrahimi } 244*62c56f98SSadaf Ebrahimi /* There's no parsing function for octet or character strings. */ 245*62c56f98SSadaf Ebrahimi /* Skip some intermediate lengths, they're boring. */ 246*62c56f98SSadaf Ebrahimi if (expected->len > 10 && data.size == 8) { 247*62c56f98SSadaf Ebrahimi data.size = expected->len - 2; 248*62c56f98SSadaf Ebrahimi } 249*62c56f98SSadaf Ebrahimi } 250*62c56f98SSadaf Ebrahimi 251*62c56f98SSadaf Ebrahimiexit: 252*62c56f98SSadaf Ebrahimi mbedtls_free(data.output); 253*62c56f98SSadaf Ebrahimi} 254*62c56f98SSadaf Ebrahimi/* END_CASE */ 255*62c56f98SSadaf Ebrahimi 256*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 257*62c56f98SSadaf Ebrahimivoid mbedtls_asn1_write_algorithm_identifier(data_t *oid, 258*62c56f98SSadaf Ebrahimi int par_len, 259*62c56f98SSadaf Ebrahimi data_t *expected) 260*62c56f98SSadaf Ebrahimi{ 261*62c56f98SSadaf Ebrahimi generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 }; 262*62c56f98SSadaf Ebrahimi int ret; 263*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 264*62c56f98SSadaf Ebrahimi unsigned char *buf_complete = NULL; 265*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 266*62c56f98SSadaf Ebrahimi 267*62c56f98SSadaf Ebrahimi for (data.size = 0; data.size <= expected->len + 1; data.size++) { 268*62c56f98SSadaf Ebrahimi if (!generic_write_start_step(&data)) { 269*62c56f98SSadaf Ebrahimi goto exit; 270*62c56f98SSadaf Ebrahimi } 271*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_algorithm_identifier( 272*62c56f98SSadaf Ebrahimi &data.p, data.start, 273*62c56f98SSadaf Ebrahimi (const char *) oid->x, oid->len, par_len); 274*62c56f98SSadaf Ebrahimi /* If params_len != 0, mbedtls_asn1_write_algorithm_identifier() 275*62c56f98SSadaf Ebrahimi * assumes that the parameters are already present in the buffer 276*62c56f98SSadaf Ebrahimi * and returns a length that accounts for this, but our test 277*62c56f98SSadaf Ebrahimi * data omits the parameters. */ 278*62c56f98SSadaf Ebrahimi if (ret >= 0) { 279*62c56f98SSadaf Ebrahimi ret -= par_len; 280*62c56f98SSadaf Ebrahimi } 281*62c56f98SSadaf Ebrahimi if (!generic_write_finish_step(&data, expected, ret)) { 282*62c56f98SSadaf Ebrahimi goto exit; 283*62c56f98SSadaf Ebrahimi } 284*62c56f98SSadaf Ebrahimi 285*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 286*62c56f98SSadaf Ebrahimi /* Only do a parse-back test if the parameters aren't too large for 287*62c56f98SSadaf Ebrahimi * a small-heap environment. The boundary is somewhat arbitrary. */ 288*62c56f98SSadaf Ebrahimi if (ret >= 0 && par_len <= 1234) { 289*62c56f98SSadaf Ebrahimi mbedtls_asn1_buf alg = { 0, 0, NULL }; 290*62c56f98SSadaf Ebrahimi mbedtls_asn1_buf params = { 0, 0, NULL }; 291*62c56f98SSadaf Ebrahimi /* The writing function doesn't write the parameters unless 292*62c56f98SSadaf Ebrahimi * they're null: it only takes their length as input. But the 293*62c56f98SSadaf Ebrahimi * parsing function requires the parameters to be present. 294*62c56f98SSadaf Ebrahimi * Thus make up parameters. */ 295*62c56f98SSadaf Ebrahimi size_t data_len = data.end - data.p; 296*62c56f98SSadaf Ebrahimi size_t len_complete = data_len + par_len; 297*62c56f98SSadaf Ebrahimi unsigned char expected_params_tag; 298*62c56f98SSadaf Ebrahimi size_t expected_params_len; 299*62c56f98SSadaf Ebrahimi TEST_CALLOC(buf_complete, len_complete); 300*62c56f98SSadaf Ebrahimi unsigned char *end_complete = buf_complete + len_complete; 301*62c56f98SSadaf Ebrahimi memcpy(buf_complete, data.p, data_len); 302*62c56f98SSadaf Ebrahimi if (par_len == 0) { 303*62c56f98SSadaf Ebrahimi /* mbedtls_asn1_write_algorithm_identifier() wrote a NULL */ 304*62c56f98SSadaf Ebrahimi expected_params_tag = 0x05; 305*62c56f98SSadaf Ebrahimi expected_params_len = 0; 306*62c56f98SSadaf Ebrahimi } else if (par_len >= 2 && par_len < 2 + 128) { 307*62c56f98SSadaf Ebrahimi /* Write an OCTET STRING with a short length encoding */ 308*62c56f98SSadaf Ebrahimi expected_params_tag = buf_complete[data_len] = 0x04; 309*62c56f98SSadaf Ebrahimi expected_params_len = par_len - 2; 310*62c56f98SSadaf Ebrahimi buf_complete[data_len + 1] = (unsigned char) expected_params_len; 311*62c56f98SSadaf Ebrahimi } else if (par_len >= 4 + 128 && par_len < 3 + 256 * 256) { 312*62c56f98SSadaf Ebrahimi /* Write an OCTET STRING with a two-byte length encoding */ 313*62c56f98SSadaf Ebrahimi expected_params_tag = buf_complete[data_len] = 0x04; 314*62c56f98SSadaf Ebrahimi expected_params_len = par_len - 4; 315*62c56f98SSadaf Ebrahimi buf_complete[data_len + 1] = 0x82; 316*62c56f98SSadaf Ebrahimi buf_complete[data_len + 2] = (unsigned char) (expected_params_len >> 8); 317*62c56f98SSadaf Ebrahimi buf_complete[data_len + 3] = (unsigned char) (expected_params_len); 318*62c56f98SSadaf Ebrahimi } else { 319*62c56f98SSadaf Ebrahimi TEST_FAIL("Bad test data: invalid length of ASN.1 element"); 320*62c56f98SSadaf Ebrahimi } 321*62c56f98SSadaf Ebrahimi unsigned char *p = buf_complete; 322*62c56f98SSadaf Ebrahimi TEST_EQUAL(mbedtls_asn1_get_alg(&p, end_complete, 323*62c56f98SSadaf Ebrahimi &alg, ¶ms), 0); 324*62c56f98SSadaf Ebrahimi TEST_EQUAL(alg.tag, MBEDTLS_ASN1_OID); 325*62c56f98SSadaf Ebrahimi TEST_MEMORY_COMPARE(alg.p, alg.len, oid->x, oid->len); 326*62c56f98SSadaf Ebrahimi TEST_EQUAL(params.tag, expected_params_tag); 327*62c56f98SSadaf Ebrahimi TEST_EQUAL(params.len, expected_params_len); 328*62c56f98SSadaf Ebrahimi mbedtls_free(buf_complete); 329*62c56f98SSadaf Ebrahimi buf_complete = NULL; 330*62c56f98SSadaf Ebrahimi } 331*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 332*62c56f98SSadaf Ebrahimi } 333*62c56f98SSadaf Ebrahimi 334*62c56f98SSadaf Ebrahimiexit: 335*62c56f98SSadaf Ebrahimi mbedtls_free(data.output); 336*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 337*62c56f98SSadaf Ebrahimi mbedtls_free(buf_complete); 338*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 339*62c56f98SSadaf Ebrahimi} 340*62c56f98SSadaf Ebrahimi/* END_CASE */ 341*62c56f98SSadaf Ebrahimi 342*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ASN1_PARSE_C */ 343*62c56f98SSadaf Ebrahimivoid mbedtls_asn1_write_len(int len, data_t *asn1, int buf_len, 344*62c56f98SSadaf Ebrahimi int result) 345*62c56f98SSadaf Ebrahimi{ 346*62c56f98SSadaf Ebrahimi int ret; 347*62c56f98SSadaf Ebrahimi unsigned char buf[150]; 348*62c56f98SSadaf Ebrahimi unsigned char *p; 349*62c56f98SSadaf Ebrahimi size_t i; 350*62c56f98SSadaf Ebrahimi size_t read_len; 351*62c56f98SSadaf Ebrahimi 352*62c56f98SSadaf Ebrahimi memset(buf, GUARD_VAL, sizeof(buf)); 353*62c56f98SSadaf Ebrahimi 354*62c56f98SSadaf Ebrahimi p = buf + GUARD_LEN + buf_len; 355*62c56f98SSadaf Ebrahimi 356*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_write_len(&p, buf + GUARD_LEN, (size_t) len); 357*62c56f98SSadaf Ebrahimi 358*62c56f98SSadaf Ebrahimi TEST_ASSERT(ret == result); 359*62c56f98SSadaf Ebrahimi 360*62c56f98SSadaf Ebrahimi /* Check for buffer overwrite on both sides */ 361*62c56f98SSadaf Ebrahimi for (i = 0; i < GUARD_LEN; i++) { 362*62c56f98SSadaf Ebrahimi TEST_ASSERT(buf[i] == GUARD_VAL); 363*62c56f98SSadaf Ebrahimi TEST_ASSERT(buf[GUARD_LEN + buf_len + i] == GUARD_VAL); 364*62c56f98SSadaf Ebrahimi } 365*62c56f98SSadaf Ebrahimi 366*62c56f98SSadaf Ebrahimi if (result >= 0) { 367*62c56f98SSadaf Ebrahimi TEST_ASSERT(p + asn1->len == buf + GUARD_LEN + buf_len); 368*62c56f98SSadaf Ebrahimi 369*62c56f98SSadaf Ebrahimi TEST_ASSERT(memcmp(p, asn1->x, asn1->len) == 0); 370*62c56f98SSadaf Ebrahimi 371*62c56f98SSadaf Ebrahimi /* Read back with mbedtls_asn1_get_len() to check */ 372*62c56f98SSadaf Ebrahimi ret = mbedtls_asn1_get_len(&p, buf + GUARD_LEN + buf_len, &read_len); 373*62c56f98SSadaf Ebrahimi 374*62c56f98SSadaf Ebrahimi if (len == 0) { 375*62c56f98SSadaf Ebrahimi TEST_ASSERT(ret == 0); 376*62c56f98SSadaf Ebrahimi } else { 377*62c56f98SSadaf Ebrahimi /* Return will be MBEDTLS_ERR_ASN1_OUT_OF_DATA because the rest of 378*62c56f98SSadaf Ebrahimi * the buffer is missing 379*62c56f98SSadaf Ebrahimi */ 380*62c56f98SSadaf Ebrahimi TEST_ASSERT(ret == MBEDTLS_ERR_ASN1_OUT_OF_DATA); 381*62c56f98SSadaf Ebrahimi } 382*62c56f98SSadaf Ebrahimi TEST_ASSERT(read_len == (size_t) len); 383*62c56f98SSadaf Ebrahimi TEST_ASSERT(p == buf + GUARD_LEN + buf_len); 384*62c56f98SSadaf Ebrahimi } 385*62c56f98SSadaf Ebrahimi} 386*62c56f98SSadaf Ebrahimi/* END_CASE */ 387*62c56f98SSadaf Ebrahimi 388*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 389*62c56f98SSadaf Ebrahimivoid test_asn1_write_bitstrings(data_t *bitstring, int bits, 390*62c56f98SSadaf Ebrahimi data_t *expected, int is_named) 391*62c56f98SSadaf Ebrahimi{ 392*62c56f98SSadaf Ebrahimi generic_write_data_t data = { NULL, NULL, NULL, NULL, 0 }; 393*62c56f98SSadaf Ebrahimi int ret; 394*62c56f98SSadaf Ebrahimi int (*func)(unsigned char **p, const unsigned char *start, 395*62c56f98SSadaf Ebrahimi const unsigned char *buf, size_t bits) = 396*62c56f98SSadaf Ebrahimi (is_named ? mbedtls_asn1_write_named_bitstring : 397*62c56f98SSadaf Ebrahimi mbedtls_asn1_write_bitstring); 398*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 399*62c56f98SSadaf Ebrahimi unsigned char *masked_bitstring = NULL; 400*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 401*62c56f98SSadaf Ebrahimi 402*62c56f98SSadaf Ebrahimi /* The API expects `bitstring->x` to contain `bits` bits. */ 403*62c56f98SSadaf Ebrahimi size_t byte_length = (bits + 7) / 8; 404*62c56f98SSadaf Ebrahimi TEST_ASSERT(bitstring->len >= byte_length); 405*62c56f98SSadaf Ebrahimi 406*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 407*62c56f98SSadaf Ebrahimi TEST_CALLOC(masked_bitstring, byte_length); 408*62c56f98SSadaf Ebrahimi if (byte_length != 0) { 409*62c56f98SSadaf Ebrahimi memcpy(masked_bitstring, bitstring->x, byte_length); 410*62c56f98SSadaf Ebrahimi if (bits % 8 != 0) { 411*62c56f98SSadaf Ebrahimi masked_bitstring[byte_length - 1] &= ~(0xff >> (bits % 8)); 412*62c56f98SSadaf Ebrahimi } 413*62c56f98SSadaf Ebrahimi } 414*62c56f98SSadaf Ebrahimi size_t value_bits = bits; 415*62c56f98SSadaf Ebrahimi if (is_named) { 416*62c56f98SSadaf Ebrahimi /* In a named bit string, all trailing 0 bits are removed. */ 417*62c56f98SSadaf Ebrahimi while (byte_length > 0 && masked_bitstring[byte_length - 1] == 0) { 418*62c56f98SSadaf Ebrahimi --byte_length; 419*62c56f98SSadaf Ebrahimi } 420*62c56f98SSadaf Ebrahimi value_bits = 8 * byte_length; 421*62c56f98SSadaf Ebrahimi if (byte_length > 0) { 422*62c56f98SSadaf Ebrahimi unsigned char last_byte = masked_bitstring[byte_length - 1]; 423*62c56f98SSadaf Ebrahimi for (unsigned b = 1; b < 0xff && (last_byte & b) == 0; b <<= 1) { 424*62c56f98SSadaf Ebrahimi --value_bits; 425*62c56f98SSadaf Ebrahimi } 426*62c56f98SSadaf Ebrahimi } 427*62c56f98SSadaf Ebrahimi } 428*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 429*62c56f98SSadaf Ebrahimi 430*62c56f98SSadaf Ebrahimi for (data.size = 0; data.size <= expected->len + 1; data.size++) { 431*62c56f98SSadaf Ebrahimi if (!generic_write_start_step(&data)) { 432*62c56f98SSadaf Ebrahimi goto exit; 433*62c56f98SSadaf Ebrahimi } 434*62c56f98SSadaf Ebrahimi ret = (*func)(&data.p, data.start, bitstring->x, bits); 435*62c56f98SSadaf Ebrahimi if (!generic_write_finish_step(&data, expected, ret)) { 436*62c56f98SSadaf Ebrahimi goto exit; 437*62c56f98SSadaf Ebrahimi } 438*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 439*62c56f98SSadaf Ebrahimi if (ret >= 0) { 440*62c56f98SSadaf Ebrahimi mbedtls_asn1_bitstring read = { 0, 0, NULL }; 441*62c56f98SSadaf Ebrahimi TEST_EQUAL(mbedtls_asn1_get_bitstring(&data.p, data.end, 442*62c56f98SSadaf Ebrahimi &read), 0); 443*62c56f98SSadaf Ebrahimi TEST_MEMORY_COMPARE(read.p, read.len, 444*62c56f98SSadaf Ebrahimi masked_bitstring, byte_length); 445*62c56f98SSadaf Ebrahimi TEST_EQUAL(read.unused_bits, 8 * byte_length - value_bits); 446*62c56f98SSadaf Ebrahimi } 447*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 448*62c56f98SSadaf Ebrahimi } 449*62c56f98SSadaf Ebrahimi 450*62c56f98SSadaf Ebrahimiexit: 451*62c56f98SSadaf Ebrahimi mbedtls_free(data.output); 452*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ASN1_PARSE_C) 453*62c56f98SSadaf Ebrahimi mbedtls_free(masked_bitstring); 454*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ASN1_PARSE_C */ 455*62c56f98SSadaf Ebrahimi} 456*62c56f98SSadaf Ebrahimi/* END_CASE */ 457*62c56f98SSadaf Ebrahimi 458*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 459*62c56f98SSadaf Ebrahimivoid store_named_data_find(data_t *oid0, data_t *oid1, 460*62c56f98SSadaf Ebrahimi data_t *oid2, data_t *oid3, 461*62c56f98SSadaf Ebrahimi data_t *needle, int from, int position) 462*62c56f98SSadaf Ebrahimi{ 463*62c56f98SSadaf Ebrahimi data_t *oid[4] = { oid0, oid1, oid2, oid3 }; 464*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data nd[] = { 465*62c56f98SSadaf Ebrahimi { { 0x06, 0, NULL }, { 0, 0, NULL }, NULL, 0 }, 466*62c56f98SSadaf Ebrahimi { { 0x06, 0, NULL }, { 0, 0, NULL }, NULL, 0 }, 467*62c56f98SSadaf Ebrahimi { { 0x06, 0, NULL }, { 0, 0, NULL }, NULL, 0 }, 468*62c56f98SSadaf Ebrahimi { { 0x06, 0, NULL }, { 0, 0, NULL }, NULL, 0 }, 469*62c56f98SSadaf Ebrahimi }; 470*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data *pointers[ARRAY_LENGTH(nd) + 1]; 471*62c56f98SSadaf Ebrahimi size_t i; 472*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data *head = NULL; 473*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data *found = NULL; 474*62c56f98SSadaf Ebrahimi 475*62c56f98SSadaf Ebrahimi for (i = 0; i < ARRAY_LENGTH(nd); i++) { 476*62c56f98SSadaf Ebrahimi pointers[i] = &nd[i]; 477*62c56f98SSadaf Ebrahimi } 478*62c56f98SSadaf Ebrahimi pointers[ARRAY_LENGTH(nd)] = NULL; 479*62c56f98SSadaf Ebrahimi for (i = 0; i < ARRAY_LENGTH(nd); i++) { 480*62c56f98SSadaf Ebrahimi TEST_CALLOC(nd[i].oid.p, oid[i]->len); 481*62c56f98SSadaf Ebrahimi memcpy(nd[i].oid.p, oid[i]->x, oid[i]->len); 482*62c56f98SSadaf Ebrahimi nd[i].oid.len = oid[i]->len; 483*62c56f98SSadaf Ebrahimi nd[i].next = pointers[i+1]; 484*62c56f98SSadaf Ebrahimi } 485*62c56f98SSadaf Ebrahimi 486*62c56f98SSadaf Ebrahimi head = pointers[from]; 487*62c56f98SSadaf Ebrahimi found = mbedtls_asn1_store_named_data(&head, 488*62c56f98SSadaf Ebrahimi (const char *) needle->x, 489*62c56f98SSadaf Ebrahimi needle->len, 490*62c56f98SSadaf Ebrahimi NULL, 0); 491*62c56f98SSadaf Ebrahimi 492*62c56f98SSadaf Ebrahimi /* In any case, the existing list structure must be unchanged. */ 493*62c56f98SSadaf Ebrahimi for (i = 0; i < ARRAY_LENGTH(nd); i++) { 494*62c56f98SSadaf Ebrahimi TEST_ASSERT(nd[i].next == pointers[i+1]); 495*62c56f98SSadaf Ebrahimi } 496*62c56f98SSadaf Ebrahimi 497*62c56f98SSadaf Ebrahimi if (position >= 0) { 498*62c56f98SSadaf Ebrahimi /* position should have been found and modified. */ 499*62c56f98SSadaf Ebrahimi TEST_ASSERT(head == pointers[from]); 500*62c56f98SSadaf Ebrahimi TEST_ASSERT(found == pointers[position]); 501*62c56f98SSadaf Ebrahimi } else { 502*62c56f98SSadaf Ebrahimi /* A new entry should have been created. */ 503*62c56f98SSadaf Ebrahimi TEST_ASSERT(found == head); 504*62c56f98SSadaf Ebrahimi TEST_ASSERT(head->next == pointers[from]); 505*62c56f98SSadaf Ebrahimi for (i = 0; i < ARRAY_LENGTH(nd); i++) { 506*62c56f98SSadaf Ebrahimi TEST_ASSERT(found != &nd[i]); 507*62c56f98SSadaf Ebrahimi } 508*62c56f98SSadaf Ebrahimi } 509*62c56f98SSadaf Ebrahimi 510*62c56f98SSadaf Ebrahimiexit: 511*62c56f98SSadaf Ebrahimi if (found != NULL && found == head && found != pointers[from]) { 512*62c56f98SSadaf Ebrahimi mbedtls_free(found->oid.p); 513*62c56f98SSadaf Ebrahimi mbedtls_free(found); 514*62c56f98SSadaf Ebrahimi } 515*62c56f98SSadaf Ebrahimi for (i = 0; i < ARRAY_LENGTH(nd); i++) { 516*62c56f98SSadaf Ebrahimi mbedtls_free(nd[i].oid.p); 517*62c56f98SSadaf Ebrahimi } 518*62c56f98SSadaf Ebrahimi} 519*62c56f98SSadaf Ebrahimi/* END_CASE */ 520*62c56f98SSadaf Ebrahimi 521*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 522*62c56f98SSadaf Ebrahimivoid store_named_data_val_found(int old_len, int new_len) 523*62c56f98SSadaf Ebrahimi{ 524*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data nd = 525*62c56f98SSadaf Ebrahimi { { 0x06, 3, (unsigned char *) "OID" }, { 0, 0, NULL }, NULL, 0 }; 526*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data *head = &nd; 527*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data *found = NULL; 528*62c56f98SSadaf Ebrahimi unsigned char *old_val = NULL; 529*62c56f98SSadaf Ebrahimi unsigned char *new_val = (unsigned char *) "new value"; 530*62c56f98SSadaf Ebrahimi 531*62c56f98SSadaf Ebrahimi if (old_len != 0) { 532*62c56f98SSadaf Ebrahimi TEST_CALLOC(nd.val.p, (size_t) old_len); 533*62c56f98SSadaf Ebrahimi old_val = nd.val.p; 534*62c56f98SSadaf Ebrahimi nd.val.len = old_len; 535*62c56f98SSadaf Ebrahimi memset(old_val, 'x', old_len); 536*62c56f98SSadaf Ebrahimi } 537*62c56f98SSadaf Ebrahimi if (new_len <= 0) { 538*62c56f98SSadaf Ebrahimi new_len = -new_len; 539*62c56f98SSadaf Ebrahimi new_val = NULL; 540*62c56f98SSadaf Ebrahimi } 541*62c56f98SSadaf Ebrahimi 542*62c56f98SSadaf Ebrahimi found = mbedtls_asn1_store_named_data(&head, "OID", 3, 543*62c56f98SSadaf Ebrahimi new_val, new_len); 544*62c56f98SSadaf Ebrahimi TEST_ASSERT(head == &nd); 545*62c56f98SSadaf Ebrahimi TEST_ASSERT(found == head); 546*62c56f98SSadaf Ebrahimi 547*62c56f98SSadaf Ebrahimi if (new_val != NULL) { 548*62c56f98SSadaf Ebrahimi TEST_MEMORY_COMPARE(found->val.p, found->val.len, 549*62c56f98SSadaf Ebrahimi new_val, (size_t) new_len); 550*62c56f98SSadaf Ebrahimi } 551*62c56f98SSadaf Ebrahimi if (new_len == 0) { 552*62c56f98SSadaf Ebrahimi TEST_ASSERT(found->val.p == NULL); 553*62c56f98SSadaf Ebrahimi } else if (new_len == old_len) { 554*62c56f98SSadaf Ebrahimi TEST_ASSERT(found->val.p == old_val); 555*62c56f98SSadaf Ebrahimi } else { 556*62c56f98SSadaf Ebrahimi TEST_ASSERT(found->val.p != old_val); 557*62c56f98SSadaf Ebrahimi } 558*62c56f98SSadaf Ebrahimi 559*62c56f98SSadaf Ebrahimiexit: 560*62c56f98SSadaf Ebrahimi mbedtls_free(nd.val.p); 561*62c56f98SSadaf Ebrahimi} 562*62c56f98SSadaf Ebrahimi/* END_CASE */ 563*62c56f98SSadaf Ebrahimi 564*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 565*62c56f98SSadaf Ebrahimivoid store_named_data_val_new(int new_len, int set_new_val) 566*62c56f98SSadaf Ebrahimi{ 567*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data *head = NULL; 568*62c56f98SSadaf Ebrahimi mbedtls_asn1_named_data *found = NULL; 569*62c56f98SSadaf Ebrahimi const unsigned char *oid = (unsigned char *) "OID"; 570*62c56f98SSadaf Ebrahimi size_t oid_len = strlen((const char *) oid); 571*62c56f98SSadaf Ebrahimi const unsigned char *new_val = (unsigned char *) "new value"; 572*62c56f98SSadaf Ebrahimi 573*62c56f98SSadaf Ebrahimi if (set_new_val == 0) { 574*62c56f98SSadaf Ebrahimi new_val = NULL; 575*62c56f98SSadaf Ebrahimi } 576*62c56f98SSadaf Ebrahimi 577*62c56f98SSadaf Ebrahimi found = mbedtls_asn1_store_named_data(&head, 578*62c56f98SSadaf Ebrahimi (const char *) oid, oid_len, 579*62c56f98SSadaf Ebrahimi new_val, (size_t) new_len); 580*62c56f98SSadaf Ebrahimi TEST_ASSERT(found != NULL); 581*62c56f98SSadaf Ebrahimi TEST_ASSERT(found == head); 582*62c56f98SSadaf Ebrahimi TEST_ASSERT(found->oid.p != oid); 583*62c56f98SSadaf Ebrahimi TEST_MEMORY_COMPARE(found->oid.p, found->oid.len, oid, oid_len); 584*62c56f98SSadaf Ebrahimi if (new_len == 0) { 585*62c56f98SSadaf Ebrahimi TEST_ASSERT(found->val.p == NULL); 586*62c56f98SSadaf Ebrahimi } else if (new_val == NULL) { 587*62c56f98SSadaf Ebrahimi TEST_ASSERT(found->val.p != NULL); 588*62c56f98SSadaf Ebrahimi } else { 589*62c56f98SSadaf Ebrahimi TEST_ASSERT(found->val.p != new_val); 590*62c56f98SSadaf Ebrahimi TEST_MEMORY_COMPARE(found->val.p, found->val.len, 591*62c56f98SSadaf Ebrahimi new_val, (size_t) new_len); 592*62c56f98SSadaf Ebrahimi } 593*62c56f98SSadaf Ebrahimi 594*62c56f98SSadaf Ebrahimiexit: 595*62c56f98SSadaf Ebrahimi if (found != NULL) { 596*62c56f98SSadaf Ebrahimi mbedtls_free(found->oid.p); 597*62c56f98SSadaf Ebrahimi mbedtls_free(found->val.p); 598*62c56f98SSadaf Ebrahimi } 599*62c56f98SSadaf Ebrahimi mbedtls_free(found); 600*62c56f98SSadaf Ebrahimi} 601*62c56f98SSadaf Ebrahimi/* END_CASE */ 602