mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

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-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, &params->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( &params, 0, sizeof(asn1_buf) );
00345 
00346     if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 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