75
75
#define MBEDTLS_ASN1_OCTET_STRING 0x04
76
76
#define MBEDTLS_ASN1_NULL 0x05
77
77
#define MBEDTLS_ASN1_OID 0x06
78
+ #define MBEDTLS_ASN1_ENUMERATED 0x0A
78
79
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
79
80
#define MBEDTLS_ASN1_SEQUENCE 0x10
80
81
#define MBEDTLS_ASN1_SET 0x11
89
90
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
90
91
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
91
92
93
+ /* Slightly smaller way to check if tag is a string tag
94
+ * compared to canonical implementation. */
95
+ #define MBEDTLS_ASN1_IS_STRING_TAG ( tag ) \
96
+ ( ( tag ) < 32u && ( \
97
+ ( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \
98
+ ( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \
99
+ ( 1u << MBEDTLS_ASN1_T61_STRING ) | \
100
+ ( 1u << MBEDTLS_ASN1_IA5_STRING ) | \
101
+ ( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \
102
+ ( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \
103
+ ( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) )
104
+
92
105
/*
93
106
* Bit masks for each of the components of an ASN.1 tag as specified in
94
107
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
119
132
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
120
133
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
121
134
135
+ #define MBEDTLS_OID_CMP_RAW (oid_str , oid_buf , oid_buf_len ) \
136
+ ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \
137
+ memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
138
+
122
139
#ifdef __cplusplus
123
140
extern "C" {
124
141
#endif
@@ -254,13 +271,32 @@ int mbedtls_asn1_get_bool( unsigned char **p,
254
271
* a valid ASN.1 INTEGER.
255
272
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
256
273
* not fit in an \c int.
257
- * \return An ASN.1 error code if the input does not start with
258
- * a valid ASN.1 INTEGER.
259
274
*/
260
275
int mbedtls_asn1_get_int ( unsigned char * * p ,
261
276
const unsigned char * end ,
262
277
int * val );
263
278
279
+ /**
280
+ * \brief Retrieve an enumerated ASN.1 tag and its value.
281
+ * Updates the pointer to immediately behind the full tag.
282
+ *
283
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
284
+ * On successful completion, \c *p points to the first byte
285
+ * beyond the ASN.1 element.
286
+ * On error, the value of \c *p is undefined.
287
+ * \param end End of data.
288
+ * \param val On success, the parsed value.
289
+ *
290
+ * \return 0 if successful.
291
+ * \return An ASN.1 error code if the input does not start with
292
+ * a valid ASN.1 ENUMERATED.
293
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
294
+ * not fit in an \c int.
295
+ */
296
+ int mbedtls_asn1_get_enum ( unsigned char * * p ,
297
+ const unsigned char * end ,
298
+ int * val );
299
+
264
300
/**
265
301
* \brief Retrieve a bitstring ASN.1 tag and its value.
266
302
* Updates the pointer to immediately behind the full tag.
@@ -307,6 +343,9 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p,
307
343
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
308
344
* Updates the pointer to immediately behind the full sequence tag.
309
345
*
346
+ * This function allocates memory for the sequence elements. You can free
347
+ * the allocated memory with mbedtls_asn1_sequence_free().
348
+ *
310
349
* \note On error, this function may return a partial list in \p cur.
311
350
* You must set `cur->next = NULL` before calling this function!
312
351
* Otherwise it is impossible to distinguish a previously non-null
@@ -340,14 +379,133 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p,
340
379
* \return 0 if successful.
341
380
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
342
381
* extra data after a valid SEQUENCE OF \p tag.
382
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with
383
+ * an ASN.1 SEQUENCE in which an element has a tag that
384
+ * is different from \p tag.
343
385
* \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.
344
386
* \return An ASN.1 error code if the input does not start with
345
- * a valid ASN.1 BIT STRING .
387
+ * a valid ASN.1 SEQUENCE .
346
388
*/
347
389
int mbedtls_asn1_get_sequence_of ( unsigned char * * p ,
348
390
const unsigned char * end ,
349
391
mbedtls_asn1_sequence * cur ,
350
392
int tag );
393
+ /**
394
+ * \brief Free a heap-allocated linked list presentation of
395
+ * an ASN.1 sequence, including the first element.
396
+ *
397
+ * There are two common ways to manage the memory used for the representation
398
+ * of a parsed ASN.1 sequence:
399
+ * - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc().
400
+ * Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of().
401
+ * When you have finished processing the sequence,
402
+ * call mbedtls_asn1_sequence_free() on `head`.
403
+ * - Allocate a head node `mbedtls_asn1_sequence *head` in any manner,
404
+ * for example on the stack. Make sure that `head->next == NULL`.
405
+ * Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of().
406
+ * When you have finished processing the sequence,
407
+ * call mbedtls_asn1_sequence_free() on `head->cur`,
408
+ * then free `head` itself in the appropriate manner.
409
+ *
410
+ * \param seq The address of the first sequence component. This may
411
+ * be \c NULL, in which case this functions returns
412
+ * immediately.
413
+ */
414
+ void mbedtls_asn1_sequence_free ( mbedtls_asn1_sequence * seq );
415
+
416
+ /**
417
+ * \brief Traverse an ASN.1 SEQUENCE container and
418
+ * call a callback for each entry.
419
+ *
420
+ * This function checks that the input is a SEQUENCE of elements that
421
+ * each have a "must" tag, and calls a callback function on the elements
422
+ * that have a "may" tag.
423
+ *
424
+ * For example, to validate that the input is a SEQUENCE of `tag1` and call
425
+ * `cb` on each element, use
426
+ * ```
427
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx);
428
+ * ```
429
+ *
430
+ * To validate that the input is a SEQUENCE of ANY and call `cb` on
431
+ * each element, use
432
+ * ```
433
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx);
434
+ * ```
435
+ *
436
+ * To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING}
437
+ * and call `cb` on each element that is an OCTET STRING, use
438
+ * ```
439
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx);
440
+ * ```
441
+ *
442
+ * The callback is called on the elements with a "may" tag from left to
443
+ * right. If the input is not a valid SEQUENCE of elements with a "must" tag,
444
+ * the callback is called on the elements up to the leftmost point where
445
+ * the input is invalid.
446
+ *
447
+ * \warning This function is still experimental and may change
448
+ * at any time.
449
+ *
450
+ * \param p The address of the pointer to the beginning of
451
+ * the ASN.1 SEQUENCE header. This is updated to
452
+ * point to the end of the ASN.1 SEQUENCE container
453
+ * on a successful invocation.
454
+ * \param end The end of the ASN.1 SEQUENCE container.
455
+ * \param tag_must_mask A mask to be applied to the ASN.1 tags found within
456
+ * the SEQUENCE before comparing to \p tag_must_value.
457
+ * \param tag_must_val The required value of each ASN.1 tag found in the
458
+ * SEQUENCE, after masking with \p tag_must_mask.
459
+ * Mismatching tags lead to an error.
460
+ * For example, a value of \c 0 for both \p tag_must_mask
461
+ * and \p tag_must_val means that every tag is allowed,
462
+ * while a value of \c 0xFF for \p tag_must_mask means
463
+ * that \p tag_must_val is the only allowed tag.
464
+ * \param tag_may_mask A mask to be applied to the ASN.1 tags found within
465
+ * the SEQUENCE before comparing to \p tag_may_value.
466
+ * \param tag_may_val The desired value of each ASN.1 tag found in the
467
+ * SEQUENCE, after masking with \p tag_may_mask.
468
+ * Mismatching tags will be silently ignored.
469
+ * For example, a value of \c 0 for \p tag_may_mask and
470
+ * \p tag_may_val means that any tag will be considered,
471
+ * while a value of \c 0xFF for \p tag_may_mask means
472
+ * that all tags with value different from \p tag_may_val
473
+ * will be ignored.
474
+ * \param cb The callback to trigger for each component
475
+ * in the ASN.1 SEQUENCE that matches \p tag_may_val.
476
+ * The callback function is called with the following
477
+ * parameters:
478
+ * - \p ctx.
479
+ * - The tag of the current element.
480
+ * - A pointer to the start of the current element's
481
+ * content inside the input.
482
+ * - The length of the content of the current element.
483
+ * If the callback returns a non-zero value,
484
+ * the function stops immediately,
485
+ * forwarding the callback's return value.
486
+ * \param ctx The context to be passed to the callback \p cb.
487
+ *
488
+ * \return \c 0 if successful the entire ASN.1 SEQUENCE
489
+ * was traversed without parsing or callback errors.
490
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input
491
+ * contains extra data after a valid SEQUENCE
492
+ * of elements with an accepted tag.
493
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts
494
+ * with an ASN.1 SEQUENCE in which an element has a tag
495
+ * that is not accepted.
496
+ * \return An ASN.1 error code if the input does not start with
497
+ * a valid ASN.1 SEQUENCE.
498
+ * \return A non-zero error code forwarded from the callback
499
+ * \p cb in case the latter returns a non-zero value.
500
+ */
501
+ int mbedtls_asn1_traverse_sequence_of (
502
+ unsigned char * * p ,
503
+ const unsigned char * end ,
504
+ unsigned char tag_must_mask , unsigned char tag_must_val ,
505
+ unsigned char tag_may_mask , unsigned char tag_may_val ,
506
+ int (* cb )( void * ctx , int tag ,
507
+ unsigned char * start , size_t len ),
508
+ void * ctx );
351
509
352
510
#if defined(MBEDTLS_BIGNUM_C )
353
511
/**
@@ -367,8 +525,6 @@ int mbedtls_asn1_get_sequence_of( unsigned char **p,
367
525
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
368
526
* not fit in an \c int.
369
527
* \return An MPI error code if the parsed value is too large.
370
- * \return An ASN.1 error code if the input does not start with
371
- * a valid ASN.1 INTEGER.
372
528
*/
373
529
int mbedtls_asn1_get_mpi ( unsigned char * * p ,
374
530
const unsigned char * end ,
0 commit comments