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