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.
Dependencies: nRF51_Vdd TextLCD BME280
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 if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) 00153 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00154 00155 *val = 0; 00156 00157 while( len-- > 0 ) 00158 { 00159 *val = ( *val << 8 ) | **p; 00160 (*p)++; 00161 } 00162 00163 return( 0 ); 00164 } 00165 00166 #if defined(MBEDTLS_BIGNUM_C) 00167 int mbedtls_asn1_get_mpi( unsigned char **p, 00168 const unsigned char *end, 00169 mbedtls_mpi *X ) 00170 { 00171 int ret; 00172 size_t len; 00173 00174 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) 00175 return( ret ); 00176 00177 ret = mbedtls_mpi_read_binary( X, *p, len ); 00178 00179 *p += len; 00180 00181 return( ret ); 00182 } 00183 #endif /* MBEDTLS_BIGNUM_C */ 00184 00185 int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, 00186 mbedtls_asn1_bitstring *bs) 00187 { 00188 int ret; 00189 00190 /* Certificate type is a single byte bitstring */ 00191 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 00192 return( ret ); 00193 00194 /* Check length, subtract one for actual bit string length */ 00195 if( bs->len < 1 ) 00196 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00197 bs->len -= 1; 00198 00199 /* Get number of unused bits, ensure unused bits <= 7 */ 00200 bs->unused_bits = **p; 00201 if( bs->unused_bits > 7 ) 00202 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00203 (*p)++; 00204 00205 /* Get actual bitstring */ 00206 bs->p = *p; 00207 *p += bs->len; 00208 00209 if( *p != end ) 00210 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00211 00212 return( 0 ); 00213 } 00214 00215 /* 00216 * Get a bit string without unused bits 00217 */ 00218 int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, 00219 size_t *len ) 00220 { 00221 int ret; 00222 00223 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) 00224 return( ret ); 00225 00226 if( (*len)-- < 2 || *(*p)++ != 0 ) 00227 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 00228 00229 return( 0 ); 00230 } 00231 00232 00233 00234 /* 00235 * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 00236 */ 00237 int mbedtls_asn1_get_sequence_of( unsigned char **p, 00238 const unsigned char *end, 00239 mbedtls_asn1_sequence *cur, 00240 int tag) 00241 { 00242 int ret; 00243 size_t len; 00244 mbedtls_asn1_buf *buf; 00245 00246 /* Get main sequence tag */ 00247 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00248 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00249 return( ret ); 00250 00251 if( *p + len != end ) 00252 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00253 00254 while( *p < end ) 00255 { 00256 buf = &(cur->buf); 00257 buf->tag = **p; 00258 00259 if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) 00260 return( ret ); 00261 00262 buf->p = *p; 00263 *p += buf->len; 00264 00265 /* Allocate and assign next pointer */ 00266 if( *p < end ) 00267 { 00268 cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, 00269 sizeof( mbedtls_asn1_sequence ) ); 00270 00271 if( cur->next == NULL ) 00272 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); 00273 00274 cur = cur->next; 00275 } 00276 } 00277 00278 /* Set final sequence entry's next pointer to NULL */ 00279 cur->next = NULL; 00280 00281 if( *p != end ) 00282 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00283 00284 return( 0 ); 00285 } 00286 00287 int mbedtls_asn1_get_alg( unsigned char **p, 00288 const unsigned char *end, 00289 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) 00290 { 00291 int ret; 00292 size_t len; 00293 00294 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00295 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00296 return( ret ); 00297 00298 if( ( end - *p ) < 1 ) 00299 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00300 00301 alg->tag = **p; 00302 end = *p + len; 00303 00304 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) 00305 return( ret ); 00306 00307 alg->p = *p; 00308 *p += alg->len; 00309 00310 if( *p == end ) 00311 { 00312 mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) ); 00313 return( 0 ); 00314 } 00315 00316 params->tag = **p; 00317 (*p)++; 00318 00319 if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) 00320 return( ret ); 00321 00322 params->p = *p; 00323 *p += params->len; 00324 00325 if( *p != end ) 00326 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00327 00328 return( 0 ); 00329 } 00330 00331 int mbedtls_asn1_get_alg_null( unsigned char **p, 00332 const unsigned char *end, 00333 mbedtls_asn1_buf *alg ) 00334 { 00335 int ret; 00336 mbedtls_asn1_buf params; 00337 00338 memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); 00339 00340 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) 00341 return( ret ); 00342 00343 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) 00344 return( MBEDTLS_ERR_ASN1_INVALID_DATA ); 00345 00346 return( 0 ); 00347 } 00348 00349 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) 00350 { 00351 if( cur == NULL ) 00352 return; 00353 00354 mbedtls_free( cur->oid.p ); 00355 mbedtls_free( cur->val.p ); 00356 00357 mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); 00358 } 00359 00360 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) 00361 { 00362 mbedtls_asn1_named_data *cur; 00363 00364 while( ( cur = *head ) != NULL ) 00365 { 00366 *head = cur->next; 00367 mbedtls_asn1_free_named_data( cur ); 00368 mbedtls_free( cur ); 00369 } 00370 } 00371 00372 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, 00373 const char *oid, size_t len ) 00374 { 00375 while( list != NULL ) 00376 { 00377 if( list->oid.len == len && 00378 memcmp( list->oid.p, oid, len ) == 0 ) 00379 { 00380 break; 00381 } 00382 00383 list = list->next; 00384 } 00385 00386 return( list ); 00387 } 00388 00389 #endif /* MBEDTLS_ASN1_PARSE_C */
Generated on Tue Jul 12 2022 15:15:39 by
