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:
parent
4c61d7aedc
commit
e8fae43768
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue