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