]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libstrongswan/tests/suites/test_identification.c
unit-tests: The pseudonym RDN is now recognized, so use something more exotic
[thirdparty/strongswan.git] / src / libstrongswan / tests / suites / test_identification.c
CommitLineData
0298be57 1/*
520fba48 2 * Copyright (C) 2013-2015 Tobias Brunner
0298be57
TB
3 * Copyright (C) 2009 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
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>.
10 *
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
14 * for more details.
15 */
16
95e99150 17#include "test_suite.h"
0298be57
TB
18
19#include <utils/identification.h>
20
06f6d802
TB
21/*******************************************************************************
22 * create (_from_encoding, _from_data, _from_string, _from_sockaddr)
23 */
24
25START_TEST(test_from_encoding)
26{
27 identification_t *a;
28 chunk_t expected, encoding;
29
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));
38 a->destroy(a);
39
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);
45 a->destroy(a);
46}
47END_TEST
48
49START_TEST(test_from_data)
50{
51 identification_t *a;
52 chunk_t expected, encoding;
53
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));
62 a->destroy(a);
63
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));
71 a->destroy(a);
72}
73END_TEST
74
75START_TEST(test_from_sockaddr)
76{
77 identification_t *a;
78 chunk_t expected, encoding;
79 struct sockaddr_in in = {
80 .sin_family = AF_INET,
81 };
82 struct sockaddr_in6 in6 = {
83 .sin6_family = AF_INET6,
84 };
85
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));
92 a->destroy(a);
93
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));
101 a->destroy(a);
102
103 in6.sin6_family = AF_UNSPEC;
104 a = identification_create_from_sockaddr((sockaddr_t*)&in6);
105 ck_assert(ID_ANY == a->get_type(a));
106 a->destroy(a);
107}
108END_TEST
109
110static struct {
111 char *id;
112 id_type_t type;
113 struct {
114 enum {
115 ENC_CHUNK,
116 ENC_STRING,
117 ENC_SIMPLE,
118 } type;
119 union {
120 chunk_t c;
121 char *s;
122 } data;
123 } result;
124} string_data[] = {
46001e11
MW
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 }},
c0da835a
MW
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" }},
65283387
MW
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" }},
06f6d802
TB
187};
188
189START_TEST(test_from_string)
190{
191 identification_t *a;
1254ad01 192 chunk_t encoding, expected = chunk_empty;
06f6d802
TB
193 char *id;
194
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);
201
202 encoding = a->get_encoding(a);
203 switch (string_data[_i].result.type)
204 {
205 case ENC_SIMPLE:
206 expected = chunk_from_str(string_data[_i].id);
207 break;
208 case ENC_STRING:
209 expected = chunk_from_str(string_data[_i].result.data.s);
210 break;
211 case ENC_CHUNK:
212 expected = string_data[_i].result.data.c;
213 break;
214 default:
215 fail("unexpected result type");
216 }
217
218 ck_assert(!id || (char*)encoding.ptr != id);
219 if (expected.ptr)
220 {
221 fail_unless(chunk_equals(encoding, expected),
222 "parsing '%s' failed\nencoding %B\nexpected %B\n",
223 id, &encoding, &expected);
224 }
225 else
226 {
227 ck_assert(encoding.ptr == NULL);
228 ck_assert(encoding.len == 0);
229 }
230 a->destroy(a);
231}
232END_TEST
233
234/*******************************************************************************
235 * printf_hook
236 */
237
238static void string_equals(char *a_str, char *b_str)
239{
240 identification_t *b;
241 char buf[128];
242
243 b = b_str ? identification_create_from_string(b_str) : NULL;
244 snprintf(buf, sizeof(buf), "%Y", b);
245 DESTROY_IF(b);
246 ck_assert_str_eq(a_str, buf);
247}
248
249static void string_equals_id(char *a_str, identification_t *b)
250{
251 char buf[128];
252
253 snprintf(buf, sizeof(buf), "%Y", b);
254 DESTROY_IF(b);
255 ck_assert_str_eq(a_str, buf);
256}
257
258START_TEST(test_printf_hook)
259{
260 string_equals("(null)", NULL);
261 string_equals("%any", "");
262 string_equals("%any", "%any");
263 string_equals("%any", "*");
264
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));
272
273 string_equals_id("(unknown ID type: 255)",
274 identification_create_from_encoding(255, chunk_empty));
275
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,
282 0x6f, 0x72, 0x67)));
283
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,
296 0x51, 0x52, 0x53)));
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)));
303
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");
321
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");
326
fbbbe43e
TB
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,
06f6d802
TB
329 chunk_from_chars(0x30, 0x19, 0x31, 0x17, 0x30, 0x09, 0x06, 0x03, 0x55,
330 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x0a, 0x06,
fbbbe43e 331 0x03, 0x55, 0x04, 0x15, 0x13, 0x03, 0x31, 0x32, 0x33)));
06f6d802
TB
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,
342 0x6f, 0x72, 0x67)));
343}
344END_TEST
345
346START_TEST(test_printf_hook_width)
347{
348 identification_t *a;
349 char buf[128];
350
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);
358 DESTROY_IF(a);
359}
360END_TEST
361
0298be57
TB
362/*******************************************************************************
363 * equals
364 */
365
366static bool id_equals(identification_t *a, char *b_str)
367{
368 identification_t *b;
369 bool equals;
370
371 b = identification_create_from_string(b_str);
372 equals = a->equals(a, b);
c409be25 373 ck_assert_int_eq(equals, b->equals(b, a));
0298be57
TB
374 b->destroy(b);
375 return equals;
376}
377
378START_TEST(test_equals)
379{
380 identification_t *a;
381 chunk_t encoding, fuzzed;
382 int i;
383
06f6d802 384 /* this test also tests identification_create_from_string with DNs */
0298be57 385 a = identification_create_from_string(
06f6d802
TB
386 "C=CH, E=moon@strongswan.org, CN=moon");
387
388 ck_assert(id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
aba55fdf 389 ck_assert(id_equals(a, "C==CH , E==moon@strongswan.org , CN==moon"));
06f6d802
TB
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"));
aba55fdf 393 ck_assert(id_equals(a, " / C=CH / E=moon@strongswan.org / CN=moon"));
06f6d802 394
aba55fdf
TB
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"));
06f6d802
TB
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"));
0298be57
TB
401
402 encoding = chunk_clone(a->get_encoding(a));
403 a->destroy(a);
404
405 /* simple fuzzing, increment each byte of encoding */
406 for (i = 0; i < encoding.len; i++)
407 {
06f6d802 408 if (i == 11 || i == 30 || i == 60)
0298be57
TB
409 { /* skip ASN.1 type fields, as equals() handles them graceful */
410 continue;
411 }
412 fuzzed = chunk_clone(encoding);
413 fuzzed.ptr[i]++;
414 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
06f6d802
TB
415 if (id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"))
416 {
417 printf("%d %B\n%B\n", i, &fuzzed, &encoding);
418 }
419 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
0298be57
TB
420 a->destroy(a);
421 free(fuzzed.ptr);
422 }
423
424 /* and decrement each byte of encoding */
425 for (i = 0; i < encoding.len; i++)
426 {
06f6d802 427 if (i == 11 || i == 30 || i == 60)
0298be57
TB
428 {
429 continue;
430 }
431 fuzzed = chunk_clone(encoding);
432 fuzzed.ptr[i]--;
433 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
06f6d802 434 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
0298be57
TB
435 a->destroy(a);
436 free(fuzzed.ptr);
437 }
438 free(encoding.ptr);
439}
440END_TEST
441
06f6d802
TB
442START_TEST(test_equals_any)
443{
444 identification_t *a, *b;
445
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));
450 b->destroy(b);
451
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));
455 a->destroy(a);
456 b->destroy(b);
457}
458END_TEST
459
460START_TEST(test_equals_binary)
461{
462 identification_t *a, *b;
463 chunk_t encoding;
464
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));
471 a->destroy(a);
472 b->destroy(b);
473}
474END_TEST
475
476START_TEST(test_equals_fqdn)
477{
478 identification_t *a;
479
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"));
485 a->destroy(a);
486}
487END_TEST
488
df12b3a6
MW
489START_TEST(test_equals_empty)
490{
491 identification_t *a;
492
493 a = identification_create_from_encoding(_i, chunk_empty);
494
495 switch (_i)
496 {
497 case ID_ANY:
498 ck_assert(id_equals(a, "%any"));
499 break;
500 case ID_IPV4_ADDR:
501 ck_assert(!id_equals(a, "192.168.1.1"));
502 break;
503 case ID_FQDN:
504 ck_assert(!id_equals(a, "moon.strongswan.org"));
505 break;
506 case ID_USER_FQDN:
507 ck_assert(!id_equals(a, "moon@strongswan.org"));
508 break;
509 case ID_IPV6_ADDR:
510 ck_assert(!id_equals(a, "fec0::1"));
511 break;
512 case ID_DER_ASN1_DN:
513 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
514 break;
515 case ID_KEY_ID:
516 ck_assert(!id_equals(a, "@#12345678"));
517 break;
518 case ID_DER_ASN1_GN:
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 */
524 break;
525 }
526
527 a->destroy(a);
528}
529END_TEST
530
0298be57
TB
531/*******************************************************************************
532 * matches
533 */
534
535static bool id_matches(identification_t *a, char *b_str, id_match_t expected)
536{
537 identification_t *b;
538 id_match_t match;
539
540 b = identification_create_from_string(b_str);
541 match = a->matches(a, b);
542 b->destroy(b);
543 return match == expected;
544}
545
546START_TEST(test_matches)
547{
548 identification_t *a;
549
06f6d802 550 a = identification_create_from_string("C=CH, E=moon@strongswan.org, CN=moon");
0298be57 551
06f6d802 552 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon", ID_MATCH_PERFECT));
dc486823 553 ck_assert(id_matches(a, "C=CH, E=*@strongswan.org, CN=moon", ID_MATCH_NONE));
06f6d802 554 ck_assert(id_matches(a, "C=CH, E=*, CN=moon", ID_MATCH_ONE_WILDCARD));
0298be57
TB
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));
06f6d802
TB
560 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
561
562 a->destroy(a);
563}
564END_TEST
565
566START_TEST(test_matches_any)
567{
568 identification_t *a;
569
570 a = identification_create_from_string("%any");
0298be57 571
06f6d802
TB
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));
577 a->destroy(a);
578}
579END_TEST
580
581START_TEST(test_matches_binary)
582{
583 identification_t *a;
584
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));
594 a->destroy(a);
595}
596END_TEST
597
598START_TEST(test_matches_string)
599{
600 identification_t *a;
601
602 a = identification_create_from_string("moon@strongswan.org");
603
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));
615 a->destroy(a);
616
617 a = identification_create_from_string("vpn.strongswan.org");
618
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));
0298be57
TB
629 a->destroy(a);
630}
631END_TEST
632
e02b12e3
MW
633START_TEST(test_matches_empty)
634{
635 identification_t *a;
636
637 a = identification_create_from_encoding(_i, chunk_empty);
638
639 switch (_i)
640 {
641 case ID_ANY:
642 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
643 break;
644 case ID_IPV4_ADDR:
645 ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_NONE));
646 break;
647 case ID_FQDN:
648 ck_assert(id_matches(a, "moon.strongswan.org", ID_MATCH_NONE));
649 break;
650 case ID_USER_FQDN:
651 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
652 break;
653 case ID_IPV6_ADDR:
654 ck_assert(id_matches(a, "fec0::1", ID_MATCH_NONE));
655 break;
656 case ID_DER_ASN1_DN:
657 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon",
658 ID_MATCH_NONE));
659 break;
660 case ID_KEY_ID:
661 ck_assert(id_matches(a, "@#12345678", ID_MATCH_NONE));
662 break;
663 case ID_DER_ASN1_GN:
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 */
669 break;
670 }
671
672 a->destroy(a);
673}
674END_TEST
675
ed3eb627
MW
676static bool id_matches_rev(identification_t *a, char *b_str, id_match_t expected)
677{
678 identification_t *b;
679 id_match_t match;
680
681 b = identification_create_from_string(b_str);
682 match = b->matches(b, a);
683 b->destroy(b);
684 return match == expected;
685}
686
687START_TEST(test_matches_empty_reverse)
688{
689 identification_t *a;
690
691 a = identification_create_from_encoding(_i, chunk_empty);
692
693 switch (_i)
694 {
695 case ID_ANY:
696 ck_assert(id_matches_rev(a, "%any", ID_MATCH_ANY));
697 break;
698 case ID_IPV4_ADDR:
699 ck_assert(id_matches_rev(a, "192.168.1.1", ID_MATCH_NONE));
700 break;
701 case ID_FQDN:
702 ck_assert(id_matches_rev(a, "moon.strongswan.org", ID_MATCH_NONE));
703 break;
704 case ID_USER_FQDN:
705 ck_assert(id_matches_rev(a, "moon@strongswan.org", ID_MATCH_NONE));
706 break;
707 case ID_IPV6_ADDR:
708 ck_assert(id_matches_rev(a, "fec0::1", ID_MATCH_NONE));
709 break;
710 case ID_DER_ASN1_DN:
711 ck_assert(id_matches_rev(a, "C=CH, E=moon@strongswan.org, CN=moon",
712 ID_MATCH_NONE));
713 break;
714 case ID_KEY_ID:
715 ck_assert(id_matches_rev(a, "@#12345678", ID_MATCH_NONE));
716 break;
717 case ID_DER_ASN1_GN:
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 */
723 break;
724 }
725
726 a->destroy(a);
727}
728END_TEST
729
520fba48
TB
730/*******************************************************************************
731 * identification hashing
732 */
733
734static bool id_hash_equals(char *str, char *b_str)
735{
736 identification_t *a, *b;
737 bool success = FALSE;
738
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);
742 a->destroy(a);
743 b->destroy(b);
744 return success;
745}
746
747START_TEST(test_hash)
748{
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));
753
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"));
759}
760END_TEST
761
762START_TEST(test_hash_any)
763{
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", ""));
768
769 ck_assert(!id_hash_equals("%any", "any"));
770}
771END_TEST
772
773START_TEST(test_hash_dn)
774{
775 identification_t *a, *b;
776
777 /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
778 * UTF8STRING) */
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));
793 a->destroy(a);
794 b->destroy(b);
795}
796END_TEST
797
798START_TEST(test_hash_inc)
799{
800 identification_t *a;
801
802 a = identification_create_from_string("vpn.strongswan.org");
803 ck_assert(a->hash(a, 0) != a->hash(a, 1));
804 a->destroy(a);
805
806 a = identification_create_from_string("C=CH, O=strongSwan");
807 ck_assert(a->hash(a, 0) != a->hash(a, 1));
808 a->destroy(a);
809}
810END_TEST
811
0298be57
TB
812/*******************************************************************************
813 * identification part enumeration
814 */
815
816START_TEST(test_parts)
817{
818 identification_t *id;
819 enumerator_t *enumerator;
820 id_part_t part;
821 chunk_t data;
822 int i = 0;
823
824 id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
825
826 enumerator = id->create_part_enumerator(id);
827 while (enumerator->enumerate(enumerator, &part, &data))
828 {
829 switch (i++)
830 {
831 case 0:
832 ck_assert(part == ID_PART_RDN_C &&
833 chunk_equals(data, chunk_create("CH", 2)));
834 break;
835 case 1:
836 ck_assert(part == ID_PART_RDN_O &&
837 chunk_equals(data, chunk_from_str("strongSwan")));
838 break;
839 case 2:
840 ck_assert(part == ID_PART_RDN_CN &&
841 chunk_equals(data, chunk_from_str("tester")));
842 break;
843 default:
844 fail("unexpected identification part %d", part);
845 }
846 }
847 ck_assert_int_eq(i, 3);
848 enumerator->destroy(enumerator);
849 id->destroy(id);
850}
851END_TEST
852
853/*******************************************************************************
854 * wildcards
855 */
856
857static bool id_contains_wildcards(char *string)
858{
859 identification_t *id;
860 bool contains;
861
862 id = identification_create_from_string(string);
863 contains = id->contains_wildcards(id);
864 id->destroy(id);
865 return contains;
866}
867
868START_TEST(test_contains_wildcards)
869{
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"));
876}
877END_TEST
878
06f6d802
TB
879/*******************************************************************************
880 * clone
881 */
882
883START_TEST(test_clone)
884{
885 identification_t *a, *b;
886 chunk_t a_enc, b_enc;
887
888 a = identification_create_from_string("moon@strongswan.org");
889 a_enc = a->get_encoding(a);
890 b = a->clone(a);
891 ck_assert(b != NULL);
892 ck_assert(a != b);
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));
896 a->destroy(a);
897 b->destroy(b);
898}
899END_TEST
900
0298be57
TB
901Suite *identification_suite_create()
902{
903 Suite *s;
904 TCase *tc;
905
906 s = suite_create("identification");
907
06f6d802
TB
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);
914
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);
919
0298be57
TB
920 tc = tcase_create("equals");
921 tcase_add_test(tc, test_equals);
06f6d802
TB
922 tcase_add_test(tc, test_equals_any);
923 tcase_add_test(tc, test_equals_binary);
924 tcase_add_test(tc, test_equals_fqdn);
df12b3a6 925 tcase_add_loop_test(tc, test_equals_empty, ID_ANY, ID_KEY_ID + 1);
0298be57
TB
926 suite_add_tcase(s, tc);
927
928 tc = tcase_create("matches");
929 tcase_add_test(tc, test_matches);
06f6d802
TB
930 tcase_add_test(tc, test_matches_any);
931 tcase_add_test(tc, test_matches_binary);
932 tcase_add_test(tc, test_matches_string);
e02b12e3 933 tcase_add_loop_test(tc, test_matches_empty, ID_ANY, ID_KEY_ID + 1);
ed3eb627 934 tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
0298be57
TB
935 suite_add_tcase(s, tc);
936
520fba48
TB
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);
943
0298be57
TB
944 tc = tcase_create("part enumeration");
945 tcase_add_test(tc, test_parts);
946 suite_add_tcase(s, tc);
947
948 tc = tcase_create("wildcards");
949 tcase_add_test(tc, test_contains_wildcards);
950 suite_add_tcase(s, tc);
951
06f6d802
TB
952 tc = tcase_create("clone");
953 tcase_add_test(tc, test_clone);
954 suite_add_tcase(s, tc);
955
0298be57
TB
956 return s;
957}