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