Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

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, Brainspark B.V.
00005  *
00006  *  This file is part of PolarSSL (http://www.polarssl.org)
00007  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
00008  *
00009  *  All rights reserved.
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License along
00022  *  with this program; if not, write to the Free Software Foundation, Inc.,
00023  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00024  */
00025 
00026 #if !defined(POLARSSL_CONFIG_FILE)
00027 #include "polarssl/config.h"
00028 #else
00029 #include POLARSSL_CONFIG_FILE
00030 #endif
00031 
00032 #if defined(POLARSSL_ASN1_PARSE_C)
00033 
00034 #include "polarssl/asn1.h"
00035 
00036 #if defined(POLARSSL_BIGNUM_C)
00037 #include "polarssl/bignum.h"
00038 #endif
00039 
00040 #if defined(POLARSSL_PLATFORM_C)
00041 #include "polarssl/platform.h"
00042 #else
00043 #define polarssl_malloc     malloc
00044 #define polarssl_free       free
00045 #endif
00046 
00047 #include <string.h>
00048 #include <stdlib.h>
00049 
00050 /*
00051  * ASN.1 DER decoding routines
00052  */
00053 int asn1_get_len( unsigned char **p,
00054                   const unsigned char *end,
00055                   size_t *len )
00056 {
00057     if( ( end - *p ) < 1 )
00058         return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00059 
00060     if( ( **p & 0x80 ) == 0 )
00061         *len = *(*p)++;
00062     else
00063     {
00064         switch( **p & 0x7F )
00065         {
00066         case 1:
00067             if( ( end - *p ) < 2 )
00068                 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00069 
00070             *len = (*p)[1];
00071             (*p) += 2;
00072             break;
00073 
00074         case 2:
00075             if( ( end - *p ) < 3 )
00076                 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00077 
00078             *len = ( (*p)[1] << 8 ) | (*p)[2];
00079             (*p) += 3;
00080             break;
00081 
00082         case 3:
00083             if( ( end - *p ) < 4 )
00084                 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00085 
00086             *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
00087             (*p) += 4;
00088             break;
00089 
00090         case 4:
00091             if( ( end - *p ) < 5 )
00092                 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00093 
00094             *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) |
00095                    (*p)[4];
00096             (*p) += 5;
00097             break;
00098 
00099         default:
00100             return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
00101         }
00102     }
00103 
00104     if( *len > (size_t) ( end - *p ) )
00105         return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00106 
00107     return( 0 );
00108 }
00109 
00110 int asn1_get_tag( unsigned char **p,
00111                   const unsigned char *end,
00112                   size_t *len, int tag )
00113 {
00114     if( ( end - *p ) < 1 )
00115         return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00116 
00117     if( **p != tag )
00118         return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00119 
00120     (*p)++;
00121 
00122     return( asn1_get_len( p, end, len ) );
00123 }
00124 
00125 int asn1_get_bool( unsigned char **p,
00126                    const unsigned char *end,
00127                    int *val )
00128 {
00129     int ret;
00130     size_t len;
00131 
00132     if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
00133         return( ret );
00134 
00135     if( len != 1 )
00136         return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
00137 
00138     *val = ( **p != 0 ) ? 1 : 0;
00139     (*p)++;
00140 
00141     return( 0 );
00142 }
00143 
00144 int asn1_get_int( unsigned char **p,
00145                   const unsigned char *end,
00146                   int *val )
00147 {
00148     int ret;
00149     size_t len;
00150 
00151     if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
00152         return( ret );
00153 
00154     if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
00155         return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
00156 
00157     *val = 0;
00158 
00159     while( len-- > 0 )
00160     {
00161         *val = ( *val << 8 ) | **p;
00162         (*p)++;
00163     }
00164 
00165     return( 0 );
00166 }
00167 
00168 #if defined(POLARSSL_BIGNUM_C)
00169 int asn1_get_mpi( unsigned char **p,
00170                   const unsigned char *end,
00171                   mpi *X )
00172 {
00173     int ret;
00174     size_t len;
00175 
00176     if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
00177         return( ret );
00178 
00179     ret = mpi_read_binary( X, *p, len );
00180 
00181     *p += len;
00182 
00183     return( ret );
00184 }
00185 #endif /* POLARSSL_BIGNUM_C */
00186 
00187 int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
00188                         asn1_bitstring *bs)
00189 {
00190     int ret;
00191 
00192     /* Certificate type is a single byte bitstring */
00193     if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
00194         return( ret );
00195 
00196     /* Check length, subtract one for actual bit string length */
00197     if ( bs->len < 1 )
00198         return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00199     bs->len -= 1;
00200 
00201     /* Get number of unused bits, ensure unused bits <= 7 */
00202     bs->unused_bits = **p;
00203     if( bs->unused_bits > 7 )
00204         return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
00205     (*p)++;
00206 
00207     /* Get actual bitstring */
00208     bs->p = *p;
00209     *p += bs->len;
00210 
00211     if( *p != end )
00212         return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00213 
00214     return 0;
00215 }
00216 
00217 /*
00218  * Get a bit string without unused bits
00219  */
00220 int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
00221                              size_t *len )
00222 {
00223     int ret;
00224 
00225     if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
00226         return( ret );
00227 
00228     if( (*len)-- < 2 || *(*p)++ != 0 )
00229         return( POLARSSL_ERR_ASN1_INVALID_DATA );
00230 
00231     return( 0 );
00232 }
00233 
00234 
00235 
00236 /*
00237  *  Parses and splits an ASN.1 "SEQUENCE OF <tag>"
00238  */
00239 int asn1_get_sequence_of( unsigned char **p,
00240                           const unsigned char *end,
00241                           asn1_sequence *cur,
00242                           int tag)
00243 {
00244     int ret;
00245     size_t len;
00246     asn1_buf *buf;
00247 
00248     /* Get main sequence tag */
00249     if( ( ret = asn1_get_tag( p, end, &len,
00250             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00251         return( ret );
00252 
00253     if( *p + len != end )
00254         return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00255 
00256     while( *p < end )
00257     {
00258         buf = &(cur->buf);
00259         buf->tag = **p;
00260 
00261         if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
00262             return( ret );
00263 
00264         buf->p = *p;
00265         *p += buf->len;
00266 
00267         /* Allocate and assign next pointer */
00268         if (*p < end)
00269         {
00270             cur->next = (asn1_sequence *) polarssl_malloc(
00271                  sizeof( asn1_sequence ) );
00272 
00273             if( cur->next == NULL )
00274                 return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
00275 
00276             cur = cur->next;
00277         }
00278     }
00279 
00280     /* Set final sequence entry's next pointer to NULL */
00281     cur->next = NULL;
00282 
00283     if( *p != end )
00284         return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00285 
00286     return( 0 );
00287 }
00288 
00289 int asn1_get_alg( unsigned char **p,
00290                   const unsigned char *end,
00291                   asn1_buf *alg, asn1_buf *params )
00292 {
00293     int ret;
00294     size_t len;
00295 
00296     if( ( ret = asn1_get_tag( p, end, &len,
00297             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00298         return( ret );
00299 
00300     if( ( end - *p ) < 1 )
00301         return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
00302 
00303     alg->tag = **p;
00304     end = *p + len;
00305 
00306     if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
00307         return( ret );
00308 
00309     alg->p = *p;
00310     *p += alg->len;
00311 
00312     if( *p == end )
00313     {
00314         memset( params, 0, sizeof(asn1_buf) );
00315         return( 0 );
00316     }
00317 
00318     params->tag = **p;
00319     (*p)++;
00320 
00321     if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
00322         return( ret );
00323 
00324     params->p = *p;
00325     *p += params->len;
00326 
00327     if( *p != end )
00328         return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00329 
00330     return( 0 );
00331 }
00332 
00333 int asn1_get_alg_null( unsigned char **p,
00334                        const unsigned char *end,
00335                        asn1_buf *alg )
00336 {
00337     int ret;
00338     asn1_buf params;
00339 
00340     memset( &params, 0, sizeof(asn1_buf) );
00341 
00342     if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
00343         return( ret );
00344 
00345     if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
00346         return( POLARSSL_ERR_ASN1_INVALID_DATA );
00347 
00348     return( 0 );
00349 }
00350 
00351 void asn1_free_named_data( asn1_named_data *cur )
00352 {
00353     if( cur == NULL )
00354         return;
00355 
00356     polarssl_free( cur->oid.p );
00357     polarssl_free( cur->val.p );
00358 
00359     memset( cur, 0, sizeof( asn1_named_data ) );
00360 }
00361 
00362 void asn1_free_named_data_list( asn1_named_data **head )
00363 {
00364     asn1_named_data *cur;
00365 
00366     while( ( cur = *head ) != NULL )
00367     {
00368         *head = cur->next;
00369         asn1_free_named_data( cur );
00370         polarssl_free( cur );
00371     }
00372 }
00373 
00374 asn1_named_data *asn1_find_named_data( asn1_named_data *list,
00375                                        const char *oid, size_t len )
00376 {
00377     while( list != NULL )
00378     {
00379         if( list->oid.len == len &&
00380             memcmp( list->oid.p, oid, len ) == 0 )
00381         {
00382             break;
00383         }
00384 
00385         list = list->next;
00386     }
00387 
00388     return( list );
00389 }
00390 
00391 #endif /* POLARSSL_ASN1_PARSE_C */
00392 
00393