]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libstrongswan/tests/suites/test_identification.c
scepclient: Remove copyright and license from man page
[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
327 /* C=CH, pseudonym=ANO (pseudonym is currently not recognized) */
328 string_equals_id("C=CH, 55:04:41=ANO", 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, 0x41, 0x13, 0x03, 0x41, 0x4e, 0x4f)));
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
TB
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=*, CN=moon", ID_MATCH_ONE_WILDCARD));
0298be57
TB
554 ck_assert(id_matches(a, "C=CH, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 1));
555 ck_assert(id_matches(a, "C=*, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 2));
556 ck_assert(id_matches(a, "C=*, E=*, CN=*, O=BADInc", ID_MATCH_NONE));
557 ck_assert(id_matches(a, "C=*, E=*", ID_MATCH_NONE));
558 ck_assert(id_matches(a, "C=*, E=a@b.c, CN=*", ID_MATCH_NONE));
06f6d802
TB
559 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
560
561 a->destroy(a);
562}
563END_TEST
564
565START_TEST(test_matches_any)
566{
567 identification_t *a;
568
569 a = identification_create_from_string("%any");
0298be57 570
06f6d802
TB
571 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
572 ck_assert(id_matches(a, "", ID_MATCH_ANY));
573 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
574 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
575 ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_NONE));
576 a->destroy(a);
577}
578END_TEST
579
580START_TEST(test_matches_binary)
581{
582 identification_t *a;
583
584 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
585 a = identification_create_from_string("foo=bar");
586 ck_assert(a->get_type(a) == ID_KEY_ID);
587 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
588 ck_assert(id_matches(a, "foo=bar", ID_MATCH_PERFECT));
589 ck_assert(id_matches(a, "bar=foo", ID_MATCH_NONE));
590 ck_assert(id_matches(a, "*=bar", ID_MATCH_NONE));
591 ck_assert(id_matches(a, "foo=*", ID_MATCH_NONE));
592 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
593 a->destroy(a);
594}
595END_TEST
596
597START_TEST(test_matches_string)
598{
599 identification_t *a;
600
601 a = identification_create_from_string("moon@strongswan.org");
602
603 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_PERFECT));
604 ck_assert(id_matches(a, "*@strongswan.org", ID_MATCH_ONE_WILDCARD));
605 ck_assert(id_matches(a, "*@*.org", ID_MATCH_NONE));
606 ck_assert(id_matches(a, "*@*", ID_MATCH_NONE));
607 /* the following two are parsed as ID_FQDN, so no match */
608 ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_NONE));
609 ck_assert(id_matches(a, "*.org", ID_MATCH_NONE));
610 ck_assert(id_matches(a, "moon@*", ID_MATCH_NONE));
611 ck_assert(id_matches(a, "**", ID_MATCH_NONE));
612 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
613 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
614 a->destroy(a);
615
616 a = identification_create_from_string("vpn.strongswan.org");
617
618 ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_PERFECT));
619 ck_assert(id_matches(a, "*.strongswan.org", ID_MATCH_ONE_WILDCARD));
620 ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_ONE_WILDCARD));
621 ck_assert(id_matches(a, "*.org", ID_MATCH_ONE_WILDCARD));
622 ck_assert(id_matches(a, "*.strongswan.*", ID_MATCH_NONE));
623 ck_assert(id_matches(a, "*vpn.strongswan.org", ID_MATCH_NONE));
624 ck_assert(id_matches(a, "vpn.strongswan.*", ID_MATCH_NONE));
625 ck_assert(id_matches(a, "**", ID_MATCH_NONE));
626 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
627 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
0298be57
TB
628 a->destroy(a);
629}
630END_TEST
631
e02b12e3
MW
632START_TEST(test_matches_empty)
633{
634 identification_t *a;
635
636 a = identification_create_from_encoding(_i, chunk_empty);
637
638 switch (_i)
639 {
640 case ID_ANY:
641 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
642 break;
643 case ID_IPV4_ADDR:
644 ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_NONE));
645 break;
646 case ID_FQDN:
647 ck_assert(id_matches(a, "moon.strongswan.org", ID_MATCH_NONE));
648 break;
649 case ID_USER_FQDN:
650 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
651 break;
652 case ID_IPV6_ADDR:
653 ck_assert(id_matches(a, "fec0::1", ID_MATCH_NONE));
654 break;
655 case ID_DER_ASN1_DN:
656 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon",
657 ID_MATCH_NONE));
658 break;
659 case ID_KEY_ID:
660 ck_assert(id_matches(a, "@#12345678", ID_MATCH_NONE));
661 break;
662 case ID_DER_ASN1_GN:
663 case ID_IPV4_ADDR_SUBNET:
664 case ID_IPV6_ADDR_SUBNET:
665 case ID_IPV4_ADDR_RANGE:
666 case ID_IPV6_ADDR_RANGE:
667 /* currently not tested */
668 break;
669 }
670
671 a->destroy(a);
672}
673END_TEST
674
ed3eb627
MW
675static bool id_matches_rev(identification_t *a, char *b_str, id_match_t expected)
676{
677 identification_t *b;
678 id_match_t match;
679
680 b = identification_create_from_string(b_str);
681 match = b->matches(b, a);
682 b->destroy(b);
683 return match == expected;
684}
685
686START_TEST(test_matches_empty_reverse)
687{
688 identification_t *a;
689
690 a = identification_create_from_encoding(_i, chunk_empty);
691
692 switch (_i)
693 {
694 case ID_ANY:
695 ck_assert(id_matches_rev(a, "%any", ID_MATCH_ANY));
696 break;
697 case ID_IPV4_ADDR:
698 ck_assert(id_matches_rev(a, "192.168.1.1", ID_MATCH_NONE));
699 break;
700 case ID_FQDN:
701 ck_assert(id_matches_rev(a, "moon.strongswan.org", ID_MATCH_NONE));
702 break;
703 case ID_USER_FQDN:
704 ck_assert(id_matches_rev(a, "moon@strongswan.org", ID_MATCH_NONE));
705 break;
706 case ID_IPV6_ADDR:
707 ck_assert(id_matches_rev(a, "fec0::1", ID_MATCH_NONE));
708 break;
709 case ID_DER_ASN1_DN:
710 ck_assert(id_matches_rev(a, "C=CH, E=moon@strongswan.org, CN=moon",
711 ID_MATCH_NONE));
712 break;
713 case ID_KEY_ID:
714 ck_assert(id_matches_rev(a, "@#12345678", ID_MATCH_NONE));
715 break;
716 case ID_DER_ASN1_GN:
717 case ID_IPV4_ADDR_SUBNET:
718 case ID_IPV6_ADDR_SUBNET:
719 case ID_IPV4_ADDR_RANGE:
720 case ID_IPV6_ADDR_RANGE:
721 /* currently not tested */
722 break;
723 }
724
725 a->destroy(a);
726}
727END_TEST
728
520fba48
TB
729/*******************************************************************************
730 * identification hashing
731 */
732
733static bool id_hash_equals(char *str, char *b_str)
734{
735 identification_t *a, *b;
736 bool success = FALSE;
737
738 a = identification_create_from_string(str);
739 b = identification_create_from_string(b_str ?: str);
740 success = a->hash(a, 0) == b->hash(b, 0);
741 a->destroy(a);
742 b->destroy(b);
743 return success;
744}
745
746START_TEST(test_hash)
747{
748 ck_assert(id_hash_equals("moon@strongswan.org", NULL));
749 ck_assert(id_hash_equals("vpn.strongswan.org", NULL));
750 ck_assert(id_hash_equals("192.168.1.1", NULL));
751 ck_assert(id_hash_equals("C=CH", NULL));
752
753 ck_assert(!id_hash_equals("moon@strongswan.org", "sun@strongswan.org"));
754 ck_assert(!id_hash_equals("vpn.strongswan.org", "*.strongswan.org"));
755 ck_assert(!id_hash_equals("192.168.1.1", "192.168.1.2"));
756 ck_assert(!id_hash_equals("C=CH", "C=DE"));
757 ck_assert(!id_hash_equals("fqdn:strongswan.org", "keyid:strongswan.org"));
758}
759END_TEST
760
761START_TEST(test_hash_any)
762{
763 ck_assert(id_hash_equals("%any", NULL));
764 ck_assert(id_hash_equals("%any", "0.0.0.0"));
765 ck_assert(id_hash_equals("%any", "*"));
766 ck_assert(id_hash_equals("%any", ""));
767
768 ck_assert(!id_hash_equals("%any", "any"));
769}
770END_TEST
771
772START_TEST(test_hash_dn)
773{
774 identification_t *a, *b;
775
776 /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
777 * UTF8STRING) */
778 a = identification_create_from_data(chunk_from_chars(
779 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
780 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31,
781 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
782 0x13, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
783 0x53, 0x77, 0x61, 0x6e));
784 b = identification_create_from_data(chunk_from_chars(
785 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
786 0x55, 0x04, 0x06, 0x0c, 0x02, 0x43, 0x48, 0x31,
787 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
788 0x0c, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
789 0x53, 0x77, 0x61, 0x6e));
790 ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
791 ck_assert(a->equals(a, b));
792 a->destroy(a);
793 b->destroy(b);
794}
795END_TEST
796
797START_TEST(test_hash_inc)
798{
799 identification_t *a;
800
801 a = identification_create_from_string("vpn.strongswan.org");
802 ck_assert(a->hash(a, 0) != a->hash(a, 1));
803 a->destroy(a);
804
805 a = identification_create_from_string("C=CH, O=strongSwan");
806 ck_assert(a->hash(a, 0) != a->hash(a, 1));
807 a->destroy(a);
808}
809END_TEST
810
0298be57
TB
811/*******************************************************************************
812 * identification part enumeration
813 */
814
815START_TEST(test_parts)
816{
817 identification_t *id;
818 enumerator_t *enumerator;
819 id_part_t part;
820 chunk_t data;
821 int i = 0;
822
823 id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
824
825 enumerator = id->create_part_enumerator(id);
826 while (enumerator->enumerate(enumerator, &part, &data))
827 {
828 switch (i++)
829 {
830 case 0:
831 ck_assert(part == ID_PART_RDN_C &&
832 chunk_equals(data, chunk_create("CH", 2)));
833 break;
834 case 1:
835 ck_assert(part == ID_PART_RDN_O &&
836 chunk_equals(data, chunk_from_str("strongSwan")));
837 break;
838 case 2:
839 ck_assert(part == ID_PART_RDN_CN &&
840 chunk_equals(data, chunk_from_str("tester")));
841 break;
842 default:
843 fail("unexpected identification part %d", part);
844 }
845 }
846 ck_assert_int_eq(i, 3);
847 enumerator->destroy(enumerator);
848 id->destroy(id);
849}
850END_TEST
851
852/*******************************************************************************
853 * wildcards
854 */
855
856static bool id_contains_wildcards(char *string)
857{
858 identification_t *id;
859 bool contains;
860
861 id = identification_create_from_string(string);
862 contains = id->contains_wildcards(id);
863 id->destroy(id);
864 return contains;
865}
866
867START_TEST(test_contains_wildcards)
868{
869 ck_assert(id_contains_wildcards("%any"));
870 ck_assert(id_contains_wildcards("C=*, O=strongSwan, CN=gw"));
871 ck_assert(id_contains_wildcards("C=CH, O=strongSwan, CN=*"));
872 ck_assert(id_contains_wildcards("*@strongswan.org"));
873 ck_assert(id_contains_wildcards("*.strongswan.org"));
874 ck_assert(!id_contains_wildcards("C=**, O=a*, CN=*a"));
875}
876END_TEST
877
06f6d802
TB
878/*******************************************************************************
879 * clone
880 */
881
882START_TEST(test_clone)
883{
884 identification_t *a, *b;
885 chunk_t a_enc, b_enc;
886
887 a = identification_create_from_string("moon@strongswan.org");
888 a_enc = a->get_encoding(a);
889 b = a->clone(a);
890 ck_assert(b != NULL);
891 ck_assert(a != b);
892 b_enc = b->get_encoding(b);
893 ck_assert(a_enc.ptr != b_enc.ptr);
894 ck_assert(chunk_equals(a_enc, b_enc));
895 a->destroy(a);
896 b->destroy(b);
897}
898END_TEST
899
0298be57
TB
900Suite *identification_suite_create()
901{
902 Suite *s;
903 TCase *tc;
904
905 s = suite_create("identification");
906
06f6d802
TB
907 tc = tcase_create("create");
908 tcase_add_test(tc, test_from_encoding);
909 tcase_add_test(tc, test_from_data);
910 tcase_add_test(tc, test_from_sockaddr);
911 tcase_add_loop_test(tc, test_from_string, 0, countof(string_data));
912 suite_add_tcase(s, tc);
913
914 tc = tcase_create("printf_hook");
915 tcase_add_test(tc, test_printf_hook);
916 tcase_add_test(tc, test_printf_hook_width);
917 suite_add_tcase(s, tc);
918
0298be57
TB
919 tc = tcase_create("equals");
920 tcase_add_test(tc, test_equals);
06f6d802
TB
921 tcase_add_test(tc, test_equals_any);
922 tcase_add_test(tc, test_equals_binary);
923 tcase_add_test(tc, test_equals_fqdn);
df12b3a6 924 tcase_add_loop_test(tc, test_equals_empty, ID_ANY, ID_KEY_ID + 1);
0298be57
TB
925 suite_add_tcase(s, tc);
926
927 tc = tcase_create("matches");
928 tcase_add_test(tc, test_matches);
06f6d802
TB
929 tcase_add_test(tc, test_matches_any);
930 tcase_add_test(tc, test_matches_binary);
931 tcase_add_test(tc, test_matches_string);
e02b12e3 932 tcase_add_loop_test(tc, test_matches_empty, ID_ANY, ID_KEY_ID + 1);
ed3eb627 933 tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
0298be57
TB
934 suite_add_tcase(s, tc);
935
520fba48
TB
936 tc = tcase_create("hash");
937 tcase_add_test(tc, test_hash);
938 tcase_add_test(tc, test_hash_any);
939 tcase_add_test(tc, test_hash_dn);
940 tcase_add_test(tc, test_hash_inc);
941 suite_add_tcase(s, tc);
942
0298be57
TB
943 tc = tcase_create("part enumeration");
944 tcase_add_test(tc, test_parts);
945 suite_add_tcase(s, tc);
946
947 tc = tcase_create("wildcards");
948 tcase_add_test(tc, test_contains_wildcards);
949 suite_add_tcase(s, tc);
950
06f6d802
TB
951 tc = tcase_create("clone");
952 tcase_add_test(tc, test_clone);
953 suite_add_tcase(s, tc);
954
0298be57
TB
955 return s;
956}