Implemented IPv4/IPv6 subnet and range identities
[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 { "{1}:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK,
238 .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
239 { "{0x02}:tester", ID_FQDN, { .type = ENC_STRING,
240 .data.s = "tester" }},
241 { "{99}:somedata", 99, { .type = ENC_STRING,
242 .data.s = "somedata" }},
243 };
244
245 START_TEST(test_from_string)
246 {
247 identification_t *a;
248 chunk_t encoding, expected = chunk_empty;
249 char *id;
250
251 id = string_data[_i].id;
252 a = identification_create_from_string(id);
253 fail_unless(a->get_type(a) == string_data[_i].type,
254 "type of id '%s' is %N, %N expected", id,
255 id_type_names, a->get_type(a),
256 id_type_names, string_data[_i].type);
257
258 encoding = a->get_encoding(a);
259 switch (string_data[_i].result.type)
260 {
261 case ENC_SIMPLE:
262 expected = chunk_from_str(string_data[_i].id);
263 break;
264 case ENC_STRING:
265 expected = chunk_from_str(string_data[_i].result.data.s);
266 break;
267 case ENC_CHUNK:
268 expected = string_data[_i].result.data.c;
269 break;
270 default:
271 fail("unexpected result type");
272 }
273
274 ck_assert(!id || (char*)encoding.ptr != id);
275 if (expected.ptr)
276 {
277 fail_unless(chunk_equals(encoding, expected),
278 "parsing '%s' failed\nencoding %B\nexpected %B\n",
279 id, &encoding, &expected);
280 }
281 else
282 {
283 ck_assert(encoding.ptr == NULL);
284 ck_assert(encoding.len == 0);
285 }
286 a->destroy(a);
287 }
288 END_TEST
289
290 /*******************************************************************************
291 * printf_hook
292 */
293
294 static void string_equals(char *a_str, char *b_str)
295 {
296 identification_t *b;
297 char buf[128];
298
299 b = b_str ? identification_create_from_string(b_str) : NULL;
300 snprintf(buf, sizeof(buf), "%Y", b);
301 DESTROY_IF(b);
302 ck_assert_str_eq(a_str, buf);
303 }
304
305 static void string_equals_id(char *a_str, identification_t *b)
306 {
307 char buf[128];
308
309 snprintf(buf, sizeof(buf), "%Y", b);
310 DESTROY_IF(b);
311 ck_assert_str_eq(a_str, buf);
312 }
313
314 START_TEST(test_printf_hook)
315 {
316 string_equals("(null)", NULL);
317 string_equals("%any", "");
318 string_equals("%any", "%any");
319 string_equals("%any", "*");
320
321 string_equals("192.168.1.1", "192.168.1.1");
322 string_equals_id("(invalid ID_IPV4_ADDR)",
323 identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty));
324 string_equals("192.168.1.1/32", "192.168.1.1/32");
325 string_equals("192.168.1.2/31", "192.168.1.2/31");
326 string_equals("192.168.1.0/24", "192.168.1.0/24");
327 string_equals("192.168.2.0/23", "192.168.2.0/23");
328 string_equals("0.0.0.0/0", "0.0.0.0/0");
329 string_equals_id("(invalid ID_IPV4_ADDR_SUBNET)",
330 identification_create_from_encoding(ID_IPV4_ADDR_SUBNET, chunk_empty));
331 string_equals("192.168.1.1-192.168.1.254", "192.168.1.1-192.168.1.254");
332 string_equals("0.0.0.0-255.255.255.255", "0.0.0.0-255.255.255.255");
333 string_equals_id("(invalid ID_IPV4_ADDR_RANGE)",
334 identification_create_from_encoding(ID_IPV4_ADDR_RANGE, chunk_empty));
335 string_equals("fec0::1", "fec0::1");
336 string_equals("fec0::1", "fec0:0:0::1");
337 string_equals_id("(invalid ID_IPV6_ADDR)",
338 identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty));
339 string_equals("fec0::1/128", "fec0::1/128");
340 string_equals("fec0::2/127", "fec0::2/127");
341 string_equals("fec0::100/120", "fec0::100/120");
342 string_equals("::/0", "::/0");
343 string_equals_id("(invalid ID_IPV6_ADDR_SUBNET)",
344 identification_create_from_encoding(ID_IPV6_ADDR_SUBNET, chunk_empty));
345 string_equals("fec0::1-fec0::4fff", "fec0::1-fec0::4fff");
346 string_equals_id("(invalid ID_IPV6_ADDR_RANGE)",
347 identification_create_from_encoding(ID_IPV6_ADDR_RANGE, chunk_empty));
348 string_equals_id("(unknown ID type: 255)",
349 identification_create_from_encoding(255, chunk_empty));
350
351 string_equals("moon@strongswan.org", "moon@strongswan.org");
352 string_equals("MOON@STRONGSWAN.ORG", "MOON@STRONGSWAN.ORG");
353 /* non-printable characters */
354 string_equals_id("????@strongswan.org", identification_create_from_encoding(ID_RFC822_ADDR,
355 chunk_from_chars(0xfa, 0xfb, 0xfc, 0xfd, 0x40, 0x73, 0x74, 0x72,
356 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
357 0x6f, 0x72, 0x67)));
358
359 /* not a DN => ID_KEY_ID => no normalization */
360 string_equals("C=CH, AsdF=asdf", "C=CH, AsdF=asdf");
361 string_equals_id("moon@strongswan.org", identification_create_from_encoding(ID_KEY_ID,
362 chunk_from_str("moon@strongswan.org")));
363 /* non-printable characters */
364 string_equals_id("de:ad:be:ef", identification_create_from_encoding(ID_KEY_ID,
365 chunk_from_chars(0xde, 0xad, 0xbe, 0xef)));
366 /* printable characters */
367 string_equals_id("ABCDEFGHIJKLMNOPQRS",
368 identification_create_from_encoding(ID_KEY_ID,
369 chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
370 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
371 0x51, 0x52, 0x53)));
372 /* ABCDEFGHIJKLMNOPQRST is printable but has the length of a SHA1 hash */
373 string_equals_id("41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54",
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, 0x54)));
378
379 string_equals_id("", identification_create_from_encoding(ID_DER_ASN1_DN, chunk_empty));
380 string_equals("C=", "C=");
381 string_equals("C=", "C=,");
382 string_equals("C=", "C=, ");
383 string_equals("C=", "C= , ");
384 string_equals("C=, O=strongSwan", "C=, O=strongSwan");
385 string_equals("C=CH, O=", "C=CH, O=");
386 string_equals("C=CH, O=strongSwan, CN=strongswan.org",
387 "C=CH, O=strongSwan, CN=strongswan.org");
388 string_equals("CN=strongswan.org, O=strongSwan, C=CH",
389 "cn=strongswan.org, o=strongSwan, c=CH");
390 string_equals("C=CH, O=strongSwan, CN=strongswan.org",
391 "C=CH,O=strongSwan,CN=strongswan.org");
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
397 string_equals("C=CH, E=moon@strongswan.org, CN=moon",
398 "C=CH, email=moon@strongswan.org, CN=moon");
399 string_equals("C=CH, E=moon@strongswan.org, CN=moon",
400 "C=CH, emailAddress=moon@strongswan.org, CN=moon");
401
402 /* C=CH, telexNumber=123 (telexNumber is currently not recognized) */
403 string_equals_id("C=CH, 55:04:15=123", identification_create_from_encoding(ID_DER_ASN1_DN,
404 chunk_from_chars(0x30, 0x19, 0x31, 0x17, 0x30, 0x09, 0x06, 0x03, 0x55,
405 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x0a, 0x06,
406 0x03, 0x55, 0x04, 0x15, 0x13, 0x03, 0x31, 0x32, 0x33)));
407 /* C=CH, O=strongSwan (but instead of a 2nd OID -0x06- we got NULL -0x05) */
408 string_equals_id("C=CH, (invalid ID_DER_ASN1_DN)", identification_create_from_encoding(ID_DER_ASN1_DN,
409 chunk_from_chars(0x30, 0x20, 0x31, 0x1e, 0x30, 0x09, 0x06, 0x03, 0x55,
410 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x11, 0x05,
411 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x73, 0x74, 0x72,
412 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e)));
413 /* moon@strongswan.org as GN */
414 string_equals_id("(ASN.1 general name)", identification_create_from_encoding(ID_DER_ASN1_GN,
415 chunk_from_chars(0x81, 0x14, 0x6d, 0x6f, 0x6f, 0x6e, 0x40, 0x73, 0x74,
416 0x72, 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
417 0x6f, 0x72, 0x67)));
418 }
419 END_TEST
420
421 START_TEST(test_printf_hook_width)
422 {
423 identification_t *a;
424 char buf[128];
425
426 a = identification_create_from_string("moon@strongswan.org");
427 snprintf(buf, sizeof(buf), "%25Y", a);
428 ck_assert_str_eq(" moon@strongswan.org", buf);
429 snprintf(buf, sizeof(buf), "%-*Y", 25, a);
430 ck_assert_str_eq("moon@strongswan.org ", buf);
431 snprintf(buf, sizeof(buf), "%5Y", a);
432 ck_assert_str_eq("moon@strongswan.org", buf);
433 DESTROY_IF(a);
434 }
435 END_TEST
436
437 /*******************************************************************************
438 * equals
439 */
440
441 static bool id_equals(identification_t *a, char *b_str)
442 {
443 identification_t *b;
444 bool equals;
445
446 b = identification_create_from_string(b_str);
447 equals = a->equals(a, b);
448 ck_assert_int_eq(equals, b->equals(b, a));
449 b->destroy(b);
450 return equals;
451 }
452
453 START_TEST(test_equals)
454 {
455 identification_t *a;
456 chunk_t encoding, fuzzed;
457 int i;
458
459 /* this test also tests identification_create_from_string with DNs */
460 a = identification_create_from_string(
461 "C=CH, E=moon@strongswan.org, CN=moon");
462
463 ck_assert(id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
464 ck_assert(id_equals(a, "C==CH , E==moon@strongswan.org , CN==moon"));
465 ck_assert(id_equals(a, " C=CH, E=moon@strongswan.org, CN=moon "));
466 ck_assert(id_equals(a, "C=ch, E=moon@STRONGSWAN.ORG, CN=Moon"));
467 ck_assert(id_equals(a, "/C=CH/E=moon@strongswan.org/CN=moon"));
468 ck_assert(id_equals(a, " / C=CH / E=moon@strongswan.org / CN=moon"));
469
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=CN, E=moon@strongswan.org, CN=moon"));
474 ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
475 ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
476
477 encoding = chunk_clone(a->get_encoding(a));
478 a->destroy(a);
479
480 /* simple fuzzing, increment each byte of encoding */
481 for (i = 0; i < encoding.len; i++)
482 {
483 if (i == 11 || i == 30 || i == 60)
484 { /* skip ASN.1 type fields, as equals() handles them graceful */
485 continue;
486 }
487 fuzzed = chunk_clone(encoding);
488 fuzzed.ptr[i]++;
489 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
490 if (id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"))
491 {
492 printf("%d %B\n%B\n", i, &fuzzed, &encoding);
493 }
494 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
495 a->destroy(a);
496 free(fuzzed.ptr);
497 }
498
499 /* and decrement each byte of encoding */
500 for (i = 0; i < encoding.len; i++)
501 {
502 if (i == 11 || i == 30 || i == 60)
503 {
504 continue;
505 }
506 fuzzed = chunk_clone(encoding);
507 fuzzed.ptr[i]--;
508 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
509 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
510 a->destroy(a);
511 free(fuzzed.ptr);
512 }
513 free(encoding.ptr);
514 }
515 END_TEST
516
517 START_TEST(test_equals_any)
518 {
519 identification_t *a, *b;
520
521 a = identification_create_from_string("%any");
522 b = identification_create_from_encoding(ID_ANY, chunk_empty);
523 ck_assert(a->equals(a, b));
524 ck_assert(b->equals(b, a));
525 b->destroy(b);
526
527 b = identification_create_from_string("C=CH, O=strongSwan, CN=strongswan.org");
528 ck_assert(!a->equals(a, b));
529 ck_assert(!b->equals(b, a));
530 a->destroy(a);
531 b->destroy(b);
532 }
533 END_TEST
534
535 START_TEST(test_equals_binary)
536 {
537 identification_t *a, *b;
538 chunk_t encoding;
539
540 encoding = chunk_from_str("foobar=");
541 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
542 a = identification_create_from_string("foobar=");
543 ck_assert(a->get_type(a) == ID_KEY_ID);
544 b = identification_create_from_encoding(ID_KEY_ID, encoding);
545 ck_assert(a->equals(a, b));
546 a->destroy(a);
547 b->destroy(b);
548 }
549 END_TEST
550
551 START_TEST(test_equals_fqdn)
552 {
553 identification_t *a;
554
555 a = identification_create_from_string("ipsec.strongswan.org");
556 ck_assert(id_equals(a, "IPSEC.strongswan.org"));
557 ck_assert(id_equals(a, "ipsec.strongSwan.org"));
558 ck_assert(id_equals(a, "ipsec.strongSwan.ORG"));
559 ck_assert(!id_equals(a, "strongswan.org"));
560 a->destroy(a);
561 }
562 END_TEST
563
564 START_TEST(test_equals_empty)
565 {
566 identification_t *a;
567
568 a = identification_create_from_encoding(_i, chunk_empty);
569
570 switch (_i)
571 {
572 case ID_ANY:
573 ck_assert(id_equals(a, "%any"));
574 break;
575 case ID_IPV4_ADDR:
576 ck_assert(!id_equals(a, "192.168.1.1"));
577 break;
578 case ID_FQDN:
579 ck_assert(!id_equals(a, "moon.strongswan.org"));
580 break;
581 case ID_USER_FQDN:
582 ck_assert(!id_equals(a, "moon@strongswan.org"));
583 break;
584 case ID_IPV6_ADDR:
585 ck_assert(!id_equals(a, "fec0::1"));
586 break;
587 case ID_DER_ASN1_DN:
588 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
589 break;
590 case ID_KEY_ID:
591 ck_assert(!id_equals(a, "@#12345678"));
592 break;
593 case ID_DER_ASN1_GN:
594 case ID_IPV4_ADDR_SUBNET:
595 case ID_IPV6_ADDR_SUBNET:
596 case ID_IPV4_ADDR_RANGE:
597 case ID_IPV6_ADDR_RANGE:
598 /* currently not tested */
599 break;
600 }
601
602 a->destroy(a);
603 }
604 END_TEST
605
606 /*******************************************************************************
607 * matches
608 */
609
610 static bool id_matches(identification_t *a, char *b_str, id_match_t expected)
611 {
612 identification_t *b;
613 id_match_t match;
614
615 b = identification_create_from_string(b_str);
616 match = a->matches(a, b);
617 b->destroy(b);
618 return match == expected;
619 }
620
621 START_TEST(test_matches)
622 {
623 identification_t *a;
624
625 a = identification_create_from_string("C=CH, E=moon@strongswan.org, CN=moon");
626
627 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon", ID_MATCH_PERFECT));
628 ck_assert(id_matches(a, "C=CH, E=*@strongswan.org, CN=moon", ID_MATCH_NONE));
629 ck_assert(id_matches(a, "C=CH, E=*, CN=moon", ID_MATCH_ONE_WILDCARD));
630 ck_assert(id_matches(a, "C=CH, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 1));
631 ck_assert(id_matches(a, "C=*, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 2));
632 ck_assert(id_matches(a, "C=*, E=*, CN=*, O=BADInc", ID_MATCH_NONE));
633 ck_assert(id_matches(a, "C=*, E=*", ID_MATCH_NONE));
634 ck_assert(id_matches(a, "C=*, E=a@b.c, CN=*", ID_MATCH_NONE));
635 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
636
637 a->destroy(a);
638 }
639 END_TEST
640
641 START_TEST(test_matches_any)
642 {
643 identification_t *a;
644
645 a = identification_create_from_string("%any");
646
647 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
648 ck_assert(id_matches(a, "", ID_MATCH_ANY));
649 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
650 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
651 ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_NONE));
652 a->destroy(a);
653 }
654 END_TEST
655
656 START_TEST(test_matches_binary)
657 {
658 identification_t *a;
659
660 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
661 a = identification_create_from_string("foo=bar");
662 ck_assert(a->get_type(a) == ID_KEY_ID);
663 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
664 ck_assert(id_matches(a, "foo=bar", ID_MATCH_PERFECT));
665 ck_assert(id_matches(a, "bar=foo", ID_MATCH_NONE));
666 ck_assert(id_matches(a, "*=bar", ID_MATCH_NONE));
667 ck_assert(id_matches(a, "foo=*", ID_MATCH_NONE));
668 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
669 a->destroy(a);
670 }
671 END_TEST
672
673 START_TEST(test_matches_range)
674 {
675 identification_t *a, *b;
676
677 /* IPv4 addresses */
678 a = identification_create_from_string("192.168.1.1");
679 ck_assert(a->get_type(a) == ID_IPV4_ADDR);
680 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
681 ck_assert(id_matches(a, "0.0.0.0/0", ID_MATCH_MAX_WILDCARDS));
682 ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_PERFECT));
683 ck_assert(id_matches(a, "192.168.1.2", ID_MATCH_NONE));
684 ck_assert(id_matches(a, "192.168.1.1/32", ID_MATCH_PERFECT));
685 ck_assert(id_matches(a, "192.168.1.0/32", ID_MATCH_NONE));
686 ck_assert(id_matches(a, "192.168.1.0/24", ID_MATCH_ONE_WILDCARD));
687 ck_assert(id_matches(a, "192.168.0.0/24", ID_MATCH_NONE));
688 ck_assert(id_matches(a, "192.168.1.1-192.168.1.1", ID_MATCH_PERFECT));
689 ck_assert(id_matches(a, "192.168.1.0-192.168.1.64", ID_MATCH_ONE_WILDCARD));
690 ck_assert(id_matches(a, "192.168.1.2-192.168.1.64", ID_MATCH_NONE));
691 ck_assert(id_matches(a, "192.168.0.240-192.168.1.0", ID_MATCH_NONE));
692 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
693
694 /* Malformed IPv4 subnet and range encoding */
695 b = identification_create_from_encoding(ID_IPV4_ADDR_SUBNET, chunk_empty);
696 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
697 b->destroy(b);
698 b = identification_create_from_encoding(ID_IPV4_ADDR_RANGE, chunk_empty);
699 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
700 b->destroy(b);
701 b = identification_create_from_encoding(ID_IPV4_ADDR_RANGE,
702 chunk_from_chars(0xc0,0xa8,0x01,0x28,0xc0,0xa8,0x01,0x00));
703 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
704 b->destroy(b);
705
706 a->destroy(a);
707
708 /* IPv6 addresses */
709 a = identification_create_from_string("fec0::1");
710 ck_assert(a->get_type(a) == ID_IPV6_ADDR);
711 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
712 ck_assert(id_matches(a, "::/0", ID_MATCH_MAX_WILDCARDS));
713 ck_assert(id_matches(a, "fec0::1", ID_MATCH_PERFECT));
714 ck_assert(id_matches(a, "fec0::2", ID_MATCH_NONE));
715 ck_assert(id_matches(a, "fec0::1/128", ID_MATCH_PERFECT));
716 ck_assert(id_matches(a, "fec0::/128", ID_MATCH_NONE));
717 ck_assert(id_matches(a, "fec0::/120", ID_MATCH_ONE_WILDCARD));
718 ck_assert(id_matches(a, "fec0::100/120", ID_MATCH_NONE));
719 ck_assert(id_matches(a, "fec0::1-fec0::1", ID_MATCH_PERFECT));
720 ck_assert(id_matches(a, "fec0::0-fec0::5", ID_MATCH_ONE_WILDCARD));
721 ck_assert(id_matches(a, "fec0::4001-fec0::4ffe", ID_MATCH_NONE));
722 ck_assert(id_matches(a, "feb0::1-fec0::0", ID_MATCH_NONE));
723 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
724
725 /* Malformed IPv6 subnet and range encoding */
726 b = identification_create_from_encoding(ID_IPV6_ADDR_SUBNET, chunk_empty);
727 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
728 b->destroy(b);
729 b = identification_create_from_encoding(ID_IPV6_ADDR_RANGE, chunk_empty);
730 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
731 b->destroy(b);
732 b = identification_create_from_encoding(ID_IPV6_ADDR_RANGE,
733 chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
734 0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0xff,
735 0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
736 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 ));
737 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
738 b->destroy(b);
739
740 a->destroy(a);
741
742 /* Malformed IPv4 address encoding */
743 a = identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty);
744 ck_assert(id_matches(a, "0.0.0.0/0", ID_MATCH_NONE));
745 ck_assert(id_matches(a, "0.0.0.0-255.255.255.255", ID_MATCH_NONE));
746 a->destroy(a);
747
748 /* Malformed IPv6 address encoding */
749 a = identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty);
750 ck_assert(id_matches(a, "::/0", ID_MATCH_NONE));
751 ck_assert(id_matches(a, "::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", ID_MATCH_NONE));
752 a->destroy(a);
753 }
754 END_TEST
755
756 START_TEST(test_matches_string)
757 {
758 identification_t *a;
759
760 a = identification_create_from_string("moon@strongswan.org");
761
762 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_PERFECT));
763 ck_assert(id_matches(a, "*@strongswan.org", ID_MATCH_ONE_WILDCARD));
764 ck_assert(id_matches(a, "*@*.org", ID_MATCH_NONE));
765 ck_assert(id_matches(a, "*@*", ID_MATCH_NONE));
766 /* the following two are parsed as ID_FQDN, so no match */
767 ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_NONE));
768 ck_assert(id_matches(a, "*.org", ID_MATCH_NONE));
769 ck_assert(id_matches(a, "moon@*", ID_MATCH_NONE));
770 ck_assert(id_matches(a, "**", ID_MATCH_NONE));
771 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
772 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
773 a->destroy(a);
774
775 a = identification_create_from_string("vpn.strongswan.org");
776
777 ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_PERFECT));
778 ck_assert(id_matches(a, "*.strongswan.org", ID_MATCH_ONE_WILDCARD));
779 ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_ONE_WILDCARD));
780 ck_assert(id_matches(a, "*.org", ID_MATCH_ONE_WILDCARD));
781 ck_assert(id_matches(a, "*.strongswan.*", ID_MATCH_NONE));
782 ck_assert(id_matches(a, "*vpn.strongswan.org", ID_MATCH_NONE));
783 ck_assert(id_matches(a, "vpn.strongswan.*", ID_MATCH_NONE));
784 ck_assert(id_matches(a, "**", ID_MATCH_NONE));
785 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
786 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
787 a->destroy(a);
788 }
789 END_TEST
790
791 START_TEST(test_matches_empty)
792 {
793 identification_t *a;
794
795 a = identification_create_from_encoding(_i, chunk_empty);
796
797 switch (_i)
798 {
799 case ID_ANY:
800 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
801 break;
802 case ID_IPV4_ADDR:
803 ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_NONE));
804 break;
805 case ID_FQDN:
806 ck_assert(id_matches(a, "moon.strongswan.org", ID_MATCH_NONE));
807 break;
808 case ID_USER_FQDN:
809 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
810 break;
811 case ID_IPV6_ADDR:
812 ck_assert(id_matches(a, "fec0::1", ID_MATCH_NONE));
813 break;
814 case ID_DER_ASN1_DN:
815 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon",
816 ID_MATCH_NONE));
817 break;
818 case ID_KEY_ID:
819 ck_assert(id_matches(a, "@#12345678", ID_MATCH_NONE));
820 break;
821 case ID_DER_ASN1_GN:
822 case ID_IPV4_ADDR_SUBNET:
823 case ID_IPV6_ADDR_SUBNET:
824 case ID_IPV4_ADDR_RANGE:
825 case ID_IPV6_ADDR_RANGE:
826 /* currently not tested */
827 break;
828 }
829
830 a->destroy(a);
831 }
832 END_TEST
833
834 static bool id_matches_rev(identification_t *a, char *b_str, id_match_t expected)
835 {
836 identification_t *b;
837 id_match_t match;
838
839 b = identification_create_from_string(b_str);
840 match = b->matches(b, a);
841 b->destroy(b);
842 return match == expected;
843 }
844
845 START_TEST(test_matches_empty_reverse)
846 {
847 identification_t *a;
848
849 a = identification_create_from_encoding(_i, chunk_empty);
850
851 switch (_i)
852 {
853 case ID_ANY:
854 ck_assert(id_matches_rev(a, "%any", ID_MATCH_ANY));
855 break;
856 case ID_IPV4_ADDR:
857 ck_assert(id_matches_rev(a, "192.168.1.1", ID_MATCH_NONE));
858 break;
859 case ID_FQDN:
860 ck_assert(id_matches_rev(a, "moon.strongswan.org", ID_MATCH_NONE));
861 break;
862 case ID_USER_FQDN:
863 ck_assert(id_matches_rev(a, "moon@strongswan.org", ID_MATCH_NONE));
864 break;
865 case ID_IPV6_ADDR:
866 ck_assert(id_matches_rev(a, "fec0::1", ID_MATCH_NONE));
867 break;
868 case ID_DER_ASN1_DN:
869 ck_assert(id_matches_rev(a, "C=CH, E=moon@strongswan.org, CN=moon",
870 ID_MATCH_NONE));
871 break;
872 case ID_KEY_ID:
873 ck_assert(id_matches_rev(a, "@#12345678", ID_MATCH_NONE));
874 break;
875 case ID_DER_ASN1_GN:
876 case ID_IPV4_ADDR_SUBNET:
877 case ID_IPV6_ADDR_SUBNET:
878 case ID_IPV4_ADDR_RANGE:
879 case ID_IPV6_ADDR_RANGE:
880 /* currently not tested */
881 break;
882 }
883
884 a->destroy(a);
885 }
886 END_TEST
887
888 /*******************************************************************************
889 * identification hashing
890 */
891
892 static bool id_hash_equals(char *str, char *b_str)
893 {
894 identification_t *a, *b;
895 bool success = FALSE;
896
897 a = identification_create_from_string(str);
898 b = identification_create_from_string(b_str ?: str);
899 success = a->hash(a, 0) == b->hash(b, 0);
900 a->destroy(a);
901 b->destroy(b);
902 return success;
903 }
904
905 START_TEST(test_hash)
906 {
907 ck_assert(id_hash_equals("moon@strongswan.org", NULL));
908 ck_assert(id_hash_equals("vpn.strongswan.org", NULL));
909 ck_assert(id_hash_equals("192.168.1.1", NULL));
910 ck_assert(id_hash_equals("C=CH", NULL));
911
912 ck_assert(!id_hash_equals("moon@strongswan.org", "sun@strongswan.org"));
913 ck_assert(!id_hash_equals("vpn.strongswan.org", "*.strongswan.org"));
914 ck_assert(!id_hash_equals("192.168.1.1", "192.168.1.2"));
915 ck_assert(!id_hash_equals("C=CH", "C=DE"));
916 ck_assert(!id_hash_equals("fqdn:strongswan.org", "keyid:strongswan.org"));
917 }
918 END_TEST
919
920 START_TEST(test_hash_any)
921 {
922 ck_assert(id_hash_equals("%any", NULL));
923 ck_assert(id_hash_equals("%any", "0.0.0.0"));
924 ck_assert(id_hash_equals("%any", "*"));
925 ck_assert(id_hash_equals("%any", ""));
926
927 ck_assert(!id_hash_equals("%any", "any"));
928 }
929 END_TEST
930
931 START_TEST(test_hash_dn)
932 {
933 identification_t *a, *b;
934
935 /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
936 * UTF8STRING) */
937 a = identification_create_from_data(chunk_from_chars(
938 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
939 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31,
940 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
941 0x13, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
942 0x53, 0x77, 0x61, 0x6e));
943 b = identification_create_from_data(chunk_from_chars(
944 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
945 0x55, 0x04, 0x06, 0x0c, 0x02, 0x43, 0x48, 0x31,
946 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
947 0x0c, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
948 0x53, 0x77, 0x61, 0x6e));
949 ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
950 ck_assert(a->equals(a, b));
951 a->destroy(a);
952 b->destroy(b);
953 }
954 END_TEST
955
956 START_TEST(test_hash_inc)
957 {
958 identification_t *a;
959
960 a = identification_create_from_string("vpn.strongswan.org");
961 ck_assert(a->hash(a, 0) != a->hash(a, 1));
962 a->destroy(a);
963
964 a = identification_create_from_string("C=CH, O=strongSwan");
965 ck_assert(a->hash(a, 0) != a->hash(a, 1));
966 a->destroy(a);
967 }
968 END_TEST
969
970 /*******************************************************************************
971 * identification part enumeration
972 */
973
974 START_TEST(test_parts)
975 {
976 identification_t *id;
977 enumerator_t *enumerator;
978 id_part_t part;
979 chunk_t data;
980 int i = 0;
981
982 id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
983
984 enumerator = id->create_part_enumerator(id);
985 while (enumerator->enumerate(enumerator, &part, &data))
986 {
987 switch (i++)
988 {
989 case 0:
990 ck_assert(part == ID_PART_RDN_C &&
991 chunk_equals(data, chunk_create("CH", 2)));
992 break;
993 case 1:
994 ck_assert(part == ID_PART_RDN_O &&
995 chunk_equals(data, chunk_from_str("strongSwan")));
996 break;
997 case 2:
998 ck_assert(part == ID_PART_RDN_CN &&
999 chunk_equals(data, chunk_from_str("tester")));
1000 break;
1001 default:
1002 fail("unexpected identification part %d", part);
1003 }
1004 }
1005 ck_assert_int_eq(i, 3);
1006 enumerator->destroy(enumerator);
1007 id->destroy(id);
1008 }
1009 END_TEST
1010
1011 /*******************************************************************************
1012 * wildcards
1013 */
1014
1015 static bool id_contains_wildcards(char *string)
1016 {
1017 identification_t *id;
1018 bool contains;
1019
1020 id = identification_create_from_string(string);
1021 contains = id->contains_wildcards(id);
1022 id->destroy(id);
1023 return contains;
1024 }
1025
1026 START_TEST(test_contains_wildcards)
1027 {
1028 ck_assert(id_contains_wildcards("%any"));
1029 ck_assert(id_contains_wildcards("C=*, O=strongSwan, CN=gw"));
1030 ck_assert(id_contains_wildcards("C=CH, O=strongSwan, CN=*"));
1031 ck_assert(id_contains_wildcards("*@strongswan.org"));
1032 ck_assert(id_contains_wildcards("*.strongswan.org"));
1033 ck_assert(!id_contains_wildcards("C=**, O=a*, CN=*a"));
1034 }
1035 END_TEST
1036
1037 /*******************************************************************************
1038 * clone
1039 */
1040
1041 START_TEST(test_clone)
1042 {
1043 identification_t *a, *b;
1044 chunk_t a_enc, b_enc;
1045
1046 a = identification_create_from_string("moon@strongswan.org");
1047 a_enc = a->get_encoding(a);
1048 b = a->clone(a);
1049 ck_assert(b != NULL);
1050 ck_assert(a != b);
1051 b_enc = b->get_encoding(b);
1052 ck_assert(a_enc.ptr != b_enc.ptr);
1053 ck_assert(chunk_equals(a_enc, b_enc));
1054 a->destroy(a);
1055 b->destroy(b);
1056 }
1057 END_TEST
1058
1059 Suite *identification_suite_create()
1060 {
1061 Suite *s;
1062 TCase *tc;
1063
1064 s = suite_create("identification");
1065
1066 tc = tcase_create("create");
1067 tcase_add_test(tc, test_from_encoding);
1068 tcase_add_test(tc, test_from_data);
1069 tcase_add_test(tc, test_from_sockaddr);
1070 tcase_add_loop_test(tc, test_from_string, 0, countof(string_data));
1071 suite_add_tcase(s, tc);
1072
1073 tc = tcase_create("printf_hook");
1074 tcase_add_test(tc, test_printf_hook);
1075 tcase_add_test(tc, test_printf_hook_width);
1076 suite_add_tcase(s, tc);
1077
1078 tc = tcase_create("equals");
1079 tcase_add_test(tc, test_equals);
1080 tcase_add_test(tc, test_equals_any);
1081 tcase_add_test(tc, test_equals_binary);
1082 tcase_add_test(tc, test_equals_fqdn);
1083 tcase_add_loop_test(tc, test_equals_empty, ID_ANY, ID_KEY_ID + 1);
1084 suite_add_tcase(s, tc);
1085
1086 tc = tcase_create("matches");
1087 tcase_add_test(tc, test_matches);
1088 tcase_add_test(tc, test_matches_any);
1089 tcase_add_test(tc, test_matches_binary);
1090 tcase_add_test(tc, test_matches_range);
1091 tcase_add_test(tc, test_matches_string);
1092 tcase_add_loop_test(tc, test_matches_empty, ID_ANY, ID_KEY_ID + 1);
1093 tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
1094 suite_add_tcase(s, tc);
1095
1096 tc = tcase_create("hash");
1097 tcase_add_test(tc, test_hash);
1098 tcase_add_test(tc, test_hash_any);
1099 tcase_add_test(tc, test_hash_dn);
1100 tcase_add_test(tc, test_hash_inc);
1101 suite_add_tcase(s, tc);
1102
1103 tc = tcase_create("part enumeration");
1104 tcase_add_test(tc, test_parts);
1105 suite_add_tcase(s, tc);
1106
1107 tc = tcase_create("wildcards");
1108 tcase_add_test(tc, test_contains_wildcards);
1109 suite_add_tcase(s, tc);
1110
1111 tc = tcase_create("clone");
1112 tcase_add_test(tc, test_clone);
1113 suite_add_tcase(s, tc);
1114
1115 return s;
1116 }