blob: 79b290124d42e91033259b41872fae4875edc510 [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
50/*
51 * ASN.1 DER decoding routines
52 */
53int asn1_get_len( unsigned char **p,
54 const unsigned char *end,
55 size_t *len )
56{
57 if( ( end - *p ) < 1 )
58 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
59
60 if( ( **p & 0x80 ) == 0 )
61 *len = *(*p)++;
62 else
63 {
64 switch( **p & 0x7F )
65 {
66 case 1:
67 if( ( end - *p ) < 2 )
68 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
69
70 *len = (*p)[1];
71 (*p) += 2;
72 break;
73
74 case 2:
75 if( ( end - *p ) < 3 )
76 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
77
78 *len = ( (*p)[1] << 8 ) | (*p)[2];
79 (*p) += 3;
80 break;
81
82 case 3:
83 if( ( end - *p ) < 4 )
84 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
85
86 *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
87 (*p) += 4;
88 break;
89
90 case 4:
91 if( ( end - *p ) < 5 )
92 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
93
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +020094 *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) |
95 (*p)[4];
Paul Bakkerefc30292011-11-10 14:43:23 +000096 (*p) += 5;
97 break;
98
99 default:
100 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
101 }
102 }
103
104 if( *len > (size_t) ( end - *p ) )
105 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
106
107 return( 0 );
108}
109
110int asn1_get_tag( unsigned char **p,
111 const unsigned char *end,
112 size_t *len, int tag )
113{
114 if( ( end - *p ) < 1 )
115 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
116
117 if( **p != tag )
118 return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
119
120 (*p)++;
121
122 return( asn1_get_len( p, end, len ) );
123}
124
125int asn1_get_bool( unsigned char **p,
126 const unsigned char *end,
127 int *val )
128{
129 int ret;
130 size_t len;
131
132 if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
133 return( ret );
134
135 if( len != 1 )
136 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
137
138 *val = ( **p != 0 ) ? 1 : 0;
139 (*p)++;
140
141 return( 0 );
142}
143
144int asn1_get_int( unsigned char **p,
145 const unsigned char *end,
146 int *val )
147{
148 int ret;
149 size_t len;
150
151 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
152 return( ret );
153
154 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
155 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
156
157 *val = 0;
158
159 while( len-- > 0 )
160 {
161 *val = ( *val << 8 ) | **p;
162 (*p)++;
163 }
164
165 return( 0 );
166}
167
168#if defined(POLARSSL_BIGNUM_C)
169int asn1_get_mpi( unsigned char **p,
170 const unsigned char *end,
171 mpi *X )
172{
173 int ret;
174 size_t len;
175
176 if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
177 return( ret );
178
179 ret = mpi_read_binary( X, *p, len );
180
181 *p += len;
182
183 return( ret );
184}
185#endif /* POLARSSL_BIGNUM_C */
186
187int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
188 asn1_bitstring *bs)
189{
190 int ret;
191
192 /* Certificate type is a single byte bitstring */
193 if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
194 return( ret );
195
196 /* Check length, subtract one for actual bit string length */
197 if ( bs->len < 1 )
198 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
199 bs->len -= 1;
200
201 /* Get number of unused bits, ensure unused bits <= 7 */
202 bs->unused_bits = **p;
203 if( bs->unused_bits > 7 )
204 return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
205 (*p)++;
206
207 /* Get actual bitstring */
208 bs->p = *p;
209 *p += bs->len;
210
211 if( *p != end )
212 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
213
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200214 return( 0 );
Paul Bakkerefc30292011-11-10 14:43:23 +0000215}
216
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200217/*
218 * Get a bit string without unused bits
219 */
220int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
221 size_t *len )
222{
223 int ret;
224
225 if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
226 return( ret );
227
Manuel Pégourié-Gonnard06dab802013-08-15 12:24:43 +0200228 if( (*len)-- < 2 || *(*p)++ != 0 )
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200229 return( POLARSSL_ERR_ASN1_INVALID_DATA );
230
231 return( 0 );
232}
233
234
Paul Bakkerefc30292011-11-10 14:43:23 +0000235
236/*
237 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
238 */
239int asn1_get_sequence_of( unsigned char **p,
240 const unsigned char *end,
241 asn1_sequence *cur,
242 int tag)
243{
244 int ret;
245 size_t len;
246 asn1_buf *buf;
247
248 /* Get main sequence tag */
249 if( ( ret = asn1_get_tag( p, end, &len,
250 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
251 return( ret );
252
253 if( *p + len != end )
254 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
255
256 while( *p < end )
257 {
258 buf = &(cur->buf);
259 buf->tag = **p;
260
261 if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
262 return( ret );
263
264 buf->p = *p;
265 *p += buf->len;
266
267 /* Allocate and assign next pointer */
268 if (*p < end)
269 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200270 cur->next = (asn1_sequence *) polarssl_malloc(
Paul Bakkerefc30292011-11-10 14:43:23 +0000271 sizeof( asn1_sequence ) );
272
273 if( cur->next == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000274 return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
Paul Bakkerefc30292011-11-10 14:43:23 +0000275
276 cur = cur->next;
277 }
278 }
279
280 /* Set final sequence entry's next pointer to NULL */
281 cur->next = NULL;
282
283 if( *p != end )
284 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
285
286 return( 0 );
287}
288
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200289int asn1_get_alg( unsigned char **p,
290 const unsigned char *end,
291 asn1_buf *alg, asn1_buf *params )
292{
293 int ret;
294 size_t len;
295
296 if( ( ret = asn1_get_tag( p, end, &len,
297 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
298 return( ret );
299
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200300 if( ( end - *p ) < 1 )
301 return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
302
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200303 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200304 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200305
306 if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
307 return( ret );
308
309 alg->p = *p;
310 *p += alg->len;
311
312 if( *p == end )
313 {
314 memset( params, 0, sizeof(asn1_buf) );
315 return( 0 );
316 }
317
318 params->tag = **p;
319 (*p)++;
320
321 if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
322 return( ret );
323
324 params->p = *p;
325 *p += params->len;
326
327 if( *p != end )
328 return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
329
330 return( 0 );
331}
332
333int asn1_get_alg_null( unsigned char **p,
334 const unsigned char *end,
335 asn1_buf *alg )
336{
337 int ret;
338 asn1_buf params;
339
340 memset( &params, 0, sizeof(asn1_buf) );
341
342 if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
343 return( ret );
344
345 if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
346 return( POLARSSL_ERR_ASN1_INVALID_DATA );
347
348 return( 0 );
349}
350
Paul Bakkere5eae762013-08-26 12:05:14 +0200351void asn1_free_named_data( asn1_named_data *cur )
352{
353 if( cur == NULL )
354 return;
355
356 polarssl_free( cur->oid.p );
357 polarssl_free( cur->val.p );
358
359 memset( cur, 0, sizeof( asn1_named_data ) );
360}
361
Paul Bakkerc547cc92013-09-09 12:01:23 +0200362void asn1_free_named_data_list( asn1_named_data **head )
363{
364 asn1_named_data *cur;
365
366 while( ( cur = *head ) != NULL )
367 {
368 *head = cur->next;
369 asn1_free_named_data( cur );
370 polarssl_free( cur );
371 }
372}
373
Paul Bakkere5eae762013-08-26 12:05:14 +0200374asn1_named_data *asn1_find_named_data( asn1_named_data *list,
375 const char *oid, size_t len )
376{
377 while( list != NULL )
378 {
379 if( list->oid.len == len &&
380 memcmp( list->oid.p, oid, len ) == 0 )
381 {
382 break;
383 }
384
385 list = list->next;
386 }
387
388 return( list );
389}
390
Paul Bakker9af723c2014-05-01 13:03:14 +0200391#endif /* POLARSSL_ASN1_PARSE_C */