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