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