ASN.1: Introduce helper function to free ASN.1 sequence

This commit is contained in:
Hanno Becker 2019-09-11 14:20:09 +01:00
parent 63e38fe914
commit 12ae27dd0e
3 changed files with 37 additions and 9 deletions

View File

@ -343,6 +343,9 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p,
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>". * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
* Updates the pointer to immediately behind the full sequence 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. * \note On error, this function may return a partial list in \p cur.
* You must set `cur->next = NULL` before calling this function! * You must set `cur->next = NULL` before calling this function!
* Otherwise it is impossible to distinguish a previously non-null * Otherwise it is impossible to distinguish a previously non-null
@ -384,6 +387,28 @@ int mbedtls_asn1_get_sequence_of( unsigned char **p,
const unsigned char *end, const unsigned char *end,
mbedtls_asn1_sequence *cur, mbedtls_asn1_sequence *cur,
int tag ); 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) #if defined(MBEDTLS_BIGNUM_C)
/** /**

View File

@ -269,7 +269,16 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end
return( 0 ); 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>" * Parses and splits an ASN.1 "SEQUENCE OF <tag>"

View File

@ -508,7 +508,7 @@ void get_sequence_of( const data_t *input, int tag,
int expected_result ) int expected_result )
{ {
mbedtls_asn1_sequence head = { { 0, 0, NULL }, NULL }; mbedtls_asn1_sequence head = { { 0, 0, NULL }, NULL };
mbedtls_asn1_sequence *cur, *next; mbedtls_asn1_sequence *cur;
unsigned char *p = input->x; unsigned char *p = input->x;
const char *rest = description; const char *rest = description;
unsigned long n; unsigned long n;
@ -549,13 +549,7 @@ void get_sequence_of( const data_t *input, int tag,
} }
exit: exit:
cur = head.next; mbedtls_asn1_sequence_free( head.next );
while( cur != NULL )
{
next = cur->next;
mbedtls_free( cur );
cur = next;
}
} }
/* END_CASE */ /* END_CASE */