1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * ASN.1 buffer writing functionality 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_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \ 11a8e1175bSopenharmony_ci defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) 12a8e1175bSopenharmony_ci 13a8e1175bSopenharmony_ci#include "mbedtls/asn1write.h" 14a8e1175bSopenharmony_ci#include "mbedtls/error.h" 15a8e1175bSopenharmony_ci 16a8e1175bSopenharmony_ci#include <string.h> 17a8e1175bSopenharmony_ci 18a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 19a8e1175bSopenharmony_ci 20a8e1175bSopenharmony_ci#if defined(MBEDTLS_ASN1_PARSE_C) 21a8e1175bSopenharmony_ci#include "mbedtls/asn1.h" 22a8e1175bSopenharmony_ci#endif 23a8e1175bSopenharmony_ci 24a8e1175bSopenharmony_ciint mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start, size_t len) 25a8e1175bSopenharmony_ci{ 26a8e1175bSopenharmony_ci#if SIZE_MAX > 0xFFFFFFFF 27a8e1175bSopenharmony_ci if (len > 0xFFFFFFFF) { 28a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_INVALID_LENGTH; 29a8e1175bSopenharmony_ci } 30a8e1175bSopenharmony_ci#endif 31a8e1175bSopenharmony_ci 32a8e1175bSopenharmony_ci int required = 1; 33a8e1175bSopenharmony_ci 34a8e1175bSopenharmony_ci if (len >= 0x80) { 35a8e1175bSopenharmony_ci for (size_t l = len; l != 0; l >>= 8) { 36a8e1175bSopenharmony_ci required++; 37a8e1175bSopenharmony_ci } 38a8e1175bSopenharmony_ci } 39a8e1175bSopenharmony_ci 40a8e1175bSopenharmony_ci if (required > (*p - start)) { 41a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 42a8e1175bSopenharmony_ci } 43a8e1175bSopenharmony_ci 44a8e1175bSopenharmony_ci do { 45a8e1175bSopenharmony_ci *--(*p) = MBEDTLS_BYTE_0(len); 46a8e1175bSopenharmony_ci len >>= 8; 47a8e1175bSopenharmony_ci } while (len); 48a8e1175bSopenharmony_ci 49a8e1175bSopenharmony_ci if (required > 1) { 50a8e1175bSopenharmony_ci *--(*p) = (unsigned char) (0x80 + required - 1); 51a8e1175bSopenharmony_ci } 52a8e1175bSopenharmony_ci 53a8e1175bSopenharmony_ci return required; 54a8e1175bSopenharmony_ci} 55a8e1175bSopenharmony_ci 56a8e1175bSopenharmony_ciint mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, unsigned char tag) 57a8e1175bSopenharmony_ci{ 58a8e1175bSopenharmony_ci if (*p - start < 1) { 59a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 60a8e1175bSopenharmony_ci } 61a8e1175bSopenharmony_ci 62a8e1175bSopenharmony_ci *--(*p) = tag; 63a8e1175bSopenharmony_ci 64a8e1175bSopenharmony_ci return 1; 65a8e1175bSopenharmony_ci} 66a8e1175bSopenharmony_ci#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */ 67a8e1175bSopenharmony_ci 68a8e1175bSopenharmony_ci#if defined(MBEDTLS_ASN1_WRITE_C) 69a8e1175bSopenharmony_cistatic int mbedtls_asn1_write_len_and_tag(unsigned char **p, 70a8e1175bSopenharmony_ci const unsigned char *start, 71a8e1175bSopenharmony_ci size_t len, 72a8e1175bSopenharmony_ci unsigned char tag) 73a8e1175bSopenharmony_ci{ 74a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 75a8e1175bSopenharmony_ci 76a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 77a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, tag)); 78a8e1175bSopenharmony_ci 79a8e1175bSopenharmony_ci return (int) len; 80a8e1175bSopenharmony_ci} 81a8e1175bSopenharmony_ci 82a8e1175bSopenharmony_ciint mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start, 83a8e1175bSopenharmony_ci const unsigned char *buf, size_t size) 84a8e1175bSopenharmony_ci{ 85a8e1175bSopenharmony_ci size_t len = 0; 86a8e1175bSopenharmony_ci 87a8e1175bSopenharmony_ci if (*p < start || (size_t) (*p - start) < size) { 88a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 89a8e1175bSopenharmony_ci } 90a8e1175bSopenharmony_ci 91a8e1175bSopenharmony_ci len = size; 92a8e1175bSopenharmony_ci (*p) -= len; 93a8e1175bSopenharmony_ci memcpy(*p, buf, len); 94a8e1175bSopenharmony_ci 95a8e1175bSopenharmony_ci return (int) len; 96a8e1175bSopenharmony_ci} 97a8e1175bSopenharmony_ci 98a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C) 99a8e1175bSopenharmony_ciint mbedtls_asn1_write_mpi(unsigned char **p, const unsigned char *start, const mbedtls_mpi *X) 100a8e1175bSopenharmony_ci{ 101a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 102a8e1175bSopenharmony_ci size_t len = 0; 103a8e1175bSopenharmony_ci 104a8e1175bSopenharmony_ci // Write the MPI 105a8e1175bSopenharmony_ci // 106a8e1175bSopenharmony_ci len = mbedtls_mpi_size(X); 107a8e1175bSopenharmony_ci 108a8e1175bSopenharmony_ci /* DER represents 0 with a sign bit (0=nonnegative) and 7 value bits, not 109a8e1175bSopenharmony_ci * as 0 digits. We need to end up with 020100, not with 0200. */ 110a8e1175bSopenharmony_ci if (len == 0) { 111a8e1175bSopenharmony_ci len = 1; 112a8e1175bSopenharmony_ci } 113a8e1175bSopenharmony_ci 114a8e1175bSopenharmony_ci if (*p < start || (size_t) (*p - start) < len) { 115a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 116a8e1175bSopenharmony_ci } 117a8e1175bSopenharmony_ci 118a8e1175bSopenharmony_ci (*p) -= len; 119a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(X, *p, len)); 120a8e1175bSopenharmony_ci 121a8e1175bSopenharmony_ci // DER format assumes 2s complement for numbers, so the leftmost bit 122a8e1175bSopenharmony_ci // should be 0 for positive numbers and 1 for negative numbers. 123a8e1175bSopenharmony_ci // 124a8e1175bSopenharmony_ci if (X->s == 1 && **p & 0x80) { 125a8e1175bSopenharmony_ci if (*p - start < 1) { 126a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 127a8e1175bSopenharmony_ci } 128a8e1175bSopenharmony_ci 129a8e1175bSopenharmony_ci *--(*p) = 0x00; 130a8e1175bSopenharmony_ci len += 1; 131a8e1175bSopenharmony_ci } 132a8e1175bSopenharmony_ci 133a8e1175bSopenharmony_ci ret = mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_INTEGER); 134a8e1175bSopenharmony_ci 135a8e1175bSopenharmony_cicleanup: 136a8e1175bSopenharmony_ci return ret; 137a8e1175bSopenharmony_ci} 138a8e1175bSopenharmony_ci#endif /* MBEDTLS_BIGNUM_C */ 139a8e1175bSopenharmony_ci 140a8e1175bSopenharmony_ciint mbedtls_asn1_write_null(unsigned char **p, const unsigned char *start) 141a8e1175bSopenharmony_ci{ 142a8e1175bSopenharmony_ci // Write NULL 143a8e1175bSopenharmony_ci // 144a8e1175bSopenharmony_ci return mbedtls_asn1_write_len_and_tag(p, start, 0, MBEDTLS_ASN1_NULL); 145a8e1175bSopenharmony_ci} 146a8e1175bSopenharmony_ci 147a8e1175bSopenharmony_ciint mbedtls_asn1_write_oid(unsigned char **p, const unsigned char *start, 148a8e1175bSopenharmony_ci const char *oid, size_t oid_len) 149a8e1175bSopenharmony_ci{ 150a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 151a8e1175bSopenharmony_ci size_t len = 0; 152a8e1175bSopenharmony_ci 153a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, 154a8e1175bSopenharmony_ci (const unsigned char *) oid, oid_len)); 155a8e1175bSopenharmony_ci return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_OID); 156a8e1175bSopenharmony_ci} 157a8e1175bSopenharmony_ci 158a8e1175bSopenharmony_ciint mbedtls_asn1_write_algorithm_identifier(unsigned char **p, const unsigned char *start, 159a8e1175bSopenharmony_ci const char *oid, size_t oid_len, 160a8e1175bSopenharmony_ci size_t par_len) 161a8e1175bSopenharmony_ci{ 162a8e1175bSopenharmony_ci return mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, par_len, 1); 163a8e1175bSopenharmony_ci} 164a8e1175bSopenharmony_ci 165a8e1175bSopenharmony_ciint mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, const unsigned char *start, 166a8e1175bSopenharmony_ci const char *oid, size_t oid_len, 167a8e1175bSopenharmony_ci size_t par_len, int has_par) 168a8e1175bSopenharmony_ci{ 169a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 170a8e1175bSopenharmony_ci size_t len = 0; 171a8e1175bSopenharmony_ci 172a8e1175bSopenharmony_ci if (has_par) { 173a8e1175bSopenharmony_ci if (par_len == 0) { 174a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start)); 175a8e1175bSopenharmony_ci } else { 176a8e1175bSopenharmony_ci len += par_len; 177a8e1175bSopenharmony_ci } 178a8e1175bSopenharmony_ci } 179a8e1175bSopenharmony_ci 180a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len)); 181a8e1175bSopenharmony_ci 182a8e1175bSopenharmony_ci return mbedtls_asn1_write_len_and_tag(p, start, len, 183a8e1175bSopenharmony_ci MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); 184a8e1175bSopenharmony_ci} 185a8e1175bSopenharmony_ci 186a8e1175bSopenharmony_ciint mbedtls_asn1_write_bool(unsigned char **p, const unsigned char *start, int boolean) 187a8e1175bSopenharmony_ci{ 188a8e1175bSopenharmony_ci size_t len = 0; 189a8e1175bSopenharmony_ci 190a8e1175bSopenharmony_ci if (*p - start < 1) { 191a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 192a8e1175bSopenharmony_ci } 193a8e1175bSopenharmony_ci 194a8e1175bSopenharmony_ci *--(*p) = (boolean) ? 255 : 0; 195a8e1175bSopenharmony_ci len++; 196a8e1175bSopenharmony_ci 197a8e1175bSopenharmony_ci return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_BOOLEAN); 198a8e1175bSopenharmony_ci} 199a8e1175bSopenharmony_ci 200a8e1175bSopenharmony_cistatic int asn1_write_tagged_int(unsigned char **p, const unsigned char *start, int val, int tag) 201a8e1175bSopenharmony_ci{ 202a8e1175bSopenharmony_ci size_t len = 0; 203a8e1175bSopenharmony_ci 204a8e1175bSopenharmony_ci do { 205a8e1175bSopenharmony_ci if (*p - start < 1) { 206a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 207a8e1175bSopenharmony_ci } 208a8e1175bSopenharmony_ci len += 1; 209a8e1175bSopenharmony_ci *--(*p) = val & 0xff; 210a8e1175bSopenharmony_ci val >>= 8; 211a8e1175bSopenharmony_ci } while (val > 0); 212a8e1175bSopenharmony_ci 213a8e1175bSopenharmony_ci if (**p & 0x80) { 214a8e1175bSopenharmony_ci if (*p - start < 1) { 215a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 216a8e1175bSopenharmony_ci } 217a8e1175bSopenharmony_ci *--(*p) = 0x00; 218a8e1175bSopenharmony_ci len += 1; 219a8e1175bSopenharmony_ci } 220a8e1175bSopenharmony_ci 221a8e1175bSopenharmony_ci return mbedtls_asn1_write_len_and_tag(p, start, len, tag); 222a8e1175bSopenharmony_ci} 223a8e1175bSopenharmony_ci 224a8e1175bSopenharmony_ciint mbedtls_asn1_write_int(unsigned char **p, const unsigned char *start, int val) 225a8e1175bSopenharmony_ci{ 226a8e1175bSopenharmony_ci return asn1_write_tagged_int(p, start, val, MBEDTLS_ASN1_INTEGER); 227a8e1175bSopenharmony_ci} 228a8e1175bSopenharmony_ci 229a8e1175bSopenharmony_ciint mbedtls_asn1_write_enum(unsigned char **p, const unsigned char *start, int val) 230a8e1175bSopenharmony_ci{ 231a8e1175bSopenharmony_ci return asn1_write_tagged_int(p, start, val, MBEDTLS_ASN1_ENUMERATED); 232a8e1175bSopenharmony_ci} 233a8e1175bSopenharmony_ci 234a8e1175bSopenharmony_ciint mbedtls_asn1_write_tagged_string(unsigned char **p, const unsigned char *start, int tag, 235a8e1175bSopenharmony_ci const char *text, size_t text_len) 236a8e1175bSopenharmony_ci{ 237a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 238a8e1175bSopenharmony_ci size_t len = 0; 239a8e1175bSopenharmony_ci 240a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, 241a8e1175bSopenharmony_ci (const unsigned char *) text, 242a8e1175bSopenharmony_ci text_len)); 243a8e1175bSopenharmony_ci 244a8e1175bSopenharmony_ci return mbedtls_asn1_write_len_and_tag(p, start, len, tag); 245a8e1175bSopenharmony_ci} 246a8e1175bSopenharmony_ci 247a8e1175bSopenharmony_ciint mbedtls_asn1_write_utf8_string(unsigned char **p, const unsigned char *start, 248a8e1175bSopenharmony_ci const char *text, size_t text_len) 249a8e1175bSopenharmony_ci{ 250a8e1175bSopenharmony_ci return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len); 251a8e1175bSopenharmony_ci} 252a8e1175bSopenharmony_ci 253a8e1175bSopenharmony_ciint mbedtls_asn1_write_printable_string(unsigned char **p, const unsigned char *start, 254a8e1175bSopenharmony_ci const char *text, size_t text_len) 255a8e1175bSopenharmony_ci{ 256a8e1175bSopenharmony_ci return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, 257a8e1175bSopenharmony_ci text_len); 258a8e1175bSopenharmony_ci} 259a8e1175bSopenharmony_ci 260a8e1175bSopenharmony_ciint mbedtls_asn1_write_ia5_string(unsigned char **p, const unsigned char *start, 261a8e1175bSopenharmony_ci const char *text, size_t text_len) 262a8e1175bSopenharmony_ci{ 263a8e1175bSopenharmony_ci return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len); 264a8e1175bSopenharmony_ci} 265a8e1175bSopenharmony_ci 266a8e1175bSopenharmony_ciint mbedtls_asn1_write_named_bitstring(unsigned char **p, 267a8e1175bSopenharmony_ci const unsigned char *start, 268a8e1175bSopenharmony_ci const unsigned char *buf, 269a8e1175bSopenharmony_ci size_t bits) 270a8e1175bSopenharmony_ci{ 271a8e1175bSopenharmony_ci size_t unused_bits, byte_len; 272a8e1175bSopenharmony_ci const unsigned char *cur_byte; 273a8e1175bSopenharmony_ci unsigned char cur_byte_shifted; 274a8e1175bSopenharmony_ci unsigned char bit; 275a8e1175bSopenharmony_ci 276a8e1175bSopenharmony_ci byte_len = (bits + 7) / 8; 277a8e1175bSopenharmony_ci unused_bits = (byte_len * 8) - bits; 278a8e1175bSopenharmony_ci 279a8e1175bSopenharmony_ci /* 280a8e1175bSopenharmony_ci * Named bitstrings require that trailing 0s are excluded in the encoding 281a8e1175bSopenharmony_ci * of the bitstring. Trailing 0s are considered part of the 'unused' bits 282a8e1175bSopenharmony_ci * when encoding this value in the first content octet 283a8e1175bSopenharmony_ci */ 284a8e1175bSopenharmony_ci if (bits != 0) { 285a8e1175bSopenharmony_ci cur_byte = buf + byte_len - 1; 286a8e1175bSopenharmony_ci cur_byte_shifted = *cur_byte >> unused_bits; 287a8e1175bSopenharmony_ci 288a8e1175bSopenharmony_ci for (;;) { 289a8e1175bSopenharmony_ci bit = cur_byte_shifted & 0x1; 290a8e1175bSopenharmony_ci cur_byte_shifted >>= 1; 291a8e1175bSopenharmony_ci 292a8e1175bSopenharmony_ci if (bit != 0) { 293a8e1175bSopenharmony_ci break; 294a8e1175bSopenharmony_ci } 295a8e1175bSopenharmony_ci 296a8e1175bSopenharmony_ci bits--; 297a8e1175bSopenharmony_ci if (bits == 0) { 298a8e1175bSopenharmony_ci break; 299a8e1175bSopenharmony_ci } 300a8e1175bSopenharmony_ci 301a8e1175bSopenharmony_ci if (bits % 8 == 0) { 302a8e1175bSopenharmony_ci cur_byte_shifted = *--cur_byte; 303a8e1175bSopenharmony_ci } 304a8e1175bSopenharmony_ci } 305a8e1175bSopenharmony_ci } 306a8e1175bSopenharmony_ci 307a8e1175bSopenharmony_ci return mbedtls_asn1_write_bitstring(p, start, buf, bits); 308a8e1175bSopenharmony_ci} 309a8e1175bSopenharmony_ci 310a8e1175bSopenharmony_ciint mbedtls_asn1_write_bitstring(unsigned char **p, const unsigned char *start, 311a8e1175bSopenharmony_ci const unsigned char *buf, size_t bits) 312a8e1175bSopenharmony_ci{ 313a8e1175bSopenharmony_ci size_t len = 0; 314a8e1175bSopenharmony_ci size_t unused_bits, byte_len; 315a8e1175bSopenharmony_ci 316a8e1175bSopenharmony_ci byte_len = (bits + 7) / 8; 317a8e1175bSopenharmony_ci unused_bits = (byte_len * 8) - bits; 318a8e1175bSopenharmony_ci 319a8e1175bSopenharmony_ci if (*p < start || (size_t) (*p - start) < byte_len + 1) { 320a8e1175bSopenharmony_ci return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; 321a8e1175bSopenharmony_ci } 322a8e1175bSopenharmony_ci 323a8e1175bSopenharmony_ci len = byte_len + 1; 324a8e1175bSopenharmony_ci 325a8e1175bSopenharmony_ci /* Write the bitstring. Ensure the unused bits are zeroed */ 326a8e1175bSopenharmony_ci if (byte_len > 0) { 327a8e1175bSopenharmony_ci byte_len--; 328a8e1175bSopenharmony_ci *--(*p) = buf[byte_len] & ~((0x1 << unused_bits) - 1); 329a8e1175bSopenharmony_ci (*p) -= byte_len; 330a8e1175bSopenharmony_ci memcpy(*p, buf, byte_len); 331a8e1175bSopenharmony_ci } 332a8e1175bSopenharmony_ci 333a8e1175bSopenharmony_ci /* Write unused bits */ 334a8e1175bSopenharmony_ci *--(*p) = (unsigned char) unused_bits; 335a8e1175bSopenharmony_ci 336a8e1175bSopenharmony_ci return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_BIT_STRING); 337a8e1175bSopenharmony_ci} 338a8e1175bSopenharmony_ci 339a8e1175bSopenharmony_ciint mbedtls_asn1_write_octet_string(unsigned char **p, const unsigned char *start, 340a8e1175bSopenharmony_ci const unsigned char *buf, size_t size) 341a8e1175bSopenharmony_ci{ 342a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 343a8e1175bSopenharmony_ci size_t len = 0; 344a8e1175bSopenharmony_ci 345a8e1175bSopenharmony_ci MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, buf, size)); 346a8e1175bSopenharmony_ci 347a8e1175bSopenharmony_ci return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_OCTET_STRING); 348a8e1175bSopenharmony_ci} 349a8e1175bSopenharmony_ci 350a8e1175bSopenharmony_ci 351a8e1175bSopenharmony_ci#if !defined(MBEDTLS_ASN1_PARSE_C) 352a8e1175bSopenharmony_ci/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(), 353a8e1175bSopenharmony_ci * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */ 354a8e1175bSopenharmony_cistatic mbedtls_asn1_named_data *asn1_find_named_data( 355a8e1175bSopenharmony_ci mbedtls_asn1_named_data *list, 356a8e1175bSopenharmony_ci const char *oid, size_t len) 357a8e1175bSopenharmony_ci{ 358a8e1175bSopenharmony_ci while (list != NULL) { 359a8e1175bSopenharmony_ci if (list->oid.len == len && 360a8e1175bSopenharmony_ci memcmp(list->oid.p, oid, len) == 0) { 361a8e1175bSopenharmony_ci break; 362a8e1175bSopenharmony_ci } 363a8e1175bSopenharmony_ci 364a8e1175bSopenharmony_ci list = list->next; 365a8e1175bSopenharmony_ci } 366a8e1175bSopenharmony_ci 367a8e1175bSopenharmony_ci return list; 368a8e1175bSopenharmony_ci} 369a8e1175bSopenharmony_ci#else 370a8e1175bSopenharmony_ci#define asn1_find_named_data(list, oid, len) \ 371a8e1175bSopenharmony_ci ((mbedtls_asn1_named_data *) mbedtls_asn1_find_named_data(list, oid, len)) 372a8e1175bSopenharmony_ci#endif 373a8e1175bSopenharmony_ci 374a8e1175bSopenharmony_cimbedtls_asn1_named_data *mbedtls_asn1_store_named_data( 375a8e1175bSopenharmony_ci mbedtls_asn1_named_data **head, 376a8e1175bSopenharmony_ci const char *oid, size_t oid_len, 377a8e1175bSopenharmony_ci const unsigned char *val, 378a8e1175bSopenharmony_ci size_t val_len) 379a8e1175bSopenharmony_ci{ 380a8e1175bSopenharmony_ci mbedtls_asn1_named_data *cur; 381a8e1175bSopenharmony_ci 382a8e1175bSopenharmony_ci if ((cur = asn1_find_named_data(*head, oid, oid_len)) == NULL) { 383a8e1175bSopenharmony_ci // Add new entry if not present yet based on OID 384a8e1175bSopenharmony_ci // 385a8e1175bSopenharmony_ci cur = (mbedtls_asn1_named_data *) mbedtls_calloc(1, 386a8e1175bSopenharmony_ci sizeof(mbedtls_asn1_named_data)); 387a8e1175bSopenharmony_ci if (cur == NULL) { 388a8e1175bSopenharmony_ci return NULL; 389a8e1175bSopenharmony_ci } 390a8e1175bSopenharmony_ci 391a8e1175bSopenharmony_ci cur->oid.len = oid_len; 392a8e1175bSopenharmony_ci cur->oid.p = mbedtls_calloc(1, oid_len); 393a8e1175bSopenharmony_ci if (cur->oid.p == NULL) { 394a8e1175bSopenharmony_ci mbedtls_free(cur); 395a8e1175bSopenharmony_ci return NULL; 396a8e1175bSopenharmony_ci } 397a8e1175bSopenharmony_ci 398a8e1175bSopenharmony_ci memcpy(cur->oid.p, oid, oid_len); 399a8e1175bSopenharmony_ci 400a8e1175bSopenharmony_ci cur->val.len = val_len; 401a8e1175bSopenharmony_ci if (val_len != 0) { 402a8e1175bSopenharmony_ci cur->val.p = mbedtls_calloc(1, val_len); 403a8e1175bSopenharmony_ci if (cur->val.p == NULL) { 404a8e1175bSopenharmony_ci mbedtls_free(cur->oid.p); 405a8e1175bSopenharmony_ci mbedtls_free(cur); 406a8e1175bSopenharmony_ci return NULL; 407a8e1175bSopenharmony_ci } 408a8e1175bSopenharmony_ci } 409a8e1175bSopenharmony_ci 410a8e1175bSopenharmony_ci cur->next = *head; 411a8e1175bSopenharmony_ci *head = cur; 412a8e1175bSopenharmony_ci } else if (val_len == 0) { 413a8e1175bSopenharmony_ci mbedtls_free(cur->val.p); 414a8e1175bSopenharmony_ci cur->val.p = NULL; 415a8e1175bSopenharmony_ci } else if (cur->val.len != val_len) { 416a8e1175bSopenharmony_ci /* 417a8e1175bSopenharmony_ci * Enlarge existing value buffer if needed 418a8e1175bSopenharmony_ci * Preserve old data until the allocation succeeded, to leave list in 419a8e1175bSopenharmony_ci * a consistent state in case allocation fails. 420a8e1175bSopenharmony_ci */ 421a8e1175bSopenharmony_ci void *p = mbedtls_calloc(1, val_len); 422a8e1175bSopenharmony_ci if (p == NULL) { 423a8e1175bSopenharmony_ci return NULL; 424a8e1175bSopenharmony_ci } 425a8e1175bSopenharmony_ci 426a8e1175bSopenharmony_ci mbedtls_free(cur->val.p); 427a8e1175bSopenharmony_ci cur->val.p = p; 428a8e1175bSopenharmony_ci cur->val.len = val_len; 429a8e1175bSopenharmony_ci } 430a8e1175bSopenharmony_ci 431a8e1175bSopenharmony_ci if (val != NULL && val_len != 0) { 432a8e1175bSopenharmony_ci memcpy(cur->val.p, val, val_len); 433a8e1175bSopenharmony_ci } 434a8e1175bSopenharmony_ci 435a8e1175bSopenharmony_ci return cur; 436a8e1175bSopenharmony_ci} 437a8e1175bSopenharmony_ci#endif /* MBEDTLS_ASN1_WRITE_C */ 438