mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:137634ff4186 1 /*
ansond 0:137634ff4186 2 * Generic ASN.1 parsing
ansond 0:137634ff4186 3 *
ansond 0:137634ff4186 4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
ansond 0:137634ff4186 5 *
ansond 0:137634ff4186 6 * This file is part of mbed TLS (https://tls.mbed.org)
ansond 0:137634ff4186 7 *
ansond 0:137634ff4186 8 * This program is free software; you can redistribute it and/or modify
ansond 0:137634ff4186 9 * it under the terms of the GNU General Public License as published by
ansond 0:137634ff4186 10 * the Free Software Foundation; either version 2 of the License, or
ansond 0:137634ff4186 11 * (at your option) any later version.
ansond 0:137634ff4186 12 *
ansond 0:137634ff4186 13 * This program is distributed in the hope that it will be useful,
ansond 0:137634ff4186 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ansond 0:137634ff4186 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ansond 0:137634ff4186 16 * GNU General Public License for more details.
ansond 0:137634ff4186 17 *
ansond 0:137634ff4186 18 * You should have received a copy of the GNU General Public License along
ansond 0:137634ff4186 19 * with this program; if not, write to the Free Software Foundation, Inc.,
ansond 0:137634ff4186 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ansond 0:137634ff4186 21 */
ansond 0:137634ff4186 22
ansond 0:137634ff4186 23 #if !defined(POLARSSL_CONFIG_FILE)
ansond 0:137634ff4186 24 #include "polarssl/config.h"
ansond 0:137634ff4186 25 #else
ansond 0:137634ff4186 26 #include POLARSSL_CONFIG_FILE
ansond 0:137634ff4186 27 #endif
ansond 0:137634ff4186 28
ansond 0:137634ff4186 29 #if defined(POLARSSL_ASN1_PARSE_C)
ansond 0:137634ff4186 30
ansond 0:137634ff4186 31 #include "polarssl/asn1.h"
ansond 0:137634ff4186 32
ansond 0:137634ff4186 33 #include <string.h>
ansond 0:137634ff4186 34
ansond 0:137634ff4186 35 #if defined(POLARSSL_BIGNUM_C)
ansond 0:137634ff4186 36 #include "polarssl/bignum.h"
ansond 0:137634ff4186 37 #endif
ansond 0:137634ff4186 38
ansond 0:137634ff4186 39 #if defined(POLARSSL_PLATFORM_C)
ansond 0:137634ff4186 40 #include "polarssl/platform.h"
ansond 0:137634ff4186 41 #else
ansond 0:137634ff4186 42 #include <stdlib.h>
ansond 0:137634ff4186 43 #define polarssl_malloc malloc
ansond 0:137634ff4186 44 #define polarssl_free free
ansond 0:137634ff4186 45 #endif
ansond 0:137634ff4186 46
ansond 0:137634ff4186 47 /* Implementation that should never be optimized out by the compiler */
ansond 0:137634ff4186 48 static void polarssl_zeroize( void *v, size_t n ) {
ansond 0:137634ff4186 49 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
ansond 0:137634ff4186 50 }
ansond 0:137634ff4186 51
ansond 0:137634ff4186 52 /*
ansond 0:137634ff4186 53 * ASN.1 DER decoding routines
ansond 0:137634ff4186 54 */
ansond 0:137634ff4186 55 int asn1_get_len( unsigned char **p,
ansond 0:137634ff4186 56 const unsigned char *end,
ansond 0:137634ff4186 57 size_t *len )
ansond 0:137634ff4186 58 {
ansond 0:137634ff4186 59 if( ( end - *p ) < 1 )
ansond 0:137634ff4186 60 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 61
ansond 0:137634ff4186 62 if( ( **p & 0x80 ) == 0 )
ansond 0:137634ff4186 63 *len = *(*p)++;
ansond 0:137634ff4186 64 else
ansond 0:137634ff4186 65 {
ansond 0:137634ff4186 66 switch( **p & 0x7F )
ansond 0:137634ff4186 67 {
ansond 0:137634ff4186 68 case 1:
ansond 0:137634ff4186 69 if( ( end - *p ) < 2 )
ansond 0:137634ff4186 70 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 71
ansond 0:137634ff4186 72 *len = (*p)[1];
ansond 0:137634ff4186 73 (*p) += 2;
ansond 0:137634ff4186 74 break;
ansond 0:137634ff4186 75
ansond 0:137634ff4186 76 case 2:
ansond 0:137634ff4186 77 if( ( end - *p ) < 3 )
ansond 0:137634ff4186 78 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 79
ansond 0:137634ff4186 80 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
ansond 0:137634ff4186 81 (*p) += 3;
ansond 0:137634ff4186 82 break;
ansond 0:137634ff4186 83
ansond 0:137634ff4186 84 case 3:
ansond 0:137634ff4186 85 if( ( end - *p ) < 4 )
ansond 0:137634ff4186 86 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 87
ansond 0:137634ff4186 88 *len = ( (size_t)(*p)[1] << 16 ) |
ansond 0:137634ff4186 89 ( (size_t)(*p)[2] << 8 ) | (*p)[3];
ansond 0:137634ff4186 90 (*p) += 4;
ansond 0:137634ff4186 91 break;
ansond 0:137634ff4186 92
ansond 0:137634ff4186 93 case 4:
ansond 0:137634ff4186 94 if( ( end - *p ) < 5 )
ansond 0:137634ff4186 95 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 96
ansond 0:137634ff4186 97 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
ansond 0:137634ff4186 98 ( (size_t)(*p)[3] << 8 ) | (*p)[4];
ansond 0:137634ff4186 99 (*p) += 5;
ansond 0:137634ff4186 100 break;
ansond 0:137634ff4186 101
ansond 0:137634ff4186 102 default:
ansond 0:137634ff4186 103 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
ansond 0:137634ff4186 104 }
ansond 0:137634ff4186 105 }
ansond 0:137634ff4186 106
ansond 0:137634ff4186 107 if( *len > (size_t) ( end - *p ) )
ansond 0:137634ff4186 108 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 109
ansond 0:137634ff4186 110 return( 0 );
ansond 0:137634ff4186 111 }
ansond 0:137634ff4186 112
ansond 0:137634ff4186 113 int asn1_get_tag( unsigned char **p,
ansond 0:137634ff4186 114 const unsigned char *end,
ansond 0:137634ff4186 115 size_t *len, int tag )
ansond 0:137634ff4186 116 {
ansond 0:137634ff4186 117 if( ( end - *p ) < 1 )
ansond 0:137634ff4186 118 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 119
ansond 0:137634ff4186 120 if( **p != tag )
ansond 0:137634ff4186 121 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
ansond 0:137634ff4186 122
ansond 0:137634ff4186 123 (*p)++;
ansond 0:137634ff4186 124
ansond 0:137634ff4186 125 return( asn1_get_len( p, end, len ) );
ansond 0:137634ff4186 126 }
ansond 0:137634ff4186 127
ansond 0:137634ff4186 128 int asn1_get_bool( unsigned char **p,
ansond 0:137634ff4186 129 const unsigned char *end,
ansond 0:137634ff4186 130 int *val )
ansond 0:137634ff4186 131 {
ansond 0:137634ff4186 132 int ret;
ansond 0:137634ff4186 133 size_t len;
ansond 0:137634ff4186 134
ansond 0:137634ff4186 135 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
ansond 0:137634ff4186 136 return( ret );
ansond 0:137634ff4186 137
ansond 0:137634ff4186 138 if( len != 1 )
ansond 0:137634ff4186 139 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
ansond 0:137634ff4186 140
ansond 0:137634ff4186 141 *val = ( **p != 0 ) ? 1 : 0;
ansond 0:137634ff4186 142 (*p)++;
ansond 0:137634ff4186 143
ansond 0:137634ff4186 144 return( 0 );
ansond 0:137634ff4186 145 }
ansond 0:137634ff4186 146
ansond 0:137634ff4186 147 int asn1_get_int( unsigned char **p,
ansond 0:137634ff4186 148 const unsigned char *end,
ansond 0:137634ff4186 149 int *val )
ansond 0:137634ff4186 150 {
ansond 0:137634ff4186 151 int ret;
ansond 0:137634ff4186 152 size_t len;
ansond 0:137634ff4186 153
ansond 0:137634ff4186 154 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
ansond 0:137634ff4186 155 return( ret );
ansond 0:137634ff4186 156
ansond 0:137634ff4186 157 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
ansond 0:137634ff4186 158 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
ansond 0:137634ff4186 159
ansond 0:137634ff4186 160 *val = 0;
ansond 0:137634ff4186 161
ansond 0:137634ff4186 162 while( len-- > 0 )
ansond 0:137634ff4186 163 {
ansond 0:137634ff4186 164 *val = ( *val << 8 ) | **p;
ansond 0:137634ff4186 165 (*p)++;
ansond 0:137634ff4186 166 }
ansond 0:137634ff4186 167
ansond 0:137634ff4186 168 return( 0 );
ansond 0:137634ff4186 169 }
ansond 0:137634ff4186 170
ansond 0:137634ff4186 171 #if defined(POLARSSL_BIGNUM_C)
ansond 0:137634ff4186 172 int asn1_get_mpi( unsigned char **p,
ansond 0:137634ff4186 173 const unsigned char *end,
ansond 0:137634ff4186 174 mpi *X )
ansond 0:137634ff4186 175 {
ansond 0:137634ff4186 176 int ret;
ansond 0:137634ff4186 177 size_t len;
ansond 0:137634ff4186 178
ansond 0:137634ff4186 179 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
ansond 0:137634ff4186 180 return( ret );
ansond 0:137634ff4186 181
ansond 0:137634ff4186 182 ret = mpi_read_binary( X, *p, len );
ansond 0:137634ff4186 183
ansond 0:137634ff4186 184 *p += len;
ansond 0:137634ff4186 185
ansond 0:137634ff4186 186 return( ret );
ansond 0:137634ff4186 187 }
ansond 0:137634ff4186 188 #endif /* POLARSSL_BIGNUM_C */
ansond 0:137634ff4186 189
ansond 0:137634ff4186 190 int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
ansond 0:137634ff4186 191 asn1_bitstring *bs)
ansond 0:137634ff4186 192 {
ansond 0:137634ff4186 193 int ret;
ansond 0:137634ff4186 194
ansond 0:137634ff4186 195 /* Certificate type is a single byte bitstring */
ansond 0:137634ff4186 196 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
ansond 0:137634ff4186 197 return( ret );
ansond 0:137634ff4186 198
ansond 0:137634ff4186 199 /* Check length, subtract one for actual bit string length */
ansond 0:137634ff4186 200 if( bs->len < 1 )
ansond 0:137634ff4186 201 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 202 bs->len -= 1;
ansond 0:137634ff4186 203
ansond 0:137634ff4186 204 /* Get number of unused bits, ensure unused bits <= 7 */
ansond 0:137634ff4186 205 bs->unused_bits = **p;
ansond 0:137634ff4186 206 if( bs->unused_bits > 7 )
ansond 0:137634ff4186 207 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
ansond 0:137634ff4186 208 (*p)++;
ansond 0:137634ff4186 209
ansond 0:137634ff4186 210 /* Get actual bitstring */
ansond 0:137634ff4186 211 bs->p = *p;
ansond 0:137634ff4186 212 *p += bs->len;
ansond 0:137634ff4186 213
ansond 0:137634ff4186 214 if( *p != end )
ansond 0:137634ff4186 215 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
ansond 0:137634ff4186 216
ansond 0:137634ff4186 217 return( 0 );
ansond 0:137634ff4186 218 }
ansond 0:137634ff4186 219
ansond 0:137634ff4186 220 /*
ansond 0:137634ff4186 221 * Get a bit string without unused bits
ansond 0:137634ff4186 222 */
ansond 0:137634ff4186 223 int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
ansond 0:137634ff4186 224 size_t *len )
ansond 0:137634ff4186 225 {
ansond 0:137634ff4186 226 int ret;
ansond 0:137634ff4186 227
ansond 0:137634ff4186 228 if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
ansond 0:137634ff4186 229 return( ret );
ansond 0:137634ff4186 230
ansond 0:137634ff4186 231 if( (*len)-- < 2 || *(*p)++ != 0 )
ansond 0:137634ff4186 232 return( POLARSSL_ERR_ASN1_INVALID_DATA );
ansond 0:137634ff4186 233
ansond 0:137634ff4186 234 return( 0 );
ansond 0:137634ff4186 235 }
ansond 0:137634ff4186 236
ansond 0:137634ff4186 237
ansond 0:137634ff4186 238
ansond 0:137634ff4186 239 /*
ansond 0:137634ff4186 240 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
ansond 0:137634ff4186 241 */
ansond 0:137634ff4186 242 int asn1_get_sequence_of( unsigned char **p,
ansond 0:137634ff4186 243 const unsigned char *end,
ansond 0:137634ff4186 244 asn1_sequence *cur,
ansond 0:137634ff4186 245 int tag)
ansond 0:137634ff4186 246 {
ansond 0:137634ff4186 247 int ret;
ansond 0:137634ff4186 248 size_t len;
ansond 0:137634ff4186 249 asn1_buf *buf;
ansond 0:137634ff4186 250
ansond 0:137634ff4186 251 /* Get main sequence tag */
ansond 0:137634ff4186 252 if( ( ret = asn1_get_tag( p, end, &len,
ansond 0:137634ff4186 253 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
ansond 0:137634ff4186 254 return( ret );
ansond 0:137634ff4186 255
ansond 0:137634ff4186 256 if( *p + len != end )
ansond 0:137634ff4186 257 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
ansond 0:137634ff4186 258
ansond 0:137634ff4186 259 while( *p < end )
ansond 0:137634ff4186 260 {
ansond 0:137634ff4186 261 buf = &(cur->buf);
ansond 0:137634ff4186 262 buf->tag = **p;
ansond 0:137634ff4186 263
ansond 0:137634ff4186 264 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
ansond 0:137634ff4186 265 return( ret );
ansond 0:137634ff4186 266
ansond 0:137634ff4186 267 buf->p = *p;
ansond 0:137634ff4186 268 *p += buf->len;
ansond 0:137634ff4186 269
ansond 0:137634ff4186 270 /* Allocate and assign next pointer */
ansond 0:137634ff4186 271 if( *p < end )
ansond 0:137634ff4186 272 {
ansond 0:137634ff4186 273 cur->next = polarssl_malloc( sizeof( asn1_sequence ) );
ansond 0:137634ff4186 274
ansond 0:137634ff4186 275 if( cur->next == NULL )
ansond 0:137634ff4186 276 return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
ansond 0:137634ff4186 277
ansond 0:137634ff4186 278 memset( cur->next, 0, sizeof( asn1_sequence ) );
ansond 0:137634ff4186 279
ansond 0:137634ff4186 280 cur = cur->next;
ansond 0:137634ff4186 281 }
ansond 0:137634ff4186 282 }
ansond 0:137634ff4186 283
ansond 0:137634ff4186 284 /* Set final sequence entry's next pointer to NULL */
ansond 0:137634ff4186 285 cur->next = NULL;
ansond 0:137634ff4186 286
ansond 0:137634ff4186 287 if( *p != end )
ansond 0:137634ff4186 288 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
ansond 0:137634ff4186 289
ansond 0:137634ff4186 290 return( 0 );
ansond 0:137634ff4186 291 }
ansond 0:137634ff4186 292
ansond 0:137634ff4186 293 int asn1_get_alg( unsigned char **p,
ansond 0:137634ff4186 294 const unsigned char *end,
ansond 0:137634ff4186 295 asn1_buf *alg, asn1_buf *params )
ansond 0:137634ff4186 296 {
ansond 0:137634ff4186 297 int ret;
ansond 0:137634ff4186 298 size_t len;
ansond 0:137634ff4186 299
ansond 0:137634ff4186 300 if( ( ret = asn1_get_tag( p, end, &len,
ansond 0:137634ff4186 301 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
ansond 0:137634ff4186 302 return( ret );
ansond 0:137634ff4186 303
ansond 0:137634ff4186 304 if( ( end - *p ) < 1 )
ansond 0:137634ff4186 305 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
ansond 0:137634ff4186 306
ansond 0:137634ff4186 307 alg->tag = **p;
ansond 0:137634ff4186 308 end = *p + len;
ansond 0:137634ff4186 309
ansond 0:137634ff4186 310 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
ansond 0:137634ff4186 311 return( ret );
ansond 0:137634ff4186 312
ansond 0:137634ff4186 313 alg->p = *p;
ansond 0:137634ff4186 314 *p += alg->len;
ansond 0:137634ff4186 315
ansond 0:137634ff4186 316 if( *p == end )
ansond 0:137634ff4186 317 {
ansond 0:137634ff4186 318 polarssl_zeroize( params, sizeof(asn1_buf) );
ansond 0:137634ff4186 319 return( 0 );
ansond 0:137634ff4186 320 }
ansond 0:137634ff4186 321
ansond 0:137634ff4186 322 params->tag = **p;
ansond 0:137634ff4186 323 (*p)++;
ansond 0:137634ff4186 324
ansond 0:137634ff4186 325 if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
ansond 0:137634ff4186 326 return( ret );
ansond 0:137634ff4186 327
ansond 0:137634ff4186 328 params->p = *p;
ansond 0:137634ff4186 329 *p += params->len;
ansond 0:137634ff4186 330
ansond 0:137634ff4186 331 if( *p != end )
ansond 0:137634ff4186 332 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
ansond 0:137634ff4186 333
ansond 0:137634ff4186 334 return( 0 );
ansond 0:137634ff4186 335 }
ansond 0:137634ff4186 336
ansond 0:137634ff4186 337 int asn1_get_alg_null( unsigned char **p,
ansond 0:137634ff4186 338 const unsigned char *end,
ansond 0:137634ff4186 339 asn1_buf *alg )
ansond 0:137634ff4186 340 {
ansond 0:137634ff4186 341 int ret;
ansond 0:137634ff4186 342 asn1_buf params;
ansond 0:137634ff4186 343
ansond 0:137634ff4186 344 memset( &params, 0, sizeof(asn1_buf) );
ansond 0:137634ff4186 345
ansond 0:137634ff4186 346 if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
ansond 0:137634ff4186 347 return( ret );
ansond 0:137634ff4186 348
ansond 0:137634ff4186 349 if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
ansond 0:137634ff4186 350 return( POLARSSL_ERR_ASN1_INVALID_DATA );
ansond 0:137634ff4186 351
ansond 0:137634ff4186 352 return( 0 );
ansond 0:137634ff4186 353 }
ansond 0:137634ff4186 354
ansond 0:137634ff4186 355 void asn1_free_named_data( asn1_named_data *cur )
ansond 0:137634ff4186 356 {
ansond 0:137634ff4186 357 if( cur == NULL )
ansond 0:137634ff4186 358 return;
ansond 0:137634ff4186 359
ansond 0:137634ff4186 360 polarssl_free( cur->oid.p );
ansond 0:137634ff4186 361 polarssl_free( cur->val.p );
ansond 0:137634ff4186 362
ansond 0:137634ff4186 363 polarssl_zeroize( cur, sizeof( asn1_named_data ) );
ansond 0:137634ff4186 364 }
ansond 0:137634ff4186 365
ansond 0:137634ff4186 366 void asn1_free_named_data_list( asn1_named_data **head )
ansond 0:137634ff4186 367 {
ansond 0:137634ff4186 368 asn1_named_data *cur;
ansond 0:137634ff4186 369
ansond 0:137634ff4186 370 while( ( cur = *head ) != NULL )
ansond 0:137634ff4186 371 {
ansond 0:137634ff4186 372 *head = cur->next;
ansond 0:137634ff4186 373 asn1_free_named_data( cur );
ansond 0:137634ff4186 374 polarssl_free( cur );
ansond 0:137634ff4186 375 }
ansond 0:137634ff4186 376 }
ansond 0:137634ff4186 377
ansond 0:137634ff4186 378 asn1_named_data *asn1_find_named_data( asn1_named_data *list,
ansond 0:137634ff4186 379 const char *oid, size_t len )
ansond 0:137634ff4186 380 {
ansond 0:137634ff4186 381 while( list != NULL )
ansond 0:137634ff4186 382 {
ansond 0:137634ff4186 383 if( list->oid.len == len &&
ansond 0:137634ff4186 384 memcmp( list->oid.p, oid, len ) == 0 )
ansond 0:137634ff4186 385 {
ansond 0:137634ff4186 386 break;
ansond 0:137634ff4186 387 }
ansond 0:137634ff4186 388
ansond 0:137634ff4186 389 list = list->next;
ansond 0:137634ff4186 390 }
ansond 0:137634ff4186 391
ansond 0:137634ff4186 392 return( list );
ansond 0:137634ff4186 393 }
ansond 0:137634ff4186 394
ansond 0:137634ff4186 395 #endif /* POLARSSL_ASN1_PARSE_C */
ansond 0:137634ff4186 396