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 #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 12:43:33 by
