blob: 6782140457adf417b12711b7821316b799e956bc [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é-Gonnard860b5162015-01-28 17:12:07 +00006 * This file is part of mbed TLS (https://polarssl.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)
Paul Bakkerefc30292011-11-10 14:43:23 +000024#include "polarssl/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
31#include "polarssl/asn1.h"
32
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)
36#include "polarssl/bignum.h"
37#endif
38
Paul Bakker7dc4c442014-02-01 22:50:26 +010039#if defined(POLARSSL_PLATFORM_C)
40#include "polarssl/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
80 *len = ( (*p)[1] << 8 ) | (*p)[2];
81 (*p) += 3;
82 break;
83
84 case 3:
85 if( ( end - *p ) < 4 )
86 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
87
88 *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
89 (*p) += 4;
90 break;
91
92 case 4:
93 if( ( end - *p ) < 5 )
94 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
95
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +020096 *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) |
97 (*p)[4];
Paul Bakkerefc30292011-11-10 14:43:23 +000098 (*p) += 5;
99 break;
100
101 default:
102 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
103 }
104 }
105
106 if( *len > (size_t) ( end - *p ) )
107 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
108
109 return( 0 );
110}
111
112int asn1_get_tag( unsigned char **p,
113 const unsigned char *end,
114 size_t *len, int tag )
115{
116 if( ( end - *p ) < 1 )
117 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
118
119 if( **p != tag )
120 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
121
122 (*p)++;
123
124 return( asn1_get_len( p, end, len ) );
125}
126
127int asn1_get_bool( unsigned char **p,
128 const unsigned char *end,
129 int *val )
130{
131 int ret;
132 size_t len;
133
134 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
135 return( ret );
136
137 if( len != 1 )
138 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
139
140 *val = ( **p != 0 ) ? 1 : 0;
141 (*p)++;
142
143 return( 0 );
144}
145
146int asn1_get_int( unsigned char **p,
147 const unsigned char *end,
148 int *val )
149{
150 int ret;
151 size_t len;
152
153 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
154 return( ret );
155
156 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
157 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
158
159 *val = 0;
160
161 while( len-- > 0 )
162 {
163 *val = ( *val << 8 ) | **p;
164 (*p)++;
165 }
166
167 return( 0 );
168}
169
170#if defined(POLARSSL_BIGNUM_C)
171int asn1_get_mpi( unsigned char **p,
172 const unsigned char *end,
173 mpi *X )
174{
175 int ret;
176 size_t len;
177
178 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
179 return( ret );
180
181 ret = mpi_read_binary( X, *p, len );
182
183 *p += len;
184
185 return( ret );
186}
187#endif /* POLARSSL_BIGNUM_C */
188
189int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
190 asn1_bitstring *bs)
191{
192 int ret;
193
194 /* Certificate type is a single byte bitstring */
195 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
196 return( ret );
197
198 /* Check length, subtract one for actual bit string length */
Paul Bakker66d5d072014-06-17 16:39:18 +0200199 if( bs->len < 1 )
Paul Bakkerefc30292011-11-10 14:43:23 +0000200 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
201 bs->len -= 1;
202
203 /* Get number of unused bits, ensure unused bits <= 7 */
204 bs->unused_bits = **p;
205 if( bs->unused_bits > 7 )
206 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
207 (*p)++;
208
209 /* Get actual bitstring */
210 bs->p = *p;
211 *p += bs->len;
212
213 if( *p != end )
214 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
215
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200216 return( 0 );
Paul Bakkerefc30292011-11-10 14:43:23 +0000217}
218
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200219/*
220 * Get a bit string without unused bits
221 */
222int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
223 size_t *len )
224{
225 int ret;
226
227 if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
228 return( ret );
229
Manuel Pégourié-Gonnard06dab802013-08-15 12:24:43 +0200230 if( (*len)-- < 2 || *(*p)++ != 0 )
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200231 return( POLARSSL_ERR_ASN1_INVALID_DATA );
232
233 return( 0 );
234}
235
236
Paul Bakkerefc30292011-11-10 14:43:23 +0000237
238/*
239 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
240 */
241int asn1_get_sequence_of( unsigned char **p,
242 const unsigned char *end,
243 asn1_sequence *cur,
244 int tag)
245{
246 int ret;
247 size_t len;
248 asn1_buf *buf;
249
250 /* Get main sequence tag */
251 if( ( ret = asn1_get_tag( p, end, &len,
252 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
253 return( ret );
254
255 if( *p + len != end )
256 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
257
258 while( *p < end )
259 {
260 buf = &(cur->buf);
261 buf->tag = **p;
262
263 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
264 return( ret );
265
266 buf->p = *p;
267 *p += buf->len;
268
269 /* Allocate and assign next pointer */
Paul Bakker66d5d072014-06-17 16:39:18 +0200270 if( *p < end )
Paul Bakkerefc30292011-11-10 14:43:23 +0000271 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200272 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkerefc30292011-11-10 14:43:23 +0000273 sizeof( asn1_sequence ) );
274
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 */