mbedtls ported to mbed-classic
Fork of mbedtls by
Embed:
(wiki syntax)
Show/hide line numbers
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 1.7.2