2 * Generic ASN.1 parsing
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
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.
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.
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.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
27 #include MBEDTLS_CONFIG_FILE
30 #if defined(MBEDTLS_ASN1_PARSE_C)
32 #include "mbedtls/asn1.h"
36 #if defined(MBEDTLS_BIGNUM_C)
37 #include "mbedtls/bignum.h"
40 #if defined(MBEDTLS_PLATFORM_C)
41 #include "mbedtls/platform.h"
44 #define mbedtls_calloc calloc
45 #define mbedtls_free free
48 /* Implementation that should never be optimized out by the compiler */
49 static void mbedtls_zeroize( void *v
, size_t n
) {
50 volatile unsigned char *p
= (unsigned char*)v
; while( n
-- ) *p
++ = 0;
54 * ASN.1 DER decoding routines
56 int mbedtls_asn1_get_len( unsigned char **p
,
57 const unsigned char *end
,
60 if( ( end
- *p
) < 1 )
61 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
63 if( ( **p
& 0x80 ) == 0 )
70 if( ( end
- *p
) < 2 )
71 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
78 if( ( end
- *p
) < 3 )
79 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
81 *len
= ( (size_t)(*p
)[1] << 8 ) | (*p
)[2];
86 if( ( end
- *p
) < 4 )
87 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
89 *len
= ( (size_t)(*p
)[1] << 16 ) |
90 ( (size_t)(*p
)[2] << 8 ) | (*p
)[3];
95 if( ( end
- *p
) < 5 )
96 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
98 *len
= ( (size_t)(*p
)[1] << 24 ) | ( (size_t)(*p
)[2] << 16 ) |
99 ( (size_t)(*p
)[3] << 8 ) | (*p
)[4];
104 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
108 if( *len
> (size_t) ( end
- *p
) )
109 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
114 int mbedtls_asn1_get_tag( unsigned char **p
,
115 const unsigned char *end
,
116 size_t *len
, int tag
)
118 if( ( end
- *p
) < 1 )
119 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
122 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
126 return( mbedtls_asn1_get_len( p
, end
, len
) );
129 int mbedtls_asn1_get_bool( unsigned char **p
,
130 const unsigned char *end
,
136 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
, MBEDTLS_ASN1_BOOLEAN
) ) != 0 )
140 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
142 *val
= ( **p
!= 0 ) ? 1 : 0;
148 int mbedtls_asn1_get_int( unsigned char **p
,
149 const unsigned char *end
,
155 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
, MBEDTLS_ASN1_INTEGER
) ) != 0 )
158 if( len
== 0 || len
> sizeof( int ) || ( **p
& 0x80 ) != 0 )
159 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
165 *val
= ( *val
<< 8 ) | **p
;
172 #if defined(MBEDTLS_BIGNUM_C)
173 int mbedtls_asn1_get_mpi( unsigned char **p
,
174 const unsigned char *end
,
180 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
, MBEDTLS_ASN1_INTEGER
) ) != 0 )
183 ret
= mbedtls_mpi_read_binary( X
, *p
, len
);
189 #endif /* MBEDTLS_BIGNUM_C */
191 int mbedtls_asn1_get_bitstring( unsigned char **p
, const unsigned char *end
,
192 mbedtls_asn1_bitstring
*bs
)
196 /* Certificate type is a single byte bitstring */
197 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &bs
->len
, MBEDTLS_ASN1_BIT_STRING
) ) != 0 )
200 /* Check length, subtract one for actual bit string length */
202 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
205 /* Get number of unused bits, ensure unused bits <= 7 */
206 bs
->unused_bits
= **p
;
207 if( bs
->unused_bits
> 7 )
208 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
211 /* Get actual bitstring */
216 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
222 * Get a bit string without unused bits
224 int mbedtls_asn1_get_bitstring_null( unsigned char **p
, const unsigned char *end
,
229 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, len
, MBEDTLS_ASN1_BIT_STRING
) ) != 0 )
232 if( (*len
)-- < 2 || *(*p
)++ != 0 )
233 return( MBEDTLS_ERR_ASN1_INVALID_DATA
);
241 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
243 int mbedtls_asn1_get_sequence_of( unsigned char **p
,
244 const unsigned char *end
,
245 mbedtls_asn1_sequence
*cur
,
250 mbedtls_asn1_buf
*buf
;
252 /* Get main sequence tag */
253 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
254 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
257 if( *p
+ len
!= end
)
258 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
265 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &buf
->len
, tag
) ) != 0 )
271 /* Allocate and assign next pointer */
274 cur
->next
= (mbedtls_asn1_sequence
*)mbedtls_calloc( 1,
275 sizeof( mbedtls_asn1_sequence
) );
277 if( cur
->next
== NULL
)
278 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED
);
284 /* Set final sequence entry's next pointer to NULL */
288 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
293 int mbedtls_asn1_get_alg( unsigned char **p
,
294 const unsigned char *end
,
295 mbedtls_asn1_buf
*alg
, mbedtls_asn1_buf
*params
)
300 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
301 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
304 if( ( end
- *p
) < 1 )
305 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
310 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &alg
->len
, MBEDTLS_ASN1_OID
) ) != 0 )
318 mbedtls_zeroize( params
, sizeof(mbedtls_asn1_buf
) );
325 if( ( ret
= mbedtls_asn1_get_len( p
, end
, ¶ms
->len
) ) != 0 )
332 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
337 int mbedtls_asn1_get_alg_null( unsigned char **p
,
338 const unsigned char *end
,
339 mbedtls_asn1_buf
*alg
)
342 mbedtls_asn1_buf params
;
344 memset( ¶ms
, 0, sizeof(mbedtls_asn1_buf
) );
346 if( ( ret
= mbedtls_asn1_get_alg( p
, end
, alg
, ¶ms
) ) != 0 )
349 if( ( params
.tag
!= MBEDTLS_ASN1_NULL
&& params
.tag
!= 0 ) || params
.len
!= 0 )
350 return( MBEDTLS_ERR_ASN1_INVALID_DATA
);
355 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data
*cur
)
360 mbedtls_free( cur
->oid
.p
);
361 mbedtls_free( cur
->val
.p
);
363 mbedtls_zeroize( cur
, sizeof( mbedtls_asn1_named_data
) );
366 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data
**head
)
368 mbedtls_asn1_named_data
*cur
;
370 while( ( cur
= *head
) != NULL
)
373 mbedtls_asn1_free_named_data( cur
);
378 mbedtls_asn1_named_data
*mbedtls_asn1_find_named_data( mbedtls_asn1_named_data
*list
,
379 const char *oid
, size_t len
)
381 while( list
!= NULL
)
383 if( list
->oid
.len
== len
&&
384 memcmp( list
->oid
.p
, oid
, len
) == 0 )
395 #endif /* MBEDTLS_ASN1_PARSE_C */