Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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