blob: 763f32ad5e039629969615edd930518cfb2a0259 [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
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 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200273 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkerefc30292011-11-10 14:43:23 +0000274 sizeof( asn1_sequence ) );
275
276 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000277 return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
Paul Bakkerefc30292011-11-10 14:43:23 +0000278
Manuel Pégourié-Gonnard0369a522014-11-11 22:17:26 +0100279 memset( cur->next, 0, sizeof( asn1_sequence ) );
280
Paul Bakkerefc30292011-11-10 14:43:23 +0000281 cur = cur->next;
282 }
283 }
284
285 /* Set final sequence entry's next pointer to NULL */
286 cur->next = NULL;
287
288 if( *p != end )
289 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
290
291 return( 0 );
292}
293
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200294int asn1_get_alg( unsigned char **p,
295 const unsigned char *end,
296 asn1_buf *alg, asn1_buf *params )
297{
298 int ret;
299 size_t len;
300
301 if( ( ret = asn1_get_tag( p, end, &len,
302 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
303 return( ret );
304
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200305 if( ( end - *p ) < 1 )
306 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
307
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200308 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200309 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200310
311 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
312 return( ret );
313
314 alg->p = *p;
315 *p += alg->len;
316
317 if( *p == end )
318 {
Manuel Pégourié-Gonnard8ef70882014-08-21 18:15:09 +0200319 polarssl_zeroize( params, sizeof(asn1_buf) );
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200320 return( 0 );
321 }
322
323 params->tag = **p;
324 (*p)++;
325
326 if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
327 return( ret );
328
329 params->p = *p;
330 *p += params->len;
331
332 if( *p != end )
333 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
334
335 return( 0 );
336}
337
338int asn1_get_alg_null( unsigned char **p,
339 const unsigned char *end,
340 asn1_buf *alg )
341{
342 int ret;
343 asn1_buf params;
344
345 memset( &params, 0, sizeof(asn1_buf) );
346
347 if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
348 return( ret );
349
350 if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
351 return( POLARSSL_ERR_ASN1_INVALID_DATA );
352
353 return( 0 );
354}
355
Paul Bakkere5eae762013-08-26 12:05:14 +0200356void asn1_free_named_data( asn1_named_data *cur )
357{
358 if( cur == NULL )
359 return;
360
361 polarssl_free( cur->oid.p );
362 polarssl_free( cur->val.p );
363
Manuel Pégourié-Gonnard8ef70882014-08-21 18:15:09 +0200364 polarssl_zeroize( cur, sizeof( asn1_named_data ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200365}
366
Paul Bakkerc547cc92013-09-09 12:01:23 +0200367void asn1_free_named_data_list( asn1_named_data **head )
368{
369 asn1_named_data *cur;
370
371 while( ( cur = *head ) != NULL )
372 {
373 *head = cur->next;
374 asn1_free_named_data( cur );
375 polarssl_free( cur );
376 }
377}
378
Paul Bakkere5eae762013-08-26 12:05:14 +0200379asn1_named_data *asn1_find_named_data( asn1_named_data *list,
380 const char *oid, size_t len )
381{
382 while( list != NULL )
383 {
384 if( list->oid.len == len &&
385 memcmp( list->oid.p, oid, len ) == 0 )
386 {
387 break;
388 }
389
390 list = list->next;
391 }
392
393 return( list );
394}
395
Paul Bakker9af723c2014-05-01 13:03:14 +0200396#endif /* POLARSSL_ASN1_PARSE_C */