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