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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user