• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params->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( &params, 0, sizeof(mbedtls_asn1_buf) );
433 
434     if( ( ret = mbedtls_asn1_get_alg( p, end, alg, &params ) ) != 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