mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
asn1parse.c
00001 /* 00002 * Generic ASN.1 parsing 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 00023 #if !defined(POLARSSL_CONFIG_FILE) 00024 #include "polarssl/config.h" 00025 #else 00026 #include POLARSSL_CONFIG_FILE 00027 #endif 00028 00029 #if defined(POLARSSL_ASN1_PARSE_C) 00030 00031 #include "polarssl/asn1.h" 00032 00033 #include <string.h> 00034 00035 #if defined(POLARSSL_BIGNUM_C) 00036 #include "polarssl/bignum.h" 00037 #endif 00038 00039 #if defined(POLARSSL_PLATFORM_C) 00040 #include "polarssl/platform.h" 00041 #else 00042 #include <stdlib.h> 00043 #define polarssl_malloc malloc 00044 #define polarssl_free free 00045 #endif 00046 00047 /* Implementation that should never be optimized out by the compiler */ 00048 static void polarssl_zeroize( void *v, size_t n ) { 00049 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00050 } 00051 00052 /* 00053 * ASN.1 DER decoding routines 00054 */ 00055 int asn1_get_len( unsigned char **p, 00056 const unsigned char *end, 00057 size_t *len ) 00058 { 00059 if( ( end - *p ) < 1 ) 00060 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00061 00062 if( ( **p & 0x80 ) == 0 ) 00063 *len = *(*p)++; 00064 else 00065 { 00066 switch( **p & 0x7F ) 00067 { 00068 case 1: 00069 if( ( end - *p ) < 2 ) 00070 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00071 00072 *len = (*p)[1]; 00073 (*p) += 2; 00074 break; 00075 00076 case 2: 00077 if( ( end - *p ) < 3 ) 00078 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00079 00080 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; 00081 (*p) += 3; 00082 break; 00083 00084 case 3: 00085 if( ( end - *p ) < 4 ) 00086 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00087 00088 *len = ( (size_t)(*p)[1] << 16 ) | 00089 ( (size_t)(*p)[2] << 8 ) | (*p)[3]; 00090 (*p) += 4; 00091 break; 00092 00093 case 4: 00094 if( ( end - *p ) < 5 ) 00095 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00096 00097 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | 00098 ( (size_t)(*p)[3] << 8 ) | (*p)[4]; 00099 (*p) += 5; 00100 break; 00101 00102 default: 00103 return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00104 } 00105 } 00106 00107 if( *len > (size_t) ( end - *p ) ) 00108 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00109 00110 return( 0 ); 00111 } 00112 00113 int asn1_get_tag( unsigned char **p, 00114 const unsigned char *end, 00115 size_t *len, int tag ) 00116 { 00117 if( ( end - *p ) < 1 ) 00118 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00119 00120 if( **p != tag ) 00121 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); 00122 00123 (*p)++; 00124 00125 return( asn1_get_len( p, end, len ) ); 00126 } 00127 00128 int asn1_get_bool( unsigned char **p, 00129 const unsigned char *end, 00130 int *val ) 00131 { 00132 int ret; 00133 size_t len; 00134 00135 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 ) 00136 return( ret ); 00137 00138 if( len != 1 ) 00139 return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00140 00141 *val = ( **p != 0 ) ? 1 : 0; 00142 (*p)++; 00143 00144 return( 0 ); 00145 } 00146 00147 int asn1_get_int( unsigned char **p, 00148 const unsigned char *end, 00149 int *val ) 00150 { 00151 int ret; 00152 size_t len; 00153 00154 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) 00155 return( ret ); 00156 00157 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 ) 00158 return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00159 00160 *val = 0; 00161 00162 while( len-- > 0 ) 00163 { 00164 *val = ( *val << 8 ) | **p; 00165 (*p)++; 00166 } 00167 00168 return( 0 ); 00169 } 00170 00171 #if defined(POLARSSL_BIGNUM_C) 00172 int asn1_get_mpi( unsigned char **p, 00173 const unsigned char *end, 00174 mpi *X ) 00175 { 00176 int ret; 00177 size_t len; 00178 00179 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) 00180 return( ret ); 00181 00182 ret = mpi_read_binary( X, *p, len ); 00183 00184 *p += len; 00185 00186 return( ret ); 00187 } 00188 #endif /* POLARSSL_BIGNUM_C */ 00189 00190 int asn1_get_bitstring( unsigned char **p, const unsigned char *end, 00191 asn1_bitstring *bs) 00192 { 00193 int ret; 00194 00195 /* Certificate type is a single byte bitstring */ 00196 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 ) 00197 return( ret ); 00198 00199 /* Check length, subtract one for actual bit string length */ 00200 if( bs->len < 1 ) 00201 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00202 bs->len -= 1; 00203 00204 /* Get number of unused bits, ensure unused bits <= 7 */ 00205 bs->unused_bits = **p; 00206 if( bs->unused_bits > 7 ) 00207 return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00208 (*p)++; 00209 00210 /* Get actual bitstring */ 00211 bs->p = *p; 00212 *p += bs->len; 00213 00214 if( *p != end ) 00215 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00216 00217 return( 0 ); 00218 } 00219 00220 /* 00221 * Get a bit string without unused bits 00222 */ 00223 int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, 00224 size_t *len ) 00225 { 00226 int ret; 00227 00228 if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 ) 00229 return( ret ); 00230 00231 if( (*len)-- < 2 || *(*p)++ != 0 ) 00232 return( POLARSSL_ERR_ASN1_INVALID_DATA ); 00233 00234 return( 0 ); 00235 } 00236 00237 00238 00239 /* 00240 * Parses and splits an ASN.1 "SEQUENCE OF <tag>" 00241 */ 00242 int asn1_get_sequence_of( unsigned char **p, 00243 const unsigned char *end, 00244 asn1_sequence *cur, 00245 int tag) 00246 { 00247 int ret; 00248 size_t len; 00249 asn1_buf *buf; 00250 00251 /* Get main sequence tag */ 00252 if( ( ret = asn1_get_tag( p, end, &len, 00253 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00254 return( ret ); 00255 00256 if( *p + len != end ) 00257 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00258 00259 while( *p < end ) 00260 { 00261 buf = &(cur->buf); 00262 buf->tag = **p; 00263 00264 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) 00265 return( ret ); 00266 00267 buf->p = *p; 00268 *p += buf->len; 00269 00270 /* Allocate and assign next pointer */ 00271 if( *p < end ) 00272 { 00273 cur->next = polarssl_malloc( sizeof( asn1_sequence ) ); 00274 00275 if( cur->next == NULL ) 00276 return( POLARSSL_ERR_ASN1_MALLOC_FAILED ); 00277 00278 memset( cur->next, 0, sizeof( asn1_sequence ) ); 00279 00280 cur = cur->next; 00281 } 00282 } 00283 00284 /* Set final sequence entry's next pointer to NULL */ 00285 cur->next = NULL; 00286 00287 if( *p != end ) 00288 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00289 00290 return( 0 ); 00291 } 00292 00293 int asn1_get_alg( unsigned char **p, 00294 const unsigned char *end, 00295 asn1_buf *alg, asn1_buf *params ) 00296 { 00297 int ret; 00298 size_t len; 00299 00300 if( ( ret = asn1_get_tag( p, end, &len, 00301 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00302 return( ret ); 00303 00304 if( ( end - *p ) < 1 ) 00305 return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00306 00307 alg->tag = **p; 00308 end = *p + len; 00309 00310 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 ) 00311 return( ret ); 00312 00313 alg->p = *p; 00314 *p += alg->len; 00315 00316 if( *p == end ) 00317 { 00318 polarssl_zeroize( params, sizeof(asn1_buf) ); 00319 return( 0 ); 00320 } 00321 00322 params->tag = **p; 00323 (*p)++; 00324 00325 if( ( ret = asn1_get_len( p, end, ¶ms->len ) ) != 0 ) 00326 return( ret ); 00327 00328 params->p = *p; 00329 *p += params->len; 00330 00331 if( *p != end ) 00332 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00333 00334 return( 0 ); 00335 } 00336 00337 int asn1_get_alg_null( unsigned char **p, 00338 const unsigned char *end, 00339 asn1_buf *alg ) 00340 { 00341 int ret; 00342 asn1_buf params; 00343 00344 memset( ¶ms, 0, sizeof(asn1_buf) ); 00345 00346 if( ( ret = asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) 00347 return( ret ); 00348 00349 if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 ) 00350 return( POLARSSL_ERR_ASN1_INVALID_DATA ); 00351 00352 return( 0 ); 00353 } 00354 00355 void asn1_free_named_data( asn1_named_data *cur ) 00356 { 00357 if( cur == NULL ) 00358 return; 00359 00360 polarssl_free( cur->oid.p ); 00361 polarssl_free( cur->val.p ); 00362 00363 polarssl_zeroize( cur, sizeof( asn1_named_data ) ); 00364 } 00365 00366 void asn1_free_named_data_list( asn1_named_data **head ) 00367 { 00368 asn1_named_data *cur; 00369 00370 while( ( cur = *head ) != NULL ) 00371 { 00372 *head = cur->next; 00373 asn1_free_named_data( cur ); 00374 polarssl_free( cur ); 00375 } 00376 } 00377 00378 asn1_named_data *asn1_find_named_data( asn1_named_data *list, 00379 const char *oid, size_t len ) 00380 { 00381 while( list != NULL ) 00382 { 00383 if( list->oid.len == len && 00384 memcmp( list->oid.p, oid, len ) == 0 ) 00385 { 00386 break; 00387 } 00388 00389 list = list->next; 00390 } 00391 00392 return( list ); 00393 } 00394 00395 #endif /* POLARSSL_ASN1_PARSE_C */ 00396
Generated on Tue Jul 12 2022 13:50:36 by 1.7.2