added unit test for identification_t.matches()
[strongswan.git] / src / charon / plugins / unit_tester / tests / test_id.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <daemon.h>
17
18 /*******************************************************************************
19 * identification part enumeration test
20 ******************************************************************************/
21 bool test_id_parts()
22 {
23 identification_t *id;
24 enumerator_t *enumerator;
25 id_part_t part;
26 chunk_t data;
27 int i = 0;
28
29 id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
30
31 enumerator = id->create_part_enumerator(id);
32 while (enumerator->enumerate(enumerator, &part, &data))
33 {
34 switch (i++)
35 {
36 case 0:
37 if (part != ID_PART_RDN_C ||
38 !chunk_equals(data, chunk_create("CH", 2)))
39 {
40 return FALSE;
41 }
42 break;
43 case 1:
44 if (part != ID_PART_RDN_O ||
45 !chunk_equals(data, chunk_create("strongSwan", 10)))
46 {
47 return FALSE;
48 }
49 break;
50 case 2:
51 if (part != ID_PART_RDN_CN ||
52 !chunk_equals(data, chunk_create("tester", 6)))
53 {
54 return FALSE;
55 }
56 break;
57 default:
58 return FALSE;
59 }
60 }
61 if (i < 3)
62 {
63 return FALSE;
64 }
65 enumerator->destroy(enumerator);
66 id->destroy(id);
67 return TRUE;
68 }
69
70 /*******************************************************************************
71 * identification contains_wildcards() test
72 ******************************************************************************/
73
74 static bool test_id_wildcards_has(char *string)
75 {
76 identification_t *id;
77 bool contains;
78
79 id = identification_create_from_string(string);
80 contains = id->contains_wildcards(id);
81 id->destroy(id);
82 return contains;
83 }
84
85 bool test_id_wildcards()
86 {
87 if (!test_id_wildcards_has("C=*, O=strongSwan, CN=gw"))
88 {
89 return FALSE;
90 }
91 if (!test_id_wildcards_has("C=CH, O=strongSwan, CN=*"))
92 {
93 return FALSE;
94 }
95 if (test_id_wildcards_has("C=**, O=a*, CN=*a"))
96 {
97 return FALSE;
98 }
99 if (!test_id_wildcards_has("*@strongswan.org"))
100 {
101 return FALSE;
102 }
103 if (!test_id_wildcards_has("*.strongswan.org"))
104 {
105 return FALSE;
106 }
107 return TRUE;
108 }
109
110 /*******************************************************************************
111 * identification equals test
112 ******************************************************************************/
113
114 static bool test_id_equals_one(identification_t *a, char *b_str)
115 {
116 identification_t *b;
117 bool equals;
118
119 b = identification_create_from_string(b_str);
120 equals = a->equals(a, b);
121 b->destroy(b);
122 return equals;
123 }
124
125 bool test_id_equals()
126 {
127 identification_t *a;
128 chunk_t encoding, fuzzed;
129 int i;
130
131 a = identification_create_from_string(
132 "C=CH, E=martin@strongswan.org, CN=martin");
133
134 if (!test_id_equals_one(a, "C=CH, E=martin@strongswan.org, CN=martin"))
135 {
136 return FALSE;
137 }
138 if (!test_id_equals_one(a, "C=ch, E=martin@STRONGSWAN.ORG, CN=Martin"))
139 {
140 return FALSE;
141 }
142 if (test_id_equals_one(a, "C=CN, E=martin@strongswan.org, CN=martin"))
143 {
144 return FALSE;
145 }
146 if (test_id_equals_one(a, "E=martin@strongswan.org, C=CH, CN=martin"))
147 {
148 return FALSE;
149 }
150 if (test_id_equals_one(a, "E=martin@strongswan.org, C=CH, CN=martin"))
151 {
152 return FALSE;
153 }
154 encoding = chunk_clone(a->get_encoding(a));
155 a->destroy(a);
156
157 /* simple fuzzing, increment each byte of encoding */
158 for (i = 0; i < encoding.len; i++)
159 {
160 if (i == 11 || i == 30 || i == 62)
161 { /* skip ASN.1 type fields, as equals() handles them graceful */
162 continue;
163 }
164 fuzzed = chunk_clone(encoding);
165 fuzzed.ptr[i]++;
166 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
167 if (test_id_equals_one(a, "C=CH, E=martin@strongswan.org, CN=martin"))
168 {
169 return FALSE;
170 }
171 a->destroy(a);
172 free(fuzzed.ptr);
173 }
174
175 /* and decrement each byte of encoding */
176 for (i = 0; i < encoding.len; i++)
177 {
178 if (i == 11 || i == 30 || i == 62)
179 {
180 continue;
181 }
182 fuzzed = chunk_clone(encoding);
183 fuzzed.ptr[i]--;
184 a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
185 if (test_id_equals_one(a, "C=CH, E=martin@strongswan.org, CN=martin"))
186 {
187 return FALSE;
188 }
189 a->destroy(a);
190 free(fuzzed.ptr);
191 }
192 free(encoding.ptr);
193 return TRUE;
194 }
195
196 /*******************************************************************************
197 * identification matches test
198 ******************************************************************************/
199
200 static id_match_t test_id_matches_one(identification_t *a, char *b_str)
201 {
202 identification_t *b;
203 id_match_t match;
204
205 b = identification_create_from_string(b_str);
206 match = a->matches(a, b);
207 b->destroy(b);
208 return match;
209 }
210
211 bool test_id_matches()
212 {
213 identification_t *a;
214
215 a = identification_create_from_string(
216 "C=CH, E=martin@strongswan.org, CN=martin");
217
218 if (test_id_matches_one(a, "C=CH, E=martin@strongswan.org, CN=martin")
219 != ID_MATCH_PERFECT)
220 {
221 return FALSE;
222 }
223 if (test_id_matches_one(a, "C=CH, E=*, CN=martin") != ID_MATCH_ONE_WILDCARD)
224 {
225 return FALSE;
226 }
227 if (test_id_matches_one(a, "C=CH, E=*, CN=*") != ID_MATCH_ONE_WILDCARD - 1)
228 {
229 return FALSE;
230 }
231 if (test_id_matches_one(a, "C=*, E=*, CN=*") != ID_MATCH_ONE_WILDCARD - 2)
232 {
233 return FALSE;
234 }
235 if (test_id_matches_one(a, "C=*, E=*, CN=*, O=BADInc") != ID_MATCH_NONE)
236 {
237 return FALSE;
238 }
239 if (test_id_matches_one(a, "C=*, E=*") != ID_MATCH_NONE)
240 {
241 return FALSE;
242 }
243 if (test_id_matches_one(a, "C=*, E=a@b.c, CN=*") != ID_MATCH_NONE)
244 {
245 return FALSE;
246 }
247 a->destroy(a);
248 return TRUE;
249 }