1*d657b5fcStb /* $OpenBSD: constraints.c,v 1.18 2023/12/13 05:59:50 tb Exp $ */
2d27446edSbeck /*
3d27446edSbeck * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4d27446edSbeck *
5d27446edSbeck * Permission to use, copy, modify, and distribute this software for any
6d27446edSbeck * purpose with or without fee is hereby granted, provided that the above
7d27446edSbeck * copyright notice and this permission notice appear in all copies.
8d27446edSbeck *
9d27446edSbeck * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10d27446edSbeck * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11d27446edSbeck * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12d27446edSbeck * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13d27446edSbeck * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14d27446edSbeck * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15d27446edSbeck * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16d27446edSbeck */
17d27446edSbeck
18d27446edSbeck #include <err.h>
19d27446edSbeck #include <string.h>
20d27446edSbeck
21d27446edSbeck #include <openssl/safestack.h>
22d27446edSbeck #include <openssl/x509.h>
23d27446edSbeck #include <openssl/x509v3.h>
24d27446edSbeck #include "x509_internal.h"
25d27446edSbeck
26d27446edSbeck #define FAIL(msg, ...) \
27d27446edSbeck do { \
28d27446edSbeck fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \
29d27446edSbeck fprintf(stderr, msg, ##__VA_ARGS__); \
30d27446edSbeck } while(0)
31d27446edSbeck
32d27446edSbeck unsigned char *valid_hostnames[] = {
33d27446edSbeck "openbsd.org",
34d27446edSbeck "op3nbsd.org",
35d27446edSbeck "org",
36d27446edSbeck "3openbsd.com",
37d27446edSbeck "3-0penb-d.c-m",
38d27446edSbeck "a",
39d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
40d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
41d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
42d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
43d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
44d27446edSbeck "open_bsd.org", /* because this is liberal */
45d27446edSbeck NULL,
46d27446edSbeck };
47d27446edSbeck
48d27446edSbeck unsigned char *valid_sandns_names[] = {
49d27446edSbeck "*.ca",
50d27446edSbeck "*.op3nbsd.org",
51fd017677Sbeck "c*.openbsd.org",
52fd017677Sbeck "foo.*.d*.c*.openbsd.org",
53d27446edSbeck NULL,
54d27446edSbeck };
55d27446edSbeck
56d27446edSbeck unsigned char *valid_domain_constraints[] = {
57d27446edSbeck "",
58d27446edSbeck ".ca",
59d27446edSbeck ".op3nbsd.org",
60d27446edSbeck ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
61d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
62d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
63d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
64d27446edSbeck "www.openbsd.org",
65d27446edSbeck NULL,
66d27446edSbeck };
67d27446edSbeck
68d27446edSbeck unsigned char *valid_mbox_names[] = {
69d27446edSbeck "\"!#$%&\\\"*+-/=?\002^_`{|}~.\"@openbsd.org",
70d27446edSbeck "beck@openbsd.org",
71d27446edSbeck "beck@openbsd.org",
72d27446edSbeck "beck@op3nbsd.org",
73d27446edSbeck "beck@org",
74d27446edSbeck "beck@3openbsd.com",
75d27446edSbeck "beck@3-0penb-d.c-m",
76d27446edSbeck "bec@a",
77d27446edSbeck "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
78d27446edSbeck "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
79d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
80d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
81d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
82d27446edSbeck "beck@open_bsd.org", /* because this is liberal */
83d27446edSbeck NULL,
84d27446edSbeck };
85d27446edSbeck
86d27446edSbeck unsigned char *invalid_hostnames[] = {
87d27446edSbeck "openbsd.org.",
88d27446edSbeck "openbsd..org",
89d27446edSbeck "openbsd.org-",
90d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
91d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
92d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
93d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
94d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a",
95d27446edSbeck "-p3nbsd.org",
96d27446edSbeck "openbs-.org",
97d27446edSbeck "openbsd\n.org",
98*d657b5fcStb "open\177bsd.org",
99d27446edSbeck "open\255bsd.org",
100fd017677Sbeck "*.openbsd.org",
101d27446edSbeck NULL,
102d27446edSbeck };
103d27446edSbeck
104d27446edSbeck unsigned char *invalid_sandns_names[] = {
105d27446edSbeck "",
106d27446edSbeck ".",
107d27446edSbeck "*.a",
108d27446edSbeck "*.",
109d27446edSbeck "*.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
110d27446edSbeck ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
111d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
112d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
113d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a",
114d27446edSbeck "*.-p3nbsd.org",
115d27446edSbeck "*.*..openbsd.org",
116d27446edSbeck "*..openbsd.org",
117d27446edSbeck ".openbsd.org",
118fd017677Sbeck "c*c.openbsd.org",
119d27446edSbeck NULL,
120d27446edSbeck };
121d27446edSbeck
122d27446edSbeck unsigned char *invalid_mbox_names[] = {
123d27446edSbeck "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
124d27446edSbeck "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
125d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
126d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
127d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a",
128d27446edSbeck "beck@.-openbsd.org",
129d27446edSbeck "beck@.openbsd.org.",
130d27446edSbeck "beck@.a",
131d27446edSbeck "beck@.",
132d27446edSbeck "beck@",
133d27446edSbeck "beck@.ca",
134d27446edSbeck "@openbsd.org",
135d27446edSbeck NULL,
136d27446edSbeck };
137d27446edSbeck
138d27446edSbeck unsigned char *invalid_domain_constraints[] = {
139d27446edSbeck ".",
140d27446edSbeck ".a",
141d27446edSbeck "..",
142d27446edSbeck ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
143d27446edSbeck ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
144d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
145d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
146d27446edSbeck "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a",
147d27446edSbeck ".-p3nbsd.org",
148d27446edSbeck "..openbsd.org",
149d27446edSbeck NULL,
150d27446edSbeck };
151d27446edSbeck
152d27446edSbeck unsigned char *invaliduri[] = {
153d27446edSbeck "https://-www.openbsd.org",
154d27446edSbeck "https://.www.openbsd.org/",
155d27446edSbeck "https://www.ope|nbsd.org%",
156d27446edSbeck "https://www.openbsd.org.#",
157c57a1965Sbeck "https://192.168.1.1./",
158c57a1965Sbeck "https://192.168.1.1|/",
159c57a1965Sbeck "https://.192.168.1.1/",
160c57a1965Sbeck "https://192.168..1.1/",
161c57a1965Sbeck "https://.2001:0DB8:AC10:FE01::/",
162c57a1965Sbeck "https://.2001:0DB8:AC10:FE01::|/",
163092bbf76Sbeck "///",
164092bbf76Sbeck "//",
165092bbf76Sbeck "/",
166092bbf76Sbeck "",
167d27446edSbeck NULL,
168d27446edSbeck };
169d27446edSbeck
170c57a1965Sbeck unsigned char *validuri[] = {
171c57a1965Sbeck "https://www.openbsd.org/meep/meep/meep/",
172c57a1965Sbeck "https://192.168.1.1/",
173c57a1965Sbeck "https://2001:0DB8:AC10:FE01::/",
174c57a1965Sbeck "https://192.168.1/", /* Not an IP, but valid component */
175c57a1965Sbeck "https://999.999.999.999/", /* Not an IP, but valid component */
176c57a1965Sbeck NULL,
177c57a1965Sbeck };
178c57a1965Sbeck
179d27446edSbeck static int
test_valid_hostnames(void)180d27446edSbeck test_valid_hostnames(void)
181d27446edSbeck {
182d27446edSbeck int i, failure = 0;
183d27446edSbeck
184d27446edSbeck for (i = 0; valid_hostnames[i] != NULL; i++) {
185f06436f8Sbeck CBS cbs;
186f06436f8Sbeck CBS_init(&cbs, valid_hostnames[i], strlen(valid_hostnames[i]));
187c57a1965Sbeck if (!x509_constraints_valid_host(&cbs, 0)) {
188d27446edSbeck FAIL("Valid hostname '%s' rejected\n",
189d27446edSbeck valid_hostnames[i]);
190d27446edSbeck failure = 1;
191d27446edSbeck goto done;
192d27446edSbeck }
193f06436f8Sbeck CBS_init(&cbs, valid_hostnames[i], strlen(valid_hostnames[i]));
194f06436f8Sbeck if (!x509_constraints_valid_sandns(&cbs)) {
195d27446edSbeck FAIL("Valid sandns '%s' rejected\n",
196d27446edSbeck valid_hostnames[i]);
197d27446edSbeck failure = 1;
198d27446edSbeck goto done;
199d27446edSbeck }
200d27446edSbeck }
201c57a1965Sbeck
202d27446edSbeck done:
203d27446edSbeck return failure;
204d27446edSbeck }
205d27446edSbeck
206d27446edSbeck static int
test_valid_sandns_names(void)207d27446edSbeck test_valid_sandns_names(void)
208d27446edSbeck {
209d27446edSbeck int i, failure = 0;
210d27446edSbeck for (i = 0; valid_sandns_names[i] != NULL; i++) {
211f06436f8Sbeck CBS cbs;
212f06436f8Sbeck CBS_init(&cbs, valid_sandns_names[i],
213f06436f8Sbeck strlen(valid_sandns_names[i]));
214f06436f8Sbeck if (!x509_constraints_valid_sandns(&cbs)) {
215d27446edSbeck FAIL("Valid dnsname '%s' rejected\n",
216d27446edSbeck valid_sandns_names[i]);
217d27446edSbeck failure = 1;
218d27446edSbeck goto done;
219d27446edSbeck }
220d27446edSbeck }
221c57a1965Sbeck
222d27446edSbeck done:
223d27446edSbeck return failure;
224d27446edSbeck }
225d27446edSbeck
226d27446edSbeck static int
test_valid_domain_constraints(void)227d27446edSbeck test_valid_domain_constraints(void)
228d27446edSbeck {
229d27446edSbeck int i, failure = 0;
230d27446edSbeck for (i = 0; valid_domain_constraints[i] != NULL; i++) {
231f06436f8Sbeck CBS cbs;
232f06436f8Sbeck CBS_init(&cbs, valid_domain_constraints[i],
233f06436f8Sbeck strlen(valid_domain_constraints[i]));
234f06436f8Sbeck if (!x509_constraints_valid_domain_constraint(&cbs)) {
235d27446edSbeck FAIL("Valid dnsname '%s' rejected\n",
236d27446edSbeck valid_domain_constraints[i]);
237d27446edSbeck failure = 1;
238d27446edSbeck goto done;
239d27446edSbeck }
240d27446edSbeck }
241c57a1965Sbeck
242d27446edSbeck done:
243d27446edSbeck return failure;
244d27446edSbeck }
245d27446edSbeck
246d27446edSbeck static int
test_valid_mbox_names(void)247d27446edSbeck test_valid_mbox_names(void)
248d27446edSbeck {
249d27446edSbeck struct x509_constraints_name name = {0};
250d27446edSbeck int i, failure = 0;
251d27446edSbeck for (i = 0; valid_mbox_names[i] != NULL; i++) {
252f06436f8Sbeck CBS cbs;
253f06436f8Sbeck CBS_init(&cbs, valid_mbox_names[i],
254f06436f8Sbeck strlen(valid_mbox_names[i]));
255f06436f8Sbeck if (!x509_constraints_parse_mailbox(&cbs, &name)) {
256d27446edSbeck FAIL("Valid mailbox name '%s' rejected\n",
257d27446edSbeck valid_mbox_names[i]);
258d27446edSbeck failure = 1;
259d27446edSbeck goto done;
260d27446edSbeck }
261d27446edSbeck free(name.name);
262d27446edSbeck name.name = NULL;
263d27446edSbeck free(name.local);
264d27446edSbeck name.local = NULL;
265d27446edSbeck }
266c57a1965Sbeck
267d27446edSbeck done:
268d27446edSbeck return failure;
269d27446edSbeck }
270d27446edSbeck
271d27446edSbeck static int
test_invalid_hostnames(void)272d27446edSbeck test_invalid_hostnames(void)
273d27446edSbeck {
274d27446edSbeck int i, failure = 0;
275db6a0a3bStb char *nulhost = "www.openbsd.org\0";
276ff16d1dcSkn CBS cbs;
277d27446edSbeck
278d27446edSbeck for (i = 0; invalid_hostnames[i] != NULL; i++) {
279f06436f8Sbeck CBS_init(&cbs, invalid_hostnames[i],
280f06436f8Sbeck strlen(invalid_hostnames[i]));
281c57a1965Sbeck if (x509_constraints_valid_host(&cbs, 0)) {
282d27446edSbeck FAIL("Invalid hostname '%s' accepted\n",
283d27446edSbeck invalid_hostnames[i]);
284d27446edSbeck failure = 1;
285d27446edSbeck goto done;
286d27446edSbeck }
287d27446edSbeck }
288f06436f8Sbeck CBS_init(&cbs, nulhost, strlen(nulhost) + 1);
289c57a1965Sbeck if (x509_constraints_valid_host(&cbs, 0)) {
290d27446edSbeck FAIL("hostname with NUL byte accepted\n");
291d27446edSbeck failure = 1;
292d27446edSbeck goto done;
293d27446edSbeck }
294f06436f8Sbeck CBS_init(&cbs, nulhost, strlen(nulhost) + 1);
295f06436f8Sbeck if (x509_constraints_valid_sandns(&cbs)) {
296d27446edSbeck FAIL("sandns with NUL byte accepted\n");
297d27446edSbeck failure = 1;
298d27446edSbeck goto done;
299d27446edSbeck }
300c57a1965Sbeck
301d27446edSbeck done:
302d27446edSbeck return failure;
303d27446edSbeck }
304d27446edSbeck
305d27446edSbeck static int
test_invalid_sandns_names(void)306d27446edSbeck test_invalid_sandns_names(void)
307d27446edSbeck {
308d27446edSbeck int i, failure = 0;
309d27446edSbeck for (i = 0; invalid_sandns_names[i] != NULL; i++) {
310f06436f8Sbeck CBS cbs;
311f06436f8Sbeck CBS_init(&cbs, invalid_sandns_names[i],
312f06436f8Sbeck strlen(invalid_sandns_names[i]));
313f06436f8Sbeck if (x509_constraints_valid_sandns(&cbs)) {
314d27446edSbeck FAIL("Valid dnsname '%s' rejected\n",
315d27446edSbeck invalid_sandns_names[i]);
316d27446edSbeck failure = 1;
317d27446edSbeck goto done;
318d27446edSbeck }
319d27446edSbeck }
320c57a1965Sbeck
321d27446edSbeck done:
322d27446edSbeck return failure;
323d27446edSbeck }
324d27446edSbeck
325d27446edSbeck static int
test_invalid_mbox_names(void)326d27446edSbeck test_invalid_mbox_names(void)
327d27446edSbeck {
328d27446edSbeck int i, failure = 0;
329d27446edSbeck struct x509_constraints_name name = {0};
330d27446edSbeck for (i = 0; invalid_mbox_names[i] != NULL; i++) {
331f06436f8Sbeck CBS cbs;
332f06436f8Sbeck CBS_init(&cbs, invalid_mbox_names[i],
333f06436f8Sbeck strlen(invalid_mbox_names[i]));
334f06436f8Sbeck if (x509_constraints_parse_mailbox(&cbs, &name)) {
335d27446edSbeck FAIL("invalid mailbox name '%s' accepted\n",
336d27446edSbeck invalid_mbox_names[i]);
337d27446edSbeck failure = 1;
338d27446edSbeck goto done;
339d27446edSbeck }
340d27446edSbeck free(name.name);
341d27446edSbeck name.name = NULL;
342d27446edSbeck free(name.local);
343d27446edSbeck name.local = NULL;
344d27446edSbeck }
345c57a1965Sbeck
346d27446edSbeck done:
347d27446edSbeck return failure;
348d27446edSbeck }
349d27446edSbeck
350d27446edSbeck static int
test_invalid_domain_constraints(void)351d27446edSbeck test_invalid_domain_constraints(void)
352d27446edSbeck {
353d27446edSbeck int i, failure = 0;
354d27446edSbeck for (i = 0; invalid_domain_constraints[i] != NULL; i++) {
355f06436f8Sbeck CBS cbs;
356f06436f8Sbeck CBS_init(&cbs, invalid_domain_constraints[i],
357f06436f8Sbeck strlen(invalid_domain_constraints[i]));
358f06436f8Sbeck if (x509_constraints_valid_domain_constraint(&cbs)) {
359d27446edSbeck FAIL("invalid dnsname '%s' accepted\n",
360d27446edSbeck invalid_domain_constraints[i]);
361d27446edSbeck failure = 1;
362d27446edSbeck goto done;
363d27446edSbeck }
364d27446edSbeck }
365c57a1965Sbeck
366d27446edSbeck done:
367d27446edSbeck return failure;
368d27446edSbeck }
369d27446edSbeck
370d27446edSbeck static int
test_invalid_uri(void)37183d21318Stb test_invalid_uri(void)
37283d21318Stb {
373d27446edSbeck int j, failure = 0;
37483d21318Stb char *hostpart = NULL;
37583d21318Stb
376d27446edSbeck for (j = 0; invaliduri[j] != NULL; j++) {
377d27446edSbeck if (x509_constraints_uri_host(invaliduri[j],
378d27446edSbeck strlen(invaliduri[j]), &hostpart) != 0) {
379d27446edSbeck FAIL("invalid URI '%s' accepted\n",
380d27446edSbeck invaliduri[j]);
381d27446edSbeck failure = 1;
382d27446edSbeck goto done;
383d27446edSbeck }
38483d21318Stb free(hostpart);
38583d21318Stb hostpart = NULL;
38656e222c1Stb }
38783d21318Stb
388d27446edSbeck done:
389d27446edSbeck return failure;
390d27446edSbeck }
391d9d2b19aStb
392c57a1965Sbeck static int
test_valid_uri(void)393c57a1965Sbeck test_valid_uri(void)
394c57a1965Sbeck {
395c57a1965Sbeck int j, failure = 0;
396c57a1965Sbeck char *hostpart = NULL;
397c57a1965Sbeck
398c57a1965Sbeck for (j = 0; validuri[j] != NULL; j++) {
399c57a1965Sbeck if (x509_constraints_uri_host(validuri[j],
400c57a1965Sbeck strlen(invaliduri[j]), &hostpart) == 0) {
401c57a1965Sbeck FAIL("Valid URI '%s' NOT accepted\n",
402c57a1965Sbeck validuri[j]);
403c57a1965Sbeck failure = 1;
404c57a1965Sbeck goto done;
405c57a1965Sbeck }
406c57a1965Sbeck free(hostpart);
407c57a1965Sbeck hostpart = NULL;
408c57a1965Sbeck }
409c57a1965Sbeck
410c57a1965Sbeck done:
411c57a1965Sbeck return failure;
412c57a1965Sbeck }
413d27446edSbeck
414d27446edSbeck static int
test_constraints1(void)41564ae88e1Stb test_constraints1(void)
416d27446edSbeck {
417f06436f8Sbeck char *c;
418f06436f8Sbeck size_t cl;
419f06436f8Sbeck char *d;
420f06436f8Sbeck size_t dl;
421d27446edSbeck int failure = 0;
422d27446edSbeck int error = 0;
423d27446edSbeck int i, j;
424d27446edSbeck unsigned char *constraints[] = {
425d27446edSbeck ".org",
426d27446edSbeck ".openbsd.org",
427d27446edSbeck "www.openbsd.org",
428d27446edSbeck NULL,
429d27446edSbeck };
430d27446edSbeck unsigned char *failing[] = {
431d27446edSbeck ".ca",
432d27446edSbeck "openbsd.ca",
433d27446edSbeck "org",
434d27446edSbeck NULL,
435d27446edSbeck };
436d27446edSbeck unsigned char *matching[] = {
437d27446edSbeck "www.openbsd.org",
438d27446edSbeck NULL,
439d27446edSbeck };
440d27446edSbeck unsigned char *matchinguri[] = {
441d27446edSbeck "https://www.openbsd.org",
442d27446edSbeck "https://www.openbsd.org/",
443d27446edSbeck "https://www.openbsd.org?",
444d27446edSbeck "https://www.openbsd.org#",
445d27446edSbeck "herp://beck@www.openbsd.org:",
446d27446edSbeck "spiffe://beck@www.openbsd.org/this/is/so/spiffe/",
447d27446edSbeck NULL,
448d27446edSbeck };
449d27446edSbeck unsigned char *failinguri[] = {
450d27446edSbeck "https://www.openbsd.ca",
451d27446edSbeck "https://www.freebsd.com/",
452d27446edSbeck "https://www.openbsd.net?",
453d27446edSbeck "https://org#",
454d27446edSbeck "herp://beck@org:",
4552b3bbd36Stb "///",
4562b3bbd36Stb "//",
4572b3bbd36Stb "/",
4582b3bbd36Stb "",
459d27446edSbeck NULL,
460d27446edSbeck };
4618e3291afSbeck unsigned char *noauthority[] = {
4628e3291afSbeck "urn:open62541.server.application",
4638e3291afSbeck NULL,
4648e3291afSbeck };
465d27446edSbeck for (i = 0; constraints[i] != NULL; i++) {
466d27446edSbeck char *constraint = constraints[i];
467d27446edSbeck size_t clen = strlen(constraints[i]);
468d27446edSbeck for (j = 0; matching[j] != NULL; j++) {
469d27446edSbeck if (!x509_constraints_domain(matching[j],
470d27446edSbeck strlen(matching[j]), constraint, clen)) {
471d27446edSbeck FAIL("constraint '%s' should have matched"
472d27446edSbeck " '%s'\n",
473d27446edSbeck constraint, matching[j]);
474d27446edSbeck failure = 1;
475d27446edSbeck goto done;
476d27446edSbeck }
477d27446edSbeck }
478d27446edSbeck for (j = 0; matchinguri[j] != NULL; j++) {
479d27446edSbeck error = 0;
480d27446edSbeck if (!x509_constraints_uri(matchinguri[j],
481d27446edSbeck strlen(matchinguri[j]), constraint, clen, &error)) {
482d27446edSbeck FAIL("constraint '%s' should have matched URI"
483d27446edSbeck " '%s' (error %d)\n",
484d27446edSbeck constraint, matchinguri[j], error);
485d27446edSbeck failure = 1;
486d27446edSbeck goto done;
487d27446edSbeck }
488d27446edSbeck }
489d27446edSbeck for (j = 0; failing[j] != NULL; j++) {
490d27446edSbeck if (x509_constraints_domain(failing[j],
491d27446edSbeck strlen(failing[j]), constraint, clen)) {
492d27446edSbeck FAIL("constraint '%s' should not have matched"
493d27446edSbeck " '%s'\n",
494d27446edSbeck constraint, failing[j]);
495d27446edSbeck failure = 1;
496d27446edSbeck goto done;
497d27446edSbeck }
498d27446edSbeck }
499d27446edSbeck for (j = 0; failinguri[j] != NULL; j++) {
500d27446edSbeck error = 0;
501d27446edSbeck if (x509_constraints_uri(failinguri[j],
502d27446edSbeck strlen(failinguri[j]), constraint, clen, &error)) {
503d27446edSbeck FAIL("constraint '%s' should not have matched URI"
504d27446edSbeck " '%s' (error %d)\n",
505d27446edSbeck constraint, failinguri[j], error);
506d27446edSbeck failure = 1;
507d27446edSbeck goto done;
508d27446edSbeck }
509d27446edSbeck }
5108e3291afSbeck for (j = 0; noauthority[j] != NULL; j++) {
5118e3291afSbeck char *hostpart = NULL;
5124f3af884Skn error = 0;
5138e3291afSbeck if (!x509_constraints_uri_host(noauthority[j],
514de7a2304Stb strlen(noauthority[j]), NULL) ||
515de7a2304Stb !x509_constraints_uri_host(noauthority[j],
5168e3291afSbeck strlen(noauthority[j]), &hostpart)) {
5178e3291afSbeck FAIL("name '%s' should parse as a URI",
5188e3291afSbeck noauthority[j]);
5198e3291afSbeck failure = 1;
5208e3291afSbeck free(hostpart);
5218e3291afSbeck goto done;
5228e3291afSbeck }
5238e3291afSbeck free(hostpart);
5248e3291afSbeck
5258e3291afSbeck if (x509_constraints_uri(noauthority[j],
5268e3291afSbeck strlen(noauthority[j]), constraint, clen, &error)) {
5278e3291afSbeck FAIL("constraint '%s' should not have matched URI"
5288e3291afSbeck " '%s' (error %d)\n",
5298e3291afSbeck constraint, failinguri[j], error);
5308e3291afSbeck failure = 1;
5318e3291afSbeck goto done;
5328e3291afSbeck }
5338e3291afSbeck }
534d27446edSbeck }
535d27446edSbeck c = ".openbsd.org";
536d27446edSbeck cl = strlen(".openbsd.org");
537d27446edSbeck d = "*.openbsd.org";
538d27446edSbeck dl = strlen("*.openbsd.org");
539d27446edSbeck if (!x509_constraints_domain(d, dl, c, cl)) {
540d27446edSbeck FAIL("constraint '%s' should have matched '%s'\n",
541d27446edSbeck c, d);
542d27446edSbeck failure = 1;
543d27446edSbeck goto done;
544d27446edSbeck }
545d27446edSbeck c = "www.openbsd.org";
546d27446edSbeck cl = strlen("www.openbsd.org");
547d27446edSbeck if (x509_constraints_domain(d, dl, c, cl)) {
548d27446edSbeck FAIL("constraint '%s' should not have matched '%s'\n",
549d27446edSbeck c, d);
550d27446edSbeck failure = 1;
551d27446edSbeck goto done;
552d27446edSbeck }
553d27446edSbeck c = "";
554d27446edSbeck cl = 0;
555d27446edSbeck if (!x509_constraints_domain(d, dl, c, cl)) {
556d27446edSbeck FAIL("constraint '%s' should have matched '%s'\n",
557d27446edSbeck c, d);
558d27446edSbeck failure = 1;
559d27446edSbeck goto done;
560d27446edSbeck }
561c57a1965Sbeck
562d27446edSbeck done:
563d27446edSbeck return failure;
564d27446edSbeck }
565d27446edSbeck
566d27446edSbeck int
main(int argc,char ** argv)567d27446edSbeck main(int argc, char **argv)
568d27446edSbeck {
569d27446edSbeck int failed = 0;
570d27446edSbeck
571d27446edSbeck failed |= test_valid_hostnames();
572d27446edSbeck failed |= test_invalid_hostnames();
573d27446edSbeck failed |= test_valid_sandns_names();
574d27446edSbeck failed |= test_invalid_sandns_names();
575d27446edSbeck failed |= test_valid_mbox_names();
576d27446edSbeck failed |= test_invalid_mbox_names();
577d27446edSbeck failed |= test_valid_domain_constraints();
578d27446edSbeck failed |= test_invalid_domain_constraints();
579d27446edSbeck failed |= test_invalid_uri();
580c57a1965Sbeck failed |= test_valid_uri();
581d27446edSbeck failed |= test_constraints1();
582d27446edSbeck
583d27446edSbeck return (failed);
584d27446edSbeck }
585