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.
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 00032 #include <string.h> 00033 00034 #if defined(MBEDTLS_BIGNUM_C) 00035 #include "mbedtls/bignum.h" 00036 #endif 00037 00038 #if defined(MBEDTLS_PLATFORM_C) 00039 #include "mbedtls/platform.h" 00040 #else 00041 #include <stdlib.h> 00042 #define mbedtls_calloc calloc 00043 #define mbedtls_free free 00044 #endif 00045 00046 /* Implementation that should never be optimized out by the compiler */ 00047 static void mbedtls_zeroize( void *v, size_t n ) { 00048 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; 00049 } 00050 00051 /* 00052 * ASN.1 DER decoding routines 00053 */ 00054 int mbedtls_asn1_get_len( unsigned char **p, 00055 const unsigned char *end, 00056 size_t *len ) 00057 { 00058 if( ( end - *p ) < 1 ) 00059 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00060 00061 if( ( **p & 0x80 ) == 0 ) 00062 *len = *(*p)++; 00063 else 00064 { 00065 switch( **p & 0x7F ) 00066 { 00067 case 1: 00068 if( ( end - *p ) < 2 ) 00069 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00070 00071 *len = (*p)[1]; 00072 (*p) += 2; 00073 break; 00074 00075 case 2: 00076 if( ( end - *p ) < 3 ) 00077 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00078 00079 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; 00080 (*p) += 3; 00081 break; 00082 00083 case 3: 00084 if( ( end - *p ) < 4 ) 00085 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00086 00087 *len = ( (size_t)(*p)[1] << 16 ) | 00088 ( (size_t)(*p)[2] << 8 ) | (*p)[3]; 00089 (*p) += 4; 00090 break; 00091 00092 case 4: 00093 if( ( end - *p ) < 5 ) 00094 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00095 00096 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | 00097 ( (size_t)(*p)[3] << 8 ) | (*p)[4]; 00098 (*p) += 5; 00099 break; 00100 00101 default: 00102 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00103 } 00104 } 00105 00106 if( *len > (size_t) ( end - *p ) ) 00107 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00108 00109 return( 0 ); 00110 } 00111 00112 int mbedtls_asn1_get_tag( unsigned char **p, 00113 const unsigned char *end, 00114 size_t *len, int tag ) 00115 { 00116 if( ( end - *p ) < 1 ) 00117 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00118 00119 if( **p != tag ) 00120 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00121 00122 (*p)++; 00123 00124 return( mbedtls_asn1_get_len( p, end, len ) ); 00125 } 00126 00127 int mbedtls_asn1_get_bool( unsigned char **p, 00128 const unsigned char *end, 00129 int *val ) 00130 { 00131 int ret; 00132 size_t len; 00133 00134 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 ) 00135 return( ret ); 00136 00137 if( len != 1 ) 00138 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00139 00140 *val = ( **p != 0 ) ? 1 : 0; 00141 (*p)++; 00142 00143 return( 0 ); 00144 } 00145 00146 int mbedtls_asn1_get_int( unsigned char **p, 00147 const unsigned char *end, 00148 int *val ) 00149 { 00150 int ret; 00151 size_t len; 00152 00153 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 00154 return( ret ); 00155 00156 if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) 00157 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00158 00159 *val = 0; 00160 00161 while( len-- > 0 ) 00162 { 00163 *val = ( *val << 8 ) | **p; 00164 (*p)++; 00165 } 00166 00167 return( 0 ); 00168 } 00169 00170 #if defined(MBEDTLS_BIGNUM_C) 00171 int mbedtls_asn1_get_mpi( unsigned char **p, 00172 const unsigned char *end, 00173 mbedtls_mpi *X ) 00174 { 00175 int ret; 00176 size_t len; 00177 00178 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 00179 return( ret ); 00180 00181 ret = mbedtls_mpi_read_binary( X, *p, len ); 00182 00183 *p += len; 00184 00185 return( ret ); 00186 } 00187 #endif /* MBEDTLS_BIGNUM_C */ 00188 00189 int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, 00190 mbedtls_asn1_bitstring *bs) 00191 { 00192 int ret; 00193 00194 /* Certificate type is a single byte bitstring */ 00195 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 00196 return( ret ); 00197 00198 /* Check length, subtract one for actual bit string length */ 00199 if( bs->len < 1 ) 00200 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00201 bs->len -= 1; 00202 00203 /* Get number of unused bits, ensure unused bits <= 7 */ 00204 bs->unused_bits = **p; 00205 if( bs->unused_bits > 7 ) 00206 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00207 (*p)++; 00208 00209 /* Get actual bitstring */ 00210 bs->p = *p; 00211 *p += bs->len; 00212 00213 if( *p != end ) 00214 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00215 00216 return( 0 ); 00217 } 00218 00219 /* 00220 * Get a bit string without unused bits 00221 */ 00222 int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, 00223 size_t *len ) 00224 { 00225 int ret; 00226 00227 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 00228 return( ret ); 00229 00230 if( (*len)-- < 2 || *(*p)++ != 0 ) 00231 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 00232 00233 return( 0 ); 00234 } 00235 00236 00237 00238 /* 00239 * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 00240 */ 00241 int mbedtls_asn1_get_sequence_of( unsigned char **p, 00242 const unsigned char *end, 00243 mbedtls_asn1_sequence *cur, 00244 int tag) 00245 { 00246 int ret; 00247 size_t len; 00248 mbedtls_asn1_buf *buf; 00249 00250 /* Get main sequence tag */ 00251 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00252 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00253 return( ret ); 00254 00255 if( *p + len != end ) 00256 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00257 00258 while( *p < end ) 00259 { 00260 buf = &(cur->buf); 00261 buf->tag = **p; 00262 00263 if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) 00264 return( ret ); 00265 00266 buf->p = *p; 00267 *p += buf->len; 00268 00269 /* Allocate and assign next pointer */ 00270 if( *p < end ) 00271 { 00272 cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, 00273 sizeof( mbedtls_asn1_sequence ) ); 00274 00275 if( cur->next == NULL ) 00276 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); 00277 00278 cur = cur->next; 00279 } 00280 } 00281 00282 /* Set final sequence entry's next pointer to NULL */ 00283 cur->next = NULL; 00284 00285 if( *p != end ) 00286 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00287 00288 return( 0 ); 00289 } 00290 00291 int mbedtls_asn1_get_alg( unsigned char **p, 00292 const unsigned char *end, 00293 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) 00294 { 00295 int ret; 00296 size_t len; 00297 00298 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00299 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00300 return( ret ); 00301 00302 if( ( end - *p ) < 1 ) 00303 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00304 00305 alg->tag = **p; 00306 end = *p + len; 00307 00308 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) 00309 return( ret ); 00310 00311 alg->p = *p; 00312 *p += alg->len; 00313 00314 if( *p == end ) 00315 { 00316 mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) ); 00317 return( 0 ); 00318 } 00319 00320 params->tag = **p; 00321 (*p)++; 00322 00323 if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) 00324 return( ret ); 00325 00326 params->p = *p; 00327 *p += params->len; 00328 00329 if( *p != end ) 00330 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00331 00332 return( 0 ); 00333 } 00334 00335 int mbedtls_asn1_get_alg_null( unsigned char **p, 00336 const unsigned char *end, 00337 mbedtls_asn1_buf *alg ) 00338 { 00339 int ret; 00340 mbedtls_asn1_buf params; 00341 00342 memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); 00343 00344 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) 00345 return( ret ); 00346 00347 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) 00348 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 00349 00350 return( 0 ); 00351 } 00352 00353 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) 00354 { 00355 if( cur == NULL ) 00356 return; 00357 00358 mbedtls_free( cur->oid.p ); 00359 mbedtls_free( cur->val.p ); 00360 00361 mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); 00362 } 00363 00364 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) 00365 { 00366 mbedtls_asn1_named_data *cur; 00367 00368 while( ( cur = *head ) != NULL ) 00369 { 00370 *head = cur->next; 00371 mbedtls_asn1_free_named_data( cur ); 00372 mbedtls_free( cur ); 00373 } 00374 } 00375 00376 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, 00377 const char *oid, size_t len ) 00378 { 00379 while( list != NULL ) 00380 { 00381 if( list->oid.len == len && 00382 memcmp( list->oid.p, oid, len ) == 0 ) 00383 { 00384 break; 00385 } 00386 00387 list = list->next; 00388 } 00389 00390 return( list ); 00391 } 00392 00393 #endif /* MBEDTLS_ASN1_PARSE_C */
Generated on Tue Jul 12 2022 12:21:40 by
