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