This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

source: ps/trunk/build/premake/premake5/contrib/mbedtls/library/asn1parse.c

Last change on this file was 20366, checked in by Itms, 7 years ago

Alpha 12 version of Premake 5, including prebuilt binary for Windows.
Directly taken from https://premake.github.io/.

Refs #3729.

File size: 9.1 KB
Line 
1/*
2 * Generic ASN.1 parsing
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_ASN1_PARSE_C)
29
30#include "mbedtls/asn1.h"
31
32#include <string.h>
33
34#if defined(MBEDTLS_BIGNUM_C)
35#include "mbedtls/bignum.h"
36#endif
37
38#if defined(MBEDTLS_PLATFORM_C)
39#include "mbedtls/platform.h"
40#else
41#include <stdlib.h>
42#define mbedtls_calloc calloc
43#define mbedtls_free free
44#endif
45
46/* Implementation that should never be optimized out by the compiler */
47static void mbedtls_zeroize( void *v, size_t n ) {
48 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
49}
50
51/*
52 * ASN.1 DER decoding routines
53 */
54int mbedtls_asn1_get_len( unsigned char **p,
55 const unsigned char *end,
56 size_t *len )
57{
58 if( ( end - *p ) < 1 )
59 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
60
61 if( ( **p & 0x80 ) == 0 )
62 *len = *(*p)++;
63 else
64 {
65 switch( **p & 0x7F )
66 {
67 case 1:
68 if( ( end - *p ) < 2 )
69 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
70
71 *len = (*p)[1];
72 (*p) += 2;
73 break;
74
75 case 2:
76 if( ( end - *p ) < 3 )
77 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
78
79 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
80 (*p) += 3;
81 break;
82
83 case 3:
84 if( ( end - *p ) < 4 )
85 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
86
87 *len = ( (size_t)(*p)[1] << 16 ) |
88 ( (size_t)(*p)[2] << 8 ) | (*p)[3];
89 (*p) += 4;
90 break;
91
92 case 4:
93 if( ( end - *p ) < 5 )
94 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
95
96 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
97 ( (size_t)(*p)[3] << 8 ) | (*p)[4];
98 (*p) += 5;
99 break;
100
101 default:
102 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
103 }
104 }
105
106 if( *len > (size_t) ( end - *p ) )
107 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
108
109 return( 0 );
110}
111
112int mbedtls_asn1_get_tag( unsigned char **p,
113 const unsigned char *end,
114 size_t *len, int tag )
115{
116 if( ( end - *p ) < 1 )
117 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
118
119 if( **p != tag )
120 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
121
122 (*p)++;
123
124 return( mbedtls_asn1_get_len( p, end, len ) );
125}
126
127int mbedtls_asn1_get_bool( unsigned char **p,
128 const unsigned char *end,
129 int *val )
130{
131 int ret;
132 size_t len;
133
134 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
135 return( ret );
136
137 if( len != 1 )
138 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
139
140 *val = ( **p != 0 ) ? 1 : 0;
141 (*p)++;
142
143 return( 0 );
144}
145
146int mbedtls_asn1_get_int( unsigned char **p,
147 const unsigned char *end,
148 int *val )
149{
150 int ret;
151 size_t len;
152
153 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
154 return( ret );
155
156 if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
157 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
158
159 *val = 0;
160
161 while( len-- > 0 )
162 {
163 *val = ( *val << 8 ) | **p;
164 (*p)++;
165 }
166
167 return( 0 );
168}
169
170#if defined(MBEDTLS_BIGNUM_C)
171int mbedtls_asn1_get_mpi( unsigned char **p,
172 const unsigned char *end,
173 mbedtls_mpi *X )
174{
175 int ret;
176 size_t len;
177
178 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
179 return( ret );
180
181 ret = mbedtls_mpi_read_binary( X, *p, len );
182
183 *p += len;
184
185 return( ret );
186}
187#endif /* MBEDTLS_BIGNUM_C */
188
189int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
190 mbedtls_asn1_bitstring *bs)
191{
192 int ret;
193
194 /* Certificate type is a single byte bitstring */
195 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
196 return( ret );
197
198 /* Check length, subtract one for actual bit string length */
199 if( bs->len < 1 )
200 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
201 bs->len -= 1;
202
203 /* Get number of unused bits, ensure unused bits <= 7 */
204 bs->unused_bits = **p;
205 if( bs->unused_bits > 7 )
206 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
207 (*p)++;
208
209 /* Get actual bitstring */
210 bs->p = *p;
211 *p += bs->len;
212
213 if( *p != end )
214 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
215
216 return( 0 );
217}
218
219/*
220 * Get a bit string without unused bits
221 */
222int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
223 size_t *len )
224{
225 int ret;
226
227 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
228 return( ret );
229
230 if( (*len)-- < 2 || *(*p)++ != 0 )
231 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
232
233 return( 0 );
234}
235
236
237
238/*
239 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
240 */
241int mbedtls_asn1_get_sequence_of( unsigned char **p,
242 const unsigned char *end,
243 mbedtls_asn1_sequence *cur,
244 int tag)
245{
246 int ret;
247 size_t len;
248 mbedtls_asn1_buf *buf;
249
250 /* Get main sequence tag */
251 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
252 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
253 return( ret );
254
255 if( *p + len != end )
256 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
257
258 while( *p < end )
259 {
260 buf = &(cur->buf);
261 buf->tag = **p;
262
263 if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
264 return( ret );
265
266 buf->p = *p;
267 *p += buf->len;
268
269 /* Allocate and assign next pointer */
270 if( *p < end )
271 {
272 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
273
274 if( cur->next == NULL )
275 return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
276
277 cur = cur->next;
278 }
279 }
280
281 /* Set final sequence entry's next pointer to NULL */
282 cur->next = NULL;
283
284 if( *p != end )
285 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
286
287 return( 0 );
288}
289
290int mbedtls_asn1_get_alg( unsigned char **p,
291 const unsigned char *end,
292 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
293{
294 int ret;
295 size_t len;
296
297 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
298 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
299 return( ret );
300
301 if( ( end - *p ) < 1 )
302 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
303
304 alg->tag = **p;
305 end = *p + len;
306
307 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
308 return( ret );
309
310 alg->p = *p;
311 *p += alg->len;
312
313 if( *p == end )
314 {
315 mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) );
316 return( 0 );
317 }
318
319 params->tag = **p;
320 (*p)++;
321
322 if( ( ret = mbedtls_asn1_get_len( p, end, &params->len ) ) != 0 )
323 return( ret );
324
325 params->p = *p;
326 *p += params->len;
327
328 if( *p != end )
329 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
330
331 return( 0 );
332}
333
334int mbedtls_asn1_get_alg_null( unsigned char **p,
335 const unsigned char *end,
336 mbedtls_asn1_buf *alg )
337{
338 int ret;
339 mbedtls_asn1_buf params;
340
341 memset( &params, 0, sizeof(mbedtls_asn1_buf) );
342
343 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, &params ) ) != 0 )
344 return( ret );
345
346 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
347 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
348
349 return( 0 );
350}
351
352void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
353{
354 if( cur == NULL )
355 return;
356
357 mbedtls_free( cur->oid.p );
358 mbedtls_free( cur->val.p );
359
360 mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
361}
362
363void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
364{
365 mbedtls_asn1_named_data *cur;
366
367 while( ( cur = *head ) != NULL )
368 {
369 *head = cur->next;
370 mbedtls_asn1_free_named_data( cur );
371 mbedtls_free( cur );
372 }
373}
374
375mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
376 const char *oid, size_t len )
377{
378 while( list != NULL )
379 {
380 if( list->oid.len == len &&
381 memcmp( list->oid.p, oid, len ) == 0 )
382 {
383 break;
384 }
385
386 list = list->next;
387 }
388
389 return( list );
390}
391
392#endif /* MBEDTLS_ASN1_PARSE_C */
Note: See TracBrowser for help on using the repository browser.