]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/tests/suites/test_identification.c
4b22024316cb83ee0bdf84ddcb13a864dcbdfdc1
[thirdparty/strongswan.git] / src / libstrongswan / tests / suites / test_identification.c
1 /*
2 * Copyright (C) 2013-2015 Tobias Brunner
3 * Copyright (C) 2016 Andreas Steffen
4 * Copyright (C) 2009 Martin Willi
5 * HSR Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include "test_suite.h"
19
20 #include <utils/identification.h>
21
22 /*******************************************************************************
23 * create (_from_encoding, _from_data, _from_string, _from_sockaddr)
24 */
25
26 START_TEST(test_from_encoding)
27 {
28 identification_t *a;
29 chunk_t expected, encoding;
30
31 /* only ID_ANY is handled differently, for all other types the following
32 * applies. should we perhaps test that this is in fact the case? */
33 expected = chunk_from_str("moon@strongswan.org");
34 a = identification_create_from_encoding(ID_RFC822_ADDR, expected);
35 ck_assert(ID_RFC822_ADDR == a->get_type(a));
36 encoding = a->get_encoding(a);
37 ck_assert(expected.ptr != encoding.ptr);
38 ck_assert(chunk_equals(expected, encoding));
39 a->destroy(a);
40
41 a = identification_create_from_encoding(ID_ANY, expected);
42 ck_assert(ID_ANY == a->get_type(a));
43 encoding = a->get_encoding(a);
44 ck_assert(encoding.ptr == NULL);
45 ck_assert(encoding.len == 0);
46 a->destroy(a);
47 }
48 END_TEST
49
50 START_TEST(test_from_data)
51 {
52 identification_t *a;
53 chunk_t expected, encoding;
54
55 /* this uses the DN parser (C=CH) */
56 expected = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
57 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48);
58 a = identification_create_from_data(expected);
59 ck_assert(ID_DER_ASN1_DN == a->get_type(a));
60 encoding = a->get_encoding(a);
61 ck_assert(expected.ptr != encoding.ptr);
62 ck_assert(chunk_equals(expected, encoding));
63 a->destroy(a);
64
65 /* everything else is handled by the string parser */
66 expected = chunk_from_str("moon@strongswan.org");
67 a = identification_create_from_data(expected);
68 ck_assert(ID_RFC822_ADDR == a->get_type(a));
69 encoding = a->get_encoding(a);
70 ck_assert(expected.ptr != encoding.ptr);
71 ck_assert(chunk_equals(expected, encoding));
72 a->destroy(a);
73 }
74 END_TEST
75
76 START_TEST(test_from_sockaddr)
77 {
78 identification_t *a;
79 chunk_t expected, encoding;
80 struct sockaddr_in in = {
81 .sin_family = AF_INET,
82 };
83 struct sockaddr_in6 in6 = {
84 .sin6_family = AF_INET6,
85 };
86
87 expected = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01);
88 memcpy(&in.sin_addr, expected.ptr, sizeof(in.sin_addr));
89 a = identification_create_from_sockaddr((sockaddr_t*)&in);
90 ck_assert(ID_IPV4_ADDR == a->get_type(a));
91 encoding = a->get_encoding(a);
92 ck_assert(chunk_equals(expected, encoding));
93 a->destroy(a);
94
95 expected = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
97 memcpy(&in6.sin6_addr, expected.ptr, sizeof(in6.sin6_addr));
98 a = identification_create_from_sockaddr((sockaddr_t*)&in6);
99 ck_assert(ID_IPV6_ADDR == a->get_type(a));
100 encoding = a->get_encoding(a);
101 ck_assert(chunk_equals(expected, encoding));
102 a->destroy(a);
103
104 in6.sin6_family = AF_UNSPEC;
105 a = identification_create_from_sockaddr((sockaddr_t*)&in6);
106 ck_assert(ID_ANY == a->get_type(a));
107 a->destroy(a);
108 }
109 END_TEST
110
111 static struct {
112 char *id;
113 id_type_t type;
114 struct {
115 enum {
116 ENC_CHUNK,
117 ENC_STRING,
118 ENC_SIMPLE,
119 } type;
120 union {
121 chunk_t c;
122 char *s;
123 } data;
124 } result;
125 } string_data[] = {
126 {NULL, ID_ANY, { .type = ENC_CHUNK }},
127 {"", ID_ANY, { .type = ENC_CHUNK }},
128 {"%any", ID_ANY, { .type = ENC_CHUNK }},
129 {"%any6", ID_ANY, { .type = ENC_CHUNK }},
130 {"0.0.0.0", ID_ANY, { .type = ENC_CHUNK }},
131 {"0::0", ID_ANY, { .type = ENC_CHUNK }},
132 {"::", ID_ANY, { .type = ENC_CHUNK }},
133 {"*", ID_ANY, { .type = ENC_CHUNK }},
134 {"any", ID_FQDN, { .type = ENC_SIMPLE }},
135 {"any6", ID_FQDN, { .type = ENC_SIMPLE }},
136 {"0", ID_FQDN, { .type = ENC_SIMPLE }},
137 {"**", ID_FQDN, { .type = ENC_SIMPLE }},
138 {"192.168.1.1", ID_IPV4_ADDR, { .type = ENC_CHUNK,
139 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
140 {"192.168.", ID_FQDN, { .type = ENC_SIMPLE }},
141 {".", ID_FQDN, { .type = ENC_SIMPLE }},
142 {"192.168.1.1/33", ID_FQDN, { .type = ENC_SIMPLE }},
143 {"192.168.1.1/32", ID_IPV4_ADDR_SUBNET, { .type = ENC_CHUNK,
144 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01,0xff,0xff,0xff,0xff) }},
145 {"192.168.1.1/31", ID_IPV4_ADDR_SUBNET, { .type = ENC_CHUNK,
146 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x00,0xff,0xff,0xff,0xfe) }},
147 {"192.168.1.8/30", ID_IPV4_ADDR_SUBNET, { .type = ENC_CHUNK,
148 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x08,0xff,0xff,0xff,0xfc) }},
149 {"192.168.1.128/25", ID_IPV4_ADDR_SUBNET, { .type = ENC_CHUNK,
150 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x80,0xff,0xff,0xff,0x80) }},
151 {"192.168.1.0/24", ID_IPV4_ADDR_SUBNET, { .type = ENC_CHUNK,
152 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x00,0xff,0xff,0xff,0x00) }},
153 {"192.168.1.0/23", ID_IPV4_ADDR_SUBNET, { .type = ENC_CHUNK,
154 .data.c = chunk_from_chars(0xc0,0xa8,0x00,0x00,0xff,0xff,0xfe,0x00) }},
155 {"192.168.4.0/22", ID_IPV4_ADDR_SUBNET, { .type = ENC_CHUNK,
156 .data.c = chunk_from_chars(0xc0,0xa8,0x04,0x00,0xff,0xff,0xfc,0x00) }},
157 {"0.0.0.0/0", ID_IPV4_ADDR_SUBNET, { .type = ENC_CHUNK,
158 .data.c = chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) }},
159 {"192.168.1.0-192.168.1.40",ID_IPV4_ADDR_RANGE, { .type = ENC_CHUNK,
160 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x00,0xc0,0xa8,0x01,0x28) }},
161 {"0.0.0.0-255.255.255.255", ID_IPV4_ADDR_RANGE, { .type = ENC_CHUNK,
162 .data.c = chunk_from_chars(0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff) }},
163 {"192.168.1.40-192.168.1.0",ID_FQDN, { .type = ENC_SIMPLE }},
164 {"fec0::1", ID_IPV6_ADDR, { .type = ENC_CHUNK,
165 .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
166 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01) }},
167 {"fec0::", ID_IPV6_ADDR, { .type = ENC_CHUNK,
168 .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
169 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) }},
170 {"fec0:", ID_KEY_ID, { .type = ENC_SIMPLE }},
171 {":", ID_KEY_ID, { .type = ENC_SIMPLE }},
172 {"fec0::1/129", ID_KEY_ID, { .type = ENC_SIMPLE }},
173 {"fec0::1/128", ID_IPV6_ADDR_SUBNET, { .type = ENC_CHUNK,
174 .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
175 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
176 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
177 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ) }},
178 {"fec0::1/127", ID_IPV6_ADDR_SUBNET, { .type = ENC_CHUNK,
179 .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
180 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
181 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
182 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe ) }},
183 {"fec0::4/126", ID_IPV6_ADDR_SUBNET, { .type = ENC_CHUNK,
184 .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
185 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
186 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
187 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc ) }},
188 {"fec0::100/120", ID_IPV6_ADDR_SUBNET, { .type = ENC_CHUNK,
189 .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
190 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
191 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
192 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 ) }},
193 {"::/0", ID_IPV6_ADDR_SUBNET, { .type = ENC_CHUNK,
194 .data.c = chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
195 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
196 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
197 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ) }},
198 {"fec0::1-fec0::4fff", ID_IPV6_ADDR_RANGE, { .type = ENC_CHUNK,
199 .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
200 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
201 0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
202 0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0xff ) }},
203 {"fec0::4fff-fec0::1", ID_KEY_ID, { .type = ENC_SIMPLE }},
204 {"fec0::1-", ID_KEY_ID, { .type = ENC_SIMPLE }},
205 {"alice@strongswan.org", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
206 {"alice@strongswan", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
207 {"alice@", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
208 {"alice", ID_FQDN, { .type = ENC_SIMPLE }},
209 {"@", ID_FQDN, { .type = ENC_CHUNK }},
210 {" @", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
211 {"@strongswan.org", ID_FQDN, { .type = ENC_STRING,
212 .data.s = "strongswan.org" }},
213 {"@#deadbeef", ID_KEY_ID, { .type = ENC_CHUNK,
214 .data.c = chunk_from_chars(0xde,0xad,0xbe,0xef) }},
215 {"@#deadbee", ID_KEY_ID, { .type = ENC_CHUNK,
216 .data.c = chunk_from_chars(0x0d,0xea,0xdb,0xee) }},
217 {"foo=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
218 {"foo=", ID_KEY_ID, { .type = ENC_SIMPLE }},
219 {"=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
220 {"C=", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
221 .data.c = chunk_from_chars(0x30,0x0b,0x31,0x09,0x30,0x07,0x06,
222 0x03,0x55,0x04,0x06,0x13,0x00) }},
223 {"C=CH", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
224 .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
225 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
226 {"C=CH,", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
227 .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
228 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
229 {"C=CH, ", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
230 .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
231 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
232 {"C=CH, O", ID_KEY_ID, { .type = ENC_SIMPLE }},
233 {"IPv4:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK,
234 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
235 { "email:tester", ID_RFC822_ADDR, { .type = ENC_STRING,
236 .data.s = "tester" }},
237 {"xmppaddr:bob@strongswan.org", ID_DER_ASN1_GN, { .type = ENC_CHUNK,
238 .data.c = chunk_from_chars(0xa0,0x20,0x06,0x08,0x2b,0x06,0x01,0x05,
239 0x05,0x07,0x08,0x05,0xa0,0x14,0x0c,0x12,
240 0x62,0x6f,0x62,0x40,0x73,0x74,0x72,0x6f,
241 0x6e,0x67,0x73,0x77,0x61,0x6e,0x2e,0x6f,
242 0x72,0x67) }},
243 { "{1}:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK,
244 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
245 { "{0x02}:tester", ID_FQDN, { .type = ENC_STRING,
246 .data.s = "tester" }},
247 { "{99}:somedata", 99, { .type = ENC_STRING,
248 .data.s = "somedata" }},
249 };
250
251 START_TEST(test_from_string)
252 {
253 identification_t *a;
254 chunk_t encoding, expected = chunk_empty;
255 char *id;
256
257 id = string_data[_i].id;
258 a = identification_create_from_string(id);
259 fail_unless(a->get_type(a) == string_data[_i].type,
260 "type of id '%s' is %N, %N expected", id,
261 id_type_names, a->get_type(a),
262 id_type_names, string_data[_i].type);
263
264 encoding = a->get_encoding(a);
265 switch (string_data[_i].result.type)
266 {
267 case ENC_SIMPLE:
268 expected = chunk_from_str(string_data[_i].id);
269 break;
270 case ENC_STRING:
271 expected = chunk_from_str(string_data[_i].result.data.s);
272 break;
273 case ENC_CHUNK:
274 expected = string_data[_i].result.data.c;
275 break;
276 default:
277 fail("unexpected result type");
278 }
279
280 ck_assert(!id || (char*)encoding.ptr != id);
281 if (expected.ptr)
282 {
283 fail_unless(chunk_equals(encoding, expected),
284 "parsing '%s' failed\nencoding %B\nexpected %B\n",
285 id, &encoding, &expected);
286 }
287 else
288 {
289 ck_assert(encoding.ptr == NULL);
290 ck_assert(encoding.len == 0);
291 }
292 a->destroy(a);
293 }
294 END_TEST
295
296 /*******************************************************************************
297 * printf_hook
298 */
299
300 static void string_equals(char *a_str, char *b_str)
301 {
302 identification_t *b;
303 char buf[128];
304
305 b = b_str ? identification_create_from_string(b_str) : NULL;
306 snprintf(buf, sizeof(buf), "%Y", b);
307 DESTROY_IF(b);
308 ck_assert_str_eq(a_str, buf);
309 }
310
311 static void string_equals_id(char *a_str, identification_t *b)
312 {
313 char buf[128];
314
315 snprintf(buf, sizeof(buf), "%Y", b);
316 DESTROY_IF(b);
317 ck_assert_str_eq(a_str, buf);
318 }
319
320 START_TEST(test_printf_hook)
321 {
322 string_equals("(null)", NULL);
323 string_equals("%any", "");
324 string_equals("%any", "%any");
325 string_equals("%any", "*");
326
327 string_equals("192.168.1.1", "192.168.1.1");
328 string_equals_id("(invalid ID_IPV4_ADDR)",
329 identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty));
330 string_equals("192.168.1.1/32", "192.168.1.1/32");
331 string_equals("192.168.1.2/31", "192.168.1.2/31");
332 string_equals("192.168.1.0/24", "192.168.1.0/24");
333 string_equals("192.168.2.0/23", "192.168.2.0/23");
334 string_equals("0.0.0.0/0", "0.0.0.0/0");
335 string_equals_id("(invalid ID_IPV4_ADDR_SUBNET)",
336 identification_create_from_encoding(ID_IPV4_ADDR_SUBNET, chunk_empty));
337 string_equals("192.168.1.1-192.168.1.254", "192.168.1.1-192.168.1.254");
338 string_equals("0.0.0.0-255.255.255.255", "0.0.0.0-255.255.255.255");
339 string_equals_id("(invalid ID_IPV4_ADDR_RANGE)",
340 identification_create_from_encoding(ID_IPV4_ADDR_RANGE, chunk_empty));
341 string_equals("fec0::1", "fec0::1");
342 string_equals("fec0::1", "fec0:0:0::1");
343 string_equals_id("(invalid ID_IPV6_ADDR)",
344 identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty));
345 string_equals("fec0::1/128", "fec0::1/128");
346 string_equals("fec0::2/127", "fec0::2/127");
347 string_equals("fec0::100/120", "fec0::100/120");
348 string_equals("::/0", "::/0");
349 string_equals_id("(invalid ID_IPV6_ADDR_SUBNET)",
350 identification_create_from_encoding(ID_IPV6_ADDR_SUBNET, chunk_empty));
351 string_equals("fec0::1-fec0::4fff", "fec0::1-fec0::4fff");
352 string_equals_id("(invalid ID_IPV6_ADDR_RANGE)",
353 identification_create_from_encoding(ID_IPV6_ADDR_RANGE, chunk_empty));
354 string_equals_id("(unknown ID type: 255)",
355 identification_create_from_encoding(255, chunk_empty));
356
357 string_equals("moon@strongswan.org", "moon@strongswan.org");
358 string_equals("MOON@STRONGSWAN.ORG", "MOON@STRONGSWAN.ORG");
359 /* non-printable characters */
360 string_equals_id("????@strongswan.org", identification_create_from_encoding(ID_RFC822_ADDR,
361 chunk_from_chars(0xfa, 0xfb, 0xfc, 0xfd, 0x40, 0x73, 0x74, 0x72,
362 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
363 0x6f, 0x72, 0x67)));
364
365 /* not a DN => ID_KEY_ID => no normalization */
366 string_equals("C=CH, AsdF=asdf", "C=CH, AsdF=asdf");
367 string_equals_id("moon@strongswan.org", identification_create_from_encoding(ID_KEY_ID,
368 chunk_from_str("moon@strongswan.org")));
369 /* non-printable characters */
370 string_equals_id("de:ad:be:ef", identification_create_from_encoding(ID_KEY_ID,
371 chunk_from_chars(0xde, 0xad, 0xbe, 0xef)));
372 /* printable characters */
373 string_equals_id("ABCDEFGHIJKLMNOPQRS",
374 identification_create_from_encoding(ID_KEY_ID,
375 chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
376 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
377 0x51, 0x52, 0x53)));
378 /* ABCDEFGHIJKLMNOPQRST is printable but has the length of a SHA1 hash */
379 string_equals_id("41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54",
380 identification_create_from_encoding(ID_KEY_ID,
381 chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
382 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
383 0x51, 0x52, 0x53, 0x54)));
384
385 string_equals_id("", identification_create_from_encoding(ID_DER_ASN1_DN, chunk_empty));
386 string_equals("C=", "C=");
387 string_equals("C=", "C=,");
388 string_equals("C=", "C=, ");
389 string_equals("C=", "C= , ");
390 string_equals("C=, O=strongSwan", "C=, O=strongSwan");
391 string_equals("C=CH, O=", "C=CH, O=");
392 string_equals("C=CH, O=strongSwan, CN=strongswan.org",
393 "C=CH, O=strongSwan, CN=strongswan.org");
394 string_equals("CN=strongswan.org, O=strongSwan, C=CH",
395 "cn=strongswan.org, o=strongSwan, c=CH");
396 string_equals("C=CH, O=strongSwan, CN=strongswan.org",
397 "C=CH,O=strongSwan,CN=strongswan.org");
398 string_equals("C=CH, O=strongSwan, CN=strongswan.org",
399 "/C=CH/O=strongSwan/CN=strongswan.org");
400 string_equals("CN=strongswan.org, O=strongSwan, C=CH",
401 "CN=strongswan.org,O=strongSwan,C=CH");
402
403 string_equals("C=CH, E=moon@strongswan.org, CN=moon",
404 "C=CH, email=moon@strongswan.org, CN=moon");
405 string_equals("C=CH, E=moon@strongswan.org, CN=moon",
406 "C=CH, emailAddress=moon@strongswan.org, CN=moon");
407
408 /* C=CH, telexNumber=123 (telexNumber is currently not recognized) */
409 string_equals_id("C=CH, 55:04:15=123", identification_create_from_encoding(ID_DER_ASN1_DN,
410 chunk_from_chars(0x30, 0x19, 0x31, 0x17, 0x30, 0x09, 0x06, 0x03, 0x55,
411 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x0a, 0x06,
412 0x03, 0x55, 0x04, 0x15, 0x13, 0x03, 0x31, 0x32, 0x33)));
413 /* C=CH, O=strongSwan (but instead of a 2nd OID -0x06- we got NULL -0x05) */
414 string_equals_id("C=CH, (invalid ID_DER_ASN1_DN)", identification_create_from_encoding(ID_DER_ASN1_DN,
415 chunk_from_chars(0x30, 0x20, 0x31, 0x1e, 0x30, 0x09, 0x06, 0x03, 0x55,
416 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x11, 0x05,
417 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x73, 0x74, 0x72,
418 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e)));
419 /* moon@strongswan.org as GN */
420 string_equals_id("(ASN.1 general name)", identification_create_from_encoding(ID_DER_ASN1_GN,
421 chunk_from_chars(0x81, 0x14, 0x6d, 0x6f, 0x6f, 0x6e, 0x40, 0x73, 0x74,
422 0x72, 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
423 0x6f, 0x72, 0x67)));
424 }
425 END_TEST
426
427 START_TEST(test_printf_hook_width)
428 {
429 identification_t *a;
430 char buf[128];
431
432 a = identification_create_from_string("moon@strongswan.org");
433 snprintf(buf, sizeof(buf), "%25Y", a);
434 ck_assert_str_eq(" moon@strongswan.org", buf);
435 snprintf(buf, sizeof(buf), "%-*Y", 25, a);
436 ck_assert_str_eq("moon@strongswan.org ", buf);
437 snprintf(buf, sizeof(buf), "%5Y", a);
438 ck_assert_str_eq("moon@strongswan.org", buf);
439 DESTROY_IF(a);
440 }
441 END_TEST
442
443 /*******************************************************************************
444 * equals
445 */
446
447 static bool id_equals(identification_t *a, char *b_str)
448 {
449 identification_t *b;
450 bool equals;
451
452 b = identification_create_from_string(b_str);
453 equals = a->equals(a, b);
454 ck_assert_int_eq(equals, b->equals(b, a));
455 b->destroy(b);
456 return equals;
457 }
458
459 START_TEST(test_equals)
460 {
461 identification_t *a;
462 chunk_t encoding, fuzzed;
463 int i;
464
465 /* this test also tests identification_create_from_string with DNs */
466 a = identification_create_from_string(
467 "C=CH, E=moon@strongswan.org, CN=moon");
468
469 ck_assert(id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
470 ck_assert(id_equals(a, "C==CH , E==moon@strongswan.org , CN==moon"));
471 ck_assert(id_equals(a, " C=CH, E=moon@strongswan.org, CN=moon "));
472 ck_assert(id_equals(a, "C=ch, E=moon@STRONGSWAN.ORG, CN=Moon"));
473 ck_assert(id_equals(a, "/C=CH/E=moon@strongswan.org/CN=moon"));
474 ck_assert(id_equals(a, " / C=CH / E=moon@strongswan.org / CN=moon"));
475
476 ck_assert(!id_equals(a, "C=CH/E=moon@strongswan.org/CN=moon"));
477 ck_assert(!id_equals(a, "C=CH/E=moon@strongswan.org,CN=moon"));
478 ck_assert(!id_equals(a, "C=CH E=moon@strongswan.org CN=moon"));
479 ck_assert(!id_equals(a, "C=CN, E=moon@strongswan.org, CN=moon"));
480 ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
481 ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
482
483 encoding = chunk_clone(a->get_encoding(a));
484 a->destroy(a);
485
486 /* simple fuzzing, increment each byte of encoding */
487 for (i = 0; i < encoding.len; i++)
488 {
489 if (i == 11 || i == 30 || i == 60)
490 { /* skip ASN.1 type fields, as equals() handles them graceful */
491 continue;
492 }
493 fuzzed = chunk_clone(encoding);
494 fuzzed.ptr[i]++;
495 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
496 if (id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"))
497 {
498 printf("%d %B\n%B\n", i, &fuzzed, &encoding);
499 }
500 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
501 a->destroy(a);
502 free(fuzzed.ptr);
503 }
504
505 /* and decrement each byte of encoding */
506 for (i = 0; i < encoding.len; i++)
507 {
508 if (i == 11 || i == 30 || i == 60)
509 {
510 continue;
511 }
512 fuzzed = chunk_clone(encoding);
513 fuzzed.ptr[i]--;
514 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
515 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
516 a->destroy(a);
517 free(fuzzed.ptr);
518 }
519 free(encoding.ptr);
520 }
521 END_TEST
522
523 START_TEST(test_equals_any)
524 {
525 identification_t *a, *b;
526
527 a = identification_create_from_string("%any");
528 b = identification_create_from_encoding(ID_ANY, chunk_empty);
529 ck_assert(a->equals(a, b));
530 ck_assert(b->equals(b, a));
531 b->destroy(b);
532
533 b = identification_create_from_string("C=CH, O=strongSwan, CN=strongswan.org");
534 ck_assert(!a->equals(a, b));
535 ck_assert(!b->equals(b, a));
536 a->destroy(a);
537 b->destroy(b);
538 }
539 END_TEST
540
541 START_TEST(test_equals_binary)
542 {
543 identification_t *a, *b;
544 chunk_t encoding;
545
546 encoding = chunk_from_str("foobar=");
547 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
548 a = identification_create_from_string("foobar=");
549 ck_assert(a->get_type(a) == ID_KEY_ID);
550 b = identification_create_from_encoding(ID_KEY_ID, encoding);
551 ck_assert(a->equals(a, b));
552 a->destroy(a);
553 b->destroy(b);
554 }
555 END_TEST
556
557 START_TEST(test_equals_fqdn)
558 {
559 identification_t *a;
560
561 a = identification_create_from_string("ipsec.strongswan.org");
562 ck_assert(id_equals(a, "IPSEC.strongswan.org"));
563 ck_assert(id_equals(a, "ipsec.strongSwan.org"));
564 ck_assert(id_equals(a, "ipsec.strongSwan.ORG"));
565 ck_assert(!id_equals(a, "strongswan.org"));
566 a->destroy(a);
567 }
568 END_TEST
569
570 START_TEST(test_equals_empty)
571 {
572 identification_t *a;
573
574 a = identification_create_from_encoding(_i, chunk_empty);
575
576 switch (_i)
577 {
578 case ID_ANY:
579 ck_assert(id_equals(a, "%any"));
580 break;
581 case ID_IPV4_ADDR:
582 ck_assert(!id_equals(a, "192.168.1.1"));
583 break;
584 case ID_FQDN:
585 ck_assert(!id_equals(a, "moon.strongswan.org"));
586 break;
587 case ID_USER_FQDN:
588 ck_assert(!id_equals(a, "moon@strongswan.org"));
589 break;
590 case ID_IPV6_ADDR:
591 ck_assert(!id_equals(a, "fec0::1"));
592 break;
593 case ID_DER_ASN1_DN:
594 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
595 break;
596 case ID_KEY_ID:
597 ck_assert(!id_equals(a, "@#12345678"));
598 break;
599 case ID_DER_ASN1_GN:
600 case ID_IPV4_ADDR_SUBNET:
601 case ID_IPV6_ADDR_SUBNET:
602 case ID_IPV4_ADDR_RANGE:
603 case ID_IPV6_ADDR_RANGE:
604 /* currently not tested */
605 break;
606 }
607
608 a->destroy(a);
609 }
610 END_TEST
611
612 /*******************************************************************************
613 * matches
614 */
615
616 static bool id_matches(identification_t *a, char *b_str, id_match_t expected)
617 {
618 identification_t *b;
619 id_match_t match;
620
621 b = identification_create_from_string(b_str);
622 match = a->matches(a, b);
623 b->destroy(b);
624 return match == expected;
625 }
626
627 START_TEST(test_matches)
628 {
629 identification_t *a;
630
631 a = identification_create_from_string("C=CH, E=moon@strongswan.org, CN=moon");
632
633 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon", ID_MATCH_PERFECT));
634 ck_assert(id_matches(a, "C=CH, E=*@strongswan.org, CN=moon", ID_MATCH_NONE));
635 ck_assert(id_matches(a, "C=CH, E=*, CN=moon", ID_MATCH_ONE_WILDCARD));
636 ck_assert(id_matches(a, "C=CH, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 1));
637 ck_assert(id_matches(a, "C=*, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 2));
638 ck_assert(id_matches(a, "C=*, E=*, CN=*, O=BADInc", ID_MATCH_NONE));
639 ck_assert(id_matches(a, "C=*, E=*", ID_MATCH_NONE));
640 ck_assert(id_matches(a, "C=*, E=a@b.c, CN=*", ID_MATCH_NONE));
641 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
642
643 a->destroy(a);
644 }
645 END_TEST
646
647 START_TEST(test_matches_any)
648 {
649 identification_t *a;
650
651 a = identification_create_from_string("%any");
652
653 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
654 ck_assert(id_matches(a, "", ID_MATCH_ANY));
655 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
656 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
657 ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_NONE));
658 a->destroy(a);
659 }
660 END_TEST
661
662 START_TEST(test_matches_binary)
663 {
664 identification_t *a;
665
666 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
667 a = identification_create_from_string("foo=bar");
668 ck_assert(a->get_type(a) == ID_KEY_ID);
669 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
670 ck_assert(id_matches(a, "foo=bar", ID_MATCH_PERFECT));
671 ck_assert(id_matches(a, "bar=foo", ID_MATCH_NONE));
672 ck_assert(id_matches(a, "*=bar", ID_MATCH_NONE));
673 ck_assert(id_matches(a, "foo=*", ID_MATCH_NONE));
674 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
675 a->destroy(a);
676 }
677 END_TEST
678
679 START_TEST(test_matches_range)
680 {
681 identification_t *a, *b;
682
683 /* IPv4 addresses */
684 a = identification_create_from_string("192.168.1.1");
685 ck_assert(a->get_type(a) == ID_IPV4_ADDR);
686 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
687 ck_assert(id_matches(a, "0.0.0.0/0", ID_MATCH_MAX_WILDCARDS));
688 ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_PERFECT));
689 ck_assert(id_matches(a, "192.168.1.2", ID_MATCH_NONE));
690 ck_assert(id_matches(a, "192.168.1.1/32", ID_MATCH_PERFECT));
691 ck_assert(id_matches(a, "192.168.1.0/32", ID_MATCH_NONE));
692 ck_assert(id_matches(a, "192.168.1.0/24", ID_MATCH_ONE_WILDCARD));
693 ck_assert(id_matches(a, "192.168.0.0/24", ID_MATCH_NONE));
694 ck_assert(id_matches(a, "192.168.1.1-192.168.1.1", ID_MATCH_PERFECT));
695 ck_assert(id_matches(a, "192.168.1.0-192.168.1.64", ID_MATCH_ONE_WILDCARD));
696 ck_assert(id_matches(a, "192.168.1.2-192.168.1.64", ID_MATCH_NONE));
697 ck_assert(id_matches(a, "192.168.0.240-192.168.1.0", ID_MATCH_NONE));
698 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
699
700 /* Malformed IPv4 subnet and range encoding */
701 b = identification_create_from_encoding(ID_IPV4_ADDR_SUBNET, chunk_empty);
702 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
703 b->destroy(b);
704 b = identification_create_from_encoding(ID_IPV4_ADDR_RANGE, chunk_empty);
705 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
706 b->destroy(b);
707 b = identification_create_from_encoding(ID_IPV4_ADDR_RANGE,
708 chunk_from_chars(0xc0,0xa8,0x01,0x28,0xc0,0xa8,0x01,0x00));
709 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
710 b->destroy(b);
711
712 a->destroy(a);
713
714 /* IPv6 addresses */
715 a = identification_create_from_string("fec0::1");
716 ck_assert(a->get_type(a) == ID_IPV6_ADDR);
717 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
718 ck_assert(id_matches(a, "::/0", ID_MATCH_MAX_WILDCARDS));
719 ck_assert(id_matches(a, "fec0::1", ID_MATCH_PERFECT));
720 ck_assert(id_matches(a, "fec0::2", ID_MATCH_NONE));
721 ck_assert(id_matches(a, "fec0::1/128", ID_MATCH_PERFECT));
722 ck_assert(id_matches(a, "fec0::/128", ID_MATCH_NONE));
723 ck_assert(id_matches(a, "fec0::/120", ID_MATCH_ONE_WILDCARD));
724 ck_assert(id_matches(a, "fec0::100/120", ID_MATCH_NONE));
725 ck_assert(id_matches(a, "fec0::1-fec0::1", ID_MATCH_PERFECT));
726 ck_assert(id_matches(a, "fec0::0-fec0::5", ID_MATCH_ONE_WILDCARD));
727 ck_assert(id_matches(a, "fec0::4001-fec0::4ffe", ID_MATCH_NONE));
728 ck_assert(id_matches(a, "feb0::1-fec0::0", ID_MATCH_NONE));
729 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
730
731 /* Malformed IPv6 subnet and range encoding */
732 b = identification_create_from_encoding(ID_IPV6_ADDR_SUBNET, chunk_empty);
733 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
734 b->destroy(b);
735 b = identification_create_from_encoding(ID_IPV6_ADDR_RANGE, chunk_empty);
736 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
737 b->destroy(b);
738 b = identification_create_from_encoding(ID_IPV6_ADDR_RANGE,
739 chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
740 0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0xff,
741 0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
742 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 ));
743 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
744 b->destroy(b);
745
746 a->destroy(a);
747
748 /* Malformed IPv4 address encoding */
749 a = identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty);
750 ck_assert(id_matches(a, "0.0.0.0/0", ID_MATCH_NONE));
751 ck_assert(id_matches(a, "0.0.0.0-255.255.255.255", ID_MATCH_NONE));
752 a->destroy(a);
753
754 /* Malformed IPv6 address encoding */
755 a = identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty);
756 ck_assert(id_matches(a, "::/0", ID_MATCH_NONE));
757 ck_assert(id_matches(a, "::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", ID_MATCH_NONE));
758 a->destroy(a);
759 }
760 END_TEST
761
762 START_TEST(test_matches_string)
763 {
764 identification_t *a;
765
766 a = identification_create_from_string("moon@strongswan.org");
767
768 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_PERFECT));
769 ck_assert(id_matches(a, "*@strongswan.org", ID_MATCH_ONE_WILDCARD));
770 ck_assert(id_matches(a, "*@*.org", ID_MATCH_NONE));
771 ck_assert(id_matches(a, "*@*", ID_MATCH_NONE));
772 /* the following two are parsed as ID_FQDN, so no match */
773 ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_NONE));
774 ck_assert(id_matches(a, "*.org", ID_MATCH_NONE));
775 ck_assert(id_matches(a, "moon@*", ID_MATCH_NONE));
776 ck_assert(id_matches(a, "**", ID_MATCH_NONE));
777 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
778 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
779 a->destroy(a);
780
781 a = identification_create_from_string("vpn.strongswan.org");
782
783 ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_PERFECT));
784 ck_assert(id_matches(a, "*.strongswan.org", ID_MATCH_ONE_WILDCARD));
785 ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_ONE_WILDCARD));
786 ck_assert(id_matches(a, "*.org", ID_MATCH_ONE_WILDCARD));
787 ck_assert(id_matches(a, "*.strongswan.*", ID_MATCH_NONE));
788 ck_assert(id_matches(a, "*vpn.strongswan.org", ID_MATCH_NONE));
789 ck_assert(id_matches(a, "vpn.strongswan.*", ID_MATCH_NONE));
790 ck_assert(id_matches(a, "**", ID_MATCH_NONE));
791 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
792 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
793 a->destroy(a);
794 }
795 END_TEST
796
797 START_TEST(test_matches_empty)
798 {
799 identification_t *a;
800
801 a = identification_create_from_encoding(_i, chunk_empty);
802
803 switch (_i)
804 {
805 case ID_ANY:
806 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
807 break;
808 case ID_IPV4_ADDR:
809 ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_NONE));
810 break;
811 case ID_FQDN:
812 ck_assert(id_matches(a, "moon.strongswan.org", ID_MATCH_NONE));
813 break;
814 case ID_USER_FQDN:
815 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
816 break;
817 case ID_IPV6_ADDR:
818 ck_assert(id_matches(a, "fec0::1", ID_MATCH_NONE));
819 break;
820 case ID_DER_ASN1_DN:
821 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon",
822 ID_MATCH_NONE));
823 break;
824 case ID_KEY_ID:
825 ck_assert(id_matches(a, "@#12345678", ID_MATCH_NONE));
826 break;
827 case ID_DER_ASN1_GN:
828 case ID_IPV4_ADDR_SUBNET:
829 case ID_IPV6_ADDR_SUBNET:
830 case ID_IPV4_ADDR_RANGE:
831 case ID_IPV6_ADDR_RANGE:
832 /* currently not tested */
833 break;
834 }
835
836 a->destroy(a);
837 }
838 END_TEST
839
840 static bool id_matches_rev(identification_t *a, char *b_str, id_match_t expected)
841 {
842 identification_t *b;
843 id_match_t match;
844
845 b = identification_create_from_string(b_str);
846 match = b->matches(b, a);
847 b->destroy(b);
848 return match == expected;
849 }
850
851 START_TEST(test_matches_empty_reverse)
852 {
853 identification_t *a;
854
855 a = identification_create_from_encoding(_i, chunk_empty);
856
857 switch (_i)
858 {
859 case ID_ANY:
860 ck_assert(id_matches_rev(a, "%any", ID_MATCH_ANY));
861 break;
862 case ID_IPV4_ADDR:
863 ck_assert(id_matches_rev(a, "192.168.1.1", ID_MATCH_NONE));
864 break;
865 case ID_FQDN:
866 ck_assert(id_matches_rev(a, "moon.strongswan.org", ID_MATCH_NONE));
867 break;
868 case ID_USER_FQDN:
869 ck_assert(id_matches_rev(a, "moon@strongswan.org", ID_MATCH_NONE));
870 break;
871 case ID_IPV6_ADDR:
872 ck_assert(id_matches_rev(a, "fec0::1", ID_MATCH_NONE));
873 break;
874 case ID_DER_ASN1_DN:
875 ck_assert(id_matches_rev(a, "C=CH, E=moon@strongswan.org, CN=moon",
876 ID_MATCH_NONE));
877 break;
878 case ID_KEY_ID:
879 ck_assert(id_matches_rev(a, "@#12345678", ID_MATCH_NONE));
880 break;
881 case ID_DER_ASN1_GN:
882 case ID_IPV4_ADDR_SUBNET:
883 case ID_IPV6_ADDR_SUBNET:
884 case ID_IPV4_ADDR_RANGE:
885 case ID_IPV6_ADDR_RANGE:
886 /* currently not tested */
887 break;
888 }
889
890 a->destroy(a);
891 }
892 END_TEST
893
894 /*******************************************************************************
895 * identification hashing
896 */
897
898 static bool id_hash_equals(char *str, char *b_str)
899 {
900 identification_t *a, *b;
901 bool success = FALSE;
902
903 a = identification_create_from_string(str);
904 b = identification_create_from_string(b_str ?: str);
905 success = a->hash(a, 0) == b->hash(b, 0);
906 a->destroy(a);
907 b->destroy(b);
908 return success;
909 }
910
911 START_TEST(test_hash)
912 {
913 ck_assert(id_hash_equals("moon@strongswan.org", NULL));
914 ck_assert(id_hash_equals("vpn.strongswan.org", NULL));
915 ck_assert(id_hash_equals("192.168.1.1", NULL));
916 ck_assert(id_hash_equals("C=CH", NULL));
917
918 ck_assert(!id_hash_equals("moon@strongswan.org", "sun@strongswan.org"));
919 ck_assert(!id_hash_equals("vpn.strongswan.org", "*.strongswan.org"));
920 ck_assert(!id_hash_equals("192.168.1.1", "192.168.1.2"));
921 ck_assert(!id_hash_equals("C=CH", "C=DE"));
922 ck_assert(!id_hash_equals("fqdn:strongswan.org", "keyid:strongswan.org"));
923 }
924 END_TEST
925
926 START_TEST(test_hash_any)
927 {
928 ck_assert(id_hash_equals("%any", NULL));
929 ck_assert(id_hash_equals("%any", "0.0.0.0"));
930 ck_assert(id_hash_equals("%any", "*"));
931 ck_assert(id_hash_equals("%any", ""));
932
933 ck_assert(!id_hash_equals("%any", "any"));
934 }
935 END_TEST
936
937 START_TEST(test_hash_dn)
938 {
939 identification_t *a, *b;
940
941 /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
942 * UTF8STRING) */
943 a = identification_create_from_data(chunk_from_chars(
944 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
945 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31,
946 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
947 0x13, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
948 0x53, 0x77, 0x61, 0x6e));
949 b = identification_create_from_data(chunk_from_chars(
950 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
951 0x55, 0x04, 0x06, 0x0c, 0x02, 0x43, 0x48, 0x31,
952 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
953 0x0c, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
954 0x53, 0x77, 0x61, 0x6e));
955 ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
956 ck_assert(a->equals(a, b));
957 a->destroy(a);
958 b->destroy(b);
959 }
960 END_TEST
961
962 START_TEST(test_hash_inc)
963 {
964 identification_t *a;
965
966 a = identification_create_from_string("vpn.strongswan.org");
967 ck_assert(a->hash(a, 0) != a->hash(a, 1));
968 a->destroy(a);
969
970 a = identification_create_from_string("C=CH, O=strongSwan");
971 ck_assert(a->hash(a, 0) != a->hash(a, 1));
972 a->destroy(a);
973 }
974 END_TEST
975
976 /*******************************************************************************
977 * identification part enumeration
978 */
979
980 START_TEST(test_parts)
981 {
982 identification_t *id;
983 enumerator_t *enumerator;
984 id_part_t part;
985 chunk_t data;
986 int i = 0;
987
988 id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
989
990 enumerator = id->create_part_enumerator(id);
991 while (enumerator->enumerate(enumerator, &part, &data))
992 {
993 switch (i++)
994 {
995 case 0:
996 ck_assert(part == ID_PART_RDN_C &&
997 chunk_equals(data, chunk_create("CH", 2)));
998 break;
999 case 1:
1000 ck_assert(part == ID_PART_RDN_O &&
1001 chunk_equals(data, chunk_from_str("strongSwan")));
1002 break;
1003 case 2:
1004 ck_assert(part == ID_PART_RDN_CN &&
1005 chunk_equals(data, chunk_from_str("tester")));
1006 break;
1007 default:
1008 fail("unexpected identification part %d", part);
1009 }
1010 }
1011 ck_assert_int_eq(i, 3);
1012 enumerator->destroy(enumerator);
1013 id->destroy(id);
1014 }
1015 END_TEST
1016
1017 /*******************************************************************************
1018 * wildcards
1019 */
1020
1021 static bool id_contains_wildcards(char *string)
1022 {
1023 identification_t *id;
1024 bool contains;
1025
1026 id = identification_create_from_string(string);
1027 contains = id->contains_wildcards(id);
1028 id->destroy(id);
1029 return contains;
1030 }
1031
1032 START_TEST(test_contains_wildcards)
1033 {
1034 ck_assert(id_contains_wildcards("%any"));
1035 ck_assert(id_contains_wildcards("C=*, O=strongSwan, CN=gw"));
1036 ck_assert(id_contains_wildcards("C=CH, O=strongSwan, CN=*"));
1037 ck_assert(id_contains_wildcards("*@strongswan.org"));
1038 ck_assert(id_contains_wildcards("*.strongswan.org"));
1039 ck_assert(!id_contains_wildcards("C=**, O=a*, CN=*a"));
1040 }
1041 END_TEST
1042
1043 /*******************************************************************************
1044 * clone
1045 */
1046
1047 START_TEST(test_clone)
1048 {
1049 identification_t *a, *b;
1050 chunk_t a_enc, b_enc;
1051
1052 a = identification_create_from_string("moon@strongswan.org");
1053 a_enc = a->get_encoding(a);
1054 b = a->clone(a);
1055 ck_assert(b != NULL);
1056 ck_assert(a != b);
1057 b_enc = b->get_encoding(b);
1058 ck_assert(a_enc.ptr != b_enc.ptr);
1059 ck_assert(chunk_equals(a_enc, b_enc));
1060 a->destroy(a);
1061 b->destroy(b);
1062 }
1063 END_TEST
1064
1065 Suite *identification_suite_create()
1066 {
1067 Suite *s;
1068 TCase *tc;
1069
1070 s = suite_create("identification");
1071
1072 tc = tcase_create("create");
1073 tcase_add_test(tc, test_from_encoding);
1074 tcase_add_test(tc, test_from_data);
1075 tcase_add_test(tc, test_from_sockaddr);
1076 tcase_add_loop_test(tc, test_from_string, 0, countof(string_data));
1077 suite_add_tcase(s, tc);
1078
1079 tc = tcase_create("printf_hook");
1080 tcase_add_test(tc, test_printf_hook);
1081 tcase_add_test(tc, test_printf_hook_width);
1082 suite_add_tcase(s, tc);
1083
1084 tc = tcase_create("equals");
1085 tcase_add_test(tc, test_equals);
1086 tcase_add_test(tc, test_equals_any);
1087 tcase_add_test(tc, test_equals_binary);
1088 tcase_add_test(tc, test_equals_fqdn);
1089 tcase_add_loop_test(tc, test_equals_empty, ID_ANY, ID_KEY_ID + 1);
1090 suite_add_tcase(s, tc);
1091
1092 tc = tcase_create("matches");
1093 tcase_add_test(tc, test_matches);
1094 tcase_add_test(tc, test_matches_any);
1095 tcase_add_test(tc, test_matches_binary);
1096 tcase_add_test(tc, test_matches_range);
1097 tcase_add_test(tc, test_matches_string);
1098 tcase_add_loop_test(tc, test_matches_empty, ID_ANY, ID_KEY_ID + 1);
1099 tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
1100 suite_add_tcase(s, tc);
1101
1102 tc = tcase_create("hash");
1103 tcase_add_test(tc, test_hash);
1104 tcase_add_test(tc, test_hash_any);
1105 tcase_add_test(tc, test_hash_dn);
1106 tcase_add_test(tc, test_hash_inc);
1107 suite_add_tcase(s, tc);
1108
1109 tc = tcase_create("part enumeration");
1110 tcase_add_test(tc, test_parts);
1111 suite_add_tcase(s, tc);
1112
1113 tc = tcase_create("wildcards");
1114 tcase_add_test(tc, test_contains_wildcards);
1115 suite_add_tcase(s, tc);
1116
1117 tc = tcase_create("clone");
1118 tcase_add_test(tc, test_clone);
1119 suite_add_tcase(s, tc);
1120
1121 return s;
1122 }