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