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.
Fork of mbedtls by
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 = 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 > 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_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); 00273 00274 if( cur->next == NULL ) 00275 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); 00276 00277 cur = cur->next; 00278 } 00279 } 00280 00281 /* Set final sequence entry's next pointer to NULL */ 00282 cur->next = NULL; 00283 00284 if( *p != end ) 00285 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00286 00287 return( 0 ); 00288 } 00289 00290 int mbedtls_asn1_get_alg( unsigned char **p, 00291 const unsigned char *end, 00292 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) 00293 { 00294 int ret; 00295 size_t len; 00296 00297 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00298 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00299 return( ret ); 00300 00301 if( ( end - *p ) < 1 ) 00302 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00303 00304 alg->tag = **p; 00305 end = *p + len; 00306 00307 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) 00308 return( ret ); 00309 00310 alg->p = *p; 00311 *p += alg->len; 00312 00313 if( *p == end ) 00314 { 00315 mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) ); 00316 return( 0 ); 00317 } 00318 00319 params->tag = **p; 00320 (*p)++; 00321 00322 if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) 00323 return( ret ); 00324 00325 params->p = *p; 00326 *p += params->len; 00327 00328 if( *p != end ) 00329 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00330 00331 return( 0 ); 00332 } 00333 00334 int mbedtls_asn1_get_alg_null( unsigned char **p, 00335 const unsigned char *end, 00336 mbedtls_asn1_buf *alg ) 00337 { 00338 int ret; 00339 mbedtls_asn1_buf params; 00340 00341 memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); 00342 00343 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) 00344 return( ret ); 00345 00346 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) 00347 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 00348 00349 return( 0 ); 00350 } 00351 00352 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) 00353 { 00354 if( cur == NULL ) 00355 return; 00356 00357 mbedtls_free( cur->oid.p ); 00358 mbedtls_free( cur->val.p ); 00359 00360 mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); 00361 } 00362 00363 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) 00364 { 00365 mbedtls_asn1_named_data *cur; 00366 00367 while( ( cur = *head ) != NULL ) 00368 { 00369 *head = cur->next; 00370 mbedtls_asn1_free_named_data( cur ); 00371 mbedtls_free( cur ); 00372 } 00373 } 00374 00375 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, 00376 const char *oid, size_t len ) 00377 { 00378 while( list != NULL ) 00379 { 00380 if( list->oid.len == len && 00381 memcmp( list->oid.p, oid, len ) == 0 ) 00382 { 00383 break; 00384 } 00385 00386 list = list->next; 00387 } 00388 00389 return( list ); 00390 } 00391 00392 #endif /* MBEDTLS_ASN1_PARSE_C */
Generated on Tue Jul 12 2022 12:52:41 by
