1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * Generic ASN.1 parsing 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 57901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 6817466cbSJens Wiklander * 7817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8817466cbSJens Wiklander * not use this file except in compliance with the License. 9817466cbSJens Wiklander * You may obtain a copy of the License at 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12817466cbSJens Wiklander * 13817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 14817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16817466cbSJens Wiklander * See the License for the specific language governing permissions and 17817466cbSJens Wiklander * limitations under the License. 18817466cbSJens Wiklander */ 19817466cbSJens Wiklander 207901324dSJerome Forissier #include "common.h" 21817466cbSJens Wiklander 22817466cbSJens Wiklander #if defined(MBEDTLS_ASN1_PARSE_C) 23817466cbSJens Wiklander 24817466cbSJens Wiklander #include "mbedtls/asn1.h" 253d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 2611fa71b9SJerome Forissier #include "mbedtls/error.h" 27817466cbSJens Wiklander 28817466cbSJens Wiklander #include <string.h> 29817466cbSJens Wiklander 30817466cbSJens Wiklander #if defined(MBEDTLS_BIGNUM_C) 31817466cbSJens Wiklander #include "mbedtls/bignum.h" 32817466cbSJens Wiklander #endif 33817466cbSJens Wiklander 34817466cbSJens Wiklander #include "mbedtls/platform.h" 35817466cbSJens Wiklander 36817466cbSJens Wiklander /* 37817466cbSJens Wiklander * ASN.1 DER decoding routines 38817466cbSJens Wiklander */ 39817466cbSJens Wiklander int mbedtls_asn1_get_len(unsigned char **p, 40817466cbSJens Wiklander const unsigned char *end, 41817466cbSJens Wiklander size_t *len) 42817466cbSJens Wiklander { 43*32b31808SJens Wiklander if ((end - *p) < 1) { 44*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 45*32b31808SJens Wiklander } 46817466cbSJens Wiklander 47*32b31808SJens Wiklander if ((**p & 0x80) == 0) { 48817466cbSJens Wiklander *len = *(*p)++; 49*32b31808SJens Wiklander } else { 50*32b31808SJens Wiklander switch (**p & 0x7F) { 51817466cbSJens Wiklander case 1: 52*32b31808SJens Wiklander if ((end - *p) < 2) { 53*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 54*32b31808SJens Wiklander } 55817466cbSJens Wiklander 56817466cbSJens Wiklander *len = (*p)[1]; 57817466cbSJens Wiklander (*p) += 2; 58817466cbSJens Wiklander break; 59817466cbSJens Wiklander 60817466cbSJens Wiklander case 2: 61*32b31808SJens Wiklander if ((end - *p) < 3) { 62*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 63*32b31808SJens Wiklander } 64817466cbSJens Wiklander 65817466cbSJens Wiklander *len = ((size_t) (*p)[1] << 8) | (*p)[2]; 66817466cbSJens Wiklander (*p) += 3; 67817466cbSJens Wiklander break; 68817466cbSJens Wiklander 69817466cbSJens Wiklander case 3: 70*32b31808SJens Wiklander if ((end - *p) < 4) { 71*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 72*32b31808SJens Wiklander } 73817466cbSJens Wiklander 74817466cbSJens Wiklander *len = ((size_t) (*p)[1] << 16) | 75817466cbSJens Wiklander ((size_t) (*p)[2] << 8) | (*p)[3]; 76817466cbSJens Wiklander (*p) += 4; 77817466cbSJens Wiklander break; 78817466cbSJens Wiklander 79817466cbSJens Wiklander case 4: 80*32b31808SJens Wiklander if ((end - *p) < 5) { 81*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 82*32b31808SJens Wiklander } 83817466cbSJens Wiklander 84817466cbSJens Wiklander *len = ((size_t) (*p)[1] << 24) | ((size_t) (*p)[2] << 16) | 85817466cbSJens Wiklander ((size_t) (*p)[3] << 8) | (*p)[4]; 86817466cbSJens Wiklander (*p) += 5; 87817466cbSJens Wiklander break; 88817466cbSJens Wiklander 89817466cbSJens Wiklander default: 90*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 91817466cbSJens Wiklander } 92817466cbSJens Wiklander } 93817466cbSJens Wiklander 94*32b31808SJens Wiklander if (*len > (size_t) (end - *p)) { 95*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 96*32b31808SJens Wiklander } 97817466cbSJens Wiklander 98*32b31808SJens Wiklander return 0; 99817466cbSJens Wiklander } 100817466cbSJens Wiklander 101817466cbSJens Wiklander int mbedtls_asn1_get_tag(unsigned char **p, 102817466cbSJens Wiklander const unsigned char *end, 103817466cbSJens Wiklander size_t *len, int tag) 104817466cbSJens Wiklander { 105*32b31808SJens Wiklander if ((end - *p) < 1) { 106*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 107*32b31808SJens Wiklander } 108817466cbSJens Wiklander 109*32b31808SJens Wiklander if (**p != tag) { 110*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; 111*32b31808SJens Wiklander } 112817466cbSJens Wiklander 113817466cbSJens Wiklander (*p)++; 114817466cbSJens Wiklander 115*32b31808SJens Wiklander return mbedtls_asn1_get_len(p, end, len); 116817466cbSJens Wiklander } 117817466cbSJens Wiklander 118817466cbSJens Wiklander int mbedtls_asn1_get_bool(unsigned char **p, 119817466cbSJens Wiklander const unsigned char *end, 120817466cbSJens Wiklander int *val) 121817466cbSJens Wiklander { 12211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 123817466cbSJens Wiklander size_t len; 124817466cbSJens Wiklander 125*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) { 126*32b31808SJens Wiklander return ret; 127*32b31808SJens Wiklander } 128817466cbSJens Wiklander 129*32b31808SJens Wiklander if (len != 1) { 130*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 131*32b31808SJens Wiklander } 132817466cbSJens Wiklander 133817466cbSJens Wiklander *val = (**p != 0) ? 1 : 0; 134817466cbSJens Wiklander (*p)++; 135817466cbSJens Wiklander 136*32b31808SJens Wiklander return 0; 137817466cbSJens Wiklander } 138817466cbSJens Wiklander 13911fa71b9SJerome Forissier static int asn1_get_tagged_int(unsigned char **p, 140817466cbSJens Wiklander const unsigned char *end, 14111fa71b9SJerome Forissier int tag, int *val) 142817466cbSJens Wiklander { 14311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 144817466cbSJens Wiklander size_t len; 145817466cbSJens Wiklander 146*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) { 147*32b31808SJens Wiklander return ret; 148*32b31808SJens Wiklander } 149817466cbSJens Wiklander 15011fa71b9SJerome Forissier /* 15111fa71b9SJerome Forissier * len==0 is malformed (0 must be represented as 020100 for INTEGER, 15211fa71b9SJerome Forissier * or 0A0100 for ENUMERATED tags 15311fa71b9SJerome Forissier */ 154*32b31808SJens Wiklander if (len == 0) { 155*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 156*32b31808SJens Wiklander } 15711fa71b9SJerome Forissier /* This is a cryptography library. Reject negative integers. */ 158*32b31808SJens Wiklander if ((**p & 0x80) != 0) { 159*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 160*32b31808SJens Wiklander } 16111fa71b9SJerome Forissier 16211fa71b9SJerome Forissier /* Skip leading zeros. */ 163*32b31808SJens Wiklander while (len > 0 && **p == 0) { 16411fa71b9SJerome Forissier ++(*p); 16511fa71b9SJerome Forissier --len; 16611fa71b9SJerome Forissier } 16711fa71b9SJerome Forissier 16811fa71b9SJerome Forissier /* Reject integers that don't fit in an int. This code assumes that 16911fa71b9SJerome Forissier * the int type has no padding bit. */ 170*32b31808SJens Wiklander if (len > sizeof(int)) { 171*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 172*32b31808SJens Wiklander } 173*32b31808SJens Wiklander if (len == sizeof(int) && (**p & 0x80) != 0) { 174*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 175*32b31808SJens Wiklander } 176817466cbSJens Wiklander 177817466cbSJens Wiklander *val = 0; 178*32b31808SJens Wiklander while (len-- > 0) { 179817466cbSJens Wiklander *val = (*val << 8) | **p; 180817466cbSJens Wiklander (*p)++; 181817466cbSJens Wiklander } 182817466cbSJens Wiklander 183*32b31808SJens Wiklander return 0; 184817466cbSJens Wiklander } 185817466cbSJens Wiklander 18611fa71b9SJerome Forissier int mbedtls_asn1_get_int(unsigned char **p, 18711fa71b9SJerome Forissier const unsigned char *end, 18811fa71b9SJerome Forissier int *val) 18911fa71b9SJerome Forissier { 190*32b31808SJens Wiklander return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val); 19111fa71b9SJerome Forissier } 19211fa71b9SJerome Forissier 19311fa71b9SJerome Forissier int mbedtls_asn1_get_enum(unsigned char **p, 19411fa71b9SJerome Forissier const unsigned char *end, 19511fa71b9SJerome Forissier int *val) 19611fa71b9SJerome Forissier { 197*32b31808SJens Wiklander return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val); 19811fa71b9SJerome Forissier } 19911fa71b9SJerome Forissier 200817466cbSJens Wiklander #if defined(MBEDTLS_BIGNUM_C) 201817466cbSJens Wiklander int mbedtls_asn1_get_mpi(unsigned char **p, 202817466cbSJens Wiklander const unsigned char *end, 203817466cbSJens Wiklander mbedtls_mpi *X) 204817466cbSJens Wiklander { 20511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 206817466cbSJens Wiklander size_t len; 207817466cbSJens Wiklander 208*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { 209*32b31808SJens Wiklander return ret; 210*32b31808SJens Wiklander } 211817466cbSJens Wiklander 212817466cbSJens Wiklander ret = mbedtls_mpi_read_binary(X, *p, len); 213817466cbSJens Wiklander 214817466cbSJens Wiklander *p += len; 215817466cbSJens Wiklander 216*32b31808SJens Wiklander return ret; 217817466cbSJens Wiklander } 218817466cbSJens Wiklander #endif /* MBEDTLS_BIGNUM_C */ 219817466cbSJens Wiklander 220817466cbSJens Wiklander int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end, 221817466cbSJens Wiklander mbedtls_asn1_bitstring *bs) 222817466cbSJens Wiklander { 22311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 224817466cbSJens Wiklander 225817466cbSJens Wiklander /* Certificate type is a single byte bitstring */ 226*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) { 227*32b31808SJens Wiklander return ret; 228*32b31808SJens Wiklander } 229817466cbSJens Wiklander 230817466cbSJens Wiklander /* Check length, subtract one for actual bit string length */ 231*32b31808SJens Wiklander if (bs->len < 1) { 232*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 233*32b31808SJens Wiklander } 234817466cbSJens Wiklander bs->len -= 1; 235817466cbSJens Wiklander 236817466cbSJens Wiklander /* Get number of unused bits, ensure unused bits <= 7 */ 237817466cbSJens Wiklander bs->unused_bits = **p; 238*32b31808SJens Wiklander if (bs->unused_bits > 7) { 239*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 240*32b31808SJens Wiklander } 241817466cbSJens Wiklander (*p)++; 242817466cbSJens Wiklander 243817466cbSJens Wiklander /* Get actual bitstring */ 244817466cbSJens Wiklander bs->p = *p; 245817466cbSJens Wiklander *p += bs->len; 246817466cbSJens Wiklander 247*32b31808SJens Wiklander if (*p != end) { 248*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 249*32b31808SJens Wiklander } 250817466cbSJens Wiklander 251*32b31808SJens Wiklander return 0; 252817466cbSJens Wiklander } 253817466cbSJens Wiklander 254817466cbSJens Wiklander /* 25511fa71b9SJerome Forissier * Traverse an ASN.1 "SEQUENCE OF <tag>" 25611fa71b9SJerome Forissier * and call a callback for each entry found. 25711fa71b9SJerome Forissier */ 25811fa71b9SJerome Forissier int mbedtls_asn1_traverse_sequence_of( 25911fa71b9SJerome Forissier unsigned char **p, 26011fa71b9SJerome Forissier const unsigned char *end, 26111fa71b9SJerome Forissier unsigned char tag_must_mask, unsigned char tag_must_val, 26211fa71b9SJerome Forissier unsigned char tag_may_mask, unsigned char tag_may_val, 26311fa71b9SJerome Forissier int (*cb)(void *ctx, int tag, 26411fa71b9SJerome Forissier unsigned char *start, size_t len), 26511fa71b9SJerome Forissier void *ctx) 26611fa71b9SJerome Forissier { 26711fa71b9SJerome Forissier int ret; 26811fa71b9SJerome Forissier size_t len; 26911fa71b9SJerome Forissier 27011fa71b9SJerome Forissier /* Get main sequence tag */ 27111fa71b9SJerome Forissier if ((ret = mbedtls_asn1_get_tag(p, end, &len, 272*32b31808SJens Wiklander MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { 273*32b31808SJens Wiklander return ret; 27411fa71b9SJerome Forissier } 27511fa71b9SJerome Forissier 276*32b31808SJens Wiklander if (*p + len != end) { 277*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 278*32b31808SJens Wiklander } 27911fa71b9SJerome Forissier 280*32b31808SJens Wiklander while (*p < end) { 28111fa71b9SJerome Forissier unsigned char const tag = *(*p)++; 28211fa71b9SJerome Forissier 283*32b31808SJens Wiklander if ((tag & tag_must_mask) != tag_must_val) { 284*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; 285*32b31808SJens Wiklander } 28611fa71b9SJerome Forissier 287*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) { 288*32b31808SJens Wiklander return ret; 289*32b31808SJens Wiklander } 29011fa71b9SJerome Forissier 291*32b31808SJens Wiklander if ((tag & tag_may_mask) == tag_may_val) { 292*32b31808SJens Wiklander if (cb != NULL) { 29311fa71b9SJerome Forissier ret = cb(ctx, tag, *p, len); 294*32b31808SJens Wiklander if (ret != 0) { 295*32b31808SJens Wiklander return ret; 296*32b31808SJens Wiklander } 29711fa71b9SJerome Forissier } 29811fa71b9SJerome Forissier } 29911fa71b9SJerome Forissier 30011fa71b9SJerome Forissier *p += len; 30111fa71b9SJerome Forissier } 30211fa71b9SJerome Forissier 303*32b31808SJens Wiklander return 0; 30411fa71b9SJerome Forissier } 30511fa71b9SJerome Forissier 30611fa71b9SJerome Forissier /* 307817466cbSJens Wiklander * Get a bit string without unused bits 308817466cbSJens Wiklander */ 309817466cbSJens Wiklander int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end, 310817466cbSJens Wiklander size_t *len) 311817466cbSJens Wiklander { 31211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 313817466cbSJens Wiklander 314*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) { 315*32b31808SJens Wiklander return ret; 316*32b31808SJens Wiklander } 317817466cbSJens Wiklander 318*32b31808SJens Wiklander if (*len == 0) { 319*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_DATA; 320*32b31808SJens Wiklander } 32111fa71b9SJerome Forissier --(*len); 32211fa71b9SJerome Forissier 323*32b31808SJens Wiklander if (**p != 0) { 324*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_DATA; 325*32b31808SJens Wiklander } 32611fa71b9SJerome Forissier ++(*p); 327817466cbSJens Wiklander 328*32b31808SJens Wiklander return 0; 329817466cbSJens Wiklander } 330817466cbSJens Wiklander 33111fa71b9SJerome Forissier void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq) 33211fa71b9SJerome Forissier { 333*32b31808SJens Wiklander while (seq != NULL) { 33411fa71b9SJerome Forissier mbedtls_asn1_sequence *next = seq->next; 33511fa71b9SJerome Forissier mbedtls_free(seq); 33611fa71b9SJerome Forissier seq = next; 33711fa71b9SJerome Forissier } 33811fa71b9SJerome Forissier } 339817466cbSJens Wiklander 340*32b31808SJens Wiklander typedef struct { 34111fa71b9SJerome Forissier int tag; 34211fa71b9SJerome Forissier mbedtls_asn1_sequence *cur; 34311fa71b9SJerome Forissier } asn1_get_sequence_of_cb_ctx_t; 34411fa71b9SJerome Forissier 34511fa71b9SJerome Forissier static int asn1_get_sequence_of_cb(void *ctx, 34611fa71b9SJerome Forissier int tag, 34711fa71b9SJerome Forissier unsigned char *start, 34811fa71b9SJerome Forissier size_t len) 34911fa71b9SJerome Forissier { 35011fa71b9SJerome Forissier asn1_get_sequence_of_cb_ctx_t *cb_ctx = 35111fa71b9SJerome Forissier (asn1_get_sequence_of_cb_ctx_t *) ctx; 35211fa71b9SJerome Forissier mbedtls_asn1_sequence *cur = 35311fa71b9SJerome Forissier cb_ctx->cur; 35411fa71b9SJerome Forissier 355*32b31808SJens Wiklander if (cur->buf.p != NULL) { 35611fa71b9SJerome Forissier cur->next = 35711fa71b9SJerome Forissier mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence)); 35811fa71b9SJerome Forissier 359*32b31808SJens Wiklander if (cur->next == NULL) { 360*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_ALLOC_FAILED; 361*32b31808SJens Wiklander } 36211fa71b9SJerome Forissier 36311fa71b9SJerome Forissier cur = cur->next; 36411fa71b9SJerome Forissier } 36511fa71b9SJerome Forissier 36611fa71b9SJerome Forissier cur->buf.p = start; 36711fa71b9SJerome Forissier cur->buf.len = len; 36811fa71b9SJerome Forissier cur->buf.tag = tag; 36911fa71b9SJerome Forissier 37011fa71b9SJerome Forissier cb_ctx->cur = cur; 371*32b31808SJens Wiklander return 0; 37211fa71b9SJerome Forissier } 373817466cbSJens Wiklander 374817466cbSJens Wiklander /* 375817466cbSJens Wiklander * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 376817466cbSJens Wiklander */ 377817466cbSJens Wiklander int mbedtls_asn1_get_sequence_of(unsigned char **p, 378817466cbSJens Wiklander const unsigned char *end, 379817466cbSJens Wiklander mbedtls_asn1_sequence *cur, 380817466cbSJens Wiklander int tag) 381817466cbSJens Wiklander { 38211fa71b9SJerome Forissier asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur }; 38311fa71b9SJerome Forissier memset(cur, 0, sizeof(mbedtls_asn1_sequence)); 384*32b31808SJens Wiklander return mbedtls_asn1_traverse_sequence_of( 38511fa71b9SJerome Forissier p, end, 0xFF, tag, 0, 0, 386*32b31808SJens Wiklander asn1_get_sequence_of_cb, &cb_ctx); 387817466cbSJens Wiklander } 388817466cbSJens Wiklander 389817466cbSJens Wiklander int mbedtls_asn1_get_alg(unsigned char **p, 390817466cbSJens Wiklander const unsigned char *end, 391817466cbSJens Wiklander mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params) 392817466cbSJens Wiklander { 39311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 394817466cbSJens Wiklander size_t len; 395817466cbSJens Wiklander 396817466cbSJens Wiklander if ((ret = mbedtls_asn1_get_tag(p, end, &len, 397*32b31808SJens Wiklander MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { 398*32b31808SJens Wiklander return ret; 399*32b31808SJens Wiklander } 400817466cbSJens Wiklander 401*32b31808SJens Wiklander if ((end - *p) < 1) { 402*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 403*32b31808SJens Wiklander } 404817466cbSJens Wiklander 405817466cbSJens Wiklander alg->tag = **p; 406817466cbSJens Wiklander end = *p + len; 407817466cbSJens Wiklander 408*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) { 409*32b31808SJens Wiklander return ret; 410*32b31808SJens Wiklander } 411817466cbSJens Wiklander 412817466cbSJens Wiklander alg->p = *p; 413817466cbSJens Wiklander *p += alg->len; 414817466cbSJens Wiklander 415*32b31808SJens Wiklander if (*p == end) { 4163d3b0591SJens Wiklander mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf)); 417*32b31808SJens Wiklander return 0; 418817466cbSJens Wiklander } 419817466cbSJens Wiklander 420817466cbSJens Wiklander params->tag = **p; 421817466cbSJens Wiklander (*p)++; 422817466cbSJens Wiklander 423*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_len(p, end, ¶ms->len)) != 0) { 424*32b31808SJens Wiklander return ret; 425*32b31808SJens Wiklander } 426817466cbSJens Wiklander 427817466cbSJens Wiklander params->p = *p; 428817466cbSJens Wiklander *p += params->len; 429817466cbSJens Wiklander 430*32b31808SJens Wiklander if (*p != end) { 431*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 432*32b31808SJens Wiklander } 433817466cbSJens Wiklander 434*32b31808SJens Wiklander return 0; 435817466cbSJens Wiklander } 436817466cbSJens Wiklander 437817466cbSJens Wiklander int mbedtls_asn1_get_alg_null(unsigned char **p, 438817466cbSJens Wiklander const unsigned char *end, 439817466cbSJens Wiklander mbedtls_asn1_buf *alg) 440817466cbSJens Wiklander { 44111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 442817466cbSJens Wiklander mbedtls_asn1_buf params; 443817466cbSJens Wiklander 444817466cbSJens Wiklander memset(¶ms, 0, sizeof(mbedtls_asn1_buf)); 445817466cbSJens Wiklander 446*32b31808SJens Wiklander if ((ret = mbedtls_asn1_get_alg(p, end, alg, ¶ms)) != 0) { 447*32b31808SJens Wiklander return ret; 448817466cbSJens Wiklander } 449817466cbSJens Wiklander 450*32b31808SJens Wiklander if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) { 451*32b31808SJens Wiklander return MBEDTLS_ERR_ASN1_INVALID_DATA; 452*32b31808SJens Wiklander } 453*32b31808SJens Wiklander 454*32b31808SJens Wiklander return 0; 455*32b31808SJens Wiklander } 456*32b31808SJens Wiklander 457*32b31808SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 458817466cbSJens Wiklander void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur) 459817466cbSJens Wiklander { 460*32b31808SJens Wiklander if (cur == NULL) { 461817466cbSJens Wiklander return; 462*32b31808SJens Wiklander } 463817466cbSJens Wiklander 464817466cbSJens Wiklander mbedtls_free(cur->oid.p); 465817466cbSJens Wiklander mbedtls_free(cur->val.p); 466817466cbSJens Wiklander 4673d3b0591SJens Wiklander mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data)); 468817466cbSJens Wiklander } 469*32b31808SJens Wiklander #endif /* MBEDTLS_DEPRECATED_REMOVED */ 470817466cbSJens Wiklander 471817466cbSJens Wiklander void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head) 472817466cbSJens Wiklander { 473817466cbSJens Wiklander mbedtls_asn1_named_data *cur; 474817466cbSJens Wiklander 475*32b31808SJens Wiklander while ((cur = *head) != NULL) { 476817466cbSJens Wiklander *head = cur->next; 477*32b31808SJens Wiklander mbedtls_free(cur->oid.p); 478*32b31808SJens Wiklander mbedtls_free(cur->val.p); 479817466cbSJens Wiklander mbedtls_free(cur); 480817466cbSJens Wiklander } 481817466cbSJens Wiklander } 482817466cbSJens Wiklander 483*32b31808SJens Wiklander void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name) 484*32b31808SJens Wiklander { 485*32b31808SJens Wiklander for (mbedtls_asn1_named_data *next; name != NULL; name = next) { 486*32b31808SJens Wiklander next = name->next; 487*32b31808SJens Wiklander mbedtls_free(name); 488*32b31808SJens Wiklander } 489*32b31808SJens Wiklander } 490*32b31808SJens Wiklander 491*32b31808SJens Wiklander const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list, 492817466cbSJens Wiklander const char *oid, size_t len) 493817466cbSJens Wiklander { 494*32b31808SJens Wiklander while (list != NULL) { 495817466cbSJens Wiklander if (list->oid.len == len && 496*32b31808SJens Wiklander memcmp(list->oid.p, oid, len) == 0) { 497817466cbSJens Wiklander break; 498817466cbSJens Wiklander } 499817466cbSJens Wiklander 500817466cbSJens Wiklander list = list->next; 501817466cbSJens Wiklander } 502817466cbSJens Wiklander 503*32b31808SJens Wiklander return list; 504817466cbSJens Wiklander } 505817466cbSJens Wiklander 506817466cbSJens Wiklander #endif /* MBEDTLS_ASN1_PARSE_C */ 507