identification: Validate ASN.1 DN in from_data() constructor

The DN is otherwise not parsed until compared/printed.  This avoids
false detections as ASN.1 DN if e.g. an email address starts with "0",
which is 0x30 = ASN.1 sequence tag, and the next character denotes
the exact length of the rest of the string (see the unit tests for an
example).
This commit is contained in:
Tobias Brunner
2020-12-03 08:23:54 +01:00
parent 4c61d7aedc
commit e8fae43768
2 changed files with 43 additions and 1 deletions
+26 -1
View File
@@ -867,6 +867,31 @@ static bool compare_dn(chunk_t t_dn, chunk_t o_dn, int *wc)
return finished;
}
/**
* Check if the data in the given chunk represents a valid DN.
*/
static bool is_valid_dn(chunk_t dn)
{
enumerator_t *enumerator;
chunk_t oid, data;
u_char type;
bool finished = FALSE;
enumerator = create_rdn_enumerator(dn);
while (enumerator->enumerate(enumerator, &oid, &type, &data))
{
/* the enumerator returns FALSE on parse error, we are finished
* if we have reached the end of the DN only */
if ((data.ptr + data.len == dn.ptr + dn.len))
{
finished = TRUE;
}
}
enumerator->destroy(enumerator);
return finished;
}
METHOD(identification_t, equals_dn, bool,
private_identification_t *this, identification_t *other)
{
@@ -1713,7 +1738,7 @@ identification_t * identification_create_from_data(chunk_t data)
{
char buf[data.len + 1];
if (is_asn1(data))
if (is_asn1(data) && is_valid_dn(data))
{
return identification_create_from_encoding(ID_DER_ASN1_DN, data);
}