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