Rtos API example

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 
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 = (unsigned char*)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 == 0 || 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_asn1_sequence*)mbedtls_calloc( 1,
00273                                             sizeof( mbedtls_asn1_sequence ) );
00274 
00275             if( cur->next == NULL )
00276                 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
00277 
00278             cur = cur->next;
00279         }
00280     }
00281 
00282     /* Set final sequence entry's next pointer to NULL */
00283     cur->next = NULL;
00284 
00285     if( *p != end )
00286         return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00287 
00288     return( 0 );
00289 }
00290 
00291 int mbedtls_asn1_get_alg( unsigned char **p,
00292                   const unsigned char *end,
00293                   mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
00294 {
00295     int ret;
00296     size_t len;
00297 
00298     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
00299             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00300         return( ret );
00301 
00302     if( ( end - *p ) < 1 )
00303         return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
00304 
00305     alg->tag = **p;
00306     end = *p + len;
00307 
00308     if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
00309         return( ret );
00310 
00311     alg->p = *p;
00312     *p += alg->len;
00313 
00314     if( *p == end )
00315     {
00316         mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) );
00317         return( 0 );
00318     }
00319 
00320     params->tag = **p;
00321     (*p)++;
00322 
00323     if( ( ret = mbedtls_asn1_get_len( p, end, &params->len ) ) != 0 )
00324         return( ret );
00325 
00326     params->p = *p;
00327     *p += params->len;
00328 
00329     if( *p != end )
00330         return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00331 
00332     return( 0 );
00333 }
00334 
00335 int mbedtls_asn1_get_alg_null( unsigned char **p,
00336                        const unsigned char *end,
00337                        mbedtls_asn1_buf *alg )
00338 {
00339     int ret;
00340     mbedtls_asn1_buf params;
00341 
00342     memset( &params, 0, sizeof(mbedtls_asn1_buf) );
00343 
00344     if( ( ret = mbedtls_asn1_get_alg( p, end, alg, &params ) ) != 0 )
00345         return( ret );
00346 
00347     if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
00348         return( MBEDTLS_ERR_ASN1_INVALID_DATA );
00349 
00350     return( 0 );
00351 }
00352 
00353 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
00354 {
00355     if( cur == NULL )
00356         return;
00357 
00358     mbedtls_free( cur->oid.p );
00359     mbedtls_free( cur->val.p );
00360 
00361     mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
00362 }
00363 
00364 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
00365 {
00366     mbedtls_asn1_named_data *cur;
00367 
00368     while( ( cur = *head ) != NULL )
00369     {
00370         *head = cur->next;
00371         mbedtls_asn1_free_named_data( cur );
00372         mbedtls_free( cur );
00373     }
00374 }
00375 
00376 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
00377                                        const char *oid, size_t len )
00378 {
00379     while( list != NULL )
00380     {
00381         if( list->oid.len == len &&
00382             memcmp( list->oid.p, oid, len ) == 0 )
00383         {
00384             break;
00385         }
00386 
00387         list = list->next;
00388     }
00389 
00390     return( list );
00391 }
00392 
00393 #endif /* MBEDTLS_ASN1_PARSE_C */