1 /*
2 * Generic ASN.1 parsing
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #include "common.h"
21
22 #if defined(MBEDTLS_ASN1_PARSE_C)
23
24 #include "mbedtls/asn1.h"
25 #include "mbedtls/platform_util.h"
26 #include "mbedtls/error.h"
27
28 #include <string.h>
29 #if defined(VENDOR_REDEFINE_TEE_API_C)
30 #include "mbedtls/hw_redefine_tee_api.h"
31 #endif
32 #if defined(MBEDTLS_BIGNUM_C)
33 #include "mbedtls/bignum.h"
34 #endif
35
36 #if defined(MBEDTLS_PLATFORM_C)
37 #include "mbedtls/platform.h"
38 #else
39 #include <stdlib.h>
40 #define mbedtls_calloc calloc
41 #define mbedtls_free free
42 #endif
43
44 /*
45 * ASN.1 DER decoding routines
46 */
mbedtls_asn1_get_len(unsigned char ** p,const unsigned char * end,size_t * len)47 int mbedtls_asn1_get_len( unsigned char **p,
48 const unsigned char *end,
49 size_t *len )
50 {
51 if( ( end - *p ) < 1 )
52 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
53
54 if( ( **p & 0x80 ) == 0 )
55 *len = *(*p)++;
56 else
57 {
58 switch( **p & 0x7F )
59 {
60 case 1:
61 if( ( end - *p ) < 2 )
62 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
63
64 *len = (*p)[1];
65 (*p) += 2;
66 break;
67
68 case 2:
69 if( ( end - *p ) < 3 )
70 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
71
72 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
73 (*p) += 3;
74 break;
75
76 case 3:
77 if( ( end - *p ) < 4 )
78 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
79
80 *len = ( (size_t)(*p)[1] << 16 ) |
81 ( (size_t)(*p)[2] << 8 ) | (*p)[3];
82 (*p) += 4;
83 break;
84
85 case 4:
86 if( ( end - *p ) < 5 )
87 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
88
89 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
90 ( (size_t)(*p)[3] << 8 ) | (*p)[4];
91 (*p) += 5;
92 break;
93
94 default:
95 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
96 }
97 }
98
99 if( *len > (size_t) ( end - *p ) )
100 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
101
102 return( 0 );
103 }
104
mbedtls_asn1_get_tag(unsigned char ** p,const unsigned char * end,size_t * len,int tag)105 int mbedtls_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( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
111
112 if( **p != tag )
113 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
114
115 (*p)++;
116
117 return( mbedtls_asn1_get_len( p, end, len ) );
118 }
119
mbedtls_asn1_get_bool(unsigned char ** p,const unsigned char * end,int * val)120 int mbedtls_asn1_get_bool( unsigned char **p,
121 const unsigned char *end,
122 int *val )
123 {
124 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
125 size_t len;
126
127 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
128 return( ret );
129
130 if( len != 1 )
131 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
132
133 *val = ( **p != 0 ) ? 1 : 0;
134 (*p)++;
135
136 return( 0 );
137 }
138
asn1_get_tagged_int(unsigned char ** p,const unsigned char * end,int tag,int * val)139 static int asn1_get_tagged_int( unsigned char **p,
140 const unsigned char *end,
141 int tag, int *val )
142 {
143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
144 size_t len;
145
146 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, tag ) ) != 0 )
147 return( ret );
148
149 /*
150 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
151 * or 0A0100 for ENUMERATED tags
152 */
153 if( len == 0 )
154 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
155 /* This is a cryptography library. Reject negative integers. */
156 if( ( **p & 0x80 ) != 0 )
157 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
158
159 /* Skip leading zeros. */
160 while( len > 0 && **p == 0 )
161 {
162 ++( *p );
163 --len;
164 }
165
166 /* Reject integers that don't fit in an int. This code assumes that
167 * the int type has no padding bit. */
168 if( len > sizeof( int ) )
169 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
170 if( len == sizeof( int ) && ( **p & 0x80 ) != 0 )
171 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
172
173 *val = 0;
174 while( len-- > 0 )
175 {
176 *val = ( *val << 8 ) | **p;
177 (*p)++;
178 }
179
180 return( 0 );
181 }
182
mbedtls_asn1_get_int(unsigned char ** p,const unsigned char * end,int * val)183 int mbedtls_asn1_get_int( unsigned char **p,
184 const unsigned char *end,
185 int *val )
186 {
187 return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_INTEGER, val) );
188 }
189
mbedtls_asn1_get_enum(unsigned char ** p,const unsigned char * end,int * val)190 int mbedtls_asn1_get_enum( unsigned char **p,
191 const unsigned char *end,
192 int *val )
193 {
194 return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_ENUMERATED, val) );
195 }
196
197 #if defined(MBEDTLS_BIGNUM_C)
mbedtls_asn1_get_mpi(unsigned char ** p,const unsigned char * end,mbedtls_mpi * X)198 int mbedtls_asn1_get_mpi( unsigned char **p,
199 const unsigned char *end,
200 mbedtls_mpi *X )
201 {
202 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
203 size_t len;
204
205 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
206 return( ret );
207
208 ret = mbedtls_mpi_read_binary( X, *p, len );
209
210 *p += len;
211
212 return( ret );
213 }
214 #endif /* MBEDTLS_BIGNUM_C */
215
mbedtls_asn1_get_bitstring(unsigned char ** p,const unsigned char * end,mbedtls_asn1_bitstring * bs)216 int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
217 mbedtls_asn1_bitstring *bs)
218 {
219 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
220
221 /* Certificate type is a single byte bitstring */
222 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
223 return( ret );
224
225 /* Check length, subtract one for actual bit string length */
226 if( bs->len < 1 )
227 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
228 bs->len -= 1;
229
230 /* Get number of unused bits, ensure unused bits <= 7 */
231 bs->unused_bits = **p;
232 if( bs->unused_bits > 7 )
233 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
234 (*p)++;
235
236 /* Get actual bitstring */
237 bs->p = *p;
238 *p += bs->len;
239
240 if( *p != end )
241 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
242
243 return( 0 );
244 }
245
246 /*
247 * Traverse an ASN.1 "SEQUENCE OF <tag>"
248 * and call a callback for each entry found.
249 */
mbedtls_asn1_traverse_sequence_of(unsigned char ** p,const unsigned char * end,unsigned char tag_must_mask,unsigned char tag_must_val,unsigned char tag_may_mask,unsigned char tag_may_val,int (* cb)(void * ctx,int tag,unsigned char * start,size_t len),void * ctx)250 int mbedtls_asn1_traverse_sequence_of(
251 unsigned char **p,
252 const unsigned char *end,
253 unsigned char tag_must_mask, unsigned char tag_must_val,
254 unsigned char tag_may_mask, unsigned char tag_may_val,
255 int (*cb)( void *ctx, int tag,
256 unsigned char *start, size_t len ),
257 void *ctx )
258 {
259 int ret;
260 size_t len;
261
262 /* Get main sequence tag */
263 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
264 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
265 {
266 return( ret );
267 }
268
269 if( *p + len != end )
270 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
271
272 while( *p < end )
273 {
274 unsigned char const tag = *(*p)++;
275
276 if( ( tag & tag_must_mask ) != tag_must_val )
277 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
278
279 if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 )
280 return( ret );
281
282 if( ( tag & tag_may_mask ) == tag_may_val )
283 {
284 if( cb != NULL )
285 {
286 ret = cb( ctx, tag, *p, len );
287 if( ret != 0 )
288 return( ret );
289 }
290 }
291
292 *p += len;
293 }
294
295 return( 0 );
296 }
297
298 /*
299 * Get a bit string without unused bits
300 */
mbedtls_asn1_get_bitstring_null(unsigned char ** p,const unsigned char * end,size_t * len)301 int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
302 size_t *len )
303 {
304 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
305
306 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
307 return( ret );
308
309 if( *len == 0 )
310 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
311 --( *len );
312
313 if( **p != 0 )
314 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
315 ++( *p );
316
317 return( 0 );
318 }
319
mbedtls_asn1_sequence_free(mbedtls_asn1_sequence * seq)320 void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
321 {
322 while( seq != NULL )
323 {
324 mbedtls_asn1_sequence *next = seq->next;
325 mbedtls_platform_zeroize( seq, sizeof( *seq ) );
326 mbedtls_free( seq );
327 seq = next;
328 }
329 }
330
331 typedef struct
332 {
333 int tag;
334 mbedtls_asn1_sequence *cur;
335 } asn1_get_sequence_of_cb_ctx_t;
336
asn1_get_sequence_of_cb(void * ctx,int tag,unsigned char * start,size_t len)337 static int asn1_get_sequence_of_cb( void *ctx,
338 int tag,
339 unsigned char *start,
340 size_t len )
341 {
342 asn1_get_sequence_of_cb_ctx_t *cb_ctx =
343 (asn1_get_sequence_of_cb_ctx_t *) ctx;
344 mbedtls_asn1_sequence *cur =
345 cb_ctx->cur;
346
347 if( cur->buf.p != NULL )
348 {
349 cur->next =
350 mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
351
352 if( cur->next == NULL )
353 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
354
355 cur = cur->next;
356 }
357
358 cur->buf.p = start;
359 cur->buf.len = len;
360 cur->buf.tag = tag;
361
362 cb_ctx->cur = cur;
363 return( 0 );
364 }
365
366 /*
367 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
368 */
mbedtls_asn1_get_sequence_of(unsigned char ** p,const unsigned char * end,mbedtls_asn1_sequence * cur,int tag)369 int mbedtls_asn1_get_sequence_of( unsigned char **p,
370 const unsigned char *end,
371 mbedtls_asn1_sequence *cur,
372 int tag)
373 {
374 asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
375 memset( cur, 0, sizeof( mbedtls_asn1_sequence ) );
376 return( mbedtls_asn1_traverse_sequence_of(
377 p, end, 0xFF, tag, 0, 0,
378 asn1_get_sequence_of_cb, &cb_ctx ) );
379 }
380
mbedtls_asn1_get_alg(unsigned char ** p,const unsigned char * end,mbedtls_asn1_buf * alg,mbedtls_asn1_buf * params)381 int mbedtls_asn1_get_alg( unsigned char **p,
382 const unsigned char *end,
383 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
384 {
385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
386 size_t len;
387
388 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
389 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
390 return( ret );
391
392 if( ( end - *p ) < 1 )
393 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
394
395 alg->tag = **p;
396 end = *p + len;
397
398 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
399 return( ret );
400
401 alg->p = *p;
402 *p += alg->len;
403
404 if( *p == end )
405 {
406 mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
407 return( 0 );
408 }
409
410 params->tag = **p;
411 (*p)++;
412
413 if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 )
414 return( ret );
415
416 params->p = *p;
417 *p += params->len;
418
419 if( *p != end )
420 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
421
422 return( 0 );
423 }
424
mbedtls_asn1_get_alg_null(unsigned char ** p,const unsigned char * end,mbedtls_asn1_buf * alg)425 int mbedtls_asn1_get_alg_null( unsigned char **p,
426 const unsigned char *end,
427 mbedtls_asn1_buf *alg )
428 {
429 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
430 mbedtls_asn1_buf params;
431
432 memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) );
433
434 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 )
435 return( ret );
436
437 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
438 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
439
440 return( 0 );
441 }
442
mbedtls_asn1_free_named_data(mbedtls_asn1_named_data * cur)443 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
444 {
445 if( cur == NULL )
446 return;
447
448 mbedtls_free( cur->oid.p );
449 mbedtls_free( cur->val.p );
450
451 mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
452 }
453
mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data ** head)454 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
455 {
456 mbedtls_asn1_named_data *cur;
457
458 while( ( cur = *head ) != NULL )
459 {
460 *head = cur->next;
461 mbedtls_asn1_free_named_data( cur );
462 mbedtls_free( cur );
463 }
464 }
465
mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data * list,const char * oid,size_t len)466 const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
467 const char *oid, size_t len )
468 {
469 while( list != NULL )
470 {
471 if( list->oid.len == len &&
472 memcmp( list->oid.p, oid, len ) == 0 )
473 {
474 break;
475 }
476
477 list = list->next;
478 }
479
480 return( list );
481 }
482
483 #endif /* MBEDTLS_ASN1_PARSE_C */
484