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-11-02 15:09:13 +01:00
parent 4c61d7aedc
commit e8fae43768
2 changed files with 43 additions and 1 deletions

View File

@ -62,6 +62,23 @@ START_TEST(test_from_data)
ck_assert(chunk_equals(expected, encoding));
a->destroy(a);
/* this is not actually ASN.1, even though it starts with 0x30 and the
* correct length (0x31=49) */
expected = chunk_from_str("01234567-aaaa-bbbb-cccc-ddddeeeeffff@strongswan.org");
a = identification_create_from_data(chunk_from_chars(
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x2d,0x61,0x61,0x61,0x61,0x2d,0x62,0x62,
0x62,0x62,0x2d,0x63,0x63,0x63,0x63,0x2d,
0x64,0x64,0x64,0x64,0x65,0x65,0x65,0x65,
0x66,0x66,0x66,0x66,0x40,0x73,0x74,0x72,
0x6f,0x6e,0x67,0x73,0x77,0x61,0x6e,0x2e,
0x6f,0x72,0x67));
ck_assert(ID_RFC822_ADDR == a->get_type(a));
encoding = a->get_encoding(a);
ck_assert(expected.ptr != encoding.ptr);
ck_assert(chunk_equals(expected, encoding));
a->destroy(a);
/* everything else is handled by the string parser */
expected = chunk_from_str("moon@strongswan.org");
a = identification_create_from_data(expected);

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);
}