2 * Copyright (C) 2013-2015 Tobias Brunner
3 * Copyright (C) 2009 Martin Willi
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "test_suite.h"
19 #include <utils/identification.h>
21 /*******************************************************************************
22 * create (_from_encoding, _from_data, _from_string, _from_sockaddr)
25 START_TEST(test_from_encoding
)
28 chunk_t expected
, encoding
;
30 /* only ID_ANY is handled differently, for all other types the following
31 * applies. should we perhaps test that this is in fact the case? */
32 expected
= chunk_from_str("moon@strongswan.org");
33 a
= identification_create_from_encoding(ID_RFC822_ADDR
, expected
);
34 ck_assert(ID_RFC822_ADDR
== a
->get_type(a
));
35 encoding
= a
->get_encoding(a
);
36 ck_assert(expected
.ptr
!= encoding
.ptr
);
37 ck_assert(chunk_equals(expected
, encoding
));
40 a
= identification_create_from_encoding(ID_ANY
, expected
);
41 ck_assert(ID_ANY
== a
->get_type(a
));
42 encoding
= a
->get_encoding(a
);
43 ck_assert(encoding
.ptr
== NULL
);
44 ck_assert(encoding
.len
== 0);
49 START_TEST(test_from_data
)
52 chunk_t expected
, encoding
;
54 /* this uses the DN parser (C=CH) */
55 expected
= chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
56 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48);
57 a
= identification_create_from_data(expected
);
58 ck_assert(ID_DER_ASN1_DN
== a
->get_type(a
));
59 encoding
= a
->get_encoding(a
);
60 ck_assert(expected
.ptr
!= encoding
.ptr
);
61 ck_assert(chunk_equals(expected
, encoding
));
64 /* everything else is handled by the string parser */
65 expected
= chunk_from_str("moon@strongswan.org");
66 a
= identification_create_from_data(expected
);
67 ck_assert(ID_RFC822_ADDR
== a
->get_type(a
));
68 encoding
= a
->get_encoding(a
);
69 ck_assert(expected
.ptr
!= encoding
.ptr
);
70 ck_assert(chunk_equals(expected
, encoding
));
75 START_TEST(test_from_sockaddr
)
78 chunk_t expected
, encoding
;
79 struct sockaddr_in in
= {
80 .sin_family
= AF_INET
,
82 struct sockaddr_in6 in6
= {
83 .sin6_family
= AF_INET6
,
86 expected
= chunk_from_chars(0xc0, 0xa8, 0x01, 0x01);
87 memcpy(&in
.sin_addr
, expected
.ptr
, sizeof(in
.sin_addr
));
88 a
= identification_create_from_sockaddr((sockaddr_t
*)&in
);
89 ck_assert(ID_IPV4_ADDR
== a
->get_type(a
));
90 encoding
= a
->get_encoding(a
);
91 ck_assert(chunk_equals(expected
, encoding
));
94 expected
= chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
96 memcpy(&in6
.sin6_addr
, expected
.ptr
, sizeof(in6
.sin6_addr
));
97 a
= identification_create_from_sockaddr((sockaddr_t
*)&in6
);
98 ck_assert(ID_IPV6_ADDR
== a
->get_type(a
));
99 encoding
= a
->get_encoding(a
);
100 ck_assert(chunk_equals(expected
, encoding
));
103 in6
.sin6_family
= AF_UNSPEC
;
104 a
= identification_create_from_sockaddr((sockaddr_t
*)&in6
);
105 ck_assert(ID_ANY
== a
->get_type(a
));
125 {NULL
, ID_ANY
, { .type
= ENC_CHUNK
}},
126 {"", ID_ANY
, { .type
= ENC_CHUNK
}},
127 {"%any", ID_ANY
, { .type
= ENC_CHUNK
}},
128 {"%any6", ID_ANY
, { .type
= ENC_CHUNK
}},
129 {"0.0.0.0", ID_ANY
, { .type
= ENC_CHUNK
}},
130 {"0::0", ID_ANY
, { .type
= ENC_CHUNK
}},
131 {"::", ID_ANY
, { .type
= ENC_CHUNK
}},
132 {"*", ID_ANY
, { .type
= ENC_CHUNK
}},
133 {"any", ID_FQDN
, { .type
= ENC_SIMPLE
}},
134 {"any6", ID_FQDN
, { .type
= ENC_SIMPLE
}},
135 {"0", ID_FQDN
, { .type
= ENC_SIMPLE
}},
136 {"**", ID_FQDN
, { .type
= ENC_SIMPLE
}},
137 {"192.168.1.1", ID_IPV4_ADDR
, { .type
= ENC_CHUNK
,
138 .data
.c
= chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
139 {"192.168.", ID_FQDN
, { .type
= ENC_SIMPLE
}},
140 {".", ID_FQDN
, { .type
= ENC_SIMPLE
}},
141 {"fec0::1", ID_IPV6_ADDR
, { .type
= ENC_CHUNK
,
142 .data
.c
= chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
143 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01) }},
144 {"fec0::", ID_IPV6_ADDR
, { .type
= ENC_CHUNK
,
145 .data
.c
= chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
146 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) }},
147 {"fec0:", ID_KEY_ID
, { .type
= ENC_SIMPLE
}},
148 {":", ID_KEY_ID
, { .type
= ENC_SIMPLE
}},
149 {"alice@strongswan.org", ID_RFC822_ADDR
, { .type
= ENC_SIMPLE
}},
150 {"alice@strongswan", ID_RFC822_ADDR
, { .type
= ENC_SIMPLE
}},
151 {"alice@", ID_RFC822_ADDR
, { .type
= ENC_SIMPLE
}},
152 {"alice", ID_FQDN
, { .type
= ENC_SIMPLE
}},
153 {"@", ID_FQDN
, { .type
= ENC_CHUNK
}},
154 {" @", ID_RFC822_ADDR
, { .type
= ENC_SIMPLE
}},
155 {"@strongswan.org", ID_FQDN
, { .type
= ENC_STRING
,
156 .data
.s
= "strongswan.org" }},
157 {"@#deadbeef", ID_KEY_ID
, { .type
= ENC_CHUNK
,
158 .data
.c
= chunk_from_chars(0xde,0xad,0xbe,0xef) }},
159 {"@#deadbee", ID_KEY_ID
, { .type
= ENC_CHUNK
,
160 .data
.c
= chunk_from_chars(0x0d,0xea,0xdb,0xee) }},
161 {"foo=bar", ID_KEY_ID
, { .type
= ENC_SIMPLE
}},
162 {"foo=", ID_KEY_ID
, { .type
= ENC_SIMPLE
}},
163 {"=bar", ID_KEY_ID
, { .type
= ENC_SIMPLE
}},
164 {"C=", ID_DER_ASN1_DN
, { .type
= ENC_CHUNK
,
165 .data
.c
= chunk_from_chars(0x30,0x0b,0x31,0x09,0x30,0x07,0x06,
166 0x03,0x55,0x04,0x06,0x13,0x00) }},
167 {"C=CH", ID_DER_ASN1_DN
, { .type
= ENC_CHUNK
,
168 .data
.c
= chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
169 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
170 {"C=CH,", ID_DER_ASN1_DN
, { .type
= ENC_CHUNK
,
171 .data
.c
= chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
172 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
173 {"C=CH, ", ID_DER_ASN1_DN
, { .type
= ENC_CHUNK
,
174 .data
.c
= chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
175 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
176 {"C=CH, O", ID_KEY_ID
, { .type
= ENC_SIMPLE
}},
177 {"IPv4:#c0a80101", ID_IPV4_ADDR
, { .type
= ENC_CHUNK
,
178 .data
.c
= chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
179 { "email:tester", ID_RFC822_ADDR
, { .type
= ENC_STRING
,
180 .data
.s
= "tester" }},
181 { "{1}:#c0a80101", ID_IPV4_ADDR
, { .type
= ENC_CHUNK
,
182 .data
.c
= chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
183 { "{0x02}:tester", ID_FQDN
, { .type
= ENC_STRING
,
184 .data
.s
= "tester" }},
185 { "{99}:somedata", 99, { .type
= ENC_STRING
,
186 .data
.s
= "somedata" }},
189 START_TEST(test_from_string
)
192 chunk_t encoding
, expected
= chunk_empty
;
195 id
= string_data
[_i
].id
;
196 a
= identification_create_from_string(id
);
197 fail_unless(a
->get_type(a
) == string_data
[_i
].type
,
198 "type of id '%s' is %N, %N expected", id
,
199 id_type_names
, a
->get_type(a
),
200 id_type_names
, string_data
[_i
].type
);
202 encoding
= a
->get_encoding(a
);
203 switch (string_data
[_i
].result
.type
)
206 expected
= chunk_from_str(string_data
[_i
].id
);
209 expected
= chunk_from_str(string_data
[_i
].result
.data
.s
);
212 expected
= string_data
[_i
].result
.data
.c
;
215 fail("unexpected result type");
218 ck_assert(!id
|| (char*)encoding
.ptr
!= id
);
221 fail_unless(chunk_equals(encoding
, expected
),
222 "parsing '%s' failed\nencoding %B\nexpected %B\n",
223 id
, &encoding
, &expected
);
227 ck_assert(encoding
.ptr
== NULL
);
228 ck_assert(encoding
.len
== 0);
234 /*******************************************************************************
238 static void string_equals(char *a_str
, char *b_str
)
243 b
= b_str ?
identification_create_from_string(b_str
) : NULL
;
244 snprintf(buf
, sizeof(buf
), "%Y", b
);
246 ck_assert_str_eq(a_str
, buf
);
249 static void string_equals_id(char *a_str
, identification_t
*b
)
253 snprintf(buf
, sizeof(buf
), "%Y", b
);
255 ck_assert_str_eq(a_str
, buf
);
258 START_TEST(test_printf_hook
)
260 string_equals("(null)", NULL
);
261 string_equals("%any", "");
262 string_equals("%any", "%any");
263 string_equals("%any", "*");
265 string_equals("192.168.1.1", "192.168.1.1");
266 string_equals_id("(invalid ID_IPV4_ADDR)",
267 identification_create_from_encoding(ID_IPV4_ADDR
, chunk_empty
));
268 string_equals("fec0::1", "fec0::1");
269 string_equals("fec0::1", "fec0:0:0::1");
270 string_equals_id("(invalid ID_IPV6_ADDR)",
271 identification_create_from_encoding(ID_IPV6_ADDR
, chunk_empty
));
273 string_equals_id("(unknown ID type: 255)",
274 identification_create_from_encoding(255, chunk_empty
));
276 string_equals("moon@strongswan.org", "moon@strongswan.org");
277 string_equals("MOON@STRONGSWAN.ORG", "MOON@STRONGSWAN.ORG");
278 /* non-printable characters */
279 string_equals_id("????@strongswan.org", identification_create_from_encoding(ID_RFC822_ADDR
,
280 chunk_from_chars(0xfa, 0xfb, 0xfc, 0xfd, 0x40, 0x73, 0x74, 0x72,
281 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
284 /* not a DN => ID_KEY_ID => no normalization */
285 string_equals("C=CH, AsdF=asdf", "C=CH, AsdF=asdf");
286 string_equals_id("moon@strongswan.org", identification_create_from_encoding(ID_KEY_ID
,
287 chunk_from_str("moon@strongswan.org")));
288 /* non-printable characters */
289 string_equals_id("de:ad:be:ef", identification_create_from_encoding(ID_KEY_ID
,
290 chunk_from_chars(0xde, 0xad, 0xbe, 0xef)));
291 /* printable characters */
292 string_equals_id("ABCDEFGHIJKLMNOPQRS",
293 identification_create_from_encoding(ID_KEY_ID
,
294 chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
295 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
297 /* ABCDEFGHIJKLMNOPQRST is printable but has the length of a SHA1 hash */
298 string_equals_id("41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54",
299 identification_create_from_encoding(ID_KEY_ID
,
300 chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
301 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
302 0x51, 0x52, 0x53, 0x54)));
304 string_equals_id("", identification_create_from_encoding(ID_DER_ASN1_DN
, chunk_empty
));
305 string_equals("C=", "C=");
306 string_equals("C=", "C=,");
307 string_equals("C=", "C=, ");
308 string_equals("C=", "C= , ");
309 string_equals("C=, O=strongSwan", "C=, O=strongSwan");
310 string_equals("C=CH, O=", "C=CH, O=");
311 string_equals("C=CH, O=strongSwan, CN=strongswan.org",
312 "C=CH, O=strongSwan, CN=strongswan.org");
313 string_equals("CN=strongswan.org, O=strongSwan, C=CH",
314 "cn=strongswan.org, o=strongSwan, c=CH");
315 string_equals("C=CH, O=strongSwan, CN=strongswan.org",
316 "C=CH,O=strongSwan,CN=strongswan.org");
317 string_equals("C=CH, O=strongSwan, CN=strongswan.org",
318 "/C=CH/O=strongSwan/CN=strongswan.org");
319 string_equals("CN=strongswan.org, O=strongSwan, C=CH",
320 "CN=strongswan.org,O=strongSwan,C=CH");
322 string_equals("C=CH, E=moon@strongswan.org, CN=moon",
323 "C=CH, email=moon@strongswan.org, CN=moon");
324 string_equals("C=CH, E=moon@strongswan.org, CN=moon",
325 "C=CH, emailAddress=moon@strongswan.org, CN=moon");
327 /* C=CH, telexNumber=123 (telexNumber is currently not recognized) */
328 string_equals_id("C=CH, 55:04:15=123", identification_create_from_encoding(ID_DER_ASN1_DN
,
329 chunk_from_chars(0x30, 0x19, 0x31, 0x17, 0x30, 0x09, 0x06, 0x03, 0x55,
330 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x0a, 0x06,
331 0x03, 0x55, 0x04, 0x15, 0x13, 0x03, 0x31, 0x32, 0x33)));
332 /* C=CH, O=strongSwan (but instead of a 2nd OID -0x06- we got NULL -0x05) */
333 string_equals_id("C=CH, (invalid ID_DER_ASN1_DN)", identification_create_from_encoding(ID_DER_ASN1_DN
,
334 chunk_from_chars(0x30, 0x20, 0x31, 0x1e, 0x30, 0x09, 0x06, 0x03, 0x55,
335 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x11, 0x05,
336 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x73, 0x74, 0x72,
337 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e)));
338 /* moon@strongswan.org as GN */
339 string_equals_id("(ASN.1 general name)", identification_create_from_encoding(ID_DER_ASN1_GN
,
340 chunk_from_chars(0x81, 0x14, 0x6d, 0x6f, 0x6f, 0x6e, 0x40, 0x73, 0x74,
341 0x72, 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
346 START_TEST(test_printf_hook_width
)
351 a
= identification_create_from_string("moon@strongswan.org");
352 snprintf(buf
, sizeof(buf
), "%25Y", a
);
353 ck_assert_str_eq(" moon@strongswan.org", buf
);
354 snprintf(buf
, sizeof(buf
), "%-*Y", 25, a
);
355 ck_assert_str_eq("moon@strongswan.org ", buf
);
356 snprintf(buf
, sizeof(buf
), "%5Y", a
);
357 ck_assert_str_eq("moon@strongswan.org", buf
);
362 /*******************************************************************************
366 static bool id_equals(identification_t
*a
, char *b_str
)
371 b
= identification_create_from_string(b_str
);
372 equals
= a
->equals(a
, b
);
373 ck_assert_int_eq(equals
, b
->equals(b
, a
));
378 START_TEST(test_equals
)
381 chunk_t encoding
, fuzzed
;
384 /* this test also tests identification_create_from_string with DNs */
385 a
= identification_create_from_string(
386 "C=CH, E=moon@strongswan.org, CN=moon");
388 ck_assert(id_equals(a
, "C=CH, E=moon@strongswan.org, CN=moon"));
389 ck_assert(id_equals(a
, "C==CH , E==moon@strongswan.org , CN==moon"));
390 ck_assert(id_equals(a
, " C=CH, E=moon@strongswan.org, CN=moon "));
391 ck_assert(id_equals(a
, "C=ch, E=moon@STRONGSWAN.ORG, CN=Moon"));
392 ck_assert(id_equals(a
, "/C=CH/E=moon@strongswan.org/CN=moon"));
393 ck_assert(id_equals(a
, " / C=CH / E=moon@strongswan.org / CN=moon"));
395 ck_assert(!id_equals(a
, "C=CH/E=moon@strongswan.org/CN=moon"));
396 ck_assert(!id_equals(a
, "C=CH/E=moon@strongswan.org,CN=moon"));
397 ck_assert(!id_equals(a
, "C=CH E=moon@strongswan.org CN=moon"));
398 ck_assert(!id_equals(a
, "C=CN, E=moon@strongswan.org, CN=moon"));
399 ck_assert(!id_equals(a
, "E=moon@strongswan.org, C=CH, CN=moon"));
400 ck_assert(!id_equals(a
, "E=moon@strongswan.org, C=CH, CN=moon"));
402 encoding
= chunk_clone(a
->get_encoding(a
));
405 /* simple fuzzing, increment each byte of encoding */
406 for (i
= 0; i
< encoding
.len
; i
++)
408 if (i
== 11 || i
== 30 || i
== 60)
409 { /* skip ASN.1 type fields, as equals() handles them graceful */
412 fuzzed
= chunk_clone(encoding
);
414 a
= identification_create_from_encoding(ID_DER_ASN1_DN
, fuzzed
);
415 if (id_equals(a
, "C=CH, E=moon@strongswan.org, CN=moon"))
417 printf("%d %B\n%B\n", i
, &fuzzed
, &encoding
);
419 ck_assert(!id_equals(a
, "C=CH, E=moon@strongswan.org, CN=moon"));
424 /* and decrement each byte of encoding */
425 for (i
= 0; i
< encoding
.len
; i
++)
427 if (i
== 11 || i
== 30 || i
== 60)
431 fuzzed
= chunk_clone(encoding
);
433 a
= identification_create_from_encoding(ID_DER_ASN1_DN
, fuzzed
);
434 ck_assert(!id_equals(a
, "C=CH, E=moon@strongswan.org, CN=moon"));
442 START_TEST(test_equals_any
)
444 identification_t
*a
, *b
;
446 a
= identification_create_from_string("%any");
447 b
= identification_create_from_encoding(ID_ANY
, chunk_empty
);
448 ck_assert(a
->equals(a
, b
));
449 ck_assert(b
->equals(b
, a
));
452 b
= identification_create_from_string("C=CH, O=strongSwan, CN=strongswan.org");
453 ck_assert(!a
->equals(a
, b
));
454 ck_assert(!b
->equals(b
, a
));
460 START_TEST(test_equals_binary
)
462 identification_t
*a
, *b
;
465 encoding
= chunk_from_str("foobar=");
466 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
467 a
= identification_create_from_string("foobar=");
468 ck_assert(a
->get_type(a
) == ID_KEY_ID
);
469 b
= identification_create_from_encoding(ID_KEY_ID
, encoding
);
470 ck_assert(a
->equals(a
, b
));
476 START_TEST(test_equals_fqdn
)
480 a
= identification_create_from_string("ipsec.strongswan.org");
481 ck_assert(id_equals(a
, "IPSEC.strongswan.org"));
482 ck_assert(id_equals(a
, "ipsec.strongSwan.org"));
483 ck_assert(id_equals(a
, "ipsec.strongSwan.ORG"));
484 ck_assert(!id_equals(a
, "strongswan.org"));
489 START_TEST(test_equals_empty
)
493 a
= identification_create_from_encoding(_i
, chunk_empty
);
498 ck_assert(id_equals(a
, "%any"));
501 ck_assert(!id_equals(a
, "192.168.1.1"));
504 ck_assert(!id_equals(a
, "moon.strongswan.org"));
507 ck_assert(!id_equals(a
, "moon@strongswan.org"));
510 ck_assert(!id_equals(a
, "fec0::1"));
513 ck_assert(!id_equals(a
, "C=CH, E=moon@strongswan.org, CN=moon"));
516 ck_assert(!id_equals(a
, "@#12345678"));
519 case ID_IPV4_ADDR_SUBNET
:
520 case ID_IPV6_ADDR_SUBNET
:
521 case ID_IPV4_ADDR_RANGE
:
522 case ID_IPV6_ADDR_RANGE
:
523 /* currently not tested */
531 /*******************************************************************************
535 static bool id_matches(identification_t
*a
, char *b_str
, id_match_t expected
)
540 b
= identification_create_from_string(b_str
);
541 match
= a
->matches(a
, b
);
543 return match
== expected
;
546 START_TEST(test_matches
)
550 a
= identification_create_from_string("C=CH, E=moon@strongswan.org, CN=moon");
552 ck_assert(id_matches(a
, "C=CH, E=moon@strongswan.org, CN=moon", ID_MATCH_PERFECT
));
553 ck_assert(id_matches(a
, "C=CH, E=*@strongswan.org, CN=moon", ID_MATCH_NONE
));
554 ck_assert(id_matches(a
, "C=CH, E=*, CN=moon", ID_MATCH_ONE_WILDCARD
));
555 ck_assert(id_matches(a
, "C=CH, E=*, CN=*", ID_MATCH_ONE_WILDCARD
- 1));
556 ck_assert(id_matches(a
, "C=*, E=*, CN=*", ID_MATCH_ONE_WILDCARD
- 2));
557 ck_assert(id_matches(a
, "C=*, E=*, CN=*, O=BADInc", ID_MATCH_NONE
));
558 ck_assert(id_matches(a
, "C=*, E=*", ID_MATCH_NONE
));
559 ck_assert(id_matches(a
, "C=*, E=a@b.c, CN=*", ID_MATCH_NONE
));
560 ck_assert(id_matches(a
, "%any", ID_MATCH_ANY
));
566 START_TEST(test_matches_any
)
570 a
= identification_create_from_string("%any");
572 ck_assert(id_matches(a
, "%any", ID_MATCH_ANY
));
573 ck_assert(id_matches(a
, "", ID_MATCH_ANY
));
574 ck_assert(id_matches(a
, "*", ID_MATCH_ANY
));
575 ck_assert(id_matches(a
, "moon@strongswan.org", ID_MATCH_NONE
));
576 ck_assert(id_matches(a
, "vpn.strongswan.org", ID_MATCH_NONE
));
581 START_TEST(test_matches_binary
)
585 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
586 a
= identification_create_from_string("foo=bar");
587 ck_assert(a
->get_type(a
) == ID_KEY_ID
);
588 ck_assert(id_matches(a
, "%any", ID_MATCH_ANY
));
589 ck_assert(id_matches(a
, "foo=bar", ID_MATCH_PERFECT
));
590 ck_assert(id_matches(a
, "bar=foo", ID_MATCH_NONE
));
591 ck_assert(id_matches(a
, "*=bar", ID_MATCH_NONE
));
592 ck_assert(id_matches(a
, "foo=*", ID_MATCH_NONE
));
593 ck_assert(id_matches(a
, "foo@bar", ID_MATCH_NONE
));
598 START_TEST(test_matches_string
)
602 a
= identification_create_from_string("moon@strongswan.org");
604 ck_assert(id_matches(a
, "moon@strongswan.org", ID_MATCH_PERFECT
));
605 ck_assert(id_matches(a
, "*@strongswan.org", ID_MATCH_ONE_WILDCARD
));
606 ck_assert(id_matches(a
, "*@*.org", ID_MATCH_NONE
));
607 ck_assert(id_matches(a
, "*@*", ID_MATCH_NONE
));
608 /* the following two are parsed as ID_FQDN, so no match */
609 ck_assert(id_matches(a
, "*strongswan.org", ID_MATCH_NONE
));
610 ck_assert(id_matches(a
, "*.org", ID_MATCH_NONE
));
611 ck_assert(id_matches(a
, "moon@*", ID_MATCH_NONE
));
612 ck_assert(id_matches(a
, "**", ID_MATCH_NONE
));
613 ck_assert(id_matches(a
, "*", ID_MATCH_ANY
));
614 ck_assert(id_matches(a
, "%any", ID_MATCH_ANY
));
617 a
= identification_create_from_string("vpn.strongswan.org");
619 ck_assert(id_matches(a
, "vpn.strongswan.org", ID_MATCH_PERFECT
));
620 ck_assert(id_matches(a
, "*.strongswan.org", ID_MATCH_ONE_WILDCARD
));
621 ck_assert(id_matches(a
, "*strongswan.org", ID_MATCH_ONE_WILDCARD
));
622 ck_assert(id_matches(a
, "*.org", ID_MATCH_ONE_WILDCARD
));
623 ck_assert(id_matches(a
, "*.strongswan.*", ID_MATCH_NONE
));
624 ck_assert(id_matches(a
, "*vpn.strongswan.org", ID_MATCH_NONE
));
625 ck_assert(id_matches(a
, "vpn.strongswan.*", ID_MATCH_NONE
));
626 ck_assert(id_matches(a
, "**", ID_MATCH_NONE
));
627 ck_assert(id_matches(a
, "*", ID_MATCH_ANY
));
628 ck_assert(id_matches(a
, "%any", ID_MATCH_ANY
));
633 START_TEST(test_matches_empty
)
637 a
= identification_create_from_encoding(_i
, chunk_empty
);
642 ck_assert(id_matches(a
, "%any", ID_MATCH_ANY
));
645 ck_assert(id_matches(a
, "192.168.1.1", ID_MATCH_NONE
));
648 ck_assert(id_matches(a
, "moon.strongswan.org", ID_MATCH_NONE
));
651 ck_assert(id_matches(a
, "moon@strongswan.org", ID_MATCH_NONE
));
654 ck_assert(id_matches(a
, "fec0::1", ID_MATCH_NONE
));
657 ck_assert(id_matches(a
, "C=CH, E=moon@strongswan.org, CN=moon",
661 ck_assert(id_matches(a
, "@#12345678", ID_MATCH_NONE
));
664 case ID_IPV4_ADDR_SUBNET
:
665 case ID_IPV6_ADDR_SUBNET
:
666 case ID_IPV4_ADDR_RANGE
:
667 case ID_IPV6_ADDR_RANGE
:
668 /* currently not tested */
676 static bool id_matches_rev(identification_t
*a
, char *b_str
, id_match_t expected
)
681 b
= identification_create_from_string(b_str
);
682 match
= b
->matches(b
, a
);
684 return match
== expected
;
687 START_TEST(test_matches_empty_reverse
)
691 a
= identification_create_from_encoding(_i
, chunk_empty
);
696 ck_assert(id_matches_rev(a
, "%any", ID_MATCH_ANY
));
699 ck_assert(id_matches_rev(a
, "192.168.1.1", ID_MATCH_NONE
));
702 ck_assert(id_matches_rev(a
, "moon.strongswan.org", ID_MATCH_NONE
));
705 ck_assert(id_matches_rev(a
, "moon@strongswan.org", ID_MATCH_NONE
));
708 ck_assert(id_matches_rev(a
, "fec0::1", ID_MATCH_NONE
));
711 ck_assert(id_matches_rev(a
, "C=CH, E=moon@strongswan.org, CN=moon",
715 ck_assert(id_matches_rev(a
, "@#12345678", ID_MATCH_NONE
));
718 case ID_IPV4_ADDR_SUBNET
:
719 case ID_IPV6_ADDR_SUBNET
:
720 case ID_IPV4_ADDR_RANGE
:
721 case ID_IPV6_ADDR_RANGE
:
722 /* currently not tested */
730 /*******************************************************************************
731 * identification hashing
734 static bool id_hash_equals(char *str
, char *b_str
)
736 identification_t
*a
, *b
;
737 bool success
= FALSE
;
739 a
= identification_create_from_string(str
);
740 b
= identification_create_from_string(b_str ?
: str
);
741 success
= a
->hash(a
, 0) == b
->hash(b
, 0);
747 START_TEST(test_hash
)
749 ck_assert(id_hash_equals("moon@strongswan.org", NULL
));
750 ck_assert(id_hash_equals("vpn.strongswan.org", NULL
));
751 ck_assert(id_hash_equals("192.168.1.1", NULL
));
752 ck_assert(id_hash_equals("C=CH", NULL
));
754 ck_assert(!id_hash_equals("moon@strongswan.org", "sun@strongswan.org"));
755 ck_assert(!id_hash_equals("vpn.strongswan.org", "*.strongswan.org"));
756 ck_assert(!id_hash_equals("192.168.1.1", "192.168.1.2"));
757 ck_assert(!id_hash_equals("C=CH", "C=DE"));
758 ck_assert(!id_hash_equals("fqdn:strongswan.org", "keyid:strongswan.org"));
762 START_TEST(test_hash_any
)
764 ck_assert(id_hash_equals("%any", NULL
));
765 ck_assert(id_hash_equals("%any", "0.0.0.0"));
766 ck_assert(id_hash_equals("%any", "*"));
767 ck_assert(id_hash_equals("%any", ""));
769 ck_assert(!id_hash_equals("%any", "any"));
773 START_TEST(test_hash_dn
)
775 identification_t
*a
, *b
;
777 /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
779 a
= identification_create_from_data(chunk_from_chars(
780 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
781 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31,
782 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
783 0x13, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
784 0x53, 0x77, 0x61, 0x6e));
785 b
= identification_create_from_data(chunk_from_chars(
786 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
787 0x55, 0x04, 0x06, 0x0c, 0x02, 0x43, 0x48, 0x31,
788 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
789 0x0c, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
790 0x53, 0x77, 0x61, 0x6e));
791 ck_assert_int_eq(a
->hash(a
, 0), b
->hash(b
, 0));
792 ck_assert(a
->equals(a
, b
));
798 START_TEST(test_hash_inc
)
802 a
= identification_create_from_string("vpn.strongswan.org");
803 ck_assert(a
->hash(a
, 0) != a
->hash(a
, 1));
806 a
= identification_create_from_string("C=CH, O=strongSwan");
807 ck_assert(a
->hash(a
, 0) != a
->hash(a
, 1));
812 /*******************************************************************************
813 * identification part enumeration
816 START_TEST(test_parts
)
818 identification_t
*id
;
819 enumerator_t
*enumerator
;
824 id
= identification_create_from_string("C=CH, O=strongSwan, CN=tester");
826 enumerator
= id
->create_part_enumerator(id
);
827 while (enumerator
->enumerate(enumerator
, &part
, &data
))
832 ck_assert(part
== ID_PART_RDN_C
&&
833 chunk_equals(data
, chunk_create("CH", 2)));
836 ck_assert(part
== ID_PART_RDN_O
&&
837 chunk_equals(data
, chunk_from_str("strongSwan")));
840 ck_assert(part
== ID_PART_RDN_CN
&&
841 chunk_equals(data
, chunk_from_str("tester")));
844 fail("unexpected identification part %d", part
);
847 ck_assert_int_eq(i
, 3);
848 enumerator
->destroy(enumerator
);
853 /*******************************************************************************
857 static bool id_contains_wildcards(char *string
)
859 identification_t
*id
;
862 id
= identification_create_from_string(string
);
863 contains
= id
->contains_wildcards(id
);
868 START_TEST(test_contains_wildcards
)
870 ck_assert(id_contains_wildcards("%any"));
871 ck_assert(id_contains_wildcards("C=*, O=strongSwan, CN=gw"));
872 ck_assert(id_contains_wildcards("C=CH, O=strongSwan, CN=*"));
873 ck_assert(id_contains_wildcards("*@strongswan.org"));
874 ck_assert(id_contains_wildcards("*.strongswan.org"));
875 ck_assert(!id_contains_wildcards("C=**, O=a*, CN=*a"));
879 /*******************************************************************************
883 START_TEST(test_clone
)
885 identification_t
*a
, *b
;
886 chunk_t a_enc
, b_enc
;
888 a
= identification_create_from_string("moon@strongswan.org");
889 a_enc
= a
->get_encoding(a
);
891 ck_assert(b
!= NULL
);
893 b_enc
= b
->get_encoding(b
);
894 ck_assert(a_enc
.ptr
!= b_enc
.ptr
);
895 ck_assert(chunk_equals(a_enc
, b_enc
));
901 Suite
*identification_suite_create()
906 s
= suite_create("identification");
908 tc
= tcase_create("create");
909 tcase_add_test(tc
, test_from_encoding
);
910 tcase_add_test(tc
, test_from_data
);
911 tcase_add_test(tc
, test_from_sockaddr
);
912 tcase_add_loop_test(tc
, test_from_string
, 0, countof(string_data
));
913 suite_add_tcase(s
, tc
);
915 tc
= tcase_create("printf_hook");
916 tcase_add_test(tc
, test_printf_hook
);
917 tcase_add_test(tc
, test_printf_hook_width
);
918 suite_add_tcase(s
, tc
);
920 tc
= tcase_create("equals");
921 tcase_add_test(tc
, test_equals
);
922 tcase_add_test(tc
, test_equals_any
);
923 tcase_add_test(tc
, test_equals_binary
);
924 tcase_add_test(tc
, test_equals_fqdn
);
925 tcase_add_loop_test(tc
, test_equals_empty
, ID_ANY
, ID_KEY_ID
+ 1);
926 suite_add_tcase(s
, tc
);
928 tc
= tcase_create("matches");
929 tcase_add_test(tc
, test_matches
);
930 tcase_add_test(tc
, test_matches_any
);
931 tcase_add_test(tc
, test_matches_binary
);
932 tcase_add_test(tc
, test_matches_string
);
933 tcase_add_loop_test(tc
, test_matches_empty
, ID_ANY
, ID_KEY_ID
+ 1);
934 tcase_add_loop_test(tc
, test_matches_empty_reverse
, ID_ANY
, ID_KEY_ID
+ 1);
935 suite_add_tcase(s
, tc
);
937 tc
= tcase_create("hash");
938 tcase_add_test(tc
, test_hash
);
939 tcase_add_test(tc
, test_hash_any
);
940 tcase_add_test(tc
, test_hash_dn
);
941 tcase_add_test(tc
, test_hash_inc
);
942 suite_add_tcase(s
, tc
);
944 tc
= tcase_create("part enumeration");
945 tcase_add_test(tc
, test_parts
);
946 suite_add_tcase(s
, tc
);
948 tc
= tcase_create("wildcards");
949 tcase_add_test(tc
, test_contains_wildcards
);
950 suite_add_tcase(s
, tc
);
952 tc
= tcase_create("clone");
953 tcase_add_test(tc
, test_clone
);
954 suite_add_tcase(s
, tc
);