From 77c3247aa0b565ea6bf2032c2d2d20413a0d5af4 Mon Sep 17 00:00:00 2001 From: beck <> Date: Fri, 11 Sep 2020 18:34:29 +0000 Subject: Add x509_constraints.c - a new implementation of x509 name constraints, with regression tests. The use of the new name constraints is not yet activated in x509_vfy.c and will be activated in a follow on commit ok jsing@ --- src/regress/lib/libcrypto/x509/constraints.c | 485 +++++++++++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 src/regress/lib/libcrypto/x509/constraints.c (limited to 'src/regress/lib/libcrypto/x509/constraints.c') diff --git a/src/regress/lib/libcrypto/x509/constraints.c b/src/regress/lib/libcrypto/x509/constraints.c new file mode 100644 index 0000000000..c04fc15000 --- /dev/null +++ b/src/regress/lib/libcrypto/x509/constraints.c @@ -0,0 +1,485 @@ +/* $OpenBSD: constraints.c */ +/* + * Copyright (c) 2020 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include "x509_verify.h" +#include "x509_internal.h" + + +#define FAIL(msg, ...) \ +do { \ + fprintf(stderr, "[%s:%d] FAIL: ", __FILE__, __LINE__); \ + fprintf(stderr, msg, ##__VA_ARGS__); \ +} while(0) + +unsigned char *valid_hostnames[] = { + "openbsd.org", + "op3nbsd.org", + "org", + "3openbsd.com", + "3-0penb-d.c-m", + "a", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "open_bsd.org", /* because this is liberal */ + NULL, +}; + +unsigned char *valid_sandns_names[] = { + "*.ca", + "*.op3nbsd.org", + NULL, +}; + +unsigned char *valid_domain_constraints[] = { + "", + ".ca", + ".op3nbsd.org", + ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "www.openbsd.org", + NULL, +}; + +unsigned char *valid_mbox_names[] = { + "\"!#$%&\\\"*+-/=?\002^_`{|}~.\"@openbsd.org", + "beck@openbsd.org", + "beck@openbsd.org", + "beck@op3nbsd.org", + "beck@org", + "beck@3openbsd.com", + "beck@3-0penb-d.c-m", + "bec@a", + "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "beck@open_bsd.org", /* because this is liberal */ + NULL, +}; + +unsigned char *invalid_hostnames[] = { + "openbsd.org.", + "openbsd..org", + "openbsd.org-", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + "-p3nbsd.org", + "openbs-.org", + "openbsd\n.org", + "open\178bsd.org", + "open\255bsd.org", + NULL, +}; + +unsigned char *invalid_sandns_names[] = { + "", + ".", + "*.a", + "*.", + "*.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + "*.-p3nbsd.org", + "a*.openbsd.org", + "*.*..openbsd.org", + "*..openbsd.org", + ".openbsd.org", + NULL, +}; + +unsigned char *invalid_mbox_names[] = { + "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + "beck@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + "beck@.-openbsd.org", + "beck@.openbsd.org.", + "beck@.a", + "beck@.", + "beck@", + "beck@.ca", + "@openbsd.org", + NULL, +}; + +unsigned char *invalid_domain_constraints[] = { + ".", + ".a", + "..", + ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", + ".aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.a", + ".-p3nbsd.org", + "..openbsd.org", + NULL, +}; + +unsigned char *invaliduri[] = { + "https://-www.openbsd.org", + "https://.www.openbsd.org/", + "https://www.ope|nbsd.org%", + "https://www.openbsd.org.#", + NULL, +}; + +static int +test_valid_hostnames(void) +{ + int i, failure = 0; + + for (i = 0; valid_hostnames[i] != NULL; i++) { + if (!x509_constraints_valid_host(valid_hostnames[i], + strlen(valid_hostnames[i]))) { + FAIL("Valid hostname '%s' rejected\n", + valid_hostnames[i]); + failure = 1; + goto done; + } + if (!x509_constraints_valid_sandns(valid_hostnames[i], + strlen(valid_hostnames[i]))) { + FAIL("Valid sandns '%s' rejected\n", + valid_hostnames[i]); + failure = 1; + goto done; + } + } + done: + return failure; +} + +static int +test_valid_sandns_names(void) +{ + int i, failure = 0; + for (i = 0; valid_sandns_names[i] != NULL; i++) { + if (!x509_constraints_valid_sandns(valid_sandns_names[i], + strlen(valid_sandns_names[i]))) { + FAIL("Valid dnsname '%s' rejected\n", + valid_sandns_names[i]); + failure = 1; + goto done; + } + } + done: + return failure; +} + +static int +test_valid_domain_constraints(void) +{ + int i, failure = 0; + for (i = 0; valid_domain_constraints[i] != NULL; i++) { + if (!x509_constraints_valid_domain_constraint(valid_domain_constraints[i], + strlen(valid_domain_constraints[i]))) { + FAIL("Valid dnsname '%s' rejected\n", + valid_domain_constraints[i]); + failure = 1; + goto done; + } + } + done: + return failure; +} + +static int +test_valid_mbox_names(void) +{ + struct x509_constraints_name name = {0}; + int i, failure = 0; + for (i = 0; valid_mbox_names[i] != NULL; i++) { + if (!x509_constraints_parse_mailbox(valid_mbox_names[i], + strlen(valid_mbox_names[i]), &name)) { + FAIL("Valid mailbox name '%s' rejected\n", + valid_mbox_names[i]); + failure = 1; + goto done; + } + free(name.name); + name.name = NULL; + free(name.local); + name.local = NULL; + } + done: + return failure; +} + +static int +test_invalid_hostnames(void) +{ + int i, failure = 0; + + for (i = 0; invalid_hostnames[i] != NULL; i++) { + if (x509_constraints_valid_host(invalid_hostnames[i], + strlen(invalid_hostnames[i]))) { + FAIL("Invalid hostname '%s' accepted\n", + invalid_hostnames[i]); + failure = 1; + goto done; + } + if (x509_constraints_valid_sandns(invalid_hostnames[i], + strlen(invalid_hostnames[i]))) { + FAIL("Invalid sandns '%s' accepted\n", + invalid_hostnames[i]); + failure = 1; + goto done; + } + } + char *nulhost = "www.openbsd.org\0"; + if (x509_constraints_valid_host(nulhost, + strlen(nulhost) + 1)) { + FAIL("hostname with NUL byte accepted\n"); + failure = 1; + goto done; + } + if (x509_constraints_valid_sandns(nulhost, + strlen(nulhost) + 1)) { + FAIL("sandns with NUL byte accepted\n"); + failure = 1; + goto done; + } + done: + return failure; +} + +static int +test_invalid_sandns_names(void) +{ + int i, failure = 0; + for (i = 0; invalid_sandns_names[i] != NULL; i++) { + if (x509_constraints_valid_sandns(invalid_sandns_names[i], + strlen(invalid_sandns_names[i]))) { + FAIL("Valid dnsname '%s' rejected\n", + invalid_sandns_names[i]); + failure = 1; + goto done; + } + } + done: + return failure; +} + +static int +test_invalid_mbox_names(void) +{ + int i, failure = 0; + struct x509_constraints_name name = {0}; + for (i = 0; invalid_mbox_names[i] != NULL; i++) { + if (x509_constraints_parse_mailbox(invalid_mbox_names[i], + strlen(invalid_mbox_names[i]), &name)) { + FAIL("invalid mailbox name '%s' accepted\n", + invalid_mbox_names[i]); + failure = 1; + goto done; + } + free(name.name); + name.name = NULL; + free(name.local); + name.local = NULL; + } + done: + return failure; +} + +static int +test_invalid_domain_constraints(void) +{ + int i, failure = 0; + for (i = 0; invalid_domain_constraints[i] != NULL; i++) { + if (x509_constraints_valid_domain_constraint(invalid_domain_constraints[i], + strlen(invalid_domain_constraints[i]))) { + FAIL("invalid dnsname '%s' accepted\n", + invalid_domain_constraints[i]); + failure = 1; + goto done; + } + } + done: + return failure; +} + +static int +test_invalid_uri(void) { + int j, failure=0; + char *hostpart; + for (j = 0; invaliduri[j] != NULL; j++) { + if (x509_constraints_uri_host(invaliduri[j], + strlen(invaliduri[j]), &hostpart) != 0) { + FAIL("invalid URI '%s' accepted\n", + invaliduri[j]); + failure = 1; + } + goto done; + } + done: + return failure; +} + +static int +test_constraints1() +{ + char *c; size_t cl; + char *d; size_t dl; + int failure = 0; + int error = 0; + int i, j; + unsigned char *constraints[] = { + ".org", + ".openbsd.org", + "www.openbsd.org", + NULL, + }; + unsigned char *failing[] = { + ".ca", + "openbsd.ca", + "org", + NULL, + }; + unsigned char *matching[] = { + "www.openbsd.org", + NULL, + }; + unsigned char *matchinguri[] = { + "https://www.openbsd.org", + "https://www.openbsd.org/", + "https://www.openbsd.org?", + "https://www.openbsd.org#", + "herp://beck@www.openbsd.org:", + "spiffe://beck@www.openbsd.org/this/is/so/spiffe/", + NULL, + }; + unsigned char *failinguri[] = { + "https://www.openbsd.ca", + "https://www.freebsd.com/", + "https://www.openbsd.net?", + "https://org#", + "herp://beck@org:", + NULL, + }; + for (i = 0; constraints[i] != NULL; i++) { + char *constraint = constraints[i]; + size_t clen = strlen(constraints[i]); + for (j = 0; matching[j] != NULL; j++) { + if (!x509_constraints_domain(matching[j], + strlen(matching[j]), constraint, clen)) { + FAIL("constraint '%s' should have matched" + " '%s'\n", + constraint, matching[j]); + failure = 1; + goto done; + } + } + for (j = 0; matchinguri[j] != NULL; j++) { + error = 0; + if (!x509_constraints_uri(matchinguri[j], + strlen(matchinguri[j]), constraint, clen, &error)) { + FAIL("constraint '%s' should have matched URI" + " '%s' (error %d)\n", + constraint, matchinguri[j], error); + failure = 1; + goto done; + } + } + for (j = 0; failing[j] != NULL; j++) { + if (x509_constraints_domain(failing[j], + strlen(failing[j]), constraint, clen)) { + FAIL("constraint '%s' should not have matched" + " '%s'\n", + constraint, failing[j]); + failure = 1; + goto done; + } + } + for (j = 0; failinguri[j] != NULL; j++) { + error = 0; + if (x509_constraints_uri(failinguri[j], + strlen(failinguri[j]), constraint, clen, &error)) { + FAIL("constraint '%s' should not have matched URI" + " '%s' (error %d)\n", + constraint, failinguri[j], error); + failure = 1; + goto done; + } + } + } + c = ".openbsd.org"; + cl = strlen(".openbsd.org"); + d = "*.openbsd.org"; + dl = strlen("*.openbsd.org"); + if (!x509_constraints_domain(d, dl, c, cl)) { + FAIL("constraint '%s' should have matched '%s'\n", + c, d); + failure = 1; + goto done; + } + c = "www.openbsd.org"; + cl = strlen("www.openbsd.org"); + if (x509_constraints_domain(d, dl, c, cl)) { + FAIL("constraint '%s' should not have matched '%s'\n", + c, d); + failure = 1; + goto done; + } + c = ""; + cl = 0; + if (!x509_constraints_domain(d, dl, c, cl)) { + FAIL("constraint '%s' should have matched '%s'\n", + c, d); + failure = 1; + goto done; + } + done: + return failure; +} + +int +main(int argc, char **argv) +{ + int failed = 0; + + failed |= test_valid_hostnames(); + failed |= test_invalid_hostnames(); + failed |= test_valid_sandns_names(); + failed |= test_invalid_sandns_names(); + failed |= test_valid_mbox_names(); + failed |= test_invalid_mbox_names(); + failed |= test_valid_domain_constraints(); + failed |= test_invalid_domain_constraints(); + failed |= test_invalid_uri(); + failed |= test_constraints1(); + + return (failed); +} -- cgit v1.2.3-55-g6feb