unit-tests: Verify that E and emailAddress result in the same ID
[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, email=moon@strongswan.org, CN=moon"));
471 ck_assert(id_equals(a, "C=CH, emailAddress=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 ck_assert(id_equals(a, "/C=CH/E=moon@strongswan.org/CN=moon"));
476 ck_assert(id_equals(a, " / C=CH / E=moon@strongswan.org / CN=moon"));
477
478 ck_assert(!id_equals(a, "C=CH/E=moon@strongswan.org/CN=moon"));
479 ck_assert(!id_equals(a, "C=CH/E=moon@strongswan.org,CN=moon"));
480 ck_assert(!id_equals(a, "C=CH E=moon@strongswan.org CN=moon"));
481 ck_assert(!id_equals(a, "C=CN, E=moon@strongswan.org, CN=moon"));
482 ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
483 ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
484
485 encoding = chunk_clone(a->get_encoding(a));
486 a->destroy(a);
487
488 /* simple fuzzing, increment each byte of encoding */
489 for (i = 0; i < encoding.len; i++)
490 {
491 if (i == 11 || i == 30 || i == 60)
492 { /* skip ASN.1 type fields, as equals() handles them graceful */
493 continue;
494 }
495 fuzzed = chunk_clone(encoding);
496 fuzzed.ptr[i]++;
497 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
498 if (id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"))
499 {
500 printf("%d %B\n%B\n", i, &fuzzed, &encoding);
501 }
502 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
503 a->destroy(a);
504 free(fuzzed.ptr);
505 }
506
507 /* and decrement each byte of encoding */
508 for (i = 0; i < encoding.len; i++)
509 {
510 if (i == 11 || i == 30 || i == 60)
511 {
512 continue;
513 }
514 fuzzed = chunk_clone(encoding);
515 fuzzed.ptr[i]--;
516 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
517 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
518 a->destroy(a);
519 free(fuzzed.ptr);
520 }
521 free(encoding.ptr);
522 }
523 END_TEST
524
525 START_TEST(test_equals_any)
526 {
527 identification_t *a, *b;
528
529 a = identification_create_from_string("%any");
530 b = identification_create_from_encoding(ID_ANY, chunk_empty);
531 ck_assert(a->equals(a, b));
532 ck_assert(b->equals(b, a));
533 b->destroy(b);
534
535 b = identification_create_from_string("C=CH, O=strongSwan, CN=strongswan.org");
536 ck_assert(!a->equals(a, b));
537 ck_assert(!b->equals(b, a));
538 a->destroy(a);
539 b->destroy(b);
540 }
541 END_TEST
542
543 START_TEST(test_equals_binary)
544 {
545 identification_t *a, *b;
546 chunk_t encoding;
547
548 encoding = chunk_from_str("foobar=");
549 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
550 a = identification_create_from_string("foobar=");
551 ck_assert(a->get_type(a) == ID_KEY_ID);
552 b = identification_create_from_encoding(ID_KEY_ID, encoding);
553 ck_assert(a->equals(a, b));
554 a->destroy(a);
555 b->destroy(b);
556 }
557 END_TEST
558
559 START_TEST(test_equals_fqdn)
560 {
561 identification_t *a;
562
563 a = identification_create_from_string("ipsec.strongswan.org");
564 ck_assert(id_equals(a, "IPSEC.strongswan.org"));
565 ck_assert(id_equals(a, "ipsec.strongSwan.org"));
566 ck_assert(id_equals(a, "ipsec.strongSwan.ORG"));
567 ck_assert(!id_equals(a, "strongswan.org"));
568 a->destroy(a);
569 }
570 END_TEST
571
572 START_TEST(test_equals_empty)
573 {
574 identification_t *a;
575
576 a = identification_create_from_encoding(_i, chunk_empty);
577
578 switch (_i)
579 {
580 case ID_ANY:
581 ck_assert(id_equals(a, "%any"));
582 break;
583 case ID_IPV4_ADDR:
584 ck_assert(!id_equals(a, "192.168.1.1"));
585 break;
586 case ID_FQDN:
587 ck_assert(!id_equals(a, "moon.strongswan.org"));
588 break;
589 case ID_USER_FQDN:
590 ck_assert(!id_equals(a, "moon@strongswan.org"));
591 break;
592 case ID_IPV6_ADDR:
593 ck_assert(!id_equals(a, "fec0::1"));
594 break;
595 case ID_DER_ASN1_DN:
596 ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
597 break;
598 case ID_KEY_ID:
599 ck_assert(!id_equals(a, "@#12345678"));
600 break;
601 case ID_DER_ASN1_GN:
602 case ID_IPV4_ADDR_SUBNET:
603 case ID_IPV6_ADDR_SUBNET:
604 case ID_IPV4_ADDR_RANGE:
605 case ID_IPV6_ADDR_RANGE:
606 /* currently not tested */
607 break;
608 }
609
610 a->destroy(a);
611 }
612 END_TEST
613
614 /*******************************************************************************
615 * matches
616 */
617
618 static bool id_matches(identification_t *a, char *b_str, id_match_t expected)
619 {
620 identification_t *b;
621 id_match_t match;
622
623 b = identification_create_from_string(b_str);
624 match = a->matches(a, b);
625 b->destroy(b);
626 return match == expected;
627 }
628
629 START_TEST(test_matches)
630 {
631 identification_t *a;
632
633 a = identification_create_from_string("C=CH, E=moon@strongswan.org, CN=moon");
634
635 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon", ID_MATCH_PERFECT));
636 ck_assert(id_matches(a, "C=CH, email=moon@strongswan.org, CN=moon", ID_MATCH_PERFECT));
637 ck_assert(id_matches(a, "C=CH, emailAddress=moon@strongswan.org, CN=moon", ID_MATCH_PERFECT));
638 ck_assert(id_matches(a, "C=CH, E=*@strongswan.org, CN=moon", ID_MATCH_NONE));
639 ck_assert(id_matches(a, "C=CH, E=*, CN=moon", ID_MATCH_ONE_WILDCARD));
640 ck_assert(id_matches(a, "C=CH, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 1));
641 ck_assert(id_matches(a, "C=*, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 2));
642 ck_assert(id_matches(a, "C=*, E=*, CN=*, O=BADInc", ID_MATCH_NONE));
643 ck_assert(id_matches(a, "C=*, E=*", ID_MATCH_NONE));
644 ck_assert(id_matches(a, "C=*, E=a@b.c, CN=*", ID_MATCH_NONE));
645 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
646
647 a->destroy(a);
648 }
649 END_TEST
650
651 START_TEST(test_matches_any)
652 {
653 identification_t *a;
654
655 a = identification_create_from_string("%any");
656
657 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
658 ck_assert(id_matches(a, "", ID_MATCH_ANY));
659 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
660 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
661 ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_NONE));
662 a->destroy(a);
663 }
664 END_TEST
665
666 START_TEST(test_matches_binary)
667 {
668 identification_t *a;
669
670 /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
671 a = identification_create_from_string("foo=bar");
672 ck_assert(a->get_type(a) == ID_KEY_ID);
673 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
674 ck_assert(id_matches(a, "foo=bar", ID_MATCH_PERFECT));
675 ck_assert(id_matches(a, "bar=foo", ID_MATCH_NONE));
676 ck_assert(id_matches(a, "*=bar", ID_MATCH_NONE));
677 ck_assert(id_matches(a, "foo=*", ID_MATCH_NONE));
678 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
679 a->destroy(a);
680 }
681 END_TEST
682
683 START_TEST(test_matches_range)
684 {
685 identification_t *a, *b;
686
687 /* IPv4 addresses */
688 a = identification_create_from_string("192.168.1.1");
689 ck_assert(a->get_type(a) == ID_IPV4_ADDR);
690 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
691 ck_assert(id_matches(a, "0.0.0.0/0", ID_MATCH_MAX_WILDCARDS));
692 ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_PERFECT));
693 ck_assert(id_matches(a, "192.168.1.2", ID_MATCH_NONE));
694 ck_assert(id_matches(a, "192.168.1.1/32", ID_MATCH_PERFECT));
695 ck_assert(id_matches(a, "192.168.1.0/32", ID_MATCH_NONE));
696 ck_assert(id_matches(a, "192.168.1.0/24", ID_MATCH_ONE_WILDCARD));
697 ck_assert(id_matches(a, "192.168.0.0/24", ID_MATCH_NONE));
698 ck_assert(id_matches(a, "192.168.1.1-192.168.1.1", ID_MATCH_PERFECT));
699 ck_assert(id_matches(a, "192.168.1.0-192.168.1.64", ID_MATCH_ONE_WILDCARD));
700 ck_assert(id_matches(a, "192.168.1.2-192.168.1.64", ID_MATCH_NONE));
701 ck_assert(id_matches(a, "192.168.0.240-192.168.1.0", ID_MATCH_NONE));
702 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
703
704 /* Malformed IPv4 subnet and range encoding */
705 b = identification_create_from_encoding(ID_IPV4_ADDR_SUBNET, chunk_empty);
706 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
707 b->destroy(b);
708 b = identification_create_from_encoding(ID_IPV4_ADDR_RANGE, chunk_empty);
709 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
710 b->destroy(b);
711 b = identification_create_from_encoding(ID_IPV4_ADDR_RANGE,
712 chunk_from_chars(0xc0,0xa8,0x01,0x28,0xc0,0xa8,0x01,0x00));
713 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
714 b->destroy(b);
715
716 a->destroy(a);
717
718 /* IPv6 addresses */
719 a = identification_create_from_string("fec0::1");
720 ck_assert(a->get_type(a) == ID_IPV6_ADDR);
721 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
722 ck_assert(id_matches(a, "::/0", ID_MATCH_MAX_WILDCARDS));
723 ck_assert(id_matches(a, "fec0::1", ID_MATCH_PERFECT));
724 ck_assert(id_matches(a, "fec0::2", ID_MATCH_NONE));
725 ck_assert(id_matches(a, "fec0::1/128", ID_MATCH_PERFECT));
726 ck_assert(id_matches(a, "fec0::/128", ID_MATCH_NONE));
727 ck_assert(id_matches(a, "fec0::/120", ID_MATCH_ONE_WILDCARD));
728 ck_assert(id_matches(a, "fec0::100/120", ID_MATCH_NONE));
729 ck_assert(id_matches(a, "fec0::1-fec0::1", ID_MATCH_PERFECT));
730 ck_assert(id_matches(a, "fec0::0-fec0::5", ID_MATCH_ONE_WILDCARD));
731 ck_assert(id_matches(a, "fec0::4001-fec0::4ffe", ID_MATCH_NONE));
732 ck_assert(id_matches(a, "feb0::1-fec0::0", ID_MATCH_NONE));
733 ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
734
735 /* Malformed IPv6 subnet and range encoding */
736 b = identification_create_from_encoding(ID_IPV6_ADDR_SUBNET, chunk_empty);
737 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
738 b->destroy(b);
739 b = identification_create_from_encoding(ID_IPV6_ADDR_RANGE, chunk_empty);
740 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
741 b->destroy(b);
742 b = identification_create_from_encoding(ID_IPV6_ADDR_RANGE,
743 chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
744 0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0xff,
745 0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
746 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 ));
747 ck_assert(a->matches(a, b) == ID_MATCH_NONE);
748 b->destroy(b);
749
750 a->destroy(a);
751
752 /* Malformed IPv4 address encoding */
753 a = identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty);
754 ck_assert(id_matches(a, "0.0.0.0/0", ID_MATCH_NONE));
755 ck_assert(id_matches(a, "0.0.0.0-255.255.255.255", ID_MATCH_NONE));
756 a->destroy(a);
757
758 /* Malformed IPv6 address encoding */
759 a = identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty);
760 ck_assert(id_matches(a, "::/0", ID_MATCH_NONE));
761 ck_assert(id_matches(a, "::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", ID_MATCH_NONE));
762 a->destroy(a);
763 }
764 END_TEST
765
766 START_TEST(test_matches_string)
767 {
768 identification_t *a;
769
770 a = identification_create_from_string("moon@strongswan.org");
771
772 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_PERFECT));
773 ck_assert(id_matches(a, "*@strongswan.org", ID_MATCH_ONE_WILDCARD));
774 ck_assert(id_matches(a, "*@*.org", ID_MATCH_NONE));
775 ck_assert(id_matches(a, "*@*", ID_MATCH_NONE));
776 /* the following two are parsed as ID_FQDN, so no match */
777 ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_NONE));
778 ck_assert(id_matches(a, "*.org", ID_MATCH_NONE));
779 ck_assert(id_matches(a, "moon@*", ID_MATCH_NONE));
780 ck_assert(id_matches(a, "**", ID_MATCH_NONE));
781 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
782 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
783 a->destroy(a);
784
785 a = identification_create_from_string("vpn.strongswan.org");
786
787 ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_PERFECT));
788 ck_assert(id_matches(a, "*.strongswan.org", ID_MATCH_ONE_WILDCARD));
789 ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_ONE_WILDCARD));
790 ck_assert(id_matches(a, "*.org", ID_MATCH_ONE_WILDCARD));
791 ck_assert(id_matches(a, "*.strongswan.*", ID_MATCH_NONE));
792 ck_assert(id_matches(a, "*vpn.strongswan.org", ID_MATCH_NONE));
793 ck_assert(id_matches(a, "vpn.strongswan.*", ID_MATCH_NONE));
794 ck_assert(id_matches(a, "**", ID_MATCH_NONE));
795 ck_assert(id_matches(a, "*", ID_MATCH_ANY));
796 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
797 a->destroy(a);
798 }
799 END_TEST
800
801 START_TEST(test_matches_empty)
802 {
803 identification_t *a;
804
805 a = identification_create_from_encoding(_i, chunk_empty);
806
807 switch (_i)
808 {
809 case ID_ANY:
810 ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
811 break;
812 case ID_IPV4_ADDR:
813 ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_NONE));
814 break;
815 case ID_FQDN:
816 ck_assert(id_matches(a, "moon.strongswan.org", ID_MATCH_NONE));
817 break;
818 case ID_USER_FQDN:
819 ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
820 break;
821 case ID_IPV6_ADDR:
822 ck_assert(id_matches(a, "fec0::1", ID_MATCH_NONE));
823 break;
824 case ID_DER_ASN1_DN:
825 ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon",
826 ID_MATCH_NONE));
827 break;
828 case ID_KEY_ID:
829 ck_assert(id_matches(a, "@#12345678", ID_MATCH_NONE));
830 break;
831 case ID_DER_ASN1_GN:
832 case ID_IPV4_ADDR_SUBNET:
833 case ID_IPV6_ADDR_SUBNET:
834 case ID_IPV4_ADDR_RANGE:
835 case ID_IPV6_ADDR_RANGE:
836 /* currently not tested */
837 break;
838 }
839
840 a->destroy(a);
841 }
842 END_TEST
843
844 static bool id_matches_rev(identification_t *a, char *b_str, id_match_t expected)
845 {
846 identification_t *b;
847 id_match_t match;
848
849 b = identification_create_from_string(b_str);
850 match = b->matches(b, a);
851 b->destroy(b);
852 return match == expected;
853 }
854
855 START_TEST(test_matches_empty_reverse)
856 {
857 identification_t *a;
858
859 a = identification_create_from_encoding(_i, chunk_empty);
860
861 switch (_i)
862 {
863 case ID_ANY:
864 ck_assert(id_matches_rev(a, "%any", ID_MATCH_ANY));
865 break;
866 case ID_IPV4_ADDR:
867 ck_assert(id_matches_rev(a, "192.168.1.1", ID_MATCH_NONE));
868 break;
869 case ID_FQDN:
870 ck_assert(id_matches_rev(a, "moon.strongswan.org", ID_MATCH_NONE));
871 break;
872 case ID_USER_FQDN:
873 ck_assert(id_matches_rev(a, "moon@strongswan.org", ID_MATCH_NONE));
874 break;
875 case ID_IPV6_ADDR:
876 ck_assert(id_matches_rev(a, "fec0::1", ID_MATCH_NONE));
877 break;
878 case ID_DER_ASN1_DN:
879 ck_assert(id_matches_rev(a, "C=CH, E=moon@strongswan.org, CN=moon",
880 ID_MATCH_NONE));
881 break;
882 case ID_KEY_ID:
883 ck_assert(id_matches_rev(a, "@#12345678", ID_MATCH_NONE));
884 break;
885 case ID_DER_ASN1_GN:
886 case ID_IPV4_ADDR_SUBNET:
887 case ID_IPV6_ADDR_SUBNET:
888 case ID_IPV4_ADDR_RANGE:
889 case ID_IPV6_ADDR_RANGE:
890 /* currently not tested */
891 break;
892 }
893
894 a->destroy(a);
895 }
896 END_TEST
897
898 /*******************************************************************************
899 * identification hashing
900 */
901
902 static bool id_hash_equals(char *str, char *b_str)
903 {
904 identification_t *a, *b;
905 bool success = FALSE;
906
907 a = identification_create_from_string(str);
908 b = identification_create_from_string(b_str ?: str);
909 success = a->hash(a, 0) == b->hash(b, 0);
910 a->destroy(a);
911 b->destroy(b);
912 return success;
913 }
914
915 START_TEST(test_hash)
916 {
917 ck_assert(id_hash_equals("moon@strongswan.org", NULL));
918 ck_assert(id_hash_equals("vpn.strongswan.org", NULL));
919 ck_assert(id_hash_equals("192.168.1.1", NULL));
920 ck_assert(id_hash_equals("C=CH", NULL));
921
922 ck_assert(!id_hash_equals("moon@strongswan.org", "sun@strongswan.org"));
923 ck_assert(!id_hash_equals("vpn.strongswan.org", "*.strongswan.org"));
924 ck_assert(!id_hash_equals("192.168.1.1", "192.168.1.2"));
925 ck_assert(!id_hash_equals("C=CH", "C=DE"));
926 ck_assert(!id_hash_equals("fqdn:strongswan.org", "keyid:strongswan.org"));
927 }
928 END_TEST
929
930 START_TEST(test_hash_any)
931 {
932 ck_assert(id_hash_equals("%any", NULL));
933 ck_assert(id_hash_equals("%any", "0.0.0.0"));
934 ck_assert(id_hash_equals("%any", "*"));
935 ck_assert(id_hash_equals("%any", ""));
936
937 ck_assert(!id_hash_equals("%any", "any"));
938 }
939 END_TEST
940
941 START_TEST(test_hash_dn)
942 {
943 identification_t *a, *b;
944
945 /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
946 * UTF8STRING) */
947 a = identification_create_from_data(chunk_from_chars(
948 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
949 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31,
950 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
951 0x13, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
952 0x53, 0x77, 0x61, 0x6e));
953 b = identification_create_from_data(chunk_from_chars(
954 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
955 0x55, 0x04, 0x06, 0x0c, 0x02, 0x43, 0x48, 0x31,
956 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
957 0x0c, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
958 0x53, 0x77, 0x61, 0x6e));
959 ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
960 ck_assert(a->equals(a, b));
961 a->destroy(a);
962 b->destroy(b);
963 }
964 END_TEST
965
966 START_TEST(test_hash_inc)
967 {
968 identification_t *a;
969
970 a = identification_create_from_string("vpn.strongswan.org");
971 ck_assert(a->hash(a, 0) != a->hash(a, 1));
972 a->destroy(a);
973
974 a = identification_create_from_string("C=CH, O=strongSwan");
975 ck_assert(a->hash(a, 0) != a->hash(a, 1));
976 a->destroy(a);
977 }
978 END_TEST
979
980 /*******************************************************************************
981 * identification part enumeration
982 */
983
984 START_TEST(test_parts)
985 {
986 identification_t *id;
987 enumerator_t *enumerator;
988 id_part_t part;
989 chunk_t data;
990 int i = 0;
991
992 id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
993
994 enumerator = id->create_part_enumerator(id);
995 while (enumerator->enumerate(enumerator, &part, &data))
996 {
997 switch (i++)
998 {
999 case 0:
1000 ck_assert(part == ID_PART_RDN_C &&
1001 chunk_equals(data, chunk_create("CH", 2)));
1002 break;
1003 case 1:
1004 ck_assert(part == ID_PART_RDN_O &&
1005 chunk_equals(data, chunk_from_str("strongSwan")));
1006 break;
1007 case 2:
1008 ck_assert(part == ID_PART_RDN_CN &&
1009 chunk_equals(data, chunk_from_str("tester")));
1010 break;
1011 default:
1012 fail("unexpected identification part %d", part);
1013 }
1014 }
1015 ck_assert_int_eq(i, 3);
1016 enumerator->destroy(enumerator);
1017 id->destroy(id);
1018 }
1019 END_TEST
1020
1021 /*******************************************************************************
1022 * wildcards
1023 */
1024
1025 static bool id_contains_wildcards(char *string)
1026 {
1027 identification_t *id;
1028 bool contains;
1029
1030 id = identification_create_from_string(string);
1031 contains = id->contains_wildcards(id);
1032 id->destroy(id);
1033 return contains;
1034 }
1035
1036 START_TEST(test_contains_wildcards)
1037 {
1038 ck_assert(id_contains_wildcards("%any"));
1039 ck_assert(id_contains_wildcards("C=*, O=strongSwan, CN=gw"));
1040 ck_assert(id_contains_wildcards("C=CH, O=strongSwan, CN=*"));
1041 ck_assert(id_contains_wildcards("*@strongswan.org"));
1042 ck_assert(id_contains_wildcards("*.strongswan.org"));
1043 ck_assert(!id_contains_wildcards("C=**, O=a*, CN=*a"));
1044 }
1045 END_TEST
1046
1047 /*******************************************************************************
1048 * clone
1049 */
1050
1051 START_TEST(test_clone)
1052 {
1053 identification_t *a, *b;
1054 chunk_t a_enc, b_enc;
1055
1056 a = identification_create_from_string("moon@strongswan.org");
1057 a_enc = a->get_encoding(a);
1058 b = a->clone(a);
1059 ck_assert(b != NULL);
1060 ck_assert(a != b);
1061 b_enc = b->get_encoding(b);
1062 ck_assert(a_enc.ptr != b_enc.ptr);
1063 ck_assert(chunk_equals(a_enc, b_enc));
1064 a->destroy(a);
1065 b->destroy(b);
1066 }
1067 END_TEST
1068
1069 Suite *identification_suite_create()
1070 {
1071 Suite *s;
1072 TCase *tc;
1073
1074 s = suite_create("identification");
1075
1076 tc = tcase_create("create");
1077 tcase_add_test(tc, test_from_encoding);
1078 tcase_add_test(tc, test_from_data);
1079 tcase_add_test(tc, test_from_sockaddr);
1080 tcase_add_loop_test(tc, test_from_string, 0, countof(string_data));
1081 suite_add_tcase(s, tc);
1082
1083 tc = tcase_create("printf_hook");
1084 tcase_add_test(tc, test_printf_hook);
1085 tcase_add_test(tc, test_printf_hook_width);
1086 suite_add_tcase(s, tc);
1087
1088 tc = tcase_create("equals");
1089 tcase_add_test(tc, test_equals);
1090 tcase_add_test(tc, test_equals_any);
1091 tcase_add_test(tc, test_equals_binary);
1092 tcase_add_test(tc, test_equals_fqdn);
1093 tcase_add_loop_test(tc, test_equals_empty, ID_ANY, ID_KEY_ID + 1);
1094 suite_add_tcase(s, tc);
1095
1096 tc = tcase_create("matches");
1097 tcase_add_test(tc, test_matches);
1098 tcase_add_test(tc, test_matches_any);
1099 tcase_add_test(tc, test_matches_binary);
1100 tcase_add_test(tc, test_matches_range);
1101 tcase_add_test(tc, test_matches_string);
1102 tcase_add_loop_test(tc, test_matches_empty, ID_ANY, ID_KEY_ID + 1);
1103 tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
1104 suite_add_tcase(s, tc);
1105
1106 tc = tcase_create("hash");
1107 tcase_add_test(tc, test_hash);
1108 tcase_add_test(tc, test_hash_any);
1109 tcase_add_test(tc, test_hash_dn);
1110 tcase_add_test(tc, test_hash_inc);
1111 suite_add_tcase(s, tc);
1112
1113 tc = tcase_create("part enumeration");
1114 tcase_add_test(tc, test_parts);
1115 suite_add_tcase(s, tc);
1116
1117 tc = tcase_create("wildcards");
1118 tcase_add_test(tc, test_contains_wildcards);
1119 suite_add_tcase(s, tc);
1120
1121 tc = tcase_create("clone");
1122 tcase_add_test(tc, test_clone);
1123 suite_add_tcase(s, tc);
1124
1125 return s;
1126 }