]> git.zerfleddert.de Git - proxmark3-svn/blob - common/mbedtls/asn1parse.c
move from polarssl to mbedtls (#708)
[proxmark3-svn] / common / mbedtls / asn1parse.c
1 /*
2 * Generic ASN.1 parsing
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
26 #else
27 #include MBEDTLS_CONFIG_FILE
28 #endif
29
30 #if defined(MBEDTLS_ASN1_PARSE_C)
31
32 #include "mbedtls/asn1.h"
33 #include "mbedtls/platform_util.h"
34
35 #include <string.h>
36
37 #if defined(MBEDTLS_BIGNUM_C)
38 #include "mbedtls/bignum.h"
39 #endif
40
41 #if defined(MBEDTLS_PLATFORM_C)
42 #include "mbedtls/platform.h"
43 #else
44 #include <stdlib.h>
45 #define mbedtls_calloc calloc
46 #define mbedtls_free free
47 #endif
48
49 /*
50 * ASN.1 DER decoding routines
51 */
52 int mbedtls_asn1_get_len( unsigned char **p,
53 const unsigned char *end,
54 size_t *len )
55 {
56 if( ( end - *p ) < 1 )
57 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
58
59 if( ( **p & 0x80 ) == 0 )
60 *len = *(*p)++;
61 else
62 {
63 switch( **p & 0x7F )
64 {
65 case 1:
66 if( ( end - *p ) < 2 )
67 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
68
69 *len = (*p)[1];
70 (*p) += 2;
71 break;
72
73 case 2:
74 if( ( end - *p ) < 3 )
75 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
76
77 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
78 (*p) += 3;
79 break;
80
81 case 3:
82 if( ( end - *p ) < 4 )
83 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
84
85 *len = ( (size_t)(*p)[1] << 16 ) |
86 ( (size_t)(*p)[2] << 8 ) | (*p)[3];
87 (*p) += 4;
88 break;
89
90 case 4:
91 if( ( end - *p ) < 5 )
92 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
93
94 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
95 ( (size_t)(*p)[3] << 8 ) | (*p)[4];
96 (*p) += 5;
97 break;
98
99 default:
100 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
101 }
102 }
103
104 if( *len > (size_t) ( end - *p ) )
105 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
106
107 return( 0 );
108 }
109
110 int mbedtls_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( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
116
117 if( **p != tag )
118 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
119
120 (*p)++;
121
122 return( mbedtls_asn1_get_len( p, end, len ) );
123 }
124
125 int mbedtls_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 = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
133 return( ret );
134
135 if( len != 1 )
136 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
137
138 *val = ( **p != 0 ) ? 1 : 0;
139 (*p)++;
140
141 return( 0 );
142 }
143
144 int mbedtls_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 = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
152 return( ret );
153
154 if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 )
155 return( MBEDTLS_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(MBEDTLS_BIGNUM_C)
169 int mbedtls_asn1_get_mpi( unsigned char **p,
170 const unsigned char *end,
171 mbedtls_mpi *X )
172 {
173 int ret;
174 size_t len;
175
176 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
177 return( ret );
178
179 ret = mbedtls_mpi_read_binary( X, *p, len );
180
181 *p += len;
182
183 return( ret );
184 }
185 #endif /* MBEDTLS_BIGNUM_C */
186
187 int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
188 mbedtls_asn1_bitstring *bs)
189 {
190 int ret;
191
192 /* Certificate type is a single byte bitstring */
193 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_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( MBEDTLS_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( MBEDTLS_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( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
213
214 return( 0 );
215 }
216
217 /*
218 * Get a bit string without unused bits
219 */
220 int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
221 size_t *len )
222 {
223 int ret;
224
225 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
226 return( ret );
227
228 if( (*len)-- < 2 || *(*p)++ != 0 )
229 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
230
231 return( 0 );
232 }
233
234
235
236 /*
237 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
238 */
239 int mbedtls_asn1_get_sequence_of( unsigned char **p,
240 const unsigned char *end,
241 mbedtls_asn1_sequence *cur,
242 int tag)
243 {
244 int ret;
245 size_t len;
246 mbedtls_asn1_buf *buf;
247
248 /* Get main sequence tag */
249 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
250 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
251 return( ret );
252
253 if( *p + len != end )
254 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
255
256 while( *p < end )
257 {
258 buf = &(cur->buf);
259 buf->tag = **p;
260
261 if( ( ret = mbedtls_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 {
270 cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1,
271 sizeof( mbedtls_asn1_sequence ) );
272
273 if( cur->next == NULL )
274 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
275
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( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
285
286 return( 0 );
287 }
288
289 int mbedtls_asn1_get_alg( unsigned char **p,
290 const unsigned char *end,
291 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
292 {
293 int ret;
294 size_t len;
295
296 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
297 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
298 return( ret );
299
300 if( ( end - *p ) < 1 )
301 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
302
303 alg->tag = **p;
304 end = *p + len;
305
306 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
307 return( ret );
308
309 alg->p = *p;
310 *p += alg->len;
311
312 if( *p == end )
313 {
314 mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
315 return( 0 );
316 }
317
318 params->tag = **p;
319 (*p)++;
320
321 if( ( ret = mbedtls_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( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
329
330 return( 0 );
331 }
332
333 int mbedtls_asn1_get_alg_null( unsigned char **p,
334 const unsigned char *end,
335 mbedtls_asn1_buf *alg )
336 {
337 int ret;
338 mbedtls_asn1_buf params;
339
340 memset( &params, 0, sizeof(mbedtls_asn1_buf) );
341
342 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, &params ) ) != 0 )
343 return( ret );
344
345 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
346 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
347
348 return( 0 );
349 }
350
351 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
352 {
353 if( cur == NULL )
354 return;
355
356 mbedtls_free( cur->oid.p );
357 mbedtls_free( cur->val.p );
358
359 mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
360 }
361
362 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
363 {
364 mbedtls_asn1_named_data *cur;
365
366 while( ( cur = *head ) != NULL )
367 {
368 *head = cur->next;
369 mbedtls_asn1_free_named_data( cur );
370 mbedtls_free( cur );
371 }
372 }
373
374 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_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
391 #endif /* MBEDTLS_ASN1_PARSE_C */
Impressum, Datenschutz