Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
asn1parse.c
00001 /* 00002 * Generic ASN.1 parsing 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if !defined(MBEDTLS_CONFIG_FILE) 00023 #include "mbedtls/config.h" 00024 #else 00025 #include MBEDTLS_CONFIG_FILE 00026 #endif 00027 00028 #if defined(MBEDTLS_ASN1_PARSE_C) 00029 00030 #include "mbedtls/asn1.h" 00031 #include "mbedtls/platform_util.h" 00032 00033 #include <string.h> 00034 00035 #if defined(MBEDTLS_BIGNUM_C) 00036 #include "mbedtls/bignum.h" 00037 #endif 00038 00039 #if defined(MBEDTLS_PLATFORM_C) 00040 #include "mbedtls/platform.h" 00041 #else 00042 #include <stdlib.h> 00043 #define mbedtls_calloc calloc 00044 #define mbedtls_free free 00045 #endif 00046 00047 /* 00048 * ASN.1 DER decoding routines 00049 */ 00050 int mbedtls_asn1_get_len( unsigned char **p, 00051 const unsigned char *end, 00052 size_t *len ) 00053 { 00054 if( ( end - *p ) < 1 ) 00055 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00056 00057 if( ( **p & 0x80 ) == 0 ) 00058 *len = *(*p)++; 00059 else 00060 { 00061 switch( **p & 0x7F ) 00062 { 00063 case 1: 00064 if( ( end - *p ) < 2 ) 00065 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00066 00067 *len = (*p)[1]; 00068 (*p) += 2; 00069 break; 00070 00071 case 2: 00072 if( ( end - *p ) < 3 ) 00073 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00074 00075 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; 00076 (*p) += 3; 00077 break; 00078 00079 case 3: 00080 if( ( end - *p ) < 4 ) 00081 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00082 00083 *len = ( (size_t)(*p)[1] << 16 ) | 00084 ( (size_t)(*p)[2] << 8 ) | (*p)[3]; 00085 (*p) += 4; 00086 break; 00087 00088 case 4: 00089 if( ( end - *p ) < 5 ) 00090 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00091 00092 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | 00093 ( (size_t)(*p)[3] << 8 ) | (*p)[4]; 00094 (*p) += 5; 00095 break; 00096 00097 default: 00098 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00099 } 00100 } 00101 00102 if( *len > (size_t) ( end - *p ) ) 00103 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00104 00105 return( 0 ); 00106 } 00107 00108 int mbedtls_asn1_get_tag( unsigned char **p, 00109 const unsigned char *end, 00110 size_t *len, int tag ) 00111 { 00112 if( ( end - *p ) < 1 ) 00113 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00114 00115 if( **p != tag ) 00116 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00117 00118 (*p)++; 00119 00120 return( mbedtls_asn1_get_len( p, end, len ) ); 00121 } 00122 00123 int mbedtls_asn1_get_bool( unsigned char **p, 00124 const unsigned char *end, 00125 int *val ) 00126 { 00127 int ret; 00128 size_t len; 00129 00130 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 ) 00131 return( ret ); 00132 00133 if( len != 1 ) 00134 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00135 00136 *val = ( **p != 0 ) ? 1 : 0; 00137 (*p)++; 00138 00139 return( 0 ); 00140 } 00141 00142 int mbedtls_asn1_get_int( unsigned char **p, 00143 const unsigned char *end, 00144 int *val ) 00145 { 00146 int ret; 00147 size_t len; 00148 00149 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 00150 return( ret ); 00151 00152 /* len==0 is malformed (0 must be represented as 020100). */ 00153 if( len == 0 ) 00154 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00155 /* This is a cryptography library. Reject negative integers. */ 00156 if( ( **p & 0x80 ) != 0 ) 00157 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00158 00159 /* Skip leading zeros. */ 00160 while( len > 0 && **p == 0 ) 00161 { 00162 ++( *p ); 00163 --len; 00164 } 00165 00166 /* Reject integers that don't fit in an int. This code assumes that 00167 * the int type has no padding bit. */ 00168 if( len > sizeof( int ) ) 00169 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00170 if( len == sizeof( int ) && ( **p & 0x80 ) != 0 ) 00171 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00172 00173 *val = 0; 00174 while( len-- > 0 ) 00175 { 00176 *val = ( *val << 8 ) | **p; 00177 (*p)++; 00178 } 00179 00180 return( 0 ); 00181 } 00182 00183 #if defined(MBEDTLS_BIGNUM_C) 00184 int mbedtls_asn1_get_mpi( unsigned char **p, 00185 const unsigned char *end, 00186 mbedtls_mpi *X ) 00187 { 00188 int ret; 00189 size_t len; 00190 00191 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 00192 return( ret ); 00193 00194 ret = mbedtls_mpi_read_binary( X, *p, len ); 00195 00196 *p += len; 00197 00198 return( ret ); 00199 } 00200 #endif /* MBEDTLS_BIGNUM_C */ 00201 00202 int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, 00203 mbedtls_asn1_bitstring *bs) 00204 { 00205 int ret; 00206 00207 /* Certificate type is a single byte bitstring */ 00208 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 00209 return( ret ); 00210 00211 /* Check length, subtract one for actual bit string length */ 00212 if( bs->len < 1 ) 00213 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00214 bs->len -= 1; 00215 00216 /* Get number of unused bits, ensure unused bits <= 7 */ 00217 bs->unused_bits = **p; 00218 if( bs->unused_bits > 7 ) 00219 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00220 (*p)++; 00221 00222 /* Get actual bitstring */ 00223 bs->p = *p; 00224 *p += bs->len; 00225 00226 if( *p != end ) 00227 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00228 00229 return( 0 ); 00230 } 00231 00232 /* 00233 * Get a bit string without unused bits 00234 */ 00235 int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, 00236 size_t *len ) 00237 { 00238 int ret; 00239 00240 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 00241 return( ret ); 00242 00243 if( *len == 0 ) 00244 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 00245 --( *len ); 00246 00247 if( **p != 0 ) 00248 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 00249 ++( *p ); 00250 00251 return( 0 ); 00252 } 00253 00254 00255 00256 /* 00257 * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 00258 */ 00259 int mbedtls_asn1_get_sequence_of( unsigned char **p, 00260 const unsigned char *end, 00261 mbedtls_asn1_sequence *cur, 00262 int tag) 00263 { 00264 int ret; 00265 size_t len; 00266 mbedtls_asn1_buf *buf; 00267 00268 /* Get main sequence tag */ 00269 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00270 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00271 return( ret ); 00272 00273 if( *p + len != end ) 00274 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00275 00276 while( *p < end ) 00277 { 00278 buf = &(cur->buf); 00279 buf->tag = **p; 00280 00281 if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) 00282 return( ret ); 00283 00284 buf->p = *p; 00285 *p += buf->len; 00286 00287 /* Allocate and assign next pointer */ 00288 if( *p < end ) 00289 { 00290 cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, 00291 sizeof( mbedtls_asn1_sequence ) ); 00292 00293 if( cur->next == NULL ) 00294 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); 00295 00296 cur = cur->next; 00297 } 00298 } 00299 00300 /* Set final sequence entry's next pointer to NULL */ 00301 cur->next = NULL; 00302 00303 if( *p != end ) 00304 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00305 00306 return( 0 ); 00307 } 00308 00309 int mbedtls_asn1_get_alg( unsigned char **p, 00310 const unsigned char *end, 00311 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) 00312 { 00313 int ret; 00314 size_t len; 00315 00316 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00317 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00318 return( ret ); 00319 00320 if( ( end - *p ) < 1 ) 00321 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00322 00323 alg->tag = **p; 00324 end = *p + len; 00325 00326 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) 00327 return( ret ); 00328 00329 alg->p = *p; 00330 *p += alg->len; 00331 00332 if( *p == end ) 00333 { 00334 mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) ); 00335 return( 0 ); 00336 } 00337 00338 params->tag = **p; 00339 (*p)++; 00340 00341 if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) 00342 return( ret ); 00343 00344 params->p = *p; 00345 *p += params->len; 00346 00347 if( *p != end ) 00348 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00349 00350 return( 0 ); 00351 } 00352 00353 int mbedtls_asn1_get_alg_null( unsigned char **p, 00354 const unsigned char *end, 00355 mbedtls_asn1_buf *alg ) 00356 { 00357 int ret; 00358 mbedtls_asn1_buf params; 00359 00360 memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); 00361 00362 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) 00363 return( ret ); 00364 00365 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) 00366 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 00367 00368 return( 0 ); 00369 } 00370 00371 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) 00372 { 00373 if( cur == NULL ) 00374 return; 00375 00376 mbedtls_free( cur->oid.p ); 00377 mbedtls_free( cur->val.p ); 00378 00379 mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); 00380 } 00381 00382 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) 00383 { 00384 mbedtls_asn1_named_data *cur; 00385 00386 while( ( cur = *head ) != NULL ) 00387 { 00388 *head = cur->next; 00389 mbedtls_asn1_free_named_data( cur ); 00390 mbedtls_free( cur ); 00391 } 00392 } 00393 00394 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, 00395 const char *oid, size_t len ) 00396 { 00397 while( list != NULL ) 00398 { 00399 if( list->oid.len == len && 00400 memcmp( list->oid.p, oid, len ) == 0 ) 00401 { 00402 break; 00403 } 00404 00405 list = list->next; 00406 } 00407 00408 return( list ); 00409 } 00410 00411 #endif /* MBEDTLS_ASN1_PARSE_C */
Generated on Tue Jul 12 2022 13:54:01 by
