xref: /aosp_15_r20/external/mbedtls/tests/suites/test_suite_asn1write.function (revision 62c56f9862f102b96d72393aff6076c951fb8148)
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, &params), 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