1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Generic ASN.1 parsing 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci#include "common.h" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \ 11a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) 12a8e1175bSopenharmony_ci 13a8e1175bSopenharmony_ci#include "mbedtls/asn1.h" 14a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h" 15a8e1175bSopenharmony_ci#include "mbedtls/error.h" 16a8e1175bSopenharmony_ci 17a8e1175bSopenharmony_ci#include <string.h> 18a8e1175bSopenharmony_ci 19a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C) 20a8e1175bSopenharmony_ci#include "mbedtls/bignum.h" 21a8e1175bSopenharmony_ci#endif 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 24a8e1175bSopenharmony_ci 25a8e1175bSopenharmony_ci/* 26a8e1175bSopenharmony_ci * ASN.1 DER decoding routines 27a8e1175bSopenharmony_ci */ 28a8e1175bSopenharmony_ciint mbedtls_asn1_get_len(unsigned char **p, 29a8e1175bSopenharmony_ci const unsigned char *end, 30a8e1175bSopenharmony_ci size_t *len) 31a8e1175bSopenharmony_ci{ 32a8e1175bSopenharmony_ci if ((end - *p) < 1) { 33a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 34a8e1175bSopenharmony_ci } 35a8e1175bSopenharmony_ci 36a8e1175bSopenharmony_ci if ((**p & 0x80) == 0) { 37a8e1175bSopenharmony_ci *len = *(*p)++; 38a8e1175bSopenharmony_ci } else { 39a8e1175bSopenharmony_ci int n = (**p) & 0x7F; 40a8e1175bSopenharmony_ci if (n == 0 || n > 4) { 41a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 42a8e1175bSopenharmony_ci } 43a8e1175bSopenharmony_ci if ((end - *p) <= n) { 44a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 45a8e1175bSopenharmony_ci } 46a8e1175bSopenharmony_ci *len = 0; 47a8e1175bSopenharmony_ci (*p)++; 48a8e1175bSopenharmony_ci while (n--) { 49a8e1175bSopenharmony_ci *len = (*len << 8) | **p; 50a8e1175bSopenharmony_ci (*p)++; 51a8e1175bSopenharmony_ci } 52a8e1175bSopenharmony_ci } 53a8e1175bSopenharmony_ci 54a8e1175bSopenharmony_ci if (*len > (size_t) (end - *p)) { 55a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 56a8e1175bSopenharmony_ci } 57a8e1175bSopenharmony_ci 58a8e1175bSopenharmony_ci return 0; 59a8e1175bSopenharmony_ci} 60a8e1175bSopenharmony_ci 61a8e1175bSopenharmony_ciint mbedtls_asn1_get_tag(unsigned char **p, 62a8e1175bSopenharmony_ci const unsigned char *end, 63a8e1175bSopenharmony_ci size_t *len, int tag) 64a8e1175bSopenharmony_ci{ 65a8e1175bSopenharmony_ci if ((end - *p) < 1) { 66a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 67a8e1175bSopenharmony_ci } 68a8e1175bSopenharmony_ci 69a8e1175bSopenharmony_ci if (**p != tag) { 70a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; 71a8e1175bSopenharmony_ci } 72a8e1175bSopenharmony_ci 73a8e1175bSopenharmony_ci (*p)++; 74a8e1175bSopenharmony_ci 75a8e1175bSopenharmony_ci return mbedtls_asn1_get_len(p, end, len); 76a8e1175bSopenharmony_ci} 77a8e1175bSopenharmony_ci#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */ 78a8e1175bSopenharmony_ci 79a8e1175bSopenharmony_ci#if defined(MBEDTLS_ASN1_PARSE_C) 80a8e1175bSopenharmony_ciint mbedtls_asn1_get_bool(unsigned char **p, 81a8e1175bSopenharmony_ci const unsigned char *end, 82a8e1175bSopenharmony_ci int *val) 83a8e1175bSopenharmony_ci{ 84a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 85a8e1175bSopenharmony_ci size_t len; 86a8e1175bSopenharmony_ci 87a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) { 88a8e1175bSopenharmony_ci return ret; 89a8e1175bSopenharmony_ci } 90a8e1175bSopenharmony_ci 91a8e1175bSopenharmony_ci if (len != 1) { 92a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 93a8e1175bSopenharmony_ci } 94a8e1175bSopenharmony_ci 95a8e1175bSopenharmony_ci *val = (**p != 0) ? 1 : 0; 96a8e1175bSopenharmony_ci (*p)++; 97a8e1175bSopenharmony_ci 98a8e1175bSopenharmony_ci return 0; 99a8e1175bSopenharmony_ci} 100a8e1175bSopenharmony_ci 101a8e1175bSopenharmony_cistatic int asn1_get_tagged_int(unsigned char **p, 102a8e1175bSopenharmony_ci const unsigned char *end, 103a8e1175bSopenharmony_ci int tag, int *val) 104a8e1175bSopenharmony_ci{ 105a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 106a8e1175bSopenharmony_ci size_t len; 107a8e1175bSopenharmony_ci 108a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) { 109a8e1175bSopenharmony_ci return ret; 110a8e1175bSopenharmony_ci } 111a8e1175bSopenharmony_ci 112a8e1175bSopenharmony_ci /* 113a8e1175bSopenharmony_ci * len==0 is malformed (0 must be represented as 020100 for INTEGER, 114a8e1175bSopenharmony_ci * or 0A0100 for ENUMERATED tags 115a8e1175bSopenharmony_ci */ 116a8e1175bSopenharmony_ci if (len == 0) { 117a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 118a8e1175bSopenharmony_ci } 119a8e1175bSopenharmony_ci /* This is a cryptography library. Reject negative integers. */ 120a8e1175bSopenharmony_ci if ((**p & 0x80) != 0) { 121a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 122a8e1175bSopenharmony_ci } 123a8e1175bSopenharmony_ci 124a8e1175bSopenharmony_ci /* Skip leading zeros. */ 125a8e1175bSopenharmony_ci while (len > 0 && **p == 0) { 126a8e1175bSopenharmony_ci ++(*p); 127a8e1175bSopenharmony_ci --len; 128a8e1175bSopenharmony_ci } 129a8e1175bSopenharmony_ci 130a8e1175bSopenharmony_ci /* Reject integers that don't fit in an int. This code assumes that 131a8e1175bSopenharmony_ci * the int type has no padding bit. */ 132a8e1175bSopenharmony_ci if (len > sizeof(int)) { 133a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 134a8e1175bSopenharmony_ci } 135a8e1175bSopenharmony_ci if (len == sizeof(int) && (**p & 0x80) != 0) { 136a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 137a8e1175bSopenharmony_ci } 138a8e1175bSopenharmony_ci 139a8e1175bSopenharmony_ci *val = 0; 140a8e1175bSopenharmony_ci while (len-- > 0) { 141a8e1175bSopenharmony_ci *val = (*val << 8) | **p; 142a8e1175bSopenharmony_ci (*p)++; 143a8e1175bSopenharmony_ci } 144a8e1175bSopenharmony_ci 145a8e1175bSopenharmony_ci return 0; 146a8e1175bSopenharmony_ci} 147a8e1175bSopenharmony_ci 148a8e1175bSopenharmony_ciint mbedtls_asn1_get_int(unsigned char **p, 149a8e1175bSopenharmony_ci const unsigned char *end, 150a8e1175bSopenharmony_ci int *val) 151a8e1175bSopenharmony_ci{ 152a8e1175bSopenharmony_ci return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val); 153a8e1175bSopenharmony_ci} 154a8e1175bSopenharmony_ci 155a8e1175bSopenharmony_ciint mbedtls_asn1_get_enum(unsigned char **p, 156a8e1175bSopenharmony_ci const unsigned char *end, 157a8e1175bSopenharmony_ci int *val) 158a8e1175bSopenharmony_ci{ 159a8e1175bSopenharmony_ci return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val); 160a8e1175bSopenharmony_ci} 161a8e1175bSopenharmony_ci 162a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C) 163a8e1175bSopenharmony_ciint mbedtls_asn1_get_mpi(unsigned char **p, 164a8e1175bSopenharmony_ci const unsigned char *end, 165a8e1175bSopenharmony_ci mbedtls_mpi *X) 166a8e1175bSopenharmony_ci{ 167a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 168a8e1175bSopenharmony_ci size_t len; 169a8e1175bSopenharmony_ci 170a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { 171a8e1175bSopenharmony_ci return ret; 172a8e1175bSopenharmony_ci } 173a8e1175bSopenharmony_ci 174a8e1175bSopenharmony_ci ret = mbedtls_mpi_read_binary(X, *p, len); 175a8e1175bSopenharmony_ci 176a8e1175bSopenharmony_ci *p += len; 177a8e1175bSopenharmony_ci 178a8e1175bSopenharmony_ci return ret; 179a8e1175bSopenharmony_ci} 180a8e1175bSopenharmony_ci#endif /* MBEDTLS_BIGNUM_C */ 181a8e1175bSopenharmony_ci 182a8e1175bSopenharmony_ciint mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end, 183a8e1175bSopenharmony_ci mbedtls_asn1_bitstring *bs) 184a8e1175bSopenharmony_ci{ 185a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 186a8e1175bSopenharmony_ci 187a8e1175bSopenharmony_ci /* Certificate type is a single byte bitstring */ 188a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) { 189a8e1175bSopenharmony_ci return ret; 190a8e1175bSopenharmony_ci } 191a8e1175bSopenharmony_ci 192a8e1175bSopenharmony_ci /* Check length, subtract one for actual bit string length */ 193a8e1175bSopenharmony_ci if (bs->len < 1) { 194a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 195a8e1175bSopenharmony_ci } 196a8e1175bSopenharmony_ci bs->len -= 1; 197a8e1175bSopenharmony_ci 198a8e1175bSopenharmony_ci /* Get number of unused bits, ensure unused bits <= 7 */ 199a8e1175bSopenharmony_ci bs->unused_bits = **p; 200a8e1175bSopenharmony_ci if (bs->unused_bits > 7) { 201a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 202a8e1175bSopenharmony_ci } 203a8e1175bSopenharmony_ci (*p)++; 204a8e1175bSopenharmony_ci 205a8e1175bSopenharmony_ci /* Get actual bitstring */ 206a8e1175bSopenharmony_ci bs->p = *p; 207a8e1175bSopenharmony_ci *p += bs->len; 208a8e1175bSopenharmony_ci 209a8e1175bSopenharmony_ci if (*p != end) { 210a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 211a8e1175bSopenharmony_ci } 212a8e1175bSopenharmony_ci 213a8e1175bSopenharmony_ci return 0; 214a8e1175bSopenharmony_ci} 215a8e1175bSopenharmony_ci 216a8e1175bSopenharmony_ci/* 217a8e1175bSopenharmony_ci * Traverse an ASN.1 "SEQUENCE OF <tag>" 218a8e1175bSopenharmony_ci * and call a callback for each entry found. 219a8e1175bSopenharmony_ci */ 220a8e1175bSopenharmony_ciint mbedtls_asn1_traverse_sequence_of( 221a8e1175bSopenharmony_ci unsigned char **p, 222a8e1175bSopenharmony_ci const unsigned char *end, 223a8e1175bSopenharmony_ci unsigned char tag_must_mask, unsigned char tag_must_val, 224a8e1175bSopenharmony_ci unsigned char tag_may_mask, unsigned char tag_may_val, 225a8e1175bSopenharmony_ci int (*cb)(void *ctx, int tag, 226a8e1175bSopenharmony_ci unsigned char *start, size_t len), 227a8e1175bSopenharmony_ci void *ctx) 228a8e1175bSopenharmony_ci{ 229a8e1175bSopenharmony_ci int ret; 230a8e1175bSopenharmony_ci size_t len; 231a8e1175bSopenharmony_ci 232a8e1175bSopenharmony_ci /* Get main sequence tag */ 233a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_tag(p, end, &len, 234a8e1175bSopenharmony_ci MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { 235a8e1175bSopenharmony_ci return ret; 236a8e1175bSopenharmony_ci } 237a8e1175bSopenharmony_ci 238a8e1175bSopenharmony_ci if (*p + len != end) { 239a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 240a8e1175bSopenharmony_ci } 241a8e1175bSopenharmony_ci 242a8e1175bSopenharmony_ci while (*p < end) { 243a8e1175bSopenharmony_ci unsigned char const tag = *(*p)++; 244a8e1175bSopenharmony_ci 245a8e1175bSopenharmony_ci if ((tag & tag_must_mask) != tag_must_val) { 246a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; 247a8e1175bSopenharmony_ci } 248a8e1175bSopenharmony_ci 249a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) { 250a8e1175bSopenharmony_ci return ret; 251a8e1175bSopenharmony_ci } 252a8e1175bSopenharmony_ci 253a8e1175bSopenharmony_ci if ((tag & tag_may_mask) == tag_may_val) { 254a8e1175bSopenharmony_ci if (cb != NULL) { 255a8e1175bSopenharmony_ci ret = cb(ctx, tag, *p, len); 256a8e1175bSopenharmony_ci if (ret != 0) { 257a8e1175bSopenharmony_ci return ret; 258a8e1175bSopenharmony_ci } 259a8e1175bSopenharmony_ci } 260a8e1175bSopenharmony_ci } 261a8e1175bSopenharmony_ci 262a8e1175bSopenharmony_ci *p += len; 263a8e1175bSopenharmony_ci } 264a8e1175bSopenharmony_ci 265a8e1175bSopenharmony_ci return 0; 266a8e1175bSopenharmony_ci} 267a8e1175bSopenharmony_ci 268a8e1175bSopenharmony_ci/* 269a8e1175bSopenharmony_ci * Get a bit string without unused bits 270a8e1175bSopenharmony_ci */ 271a8e1175bSopenharmony_ciint mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end, 272a8e1175bSopenharmony_ci size_t *len) 273a8e1175bSopenharmony_ci{ 274a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 275a8e1175bSopenharmony_ci 276a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) { 277a8e1175bSopenharmony_ci return ret; 278a8e1175bSopenharmony_ci } 279a8e1175bSopenharmony_ci 280a8e1175bSopenharmony_ci if (*len == 0) { 281a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_DATA; 282a8e1175bSopenharmony_ci } 283a8e1175bSopenharmony_ci --(*len); 284a8e1175bSopenharmony_ci 285a8e1175bSopenharmony_ci if (**p != 0) { 286a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_DATA; 287a8e1175bSopenharmony_ci } 288a8e1175bSopenharmony_ci ++(*p); 289a8e1175bSopenharmony_ci 290a8e1175bSopenharmony_ci return 0; 291a8e1175bSopenharmony_ci} 292a8e1175bSopenharmony_ci 293a8e1175bSopenharmony_civoid mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq) 294a8e1175bSopenharmony_ci{ 295a8e1175bSopenharmony_ci while (seq != NULL) { 296a8e1175bSopenharmony_ci mbedtls_asn1_sequence *next = seq->next; 297a8e1175bSopenharmony_ci mbedtls_free(seq); 298a8e1175bSopenharmony_ci seq = next; 299a8e1175bSopenharmony_ci } 300a8e1175bSopenharmony_ci} 301a8e1175bSopenharmony_ci 302a8e1175bSopenharmony_citypedef struct { 303a8e1175bSopenharmony_ci int tag; 304a8e1175bSopenharmony_ci mbedtls_asn1_sequence *cur; 305a8e1175bSopenharmony_ci} asn1_get_sequence_of_cb_ctx_t; 306a8e1175bSopenharmony_ci 307a8e1175bSopenharmony_cistatic int asn1_get_sequence_of_cb(void *ctx, 308a8e1175bSopenharmony_ci int tag, 309a8e1175bSopenharmony_ci unsigned char *start, 310a8e1175bSopenharmony_ci size_t len) 311a8e1175bSopenharmony_ci{ 312a8e1175bSopenharmony_ci asn1_get_sequence_of_cb_ctx_t *cb_ctx = 313a8e1175bSopenharmony_ci (asn1_get_sequence_of_cb_ctx_t *) ctx; 314a8e1175bSopenharmony_ci mbedtls_asn1_sequence *cur = 315a8e1175bSopenharmony_ci cb_ctx->cur; 316a8e1175bSopenharmony_ci 317a8e1175bSopenharmony_ci if (cur->buf.p != NULL) { 318a8e1175bSopenharmony_ci cur->next = 319a8e1175bSopenharmony_ci mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence)); 320a8e1175bSopenharmony_ci 321a8e1175bSopenharmony_ci if (cur->next == NULL) { 322a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_ALLOC_FAILED; 323a8e1175bSopenharmony_ci } 324a8e1175bSopenharmony_ci 325a8e1175bSopenharmony_ci cur = cur->next; 326a8e1175bSopenharmony_ci } 327a8e1175bSopenharmony_ci 328a8e1175bSopenharmony_ci cur->buf.p = start; 329a8e1175bSopenharmony_ci cur->buf.len = len; 330a8e1175bSopenharmony_ci cur->buf.tag = tag; 331a8e1175bSopenharmony_ci 332a8e1175bSopenharmony_ci cb_ctx->cur = cur; 333a8e1175bSopenharmony_ci return 0; 334a8e1175bSopenharmony_ci} 335a8e1175bSopenharmony_ci 336a8e1175bSopenharmony_ci/* 337a8e1175bSopenharmony_ci * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 338a8e1175bSopenharmony_ci */ 339a8e1175bSopenharmony_ciint mbedtls_asn1_get_sequence_of(unsigned char **p, 340a8e1175bSopenharmony_ci const unsigned char *end, 341a8e1175bSopenharmony_ci mbedtls_asn1_sequence *cur, 342a8e1175bSopenharmony_ci int tag) 343a8e1175bSopenharmony_ci{ 344a8e1175bSopenharmony_ci asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur }; 345a8e1175bSopenharmony_ci memset(cur, 0, sizeof(mbedtls_asn1_sequence)); 346a8e1175bSopenharmony_ci return mbedtls_asn1_traverse_sequence_of( 347a8e1175bSopenharmony_ci p, end, 0xFF, tag, 0, 0, 348a8e1175bSopenharmony_ci asn1_get_sequence_of_cb, &cb_ctx); 349a8e1175bSopenharmony_ci} 350a8e1175bSopenharmony_ci 351a8e1175bSopenharmony_ciint mbedtls_asn1_get_alg(unsigned char **p, 352a8e1175bSopenharmony_ci const unsigned char *end, 353a8e1175bSopenharmony_ci mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params) 354a8e1175bSopenharmony_ci{ 355a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 356a8e1175bSopenharmony_ci size_t len; 357a8e1175bSopenharmony_ci 358a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_tag(p, end, &len, 359a8e1175bSopenharmony_ci MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { 360a8e1175bSopenharmony_ci return ret; 361a8e1175bSopenharmony_ci } 362a8e1175bSopenharmony_ci 363a8e1175bSopenharmony_ci if ((end - *p) < 1) { 364a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_OUT_OF_DATA; 365a8e1175bSopenharmony_ci } 366a8e1175bSopenharmony_ci 367a8e1175bSopenharmony_ci alg->tag = **p; 368a8e1175bSopenharmony_ci end = *p + len; 369a8e1175bSopenharmony_ci 370a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) { 371a8e1175bSopenharmony_ci return ret; 372a8e1175bSopenharmony_ci } 373a8e1175bSopenharmony_ci 374a8e1175bSopenharmony_ci alg->p = *p; 375a8e1175bSopenharmony_ci *p += alg->len; 376a8e1175bSopenharmony_ci 377a8e1175bSopenharmony_ci if (*p == end) { 378a8e1175bSopenharmony_ci mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf)); 379a8e1175bSopenharmony_ci return 0; 380a8e1175bSopenharmony_ci } 381a8e1175bSopenharmony_ci 382a8e1175bSopenharmony_ci params->tag = **p; 383a8e1175bSopenharmony_ci (*p)++; 384a8e1175bSopenharmony_ci 385a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_len(p, end, ¶ms->len)) != 0) { 386a8e1175bSopenharmony_ci return ret; 387a8e1175bSopenharmony_ci } 388a8e1175bSopenharmony_ci 389a8e1175bSopenharmony_ci params->p = *p; 390a8e1175bSopenharmony_ci *p += params->len; 391a8e1175bSopenharmony_ci 392a8e1175bSopenharmony_ci if (*p != end) { 393a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 394a8e1175bSopenharmony_ci } 395a8e1175bSopenharmony_ci 396a8e1175bSopenharmony_ci return 0; 397a8e1175bSopenharmony_ci} 398a8e1175bSopenharmony_ci 399a8e1175bSopenharmony_ciint mbedtls_asn1_get_alg_null(unsigned char **p, 400a8e1175bSopenharmony_ci const unsigned char *end, 401a8e1175bSopenharmony_ci mbedtls_asn1_buf *alg) 402a8e1175bSopenharmony_ci{ 403a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 404a8e1175bSopenharmony_ci mbedtls_asn1_buf params; 405a8e1175bSopenharmony_ci 406a8e1175bSopenharmony_ci memset(¶ms, 0, sizeof(mbedtls_asn1_buf)); 407a8e1175bSopenharmony_ci 408a8e1175bSopenharmony_ci if ((ret = mbedtls_asn1_get_alg(p, end, alg, ¶ms)) != 0) { 409a8e1175bSopenharmony_ci return ret; 410a8e1175bSopenharmony_ci } 411a8e1175bSopenharmony_ci 412a8e1175bSopenharmony_ci if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) { 413a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_DATA; 414a8e1175bSopenharmony_ci } 415a8e1175bSopenharmony_ci 416a8e1175bSopenharmony_ci return 0; 417a8e1175bSopenharmony_ci} 418a8e1175bSopenharmony_ci 419a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DEPRECATED_REMOVED) 420a8e1175bSopenharmony_civoid mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur) 421a8e1175bSopenharmony_ci{ 422a8e1175bSopenharmony_ci if (cur == NULL) { 423a8e1175bSopenharmony_ci return; 424a8e1175bSopenharmony_ci } 425a8e1175bSopenharmony_ci 426a8e1175bSopenharmony_ci mbedtls_free(cur->oid.p); 427a8e1175bSopenharmony_ci mbedtls_free(cur->val.p); 428a8e1175bSopenharmony_ci 429a8e1175bSopenharmony_ci mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data)); 430a8e1175bSopenharmony_ci} 431a8e1175bSopenharmony_ci#endif /* MBEDTLS_DEPRECATED_REMOVED */ 432a8e1175bSopenharmony_ci 433a8e1175bSopenharmony_civoid mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head) 434a8e1175bSopenharmony_ci{ 435a8e1175bSopenharmony_ci mbedtls_asn1_named_data *cur; 436a8e1175bSopenharmony_ci 437a8e1175bSopenharmony_ci while ((cur = *head) != NULL) { 438a8e1175bSopenharmony_ci *head = cur->next; 439a8e1175bSopenharmony_ci mbedtls_free(cur->oid.p); 440a8e1175bSopenharmony_ci mbedtls_free(cur->val.p); 441a8e1175bSopenharmony_ci mbedtls_free(cur); 442a8e1175bSopenharmony_ci } 443a8e1175bSopenharmony_ci} 444a8e1175bSopenharmony_ci 445a8e1175bSopenharmony_civoid mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name) 446a8e1175bSopenharmony_ci{ 447a8e1175bSopenharmony_ci for (mbedtls_asn1_named_data *next; name != NULL; name = next) { 448a8e1175bSopenharmony_ci next = name->next; 449a8e1175bSopenharmony_ci mbedtls_free(name); 450a8e1175bSopenharmony_ci } 451a8e1175bSopenharmony_ci} 452a8e1175bSopenharmony_ci 453a8e1175bSopenharmony_ciconst mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list, 454a8e1175bSopenharmony_ci const char *oid, size_t len) 455a8e1175bSopenharmony_ci{ 456a8e1175bSopenharmony_ci while (list != NULL) { 457a8e1175bSopenharmony_ci if (list->oid.len == len && 458a8e1175bSopenharmony_ci memcmp(list->oid.p, oid, len) == 0) { 459a8e1175bSopenharmony_ci break; 460a8e1175bSopenharmony_ci } 461a8e1175bSopenharmony_ci 462a8e1175bSopenharmony_ci list = list->next; 463a8e1175bSopenharmony_ci } 464a8e1175bSopenharmony_ci 465a8e1175bSopenharmony_ci return list; 466a8e1175bSopenharmony_ci} 467a8e1175bSopenharmony_ci 468a8e1175bSopenharmony_ci#endif /* MBEDTLS_ASN1_PARSE_C */ 469