1/** \file asn1_helpers.c
2 *
3 * \brief Helper functions for tests that manipulate ASN.1 data.
4 */
5
6/*
7 *  Copyright The Mbed TLS Contributors
8 *  SPDX-License-Identifier: Apache-2.0
9 *
10 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
11 *  not use this file except in compliance with the License.
12 *  You may obtain a copy of the License at
13 *
14 *  http://www.apache.org/licenses/LICENSE-2.0
15 *
16 *  Unless required by applicable law or agreed to in writing, software
17 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 *  See the License for the specific language governing permissions and
20 *  limitations under the License.
21 */
22
23#include <test/helpers.h>
24#include <test/macros.h>
25
26#if defined(MBEDTLS_ASN1_PARSE_C)
27
28#include <mbedtls/asn1.h>
29
30int mbedtls_test_asn1_skip_integer(unsigned char **p, const unsigned char *end,
31                                   size_t min_bits, size_t max_bits,
32                                   int must_be_odd)
33{
34    size_t len;
35    size_t actual_bits;
36    unsigned char msb;
37    TEST_EQUAL(mbedtls_asn1_get_tag(p, end, &len,
38                                    MBEDTLS_ASN1_INTEGER),
39               0);
40
41    /* Check if the retrieved length doesn't extend the actual buffer's size.
42     * It is assumed here, that end >= p, which validates casting to size_t. */
43    TEST_ASSERT(len <= (size_t) (end - *p));
44
45    /* Tolerate a slight departure from DER encoding:
46     * - 0 may be represented by an empty string or a 1-byte string.
47     * - The sign bit may be used as a value bit. */
48    if ((len == 1 && (*p)[0] == 0) ||
49        (len > 1 && (*p)[0] == 0 && ((*p)[1] & 0x80) != 0)) {
50        ++(*p);
51        --len;
52    }
53    if (min_bits == 0 && len == 0) {
54        return 1;
55    }
56    msb = (*p)[0];
57    TEST_ASSERT(msb != 0);
58    actual_bits = 8 * (len - 1);
59    while (msb != 0) {
60        msb >>= 1;
61        ++actual_bits;
62    }
63    TEST_ASSERT(actual_bits >= min_bits);
64    TEST_ASSERT(actual_bits <= max_bits);
65    if (must_be_odd) {
66        TEST_ASSERT(((*p)[len-1] & 1) != 0);
67    }
68    *p += len;
69    return 1;
70exit:
71    return 0;
72}
73
74#endif /* MBEDTLS_ASN1_PARSE_C */
75