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"
33 #include "mbedtls/platform_util.h"
37 #if defined(MBEDTLS_BIGNUM_C)
38 #include "mbedtls/bignum.h"
41 #if defined(MBEDTLS_PLATFORM_C)
42 #include "mbedtls/platform.h"
45 #define mbedtls_calloc calloc
46 #define mbedtls_free free
50 * ASN.1 DER decoding routines
52 int mbedtls_asn1_get_len( unsigned char **p
,
53 const unsigned char *end
,
56 if( ( end
- *p
) < 1 )
57 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
59 if( ( **p
& 0x80 ) == 0 )
66 if( ( end
- *p
) < 2 )
67 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
74 if( ( end
- *p
) < 3 )
75 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
77 *len
= ( (size_t)(*p
)[1] << 8 ) | (*p
)[2];
82 if( ( end
- *p
) < 4 )
83 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
85 *len
= ( (size_t)(*p
)[1] << 16 ) |
86 ( (size_t)(*p
)[2] << 8 ) | (*p
)[3];
91 if( ( end
- *p
) < 5 )
92 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
94 *len
= ( (size_t)(*p
)[1] << 24 ) | ( (size_t)(*p
)[2] << 16 ) |
95 ( (size_t)(*p
)[3] << 8 ) | (*p
)[4];
100 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
104 if( *len
> (size_t) ( end
- *p
) )
105 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
110 int mbedtls_asn1_get_tag( unsigned char **p
,
111 const unsigned char *end
,
112 size_t *len
, int tag
)
114 if( ( end
- *p
) < 1 )
115 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
118 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
122 return( mbedtls_asn1_get_len( p
, end
, len
) );
125 int mbedtls_asn1_get_bool( unsigned char **p
,
126 const unsigned char *end
,
132 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
, MBEDTLS_ASN1_BOOLEAN
) ) != 0 )
136 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
138 *val
= ( **p
!= 0 ) ? 1 : 0;
144 int mbedtls_asn1_get_int( unsigned char **p
,
145 const unsigned char *end
,
151 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
, MBEDTLS_ASN1_INTEGER
) ) != 0 )
154 if( len
== 0 || len
> sizeof( int ) || ( **p
& 0x80 ) != 0 )
155 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
161 *val
= ( *val
<< 8 ) | **p
;
168 #if defined(MBEDTLS_BIGNUM_C)
169 int mbedtls_asn1_get_mpi( unsigned char **p
,
170 const unsigned char *end
,
176 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
, MBEDTLS_ASN1_INTEGER
) ) != 0 )
179 ret
= mbedtls_mpi_read_binary( X
, *p
, len
);
185 #endif /* MBEDTLS_BIGNUM_C */
187 int mbedtls_asn1_get_bitstring( unsigned char **p
, const unsigned char *end
,
188 mbedtls_asn1_bitstring
*bs
)
192 /* Certificate type is a single byte bitstring */
193 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &bs
->len
, MBEDTLS_ASN1_BIT_STRING
) ) != 0 )
196 /* Check length, subtract one for actual bit string length */
198 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
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
);
207 /* Get actual bitstring */
212 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
218 * Get a bit string without unused bits
220 int mbedtls_asn1_get_bitstring_null( unsigned char **p
, const unsigned char *end
,
225 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, len
, MBEDTLS_ASN1_BIT_STRING
) ) != 0 )
228 if( (*len
)-- < 2 || *(*p
)++ != 0 )
229 return( MBEDTLS_ERR_ASN1_INVALID_DATA
);
237 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
239 int mbedtls_asn1_get_sequence_of( unsigned char **p
,
240 const unsigned char *end
,
241 mbedtls_asn1_sequence
*cur
,
246 mbedtls_asn1_buf
*buf
;
248 /* Get main sequence tag */
249 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
250 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
253 if( *p
+ len
!= end
)
254 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
261 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &buf
->len
, tag
) ) != 0 )
267 /* Allocate and assign next pointer */
270 cur
->next
= (mbedtls_asn1_sequence
*)mbedtls_calloc( 1,
271 sizeof( mbedtls_asn1_sequence
) );
273 if( cur
->next
== NULL
)
274 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED
);
280 /* Set final sequence entry's next pointer to NULL */
284 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
289 int mbedtls_asn1_get_alg( unsigned char **p
,
290 const unsigned char *end
,
291 mbedtls_asn1_buf
*alg
, mbedtls_asn1_buf
*params
)
296 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
297 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
300 if( ( end
- *p
) < 1 )
301 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
306 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &alg
->len
, MBEDTLS_ASN1_OID
) ) != 0 )
314 mbedtls_platform_zeroize( params
, sizeof(mbedtls_asn1_buf
) );
321 if( ( ret
= mbedtls_asn1_get_len( p
, end
, ¶ms
->len
) ) != 0 )
328 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
333 int mbedtls_asn1_get_alg_null( unsigned char **p
,
334 const unsigned char *end
,
335 mbedtls_asn1_buf
*alg
)
338 mbedtls_asn1_buf params
;
340 memset( ¶ms
, 0, sizeof(mbedtls_asn1_buf
) );
342 if( ( ret
= mbedtls_asn1_get_alg( p
, end
, alg
, ¶ms
) ) != 0 )
345 if( ( params
.tag
!= MBEDTLS_ASN1_NULL
&& params
.tag
!= 0 ) || params
.len
!= 0 )
346 return( MBEDTLS_ERR_ASN1_INVALID_DATA
);
351 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data
*cur
)
356 mbedtls_free( cur
->oid
.p
);
357 mbedtls_free( cur
->val
.p
);
359 mbedtls_platform_zeroize( cur
, sizeof( mbedtls_asn1_named_data
) );
362 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data
**head
)
364 mbedtls_asn1_named_data
*cur
;
366 while( ( cur
= *head
) != NULL
)
369 mbedtls_asn1_free_named_data( cur
);
374 mbedtls_asn1_named_data
*mbedtls_asn1_find_named_data( mbedtls_asn1_named_data
*list
,
375 const char *oid
, size_t len
)
377 while( list
!= NULL
)
379 if( list
->oid
.len
== len
&&
380 memcmp( list
->oid
.p
, oid
, len
) == 0 )
391 #endif /* MBEDTLS_ASN1_PARSE_C */