diff --git a/lib/libcrypto/x509/x509_constraints.c b/lib/libcrypto/x509/x509_constraints.c index 0773d2ba719..c4f32c9cfc7 100644 --- a/lib/libcrypto/x509/x509_constraints.c +++ b/lib/libcrypto/x509/x509_constraints.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_constraints.c,v 1.32 2023/09/29 15:53:59 beck Exp $ */ +/* $OpenBSD: x509_constraints.c,v 1.33 2026/04/13 17:04:23 beck Exp $ */ /* * Copyright (c) 2020 Bob Beck * @@ -578,11 +578,30 @@ x509_constraints_sandns(char *sandns, size_t dlen, char *constraint, size_t len) if (len == 0) return 1; /* an empty constraint matches everything */ - /* match the end of the domain */ if (dlen < len) return 0; - suffix = sandns + (dlen - len); - return (strncasecmp(suffix, constraint, len) == 0); + + if (dlen == len) + return (strncasecmp(sandns, constraint, len) == 0); + + /* Support a constraint with a leading "." */ + if (constraint[0] == '.') { + constraint++; + len--; + } + + /* + * Otherwise we must have at least one extra component + * to match, so there must be more than just a leading . + */ + if (dlen - len > 1) { + suffix = sandns + (dlen - len); + if (suffix[-1] != '.') + return 0; + return (strncasecmp(suffix, constraint, len) == 0); + } + + return 0; } /* diff --git a/lib/libcrypto/x509/x509_internal.h b/lib/libcrypto/x509/x509_internal.h index 9b9980ece57..e933cd9f2d1 100644 --- a/lib/libcrypto/x509/x509_internal.h +++ b/lib/libcrypto/x509/x509_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_internal.h,v 1.28 2024/05/19 07:12:50 jsg Exp $ */ +/* $OpenBSD: x509_internal.h,v 1.29 2026/04/13 17:04:23 beck Exp $ */ /* * Copyright (c) 2020 Bob Beck * @@ -116,6 +116,8 @@ int x509_constraints_valid_host(CBS *cbs, int permit_ip); int x509_constraints_valid_sandns(CBS *cbs); int x509_constraints_domain(char *domain, size_t dlen, char *constraint, size_t len); +int x509_constraints_sandns(char *domain, size_t dlen, char *constraint, + size_t len); int x509_constraints_parse_mailbox(CBS *candidate, struct x509_constraints_name *name); int x509_constraints_valid_domain_constraint(CBS *cbs); diff --git a/regress/lib/libcrypto/x509/constraints.c b/regress/lib/libcrypto/x509/constraints.c index 16e135bb44c..54bb654a31b 100644 --- a/regress/lib/libcrypto/x509/constraints.c +++ b/regress/lib/libcrypto/x509/constraints.c @@ -1,4 +1,4 @@ -/* $OpenBSD: constraints.c,v 1.18 2023/12/13 05:59:50 tb Exp $ */ +/* $OpenBSD: constraints.c,v 1.19 2026/04/13 17:04:23 beck Exp $ */ /* * Copyright (c) 2020 Bob Beck * @@ -558,7 +558,54 @@ test_constraints1(void) failure = 1; goto done; } - + c = "openbsd.org"; + cl = strlen("openbsd.org"); + d = "oopenbsd.org"; + dl = strlen("oopenbsd.org"); + if (x509_constraints_sandns(d, dl, c, cl)) { + FAIL("constraint '%s' should not have matched '%s'\n", + c, d); + failure = 1; + goto done; + } + d = "*.openbsd.org"; + dl = strlen("*.openbsd.org"); + if (!x509_constraints_sandns(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_sandns(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_sandns(d, dl, c, cl)) { + FAIL("constraint '%s' should have matched '%s'\n", + c, d); + failure = 1; + goto done; + } + /* + * Note that this *will* match, but we do not allow ".openbsd.org" + * as a sandns name - see invalid sandnsname tests above. + */ + c = ".openbsd.org"; + cl = strlen(".openbsd.org"); + d = ".openbsd.org"; + dl = strlen(".openbsd.org"); + if (!x509_constraints_sandns(d, dl, c, cl)) { + FAIL("constraint '%s' should have matched '%s'\n", + c, d); + failure = 1; + goto done; + } done: return failure; }