blob: fe62bc683e26f7983c307f632b8759c814c5c5aa [file] [log] [blame]
Paul Bakkerefc30292011-11-10 14:43:23 +00001/*
2 * Generic ASN.1 parsing
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * 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.
Paul Bakkerefc30292011-11-10 14:43:23 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerefc30292011-11-10 14:43:23 +000020 */
21
Gilles Peskinedb09ef62020-06-03 01:43:33 +020022#include "common.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000023
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020024#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakkerefc30292011-11-10 14:43:23 +000025
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000026#include "mbedtls/asn1.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050027#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000028#include "mbedtls/error.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_BIGNUM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000033#include "mbedtls/bignum.h"
Paul Bakkerefc30292011-11-10 14:43:23 +000034#endif
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020038#else
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020040#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_free free
Paul Bakker6e339b52013-07-03 13:37:05 +020042#endif
43
Paul Bakkerefc30292011-11-10 14:43:23 +000044/*
45 * ASN.1 DER decoding routines
46 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047int mbedtls_asn1_get_len( unsigned char **p,
Paul Bakkerefc30292011-11-10 14:43:23 +000048 const unsigned char *end,
49 size_t *len )
50{
51 if( ( end - *p ) < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerefc30292011-11-10 14:43:23 +000053
54 if( ( **p & 0x80 ) == 0 )
55 *len = *(*p)++;
56 else
57 {
58 switch( **p & 0x7F )
59 {
60 case 1:
61 if( ( end - *p ) < 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerefc30292011-11-10 14:43:23 +000063
64 *len = (*p)[1];
65 (*p) += 2;
66 break;
67
68 case 2:
69 if( ( end - *p ) < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerefc30292011-11-10 14:43:23 +000071
Manuel Pégourié-Gonnard6fdc4ca2015-02-13 17:15:18 +000072 *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
Paul Bakkerefc30292011-11-10 14:43:23 +000073 (*p) += 3;
74 break;
75
76 case 3:
77 if( ( end - *p ) < 4 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerefc30292011-11-10 14:43:23 +000079
Manuel Pégourié-Gonnard6fdc4ca2015-02-13 17:15:18 +000080 *len = ( (size_t)(*p)[1] << 16 ) |
81 ( (size_t)(*p)[2] << 8 ) | (*p)[3];
Paul Bakkerefc30292011-11-10 14:43:23 +000082 (*p) += 4;
83 break;
84
85 case 4:
86 if( ( end - *p ) < 5 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerefc30292011-11-10 14:43:23 +000088
Manuel Pégourié-Gonnard6fdc4ca2015-02-13 17:15:18 +000089 *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
90 ( (size_t)(*p)[3] << 8 ) | (*p)[4];
Paul Bakkerefc30292011-11-10 14:43:23 +000091 (*p) += 5;
92 break;
93
94 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
Paul Bakkerefc30292011-11-10 14:43:23 +000096 }
97 }
98
99 if( *len > (size_t) ( end - *p ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerefc30292011-11-10 14:43:23 +0000101
102 return( 0 );
103}
104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105int mbedtls_asn1_get_tag( unsigned char **p,
Paul Bakkerefc30292011-11-10 14:43:23 +0000106 const unsigned char *end,
107 size_t *len, int tag )
108{
109 if( ( end - *p ) < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerefc30292011-11-10 14:43:23 +0000111
112 if( **p != tag )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113 return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakkerefc30292011-11-10 14:43:23 +0000114
115 (*p)++;
116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117 return( mbedtls_asn1_get_len( p, end, len ) );
Paul Bakkerefc30292011-11-10 14:43:23 +0000118}
119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120int mbedtls_asn1_get_bool( unsigned char **p,
Paul Bakkerefc30292011-11-10 14:43:23 +0000121 const unsigned char *end,
122 int *val )
123{
Janos Follath24eed8d2019-11-22 13:21:35 +0000124 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000125 size_t len;
126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
Paul Bakkerefc30292011-11-10 14:43:23 +0000128 return( ret );
129
130 if( len != 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
Paul Bakkerefc30292011-11-10 14:43:23 +0000132
133 *val = ( **p != 0 ) ? 1 : 0;
134 (*p)++;
135
136 return( 0 );
137}
138
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200139static int asn1_get_tagged_int( unsigned char **p,
140 const unsigned char *end,
141 int tag, int *val )
Paul Bakkerefc30292011-11-10 14:43:23 +0000142{
Janos Follath24eed8d2019-11-22 13:21:35 +0000143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000144 size_t len;
145
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200146 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, tag ) ) != 0 )
Paul Bakkerefc30292011-11-10 14:43:23 +0000147 return( ret );
148
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200149 /*
150 * len==0 is malformed (0 must be represented as 020100 for INTEGER,
151 * or 0A0100 for ENUMERATED tags
152 */
Gilles Peskine9fd97942019-10-10 19:27:53 +0200153 if( len == 0 )
154 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
155 /* This is a cryptography library. Reject negative integers. */
156 if( ( **p & 0x80 ) != 0 )
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100157 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
158
Gilles Peskine9fd97942019-10-10 19:27:53 +0200159 /* Skip leading zeros. */
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100160 while( len > 0 && **p == 0 )
161 {
162 ++( *p );
163 --len;
164 }
Gilles Peskine9fd97942019-10-10 19:27:53 +0200165
166 /* Reject integers that don't fit in an int. This code assumes that
167 * the int type has no padding bit. */
Gilles Peskinef7d6acd2019-03-01 18:06:08 +0100168 if( len > sizeof( int ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
Gilles Peskine37570e82019-10-10 19:29:27 +0200170 if( len == sizeof( int ) && ( **p & 0x80 ) != 0 )
171 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
Paul Bakkerefc30292011-11-10 14:43:23 +0000172
173 *val = 0;
Paul Bakkerefc30292011-11-10 14:43:23 +0000174 while( len-- > 0 )
175 {
176 *val = ( *val << 8 ) | **p;
177 (*p)++;
178 }
179
180 return( 0 );
181}
182
Mykhailo Sopiha20180ca2019-10-29 15:58:10 +0200183int 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
190int 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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197#if defined(MBEDTLS_BIGNUM_C)
198int mbedtls_asn1_get_mpi( unsigned char **p,
Paul Bakkerefc30292011-11-10 14:43:23 +0000199 const unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 mbedtls_mpi *X )
Paul Bakkerefc30292011-11-10 14:43:23 +0000201{
Janos Follath24eed8d2019-11-22 13:21:35 +0000202 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000203 size_t len;
204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
Paul Bakkerefc30292011-11-10 14:43:23 +0000206 return( ret );
207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 ret = mbedtls_mpi_read_binary( X, *p, len );
Paul Bakkerefc30292011-11-10 14:43:23 +0000209
210 *p += len;
211
212 return( ret );
213}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214#endif /* MBEDTLS_BIGNUM_C */
Paul Bakkerefc30292011-11-10 14:43:23 +0000215
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
217 mbedtls_asn1_bitstring *bs)
Paul Bakkerefc30292011-11-10 14:43:23 +0000218{
Janos Follath24eed8d2019-11-22 13:21:35 +0000219 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerefc30292011-11-10 14:43:23 +0000220
221 /* Certificate type is a single byte bitstring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222 if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
Paul Bakkerefc30292011-11-10 14:43:23 +0000223 return( ret );
224
225 /* Check length, subtract one for actual bit string length */
Paul Bakker66d5d072014-06-17 16:39:18 +0200226 if( bs->len < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakkerefc30292011-11-10 14:43:23 +0000228 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 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
Paul Bakkerefc30292011-11-10 14:43:23 +0000234 (*p)++;
235
236 /* Get actual bitstring */
237 bs->p = *p;
238 *p += bs->len;
239
240 if( *p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakkerefc30292011-11-10 14:43:23 +0000242
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200243 return( 0 );
Paul Bakkerefc30292011-11-10 14:43:23 +0000244}
245
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200246/*
Hanno Becker199b7092019-09-11 14:21:26 +0100247 * Traverse an ASN.1 "SEQUENCE OF <tag>"
248 * and call a callback for each entry found.
249 */
250int mbedtls_asn1_traverse_sequence_of(
251 unsigned char **p,
252 const unsigned char *end,
Hanno Becker34aada22020-02-03 10:39:55 +0000253 unsigned char tag_must_mask, unsigned char tag_must_val,
254 unsigned char tag_may_mask, unsigned char tag_may_val,
Hanno Becker199b7092019-09-11 14:21:26 +0100255 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/*
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200299 * Get a bit string without unused bits
300 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200302 size_t *len )
303{
Janos Follath24eed8d2019-11-22 13:21:35 +0000304 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200307 return( ret );
308
Gilles Peskinee40d1202019-03-01 18:08:35 +0100309 if( *len == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Gilles Peskinee40d1202019-03-01 18:08:35 +0100311 --( *len );
312
313 if( **p != 0 )
314 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
315 ++( *p );
Manuel Pégourié-Gonnarda2d4e642013-07-11 13:59:02 +0200316
317 return( 0 );
318}
319
Hanno Becker12ae27d2019-09-11 14:20:09 +0100320void 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}
Paul Bakkerefc30292011-11-10 14:43:23 +0000330
Hanno Becker1505f632019-09-11 14:25:26 +0100331typedef struct
332{
333 int tag;
334 mbedtls_asn1_sequence *cur;
335} asn1_get_sequence_of_cb_ctx_t;
336
337static 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
Paul Bakkerefc30292011-11-10 14:43:23 +0000366/*
367 * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
368 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369int mbedtls_asn1_get_sequence_of( unsigned char **p,
Paul Bakkerefc30292011-11-10 14:43:23 +0000370 const unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 mbedtls_asn1_sequence *cur,
Paul Bakkerefc30292011-11-10 14:43:23 +0000372 int tag)
373{
Hanno Becker1505f632019-09-11 14:25:26 +0100374 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 ) );
Paul Bakkerefc30292011-11-10 14:43:23 +0000379}
380
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381int mbedtls_asn1_get_alg( unsigned char **p,
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200382 const unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200384{
Janos Follath24eed8d2019-11-22 13:21:35 +0000385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200386 size_t len;
387
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
389 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200390 return( ret );
391
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200392 if( ( end - *p ) < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200393 return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200394
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200395 alg->tag = **p;
Manuel Pégourié-Gonnardba77bbf2013-08-15 13:38:13 +0200396 end = *p + len;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200399 return( ret );
400
401 alg->p = *p;
402 *p += alg->len;
403
404 if( *p == end )
405 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500406 mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200407 return( 0 );
408 }
409
410 params->tag = **p;
411 (*p)++;
412
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 if( ( ret = mbedtls_asn1_get_len( p, end, &params->len ) ) != 0 )
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200414 return( ret );
415
416 params->p = *p;
417 *p += params->len;
418
419 if( *p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200421
422 return( 0 );
423}
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425int mbedtls_asn1_get_alg_null( unsigned char **p,
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200426 const unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 mbedtls_asn1_buf *alg )
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200428{
Janos Follath24eed8d2019-11-22 13:21:35 +0000429 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 mbedtls_asn1_buf params;
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 memset( &params, 0, sizeof(mbedtls_asn1_buf) );
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, &params ) ) != 0 )
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200435 return( ret );
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
438 return( MBEDTLS_ERR_ASN1_INVALID_DATA );
Paul Bakkerf8d018a2013-06-29 12:16:17 +0200439
440 return( 0 );
441}
442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
Paul Bakkere5eae762013-08-26 12:05:14 +0200444{
445 if( cur == NULL )
446 return;
447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 mbedtls_free( cur->oid.p );
449 mbedtls_free( cur->val.p );
Paul Bakkere5eae762013-08-26 12:05:14 +0200450
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500451 mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200452}
453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
Paul Bakkerc547cc92013-09-09 12:01:23 +0200455{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 mbedtls_asn1_named_data *cur;
Paul Bakkerc547cc92013-09-09 12:01:23 +0200457
458 while( ( cur = *head ) != NULL )
459 {
460 *head = cur->next;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 mbedtls_asn1_free_named_data( cur );
462 mbedtls_free( cur );
Paul Bakkerc547cc92013-09-09 12:01:23 +0200463 }
464}
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
Paul Bakkere5eae762013-08-26 12:05:14 +0200467 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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483#endif /* MBEDTLS_ASN1_PARSE_C */