blob: a3a2b56a2bcfb8bda6eb45895ffc77af78cc0f13 [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 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * 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
281 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 */