Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers asn1parse.c Source File

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, &params->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( &params, 0, sizeof(mbedtls_asn1_buf) );
00339 
00340     if( ( ret = mbedtls_asn1_get_alg( p, end, alg, &params ) ) != 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 */