1 /* 2 * Generic ASN.1 parsing 3 * 4 * Copyright The Mbed TLS Contributors 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 47 #if !defined(MBEDTLS_CONFIG_FILE) 48 #include "mbedtls/config.h" 49 #else 50 #include MBEDTLS_CONFIG_FILE 51 #endif 52 53 #if defined(MBEDTLS_ASN1_PARSE_C) 54 55 #include "mbedtls/asn1.h" 56 #include "mbedtls/platform_util.h" 57 58 #include <string.h> 59 60 #if defined(MBEDTLS_BIGNUM_C) 61 #include "mbedtls/bignum.h" 62 #endif 63 64 #if defined(MBEDTLS_PLATFORM_C) 65 #include "mbedtls/platform.h" 66 #else 67 #include <stdlib.h> 68 #define mbedtls_calloc calloc 69 #define mbedtls_free free 70 #endif 71 72 /* 73 * ASN.1 DER decoding routines 74 */ 75 int mbedtls_asn1_get_len( unsigned char **p, 76 const unsigned char *end, 77 size_t *len ) 78 { 79 if( ( end - *p ) < 1 ) 80 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 81 82 if( ( **p & 0x80 ) == 0 ) 83 *len = *(*p)++; 84 else 85 { 86 switch( **p & 0x7F ) 87 { 88 case 1: 89 if( ( end - *p ) < 2 ) 90 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 91 92 *len = (*p)[1]; 93 (*p) += 2; 94 break; 95 96 case 2: 97 if( ( end - *p ) < 3 ) 98 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 99 100 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; 101 (*p) += 3; 102 break; 103 104 case 3: 105 if( ( end - *p ) < 4 ) 106 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 107 108 *len = ( (size_t)(*p)[1] << 16 ) | 109 ( (size_t)(*p)[2] << 8 ) | (*p)[3]; 110 (*p) += 4; 111 break; 112 113 case 4: 114 if( ( end - *p ) < 5 ) 115 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 116 117 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | 118 ( (size_t)(*p)[3] << 8 ) | (*p)[4]; 119 (*p) += 5; 120 break; 121 122 default: 123 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 124 } 125 } 126 127 if( *len > (size_t) ( end - *p ) ) 128 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 129 130 return( 0 ); 131 } 132 133 int mbedtls_asn1_get_tag( unsigned char **p, 134 const unsigned char *end, 135 size_t *len, int tag ) 136 { 137 if( ( end - *p ) < 1 ) 138 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 139 140 if( **p != tag ) 141 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 142 143 (*p)++; 144 145 return( mbedtls_asn1_get_len( p, end, len ) ); 146 } 147 148 int mbedtls_asn1_get_bool( unsigned char **p, 149 const unsigned char *end, 150 int *val ) 151 { 152 int ret; 153 size_t len; 154 155 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 ) 156 return( ret ); 157 158 if( len != 1 ) 159 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 160 161 *val = ( **p != 0 ) ? 1 : 0; 162 (*p)++; 163 164 return( 0 ); 165 } 166 167 int mbedtls_asn1_get_int( unsigned char **p, 168 const unsigned char *end, 169 int *val ) 170 { 171 int ret; 172 size_t len; 173 174 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 175 return( ret ); 176 177 if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) 178 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 179 180 *val = 0; 181 182 while( len-- > 0 ) 183 { 184 *val = ( *val << 8 ) | **p; 185 (*p)++; 186 } 187 188 return( 0 ); 189 } 190 191 #if defined(MBEDTLS_BIGNUM_C) 192 int mbedtls_asn1_get_mpi( unsigned char **p, 193 const unsigned char *end, 194 mbedtls_mpi *X ) 195 { 196 int ret; 197 size_t len; 198 199 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 200 return( ret ); 201 202 ret = mbedtls_mpi_read_binary( X, *p, len ); 203 204 *p += len; 205 206 return( ret ); 207 } 208 #endif /* MBEDTLS_BIGNUM_C */ 209 210 int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, 211 mbedtls_asn1_bitstring *bs) 212 { 213 int ret; 214 215 /* Certificate type is a single byte bitstring */ 216 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 217 return( ret ); 218 219 /* Check length, subtract one for actual bit string length */ 220 if( bs->len < 1 ) 221 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 222 bs->len -= 1; 223 224 /* Get number of unused bits, ensure unused bits <= 7 */ 225 bs->unused_bits = **p; 226 if( bs->unused_bits > 7 ) 227 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 228 (*p)++; 229 230 /* Get actual bitstring */ 231 bs->p = *p; 232 *p += bs->len; 233 234 if( *p != end ) 235 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 236 237 return( 0 ); 238 } 239 240 /* 241 * Get a bit string without unused bits 242 */ 243 int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, 244 size_t *len ) 245 { 246 int ret; 247 248 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 249 return( ret ); 250 251 if( (*len)-- < 2 || *(*p)++ != 0 ) 252 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 253 254 return( 0 ); 255 } 256 257 258 259 /* 260 * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 261 */ 262 int mbedtls_asn1_get_sequence_of( unsigned char **p, 263 const unsigned char *end, 264 mbedtls_asn1_sequence *cur, 265 int tag) 266 { 267 int ret; 268 size_t len; 269 mbedtls_asn1_buf *buf; 270 271 /* Get main sequence tag */ 272 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 273 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 274 return( ret ); 275 276 if( *p + len != end ) 277 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 278 279 while( *p < end ) 280 { 281 buf = &(cur->buf); 282 buf->tag = **p; 283 284 if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) 285 return( ret ); 286 287 buf->p = *p; 288 *p += buf->len; 289 290 /* Allocate and assign next pointer */ 291 if( *p < end ) 292 { 293 cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, 294 sizeof( mbedtls_asn1_sequence ) ); 295 296 if( cur->next == NULL ) 297 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); 298 299 cur = cur->next; 300 } 301 } 302 303 /* Set final sequence entry's next pointer to NULL */ 304 cur->next = NULL; 305 306 if( *p != end ) 307 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 308 309 return( 0 ); 310 } 311 312 int mbedtls_asn1_get_alg( unsigned char **p, 313 const unsigned char *end, 314 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) 315 { 316 int ret; 317 size_t len; 318 319 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 320 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 321 return( ret ); 322 323 if( ( end - *p ) < 1 ) 324 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 325 326 alg->tag = **p; 327 end = *p + len; 328 329 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) 330 return( ret ); 331 332 alg->p = *p; 333 *p += alg->len; 334 335 if( *p == end ) 336 { 337 mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) ); 338 return( 0 ); 339 } 340 341 params->tag = **p; 342 (*p)++; 343 344 if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) 345 return( ret ); 346 347 params->p = *p; 348 *p += params->len; 349 350 if( *p != end ) 351 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 352 353 return( 0 ); 354 } 355 356 int mbedtls_asn1_get_alg_null( unsigned char **p, 357 const unsigned char *end, 358 mbedtls_asn1_buf *alg ) 359 { 360 int ret; 361 mbedtls_asn1_buf params; 362 363 memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); 364 365 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) 366 return( ret ); 367 368 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) 369 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 370 371 return( 0 ); 372 } 373 374 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) 375 { 376 if( cur == NULL ) 377 return; 378 379 mbedtls_free( cur->oid.p ); 380 mbedtls_free( cur->val.p ); 381 382 mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); 383 } 384 385 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) 386 { 387 mbedtls_asn1_named_data *cur; 388 389 while( ( cur = *head ) != NULL ) 390 { 391 *head = cur->next; 392 mbedtls_asn1_free_named_data( cur ); 393 mbedtls_free( cur ); 394 } 395 } 396 397 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, 398 const char *oid, size_t len ) 399 { 400 while( list != NULL ) 401 { 402 if( list->oid.len == len && 403 memcmp( list->oid.p, oid, len ) == 0 ) 404 { 405 break; 406 } 407 408 list = list->next; 409 } 410 411 return( list ); 412 } 413 414 #endif /* MBEDTLS_ASN1_PARSE_C */ 415