ASN.1: Introduce helper function to free ASN.1 sequence
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index 5f15ddb..43ab9ae 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -343,6 +343,9 @@
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
* Updates the pointer to immediately behind the full sequence tag.
*
+ * This function allocates memory for the sequence elements. You can free
+ * the allocated memory with mbedtls_asn1_sequence_free().
+ *
* \note On error, this function may return a partial list in \p cur.
* You must set `cur->next = NULL` before calling this function!
* Otherwise it is impossible to distinguish a previously non-null
@@ -384,6 +387,28 @@
const unsigned char *end,
mbedtls_asn1_sequence *cur,
int tag );
+/**
+ * \brief Free a heap-allocated linked list presentation of
+ * an ASN.1 sequence, including the first element.
+ *
+ * There are two common ways to manage the memory used for the representation
+ * of a parsed ASN.1 sequence:
+ * - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc().
+ * Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of().
+ * When you have finished processing the sequence,
+ * call mbedtls_asn1_sequence_free() on `head`.
+ * - Allocate a head node `mbedtls_asn1_sequence *head` in any manner,
+ * for example on the stack. Make sure that `head->next == NULL`.
+ * Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of().
+ * When you have finished processing the sequence,
+ * call mbedtls_asn1_sequence_free() on `head->cur`,
+ * then free `head` itself in the appropriate manner.
+ *
+ * \param seq The address of the first sequence component. This may
+ * be \c NULL, in which case this functions returns
+ * immediately.
+ */
+void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq );
#if defined(MBEDTLS_BIGNUM_C)
/**
diff --git a/library/asn1parse.c b/library/asn1parse.c
index e7e4d13..3105d32 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -269,7 +269,16 @@
return( 0 );
}
-
+void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
+{
+ while( seq != NULL )
+ {
+ mbedtls_asn1_sequence *next = seq->next;
+ mbedtls_platform_zeroize( seq, sizeof( *seq ) );
+ mbedtls_free( seq );
+ seq = next;
+ }
+}
/*
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
diff --git a/tests/suites/test_suite_asn1parse.function b/tests/suites/test_suite_asn1parse.function
index f07fd40..898f729 100644
--- a/tests/suites/test_suite_asn1parse.function
+++ b/tests/suites/test_suite_asn1parse.function
@@ -508,7 +508,7 @@
int expected_result )
{
mbedtls_asn1_sequence head = { { 0, 0, NULL }, NULL };
- mbedtls_asn1_sequence *cur, *next;
+ mbedtls_asn1_sequence *cur;
unsigned char *p = input->x;
const char *rest = description;
unsigned long n;
@@ -549,13 +549,7 @@
}
exit:
- cur = head.next;
- while( cur != NULL )
- {
- next = cur->next;
- mbedtls_free( cur );
- cur = next;
- }
+ mbedtls_asn1_sequence_free( head.next );
}
/* END_CASE */