mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

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