blob: 202a6ce2749f971f9161e93fd04da5ad89dd23c6 [file] [log] [blame]
Paul Bakkerefc30292011-11-10 14:43:23 +00001/*
2 * Generic ASN.1 parsing
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerefc30292011-11-10 14:43:23 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerefc30292011-11-10 14:43:23 +00007 *
Paul Bakkerefc30292011-11-10 14:43:23 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020023#if !defined(POLARSSL_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020025#else
26#include POLARSSL_CONFIG_FILE
27#endif
Paul Bakkerefc30292011-11-10 14:43:23 +000028
29#if defined(POLARSSL_ASN1_PARSE_C)
30
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/asn1.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000032
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <string.h>
34
Paul Bakkerefc30292011-11-10 14:43:23 +000035#if defined(POLARSSL_BIGNUM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/bignum.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000037#endif
38
Paul Bakker7dc4c442014-02-01 22:50:26 +010039#if defined(POLARSSL_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020041#else
Rich Evans00ab4702015-02-06 13:43:58 +000042#include <stdlib.h>
Paul Bakker6e339b52013-07-03 13:37:05 +020043#define polarssl_malloc malloc
44#define polarssl_free free
45#endif
46
Manuel Pégourié-Gonnard8ef70882014-08-21 18:15:09 +020047/* Implementation that should never be optimized out by the compiler */
48static void polarssl_zeroize( void *v, size_t n ) {
49 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
50}
51
Paul Bakkerefc30292011-11-10 14:43:23 +000052/*
53 * ASN.1 DER decoding routines
54 */
55int asn1_get_len( unsigned char **p,
56 const unsigned char *end,
57 size_t *len )
58{
59 if( ( end - *p ) < 1 )
60 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
61
62 if( ( **p & 0x80 ) == 0 )
63 *len = *(*p)++;
64 else
65 {
66 switch( **p & 0x7F )
67 {
68 case 1:
69 if( ( end - *p ) < 2 )
70 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
71
72 *len = (*p)[1];
73 (*p) += 2;
74 break;
75
76 case 2:
77 if( ( end - *p ) < 3 )
78 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
79
Manuel Pégourié-Gonnard6fdc4ca2015-02-13 17:15:18 +000080 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
Paul Bakkerefc30292011-11-10 14:43:23 +000081 (*p) += 3;
82 break;
83
84 case 3:
85 if( ( end - *p ) < 4 )
86 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
87
Manuel Pégourié-Gonnard6fdc4ca2015-02-13 17:15:18 +000088 *len = ( (size_t)(*p)[1] << 16 ) |
89 ( (size_t)(*p)[2] << 8 ) | (*p)[3];
Paul Bakkerefc30292011-11-10 14:43:23 +000090 (*p) += 4;
91 break;
92
93 case 4:
94 if( ( end - *p ) < 5 )
95 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
96
Manuel Pégourié-Gonnard6fdc4ca2015-02-13 17:15:18 +000097 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
98 ( (size_t)(*p)[3] << 8 ) | (*p)[4];
Paul Bakkerefc30292011-11-10 14:43:23 +000099 (*p) += 5;
100 break;
101
102 default:
103 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
104 }
105 }
106
107 if( *len > (size_t) ( end - *p ) )
108 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
109
110 return( 0 );
111}
112
113int asn1_get_tag( unsigned char **p,
114 const unsigned char *end,
115 size_t *len, int tag )
116{
117 if( ( end - *p ) < 1 )
118 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
119
120 if( **p != tag )
121 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
122
123 (*p)++;
124
125 return( asn1_get_len( p, end, len ) );
126}
127
128int asn1_get_bool( unsigned char **p,
129 const unsigned char *end,
130 int *val )
131{
132 int ret;
133 size_t len;
134
135 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
136 return( ret );
137
138 if( len != 1 )
139 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
140
141 *val = ( **p != 0 ) ? 1 : 0;
142 (*p)++;
143
144 return( 0 );
145}
146
147int asn1_get_int( unsigned char **p,
148 const unsigned char *end,
149 int *val )
150{
151 int ret;
152 size_t len;
153
154 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
155 return( ret );
156
157 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
158 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
159
160 *val = 0;
161
162 while( len-- > 0 )
163 {
164 *val = ( *val << 8 ) | **p;
165 (*p)++;
166 }
167
168 return( 0 );
169}
170
171#if defined(POLARSSL_BIGNUM_C)
172int asn1_get_mpi( unsigned char **p,
173 const unsigned char *end,
174 mpi *X )
175{
176 int ret;
177 size_t len;
178
179 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
180 return( ret );
181
182 ret = mpi_read_binary( X, *p, len );
183
184 *p += len;
185
186 return( ret );
187}
188#endif /* POLARSSL_BIGNUM_C */
189
190int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
191 asn1_bitstring *bs)
192{
193 int ret;
194
195 /* Certificate type is a single byte bitstring */
196 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
197 return( ret );
198
199 /* Check length, subtract one for actual bit string length */
Paul Bakker66d5d072014-06-17 16:39:18 +0200200 if( bs->len < 1 )
Paul Bakkerefc30292011-11-10 14:43:23 +0000201 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
202 bs->len -= 1;
203
204 /* Get number of unused bits, ensure unused bits <= 7 */
205 bs->unused_bits = **p;
206 if( bs->unused_bits > 7 )
207 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
208 (*p)++;
209
210 /* Get actual bitstring */
211 bs->p = *p;
212 *p += bs->len;
213
214 if( *p != end )
215 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
216
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200217 return( 0 );
Paul Bakkerefc30292011-11-10 14:43:23 +0000218}
219
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200220/*
221 * Get a bit string without unused bits
222 */
223int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
224 size_t *len )
225{
226 int ret;
227
228 if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
229 return( ret );
230
Manuel Pégourié-Gonnard06dab802013-08-15 12:24:43 +0200231 if( (*len)-- < 2 || *(*p)++ != 0 )
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200232 return( POLARSSL_ERR_ASN1_INVALID_DATA );
233
234 return( 0 );
235}
236
237
Paul Bakkerefc30292011-11-10 14:43:23 +0000238
239/*
240 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
241 */
242int asn1_get_sequence_of( unsigned char **p,
243 const unsigned char *end,
244 asn1_sequence *cur,
245 int tag)
246{
247 int ret;
248 size_t len;
249 asn1_buf *buf;
250
251 /* Get main sequence tag */
252 if( ( ret = asn1_get_tag( p, end, &len,
253 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
254 return( ret );
255
256 if( *p + len != end )
257 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
258
259 while( *p < end )
260 {
261 buf = &(cur->buf);
262 buf->tag = **p;
263
264 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
265 return( ret );
266
267 buf->p = *p;
268 *p += buf->len;
269
270 /* Allocate and assign next pointer */
Paul Bakker66d5d072014-06-17 16:39:18 +0200271 if( *p < end )
Paul Bakkerefc30292011-11-10 14:43:23 +0000272 {
Mansour Moufid99b92592015-02-15 17:46:32 -0500273 cur->next = polarssl_malloc( sizeof( asn1_sequence ) );
Paul Bakkerefc30292011-11-10 14:43:23 +0000274
275 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000276 return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
Paul Bakkerefc30292011-11-10 14:43:23 +0000277
Manuel Pégourié-Gonnard0369a522014-11-11 22:17:26 +0100278 memset( cur->next, 0, sizeof( asn1_sequence ) );
279
Paul Bakkerefc30292011-11-10 14:43:23 +0000280 cur = cur->next;
281 }
282 }
283
284 /* Set final sequence entry's next pointer to NULL */
285 cur->next = NULL;
286
287 if( *p != end )
288 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
289
290 return( 0 );
291}
292
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200293int asn1_get_alg( unsigned char **p,
294 const unsigned char *end,
295 asn1_buf *alg, asn1_buf *params )
296{
297 int ret;
298 size_t len;
299
300 if( ( ret = asn1_get_tag( p, end, &len,
301 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
302 return( ret );
303
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200304 if( ( end - *p ) < 1 )
305 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
306
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200307 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200308 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200309
310 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
311 return( ret );
312
313 alg->p = *p;
314 *p += alg->len;
315
316 if( *p == end )
317 {
Manuel Pégourié-Gonnard8ef70882014-08-21 18:15:09 +0200318 polarssl_zeroize( params, sizeof(asn1_buf) );
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200319 return( 0 );
320 }
321
322 params->tag = **p;
323 (*p)++;
324
325 if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
326 return( ret );
327
328 params->p = *p;
329 *p += params->len;
330
331 if( *p != end )
332 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
333
334 return( 0 );
335}
336
337int asn1_get_alg_null( unsigned char **p,
338 const unsigned char *end,
339 asn1_buf *alg )
340{
341 int ret;
342 asn1_buf params;
343
344 memset( &params, 0, sizeof(asn1_buf) );
345
346 if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
347 return( ret );
348
349 if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
350 return( POLARSSL_ERR_ASN1_INVALID_DATA );
351
352 return( 0 );
353}
354
Paul Bakkere5eae762013-08-26 12:05:14 +0200355void asn1_free_named_data( asn1_named_data *cur )
356{
357 if( cur == NULL )
358 return;
359
360 polarssl_free( cur->oid.p );
361 polarssl_free( cur->val.p );
362
Manuel Pégourié-Gonnard8ef70882014-08-21 18:15:09 +0200363 polarssl_zeroize( cur, sizeof( asn1_named_data ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200364}
365
Paul Bakkerc547cc92013-09-09 12:01:23 +0200366void asn1_free_named_data_list( asn1_named_data **head )
367{
368 asn1_named_data *cur;
369
370 while( ( cur = *head ) != NULL )
371 {
372 *head = cur->next;
373 asn1_free_named_data( cur );
374 polarssl_free( cur );
375 }
376}
377
Paul Bakkere5eae762013-08-26 12:05:14 +0200378asn1_named_data *asn1_find_named_data( asn1_named_data *list,
379 const char *oid, size_t len )
380{
381 while( list != NULL )
382 {
383 if( list->oid.len == len &&
384 memcmp( list->oid.p, oid, len ) == 0 )
385 {
386 break;
387 }
388
389 list = list->next;
390 }
391
392 return( list );
393}
394
Paul Bakker9af723c2014-05-01 13:03:14 +0200395#endif /* POLARSSL_ASN1_PARSE_C */