1 /*
2 * Copyright (C) 2016 Free Software Foundation, Inc.
3 *
4 * Author: Nikos Mavrogiannopoulos, Martin Ukrop
5 *
6 * This file is part of GnuTLS.
7 *
8 * GnuTLS is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GnuTLS is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GnuTLS; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32
33 #include <stdarg.h>
34 #include <stddef.h>
35 #include <setjmp.h>
36 #include <cmocka.h>
37
38 #include <gnutls/gnutls.h>
39 #include <gnutls/x509.h>
40 #include "../lib/x509/ip.h"
41
42 typedef struct test_vars_t {
43 gnutls_x509_name_constraints_t nc;
44 gnutls_x509_name_constraints_t nc2;
45 gnutls_datum_t ip;
46 } test_vars_t;
47
48 /* just declaration: function is exported privately
49 from lib/x509/name_constraints.c (declared in lib/x509/x509_int.h)
50 but including the header breaks includes */
51 extern int _gnutls_x509_name_constraints_merge(
52 gnutls_x509_name_constraints_t nc,
53 gnutls_x509_name_constraints_t nc2);
54
check_for_error(int ret)55 static void check_for_error(int ret) {
56 if (ret != GNUTLS_E_SUCCESS)
57 fail_msg("error in %d: %s\n", __LINE__, gnutls_strerror(ret));
58 }
59
60 #define IP_ACCEPTED 1
61 #define IP_REJECTED 0
62
check_test_result(int ret,int expected_outcome,gnutls_datum_t * tested_ip)63 static void check_test_result(int ret, int expected_outcome,
64 gnutls_datum_t *tested_ip) {
65 if (expected_outcome == IP_ACCEPTED ? ret == 0 : ret != 0) {
66 char ip_out[48];
67 _gnutls_ip_to_string(tested_ip->data, tested_ip->size, ip_out, sizeof(ip_out));
68 if (expected_outcome == IP_ACCEPTED) {
69 fail_msg("Checking %.*s should have succeeded.\n",
70 (int) sizeof(ip_out), ip_out);
71 } else {
72 fail_msg("Checking %.*s should have failed.\n",
73 (int) sizeof(ip_out), ip_out);
74 }
75 }
76 }
77
parse_cidr(const char * cidr,gnutls_datum_t * datum)78 static void parse_cidr(const char* cidr, gnutls_datum_t *datum) {
79 if (datum->data != NULL) {
80 gnutls_free(datum->data);
81 }
82 int ret = gnutls_x509_cidr_to_rfc5280(cidr, datum);
83 check_for_error(ret);
84 }
85
tls_log_func(int level,const char * str)86 static void tls_log_func(int level, const char *str) {
87 fprintf(stderr, "<%d>| %s", level, str);
88 }
89
90 static unsigned char cert_pem[] =
91 "-----BEGIN CERTIFICATE-----\n"
92 "MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix\n"
93 "RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1\n"
94 "dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p\n"
95 "YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw\n"
96 "NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK\n"
97 "EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl\n"
98 "cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl\n"
99 "c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB\n"
100 "BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz\n"
101 "dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ\n"
102 "fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns\n"
103 "bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD\n"
104 "75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP\n"
105 "FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV\n"
106 "HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp\n"
107 "5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu\n"
108 "b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA\n"
109 "A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p\n"
110 "6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8\n"
111 "TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7\n"
112 "dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys\n"
113 "Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI\n"
114 "l7WdmplNsDz4SgCbZN2fOUvRJ9e4\n"
115 "-----END CERTIFICATE-----\n";
116
117 const gnutls_datum_t cert = { cert_pem, sizeof(cert_pem) };
118
119 // CIDRs mostly use prefix for documentation purposes (RFC5737, RFC3849)
120
check_generation_reading_basic_checking(void ** glob_state)121 static void check_generation_reading_basic_checking(void **glob_state)
122 {
123 int ret;
124 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
125 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
126
127 unsigned int i, num_permitted, num_excluded, type;
128 gnutls_x509_crt_t crt;
129 gnutls_datum_t name;
130
131 gnutls_global_set_log_function(tls_log_func);
132 gnutls_global_set_log_level(2);
133
134 /* 1: test the generation of name constraints */
135
136 ret = gnutls_x509_crt_init(&crt);
137 check_for_error(ret);
138
139 ret = gnutls_x509_crt_import(crt, &cert, GNUTLS_X509_FMT_PEM);
140 check_for_error(ret);
141
142 num_permitted = num_excluded = 0;
143
144 parse_cidr("203.0.113.0/24", ip);
145 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
146 num_permitted++;
147 check_for_error(ret);
148
149 parse_cidr("2001:DB8::/32", ip);
150 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
151 num_permitted++;
152 check_for_error(ret);
153
154 parse_cidr("203.0.113.0/26", ip);
155 ret = gnutls_x509_name_constraints_add_excluded(nc, GNUTLS_SAN_IPADDRESS, ip);
156 num_excluded++;
157 check_for_error(ret);
158
159 parse_cidr("2001:DB8::/34", ip);
160 ret = gnutls_x509_name_constraints_add_excluded(nc, GNUTLS_SAN_IPADDRESS, ip);
161 num_excluded++;
162 check_for_error(ret);
163
164 // Try to add invalid name constraints
165
166 parse_cidr("2001:DB8::/34", ip);
167 ip->data[30] = 2;
168 ret = gnutls_x509_name_constraints_add_excluded(nc, GNUTLS_SAN_IPADDRESS, ip);
169 if (ret == 0)
170 fail_msg("Checking invalid network mask should have failed.");
171
172 parse_cidr("2001:DB8::/34", ip);
173 ip->size = 31;
174 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
175 if (ret == 0)
176 fail_msg("Checking invalid IP size should have failed.");
177
178 ret = gnutls_x509_crt_set_name_constraints(crt, nc, 1);
179 check_for_error(ret);
180
181 /* 2: test the reading of the generated constraints */
182
183 i = 0;
184 do {
185 ret = gnutls_x509_name_constraints_get_permitted(nc, i++, &type, &name);
186 #ifdef DEBUG
187 _gnutls_cidr_to_string(name.data, name.size, ip_out, sizeof(ip_out));
188 printf("Loaded name constraint: %s\n",ip_out);
189 #endif
190 } while(ret == 0);
191
192 if (i-1 != num_permitted) {
193 fail_msg("Could not read all contraints; read %d, expected %d\n", i-1, num_permitted);
194 }
195
196 i = 0;
197 do {
198 ret = gnutls_x509_name_constraints_get_excluded(nc, i++, &type, &name);
199 #ifdef DEBUG
200 _gnutls_cidr_to_string(name.data, name.size, ip_out, sizeof(ip_out));
201 printf("Loaded name constraint: %s\n",ip_out);
202 #endif
203 } while(ret == 0);
204
205 if (i-1 != num_excluded) {
206 fail_msg("Could not read all excluded contraints; read %d, expected %d\n", i-1, num_excluded);
207 }
208
209 /* 3: test the name constraints check function */
210
211 parse_cidr("203.0.113.250/32", ip);
212 ip->size = 4; // strip network mask
213 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
214 check_test_result(ret, IP_ACCEPTED, ip);
215
216 parse_cidr("203.0.114.0/32", ip);
217 ip->size = 4; // strip network mask
218 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
219 check_test_result(ret, IP_REJECTED, ip);
220
221 parse_cidr("203.0.113.10/32", ip);
222 ip->size = 4; // strip network mask
223 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
224 check_test_result(ret, IP_REJECTED, ip);
225
226
227 parse_cidr("2001:DB8:4000::/128", ip);
228 ip->size = 16; // strip network mask
229 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
230 check_test_result(ret, IP_ACCEPTED, ip);
231
232 parse_cidr("2001:DB9::/128", ip);
233 ip->size = 16; // strip network mask
234 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
235 check_test_result(ret, IP_REJECTED, ip);
236
237 parse_cidr("2001:DB8:10::/128", ip);
238 ip->size = 16; // strip network mask
239 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
240 check_test_result(ret, IP_REJECTED, ip);
241
242 gnutls_x509_crt_deinit(crt);
243 }
244
check_universal_constraint_checking(void ** glob_state)245 static void check_universal_constraint_checking(void **glob_state)
246 {
247 /* 3b setting universal constraint */
248 int ret;
249 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
250 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
251
252 parse_cidr("2001:DB8::/0", ip);
253 ret = gnutls_x509_name_constraints_add_excluded(nc, GNUTLS_SAN_IPADDRESS, ip);
254 check_for_error(ret);
255
256 parse_cidr("2001:DB8:10::/128", ip);
257 ip->size = 16; // strip network mask
258 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
259 check_test_result(ret, IP_REJECTED, ip);
260
261 parse_cidr("::/128", ip);
262 ip->size = 16; // strip network mask
263 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
264 check_test_result(ret, IP_REJECTED, ip);
265 }
266
check_simple_intersection(void ** glob_state)267 static void check_simple_intersection(void **glob_state)
268 {
269 /* 4: simple intersection
270 * --------P:203.0.113.0/24--------
271 * --P:203.0.113.0/26--
272 * A B C
273 */
274 int ret;
275 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
276 gnutls_x509_name_constraints_t nc2 = ((test_vars_t*)*glob_state)->nc2;
277 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
278
279 parse_cidr("203.0.113.0/24", ip);
280 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
281 check_for_error(ret);
282 parse_cidr("203.0.113.0/26", ip);
283 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
284 check_for_error(ret);
285 ret = _gnutls_x509_name_constraints_merge(nc, nc2);
286 check_for_error(ret);
287
288 parse_cidr("203.0.113.2/32", ip); // A
289 ip->size = 4; // strip network mask
290 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
291 check_test_result(ret, IP_ACCEPTED, ip);
292
293 parse_cidr("203.0.113.250/32", ip); // B
294 ip->size = 4; // strip network mask
295 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
296 check_test_result(ret, IP_REJECTED, ip);
297
298 parse_cidr("203.0.114.0/32", ip); // C
299 ip->size = 4; // strip network mask
300 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
301 check_test_result(ret, IP_REJECTED, ip);
302 }
303
check_empty_intersection(void ** glob_state)304 static void check_empty_intersection(void **glob_state)
305 {
306 /* 5: empty intersection
307 * --P:127.0.113.0/24--
308 * --P:255.0.113.0/24--
309 * A B C
310 */
311 int ret;
312 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
313 gnutls_x509_name_constraints_t nc2 = ((test_vars_t*)*glob_state)->nc2;
314 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
315
316 parse_cidr("127.0.113.0/24", ip);
317 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
318 check_for_error(ret);
319 parse_cidr("255.0.113.0/24", ip);
320 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
321 check_for_error(ret);
322 ret = _gnutls_x509_name_constraints_merge(nc, nc2);
323 check_for_error(ret);
324
325 parse_cidr("127.0.113.2/32", ip); // A
326 ip->size = 4; // strip network mask
327 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
328 check_test_result(ret, IP_REJECTED, ip);
329
330 parse_cidr("255.0.0.2/32", ip); // B
331 ip->size = 4; // strip network mask
332 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
333 check_test_result(ret, IP_REJECTED, ip);
334
335 parse_cidr("255.0.113.2/32", ip); // C
336 ip->size = 4; // strip network mask
337 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
338 check_test_result(ret, IP_REJECTED, ip);
339 }
340
check_mediocre_intersection(void ** glob_state)341 static void check_mediocre_intersection(void **glob_state)
342 {
343 /* 6: mediocre intersection
344 * --------P:127.0.113.0/24--------
345 * --P:127.0.113.0/26-- --P:255.0.113.0/24--
346 * A B C D
347 */
348 int ret;
349 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
350 gnutls_x509_name_constraints_t nc2 = ((test_vars_t*)*glob_state)->nc2;
351 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
352
353 parse_cidr("127.0.113.0/24", ip);
354 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
355 check_for_error(ret);
356 parse_cidr("127.0.113.0/26", ip);
357 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
358 check_for_error(ret);
359 parse_cidr("255.0.113.0/24", ip);
360 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
361 check_for_error(ret);
362 ret = _gnutls_x509_name_constraints_merge(nc, nc2);
363 check_for_error(ret);
364
365 parse_cidr("127.0.113.2/32", ip); // A
366 ip->size = 4; // strip network mask
367 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
368 check_test_result(ret, IP_ACCEPTED, ip);
369
370 parse_cidr("127.0.113.250/32", ip); // B
371 ip->size = 4; // strip network mask
372 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
373 check_test_result(ret, IP_REJECTED, ip);
374
375 parse_cidr("255.0.0.2/32", ip); // C
376 ip->size = 4; // strip network mask
377 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
378 check_test_result(ret, IP_REJECTED, ip);
379
380 parse_cidr("255.0.113.2/32", ip); // D
381 ip->size = 4; // strip network mask
382 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
383 check_test_result(ret, IP_REJECTED, ip);
384 }
385
check_difficult_intersection(void ** glob_state)386 static void check_difficult_intersection(void **glob_state)
387 {
388 /* 7: difficult intersection
389 * --------P:0.0.0.0/3--------------- --P:88.0.0.0/5--
390 * --P:0.0.0.0/5-- --P:16.0.0.0/5-- ----P:64.0.0.0/3----
391 * A B C D E F G H
392 */
393 int ret;
394 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
395 gnutls_x509_name_constraints_t nc2 = ((test_vars_t*)*glob_state)->nc2;
396 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
397
398 parse_cidr("0.0.0.0/3", ip);
399 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
400 check_for_error(ret);
401 parse_cidr("88.0.0.0/5", ip);
402 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
403 check_for_error(ret);
404 parse_cidr("0.0.0.0/5", ip);
405 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
406 check_for_error(ret);
407 parse_cidr("16.0.0.0/5", ip);
408 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
409 check_for_error(ret);
410 parse_cidr("64.0.0.0/3", ip);
411 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
412 check_for_error(ret);
413 ret = _gnutls_x509_name_constraints_merge(nc, nc2);
414 check_for_error(ret);
415
416 parse_cidr("0.0.113.2/32", ip); // A
417 ip->size = 4; // strip network mask
418 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
419 check_test_result(ret, IP_ACCEPTED, ip);
420
421 parse_cidr("15.255.255.255/32", ip); // B
422 ip->size = 4; // strip network mask
423 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
424 check_test_result(ret, IP_REJECTED, ip);
425
426 parse_cidr("16.0.0.0/32", ip); // C
427 ip->size = 4; // strip network mask
428 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
429 check_test_result(ret, IP_ACCEPTED, ip);
430
431 parse_cidr("31.12.25.2/32", ip); // D
432 ip->size = 4; // strip network mask
433 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
434 check_test_result(ret, IP_REJECTED, ip);
435
436 parse_cidr("63.255.255.255/32", ip); // E
437 ip->size = 4; // strip network mask
438 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
439 check_test_result(ret, IP_REJECTED, ip);
440
441 parse_cidr("64.0.0.0/32", ip); // F
442 ip->size = 4; // strip network mask
443 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
444 check_test_result(ret, IP_REJECTED, ip);
445
446 parse_cidr("89.125.7.187/32", ip); // G
447 ip->size = 4; // strip network mask
448 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
449 check_test_result(ret, IP_ACCEPTED, ip);
450
451 parse_cidr("96.0.0.0/32", ip); // H
452 ip->size = 4; // strip network mask
453 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
454 check_test_result(ret, IP_REJECTED, ip);
455 }
456
check_ipv6_intersection(void ** glob_state)457 static void check_ipv6_intersection(void **glob_state)
458 {
459 /* 8: IPv6 intersection
460 * --------P:affb::/16----- --P:affd:0000::/20--
461 * --P:affb:aa00::/24--
462 * A B C D E F G
463 */
464 int ret;
465 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
466 gnutls_x509_name_constraints_t nc2 = ((test_vars_t*)*glob_state)->nc2;
467 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
468
469 parse_cidr("affb::/16", ip);
470 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
471 check_for_error(ret);
472 parse_cidr("affd:0000::/20", ip);
473 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
474 check_for_error(ret);
475 parse_cidr("affb:aa00::/24", ip);
476 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
477 check_for_error(ret);
478 ret = _gnutls_x509_name_constraints_merge(nc, nc2);
479 check_for_error(ret);
480
481 parse_cidr("affa:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", ip); // A
482 ip->size = 16; // strip network mask
483 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
484 check_test_result(ret, IP_REJECTED, ip);
485
486 parse_cidr("affb:a500::/128", ip); // B
487 ip->size = 16; // strip network mask
488 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
489 check_test_result(ret, IP_REJECTED, ip);
490
491 parse_cidr("affb:aa00::/128", ip); // C
492 ip->size = 16; // strip network mask
493 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
494 check_test_result(ret, IP_ACCEPTED, ip);
495
496 parse_cidr("affb:ab01::/128", ip); // D
497 ip->size = 16; // strip network mask
498 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
499 check_test_result(ret, IP_REJECTED, ip);
500
501 parse_cidr("affc::/128", ip); // E
502 ip->size = 16; // strip network mask
503 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
504 check_test_result(ret, IP_REJECTED, ip);
505
506 parse_cidr("affd:0fff::/128", ip); // F
507 ip->size = 16; // strip network mask
508 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
509 check_test_result(ret, IP_REJECTED, ip);
510
511 parse_cidr("affd:1000::/128", ip); // G
512 ip->size = 16; // strip network mask
513 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
514 check_test_result(ret, IP_REJECTED, ip);
515 }
516
check_empty_ipv4_intersection_ipv6_remains(void ** glob_state)517 static void check_empty_ipv4_intersection_ipv6_remains(void **glob_state)
518 {
519 /* 9: IPv4 and IPv6 in a common test case
520 * IPv4 with empty intersection, but IPv6 gets restricted as well
521 * --P:127.0.113.0/24--
522 * --P:255.0.113.0/24--
523 * A B C
524 *
525 * --P:bfa6::/16--
526 * D E
527 */
528 int ret;
529 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
530 gnutls_x509_name_constraints_t nc2 = ((test_vars_t*)*glob_state)->nc2;
531 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
532
533 parse_cidr("127.0.113.0/24", ip);
534 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
535 check_for_error(ret);
536 parse_cidr("bfa6::/16", ip);
537 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
538 check_for_error(ret);
539 parse_cidr("255.0.113.0/24", ip);
540 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
541 check_for_error(ret);
542 ret = _gnutls_x509_name_constraints_merge(nc, nc2);
543 check_for_error(ret);
544
545 parse_cidr("127.0.113.2/32", ip); // A
546 ip->size = 4; // strip network mask
547 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
548 check_test_result(ret, IP_REJECTED, ip);
549
550 parse_cidr("255.0.0.2/32", ip); // B
551 ip->size = 4; // strip network mask
552 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
553 check_test_result(ret, IP_REJECTED, ip);
554
555 parse_cidr("255.0.113.2/32", ip); // C
556 ip->size = 4; // strip network mask
557 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
558 check_test_result(ret, IP_REJECTED, ip);
559
560 parse_cidr("bfa6:ab01::/128", ip); // D
561 ip->size = 16; // strip network mask
562 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
563 check_test_result(ret, IP_REJECTED, ip);
564
565 parse_cidr("bfa7::/128", ip); // E
566 ip->size = 16; // strip network mask
567 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
568 check_test_result(ret, IP_REJECTED, ip);
569 }
570
check_empty_ipv4v6_intersections(void ** glob_state)571 static void check_empty_ipv4v6_intersections(void **glob_state)
572 {
573 /* 10: IPv4 and IPv6 in a common test case
574 * both IPv4 and IPv6 have empty intersection
575 * --P:127.0.113.0/24--
576 * --P:255.0.113.0/24--
577 * A B C
578 *
579 * --P:bfa6::/16--
580 * --P:cfa6::/16--
581 * D E F
582 */
583 int ret;
584 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
585 gnutls_x509_name_constraints_t nc2 = ((test_vars_t*)*glob_state)->nc2;
586 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
587
588 parse_cidr("127.0.113.0/24", ip);
589 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
590 check_for_error(ret);
591 parse_cidr("bfa6::/16", ip);
592 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
593 check_for_error(ret);
594 parse_cidr("255.0.113.0/24", ip);
595 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
596 check_for_error(ret);
597 parse_cidr("cfa6::/16", ip);
598 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
599 check_for_error(ret);
600 ret = _gnutls_x509_name_constraints_merge(nc, nc2);
601 check_for_error(ret);
602
603 parse_cidr("127.0.113.2/32", ip); // A
604 ip->size = 4; // strip network mask
605 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
606 check_test_result(ret, IP_REJECTED, ip);
607
608 parse_cidr("255.0.0.2/32", ip); // B
609 ip->size = 4; // strip network mask
610 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
611 check_test_result(ret, IP_REJECTED, ip);
612
613 parse_cidr("255.0.113.2/32", ip); // C
614 ip->size = 4; // strip network mask
615 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
616 check_test_result(ret, IP_REJECTED, ip);
617
618 parse_cidr("bfa6:ab01::/128", ip); // D
619 ip->size = 16; // strip network mask
620 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
621 check_test_result(ret, IP_REJECTED, ip);
622
623 parse_cidr("bfa7::/128", ip); // E
624 ip->size = 16; // strip network mask
625 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
626 check_test_result(ret, IP_REJECTED, ip);
627
628 parse_cidr("cfa7:00cc::/128", ip); // F
629 ip->size = 16; // strip network mask
630 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
631 check_test_result(ret, IP_REJECTED, ip);
632 }
633
check_ipv4v6_single_constraint_each(void ** glob_state)634 static void check_ipv4v6_single_constraint_each(void **glob_state)
635 {
636 /* 11: 1 IPv4 range and 1 IPv6 range in a common test case
637 * (no overlap)
638 * --P:127.0.113.0/24--
639 * A B
640 *
641 * --P:bfa6::/16--
642 * C D
643 */
644 int ret;
645 gnutls_x509_name_constraints_t nc = ((test_vars_t*)*glob_state)->nc;
646 gnutls_x509_name_constraints_t nc2 = ((test_vars_t*)*glob_state)->nc2;
647 gnutls_datum_t *ip = &(((test_vars_t*)*glob_state)->ip);
648
649 parse_cidr("127.0.113.0/24", ip);
650 ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_IPADDRESS, ip);
651 check_for_error(ret);
652 parse_cidr("bfa6::/16", ip);
653 ret = gnutls_x509_name_constraints_add_permitted(nc2, GNUTLS_SAN_IPADDRESS, ip);
654 check_for_error(ret);
655 ret = _gnutls_x509_name_constraints_merge(nc, nc2);
656 check_for_error(ret);
657
658 parse_cidr("127.0.113.2/32", ip); // A
659 ip->size = 4; // strip network mask
660 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
661 check_test_result(ret, IP_REJECTED, ip);
662
663 parse_cidr("255.0.0.2/32", ip); // B
664 ip->size = 4; // strip network mask
665 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
666 check_test_result(ret, IP_REJECTED, ip);
667
668 parse_cidr("bfa6:ab01::/128", ip); // C
669 ip->size = 16; // strip network mask
670 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
671 check_test_result(ret, IP_REJECTED, ip);
672
673 parse_cidr("bfa7::/128", ip); // D
674 ip->size = 16; // strip network mask
675 ret = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_IPADDRESS, ip);
676 check_test_result(ret, IP_REJECTED, ip);
677 }
678
setup(void ** state)679 static int setup(void **state) {
680 test_vars_t* test_vars = gnutls_malloc(sizeof(test_vars_t));
681 if (test_vars == NULL)
682 return -1;
683 test_vars->ip.size = 0;
684 test_vars->ip.data = NULL;
685
686 int ret;
687 ret = gnutls_x509_name_constraints_init(&(test_vars->nc));
688 check_for_error(ret);
689 ret = gnutls_x509_name_constraints_init(&(test_vars->nc2));
690 check_for_error(ret);
691
692 *state = test_vars;
693 return 0;
694 }
695
teardown(void ** state)696 static int teardown(void **state) {
697 test_vars_t* test_vars = *state;
698 gnutls_free(test_vars->ip.data);
699 gnutls_x509_name_constraints_deinit(test_vars->nc);
700 gnutls_x509_name_constraints_deinit(test_vars->nc2);
701 gnutls_free(*state);
702 return 0;
703 }
704
main(int argc,char ** argv)705 int main(int argc, char **argv)
706 {
707 const struct CMUnitTest tests[] = {
708 cmocka_unit_test_setup_teardown(check_generation_reading_basic_checking, setup, teardown),
709 cmocka_unit_test_setup_teardown(check_universal_constraint_checking, setup, teardown),
710 cmocka_unit_test_setup_teardown(check_simple_intersection, setup, teardown),
711 cmocka_unit_test_setup_teardown(check_empty_intersection, setup, teardown),
712 cmocka_unit_test_setup_teardown(check_mediocre_intersection, setup, teardown),
713 cmocka_unit_test_setup_teardown(check_difficult_intersection, setup, teardown),
714 cmocka_unit_test_setup_teardown(check_ipv6_intersection, setup, teardown),
715 cmocka_unit_test_setup_teardown(check_empty_ipv4_intersection_ipv6_remains, setup, teardown),
716 cmocka_unit_test_setup_teardown(check_empty_ipv4v6_intersections, setup, teardown),
717 cmocka_unit_test_setup_teardown(check_ipv4v6_single_constraint_each, setup, teardown)
718 };
719 cmocka_run_group_tests(tests, NULL, NULL);
720 }
721