1 /* 2 * Generic ASN.1 parsing 3 * 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6 * 7 * This file is provided under the Apache License 2.0, or the 8 * GNU General Public License v2.0 or later. 9 * 10 * ********** 11 * Apache License 2.0: 12 * 13 * Licensed under the Apache License, Version 2.0 (the "License"); you may 14 * not use this file except in compliance with the License. 15 * You may obtain a copy of the License at 16 * 17 * http://www.apache.org/licenses/LICENSE-2.0 18 * 19 * Unless required by applicable law or agreed to in writing, software 20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the License for the specific language governing permissions and 23 * limitations under the License. 24 * 25 * ********** 26 * 27 * ********** 28 * GNU General Public License v2.0 or later: 29 * 30 * This program is free software; you can redistribute it and/or modify 31 * it under the terms of the GNU General Public License as published by 32 * the Free Software Foundation; either version 2 of the License, or 33 * (at your option) any later version. 34 * 35 * This program is distributed in the hope that it will be useful, 36 * but WITHOUT ANY WARRANTY; without even the implied warranty of 37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 38 * GNU General Public License for more details. 39 * 40 * You should have received a copy of the GNU General Public License along 41 * with this program; if not, write to the Free Software Foundation, Inc., 42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 43 * 44 * ********** 45 * 46 * This file is part of mbed TLS (https://tls.mbed.org) 47 */ 48 49 #if !defined(MBEDTLS_CONFIG_FILE) 50 #include "mbedtls/config.h" 51 #else 52 #include MBEDTLS_CONFIG_FILE 53 #endif 54 55 #if defined(MBEDTLS_ASN1_PARSE_C) 56 57 #include "mbedtls/asn1.h" 58 59 #include <string.h> 60 61 #if defined(MBEDTLS_BIGNUM_C) 62 #include "mbedtls/bignum.h" 63 #endif 64 65 #if defined(MBEDTLS_PLATFORM_C) 66 #include "mbedtls/platform.h" 67 #else 68 #include <stdlib.h> 69 #define mbedtls_calloc calloc 70 #define mbedtls_free free 71 #endif 72 73 /* Implementation that should never be optimized out by the compiler */ 74 static void mbedtls_zeroize( void *v, size_t n ) { 75 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; 76 } 77 78 /* 79 * ASN.1 DER decoding routines 80 */ 81 int mbedtls_asn1_get_len( unsigned char **p, 82 const unsigned char *end, 83 size_t *len ) 84 { 85 if( ( end - *p ) < 1 ) 86 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 87 88 if( ( **p & 0x80 ) == 0 ) 89 *len = *(*p)++; 90 else 91 { 92 switch( **p & 0x7F ) 93 { 94 case 1: 95 if( ( end - *p ) < 2 ) 96 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 97 98 *len = (*p)[1]; 99 (*p) += 2; 100 break; 101 102 case 2: 103 if( ( end - *p ) < 3 ) 104 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 105 106 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; 107 (*p) += 3; 108 break; 109 110 case 3: 111 if( ( end - *p ) < 4 ) 112 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 113 114 *len = ( (size_t)(*p)[1] << 16 ) | 115 ( (size_t)(*p)[2] << 8 ) | (*p)[3]; 116 (*p) += 4; 117 break; 118 119 case 4: 120 if( ( end - *p ) < 5 ) 121 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 122 123 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | 124 ( (size_t)(*p)[3] << 8 ) | (*p)[4]; 125 (*p) += 5; 126 break; 127 128 default: 129 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 130 } 131 } 132 133 if( *len > (size_t) ( end - *p ) ) 134 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 135 136 return( 0 ); 137 } 138 139 int mbedtls_asn1_get_tag( unsigned char **p, 140 const unsigned char *end, 141 size_t *len, int tag ) 142 { 143 if( ( end - *p ) < 1 ) 144 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 145 146 if( **p != tag ) 147 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 148 149 (*p)++; 150 151 return( mbedtls_asn1_get_len( p, end, len ) ); 152 } 153 154 int mbedtls_asn1_get_bool( unsigned char **p, 155 const unsigned char *end, 156 int *val ) 157 { 158 int ret; 159 size_t len; 160 161 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 ) 162 return( ret ); 163 164 if( len != 1 ) 165 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 166 167 *val = ( **p != 0 ) ? 1 : 0; 168 (*p)++; 169 170 return( 0 ); 171 } 172 173 int mbedtls_asn1_get_int( unsigned char **p, 174 const unsigned char *end, 175 int *val ) 176 { 177 int ret; 178 size_t len; 179 180 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 181 return( ret ); 182 183 if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) 184 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 185 186 *val = 0; 187 188 while( len-- > 0 ) 189 { 190 *val = ( *val << 8 ) | **p; 191 (*p)++; 192 } 193 194 return( 0 ); 195 } 196 197 #if defined(MBEDTLS_BIGNUM_C) 198 int mbedtls_asn1_get_mpi( unsigned char **p, 199 const unsigned char *end, 200 mbedtls_mpi *X ) 201 { 202 int ret; 203 size_t len; 204 205 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 206 return( ret ); 207 208 ret = mbedtls_mpi_read_binary( X, *p, len ); 209 210 *p += len; 211 212 return( ret ); 213 } 214 #endif /* MBEDTLS_BIGNUM_C */ 215 216 int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, 217 mbedtls_asn1_bitstring *bs) 218 { 219 int ret; 220 221 /* Certificate type is a single byte bitstring */ 222 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 223 return( ret ); 224 225 /* Check length, subtract one for actual bit string length */ 226 if( bs->len < 1 ) 227 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 228 bs->len -= 1; 229 230 /* Get number of unused bits, ensure unused bits <= 7 */ 231 bs->unused_bits = **p; 232 if( bs->unused_bits > 7 ) 233 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 234 (*p)++; 235 236 /* Get actual bitstring */ 237 bs->p = *p; 238 *p += bs->len; 239 240 if( *p != end ) 241 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 242 243 return( 0 ); 244 } 245 246 /* 247 * Get a bit string without unused bits 248 */ 249 int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, 250 size_t *len ) 251 { 252 int ret; 253 254 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 255 return( ret ); 256 257 if( (*len)-- < 2 || *(*p)++ != 0 ) 258 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 259 260 return( 0 ); 261 } 262 263 264 265 /* 266 * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 267 */ 268 int mbedtls_asn1_get_sequence_of( unsigned char **p, 269 const unsigned char *end, 270 mbedtls_asn1_sequence *cur, 271 int tag) 272 { 273 int ret; 274 size_t len; 275 mbedtls_asn1_buf *buf; 276 277 /* Get main sequence tag */ 278 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 279 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 280 return( ret ); 281 282 if( *p + len != end ) 283 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 284 285 while( *p < end ) 286 { 287 buf = &(cur->buf); 288 buf->tag = **p; 289 290 if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) 291 return( ret ); 292 293 buf->p = *p; 294 *p += buf->len; 295 296 /* Allocate and assign next pointer */ 297 if( *p < end ) 298 { 299 cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, 300 sizeof( mbedtls_asn1_sequence ) ); 301 302 if( cur->next == NULL ) 303 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); 304 305 cur = cur->next; 306 } 307 } 308 309 /* Set final sequence entry's next pointer to NULL */ 310 cur->next = NULL; 311 312 if( *p != end ) 313 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 314 315 return( 0 ); 316 } 317 318 int mbedtls_asn1_get_alg( unsigned char **p, 319 const unsigned char *end, 320 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) 321 { 322 int ret; 323 size_t len; 324 325 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 326 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 327 return( ret ); 328 329 if( ( end - *p ) < 1 ) 330 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 331 332 alg->tag = **p; 333 end = *p + len; 334 335 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) 336 return( ret ); 337 338 alg->p = *p; 339 *p += alg->len; 340 341 if( *p == end ) 342 { 343 mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) ); 344 return( 0 ); 345 } 346 347 params->tag = **p; 348 (*p)++; 349 350 if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) 351 return( ret ); 352 353 params->p = *p; 354 *p += params->len; 355 356 if( *p != end ) 357 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 358 359 return( 0 ); 360 } 361 362 int mbedtls_asn1_get_alg_null( unsigned char **p, 363 const unsigned char *end, 364 mbedtls_asn1_buf *alg ) 365 { 366 int ret; 367 mbedtls_asn1_buf params; 368 369 memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); 370 371 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) 372 return( ret ); 373 374 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) 375 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 376 377 return( 0 ); 378 } 379 380 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) 381 { 382 if( cur == NULL ) 383 return; 384 385 mbedtls_free( cur->oid.p ); 386 mbedtls_free( cur->val.p ); 387 388 mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); 389 } 390 391 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) 392 { 393 mbedtls_asn1_named_data *cur; 394 395 while( ( cur = *head ) != NULL ) 396 { 397 *head = cur->next; 398 mbedtls_asn1_free_named_data( cur ); 399 mbedtls_free( cur ); 400 } 401 } 402 403 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, 404 const char *oid, size_t len ) 405 { 406 while( list != NULL ) 407 { 408 if( list->oid.len == len && 409 memcmp( list->oid.p, oid, len ) == 0 ) 410 { 411 break; 412 } 413 414 list = list->next; 415 } 416 417 return( list ); 418 } 419 420 #endif /* MBEDTLS_ASN1_PARSE_C */ 421