diff options
| author | beck <> | 2026-04-13 17:04:23 +0000 |
|---|---|---|
| committer | beck <> | 2026-04-13 17:04:23 +0000 |
| commit | cf3eec32e7a6acbaecd14871fb75ad34fb76c3e7 (patch) | |
| tree | efa04762242365a86b1b6bbcc2b67d2f12172f99 /src | |
| parent | d58a3236dc52156e5514e3212cbb63805e90915e (diff) | |
| download | openbsd-cf3eec32e7a6acbaecd14871fb75ad34fb76c3e7.tar.gz openbsd-cf3eec32e7a6acbaecd14871fb75ad34fb76c3e7.tar.bz2 openbsd-cf3eec32e7a6acbaecd14871fb75ad34fb76c3e7.zip | |
Prior to this we substring matched and allowed a leading .
on a SAN DNSname constraint. This is not correct, as with
a DNSname constraint, it may exacly match or match zero or
more additional components on the front of the candidte to
match.
Spotted by Haruto Kimura <hkimura2026@gmail.com>
ok tb@ kenjiro@
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_constraints.c | 27 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_internal.h | 4 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/x509/constraints.c | 51 |
3 files changed, 75 insertions, 7 deletions
diff --git a/src/lib/libcrypto/x509/x509_constraints.c b/src/lib/libcrypto/x509/x509_constraints.c index 0773d2ba71..c4f32c9cfc 100644 --- a/src/lib/libcrypto/x509/x509_constraints.c +++ b/src/lib/libcrypto/x509/x509_constraints.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_constraints.c,v 1.32 2023/09/29 15:53:59 beck Exp $ */ | 1 | /* $OpenBSD: x509_constraints.c,v 1.33 2026/04/13 17:04:23 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -578,11 +578,30 @@ x509_constraints_sandns(char *sandns, size_t dlen, char *constraint, size_t len) | |||
| 578 | if (len == 0) | 578 | if (len == 0) |
| 579 | return 1; /* an empty constraint matches everything */ | 579 | return 1; /* an empty constraint matches everything */ |
| 580 | 580 | ||
| 581 | /* match the end of the domain */ | ||
| 582 | if (dlen < len) | 581 | if (dlen < len) |
| 583 | return 0; | 582 | return 0; |
| 584 | suffix = sandns + (dlen - len); | 583 | |
| 585 | return (strncasecmp(suffix, constraint, len) == 0); | 584 | if (dlen == len) |
| 585 | return (strncasecmp(sandns, constraint, len) == 0); | ||
| 586 | |||
| 587 | /* Support a constraint with a leading "." */ | ||
| 588 | if (constraint[0] == '.') { | ||
| 589 | constraint++; | ||
| 590 | len--; | ||
| 591 | } | ||
| 592 | |||
| 593 | /* | ||
| 594 | * Otherwise we must have at least one extra component | ||
| 595 | * to match, so there must be more than just a leading . | ||
| 596 | */ | ||
| 597 | if (dlen - len > 1) { | ||
| 598 | suffix = sandns + (dlen - len); | ||
| 599 | if (suffix[-1] != '.') | ||
| 600 | return 0; | ||
| 601 | return (strncasecmp(suffix, constraint, len) == 0); | ||
| 602 | } | ||
| 603 | |||
| 604 | return 0; | ||
| 586 | } | 605 | } |
| 587 | 606 | ||
| 588 | /* | 607 | /* |
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h index 9b9980ece5..e933cd9f2d 100644 --- a/src/lib/libcrypto/x509/x509_internal.h +++ b/src/lib/libcrypto/x509/x509_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_internal.h,v 1.28 2024/05/19 07:12:50 jsg Exp $ */ | 1 | /* $OpenBSD: x509_internal.h,v 1.29 2026/04/13 17:04:23 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -116,6 +116,8 @@ int x509_constraints_valid_host(CBS *cbs, int permit_ip); | |||
| 116 | int x509_constraints_valid_sandns(CBS *cbs); | 116 | int x509_constraints_valid_sandns(CBS *cbs); |
| 117 | int x509_constraints_domain(char *domain, size_t dlen, char *constraint, | 117 | int x509_constraints_domain(char *domain, size_t dlen, char *constraint, |
| 118 | size_t len); | 118 | size_t len); |
| 119 | int x509_constraints_sandns(char *domain, size_t dlen, char *constraint, | ||
| 120 | size_t len); | ||
| 119 | int x509_constraints_parse_mailbox(CBS *candidate, | 121 | int x509_constraints_parse_mailbox(CBS *candidate, |
| 120 | struct x509_constraints_name *name); | 122 | struct x509_constraints_name *name); |
| 121 | int x509_constraints_valid_domain_constraint(CBS *cbs); | 123 | int x509_constraints_valid_domain_constraint(CBS *cbs); |
diff --git a/src/regress/lib/libcrypto/x509/constraints.c b/src/regress/lib/libcrypto/x509/constraints.c index 16e135bb44..54bb654a31 100644 --- a/src/regress/lib/libcrypto/x509/constraints.c +++ b/src/regress/lib/libcrypto/x509/constraints.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: constraints.c,v 1.18 2023/12/13 05:59:50 tb Exp $ */ | 1 | /* $OpenBSD: constraints.c,v 1.19 2026/04/13 17:04:23 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -558,7 +558,54 @@ test_constraints1(void) | |||
| 558 | failure = 1; | 558 | failure = 1; |
| 559 | goto done; | 559 | goto done; |
| 560 | } | 560 | } |
| 561 | 561 | c = "openbsd.org"; | |
| 562 | cl = strlen("openbsd.org"); | ||
| 563 | d = "oopenbsd.org"; | ||
| 564 | dl = strlen("oopenbsd.org"); | ||
| 565 | if (x509_constraints_sandns(d, dl, c, cl)) { | ||
| 566 | FAIL("constraint '%s' should not have matched '%s'\n", | ||
| 567 | c, d); | ||
| 568 | failure = 1; | ||
| 569 | goto done; | ||
| 570 | } | ||
| 571 | d = "*.openbsd.org"; | ||
| 572 | dl = strlen("*.openbsd.org"); | ||
| 573 | if (!x509_constraints_sandns(d, dl, c, cl)) { | ||
| 574 | FAIL("constraint '%s' should have matched '%s'\n", | ||
| 575 | c, d); | ||
| 576 | failure = 1; | ||
| 577 | goto done; | ||
| 578 | } | ||
| 579 | c = "www.openbsd.org"; | ||
| 580 | cl = strlen("www.openbsd.org"); | ||
| 581 | if (x509_constraints_sandns(d, dl, c, cl)) { | ||
| 582 | FAIL("constraint '%s' should not have matched '%s'\n", | ||
| 583 | c, d); | ||
| 584 | failure = 1; | ||
| 585 | goto done; | ||
| 586 | } | ||
| 587 | c = ""; | ||
| 588 | cl = 0; | ||
| 589 | if (!x509_constraints_sandns(d, dl, c, cl)) { | ||
| 590 | FAIL("constraint '%s' should have matched '%s'\n", | ||
| 591 | c, d); | ||
| 592 | failure = 1; | ||
| 593 | goto done; | ||
| 594 | } | ||
| 595 | /* | ||
| 596 | * Note that this *will* match, but we do not allow ".openbsd.org" | ||
| 597 | * as a sandns name - see invalid sandnsname tests above. | ||
| 598 | */ | ||
| 599 | c = ".openbsd.org"; | ||
| 600 | cl = strlen(".openbsd.org"); | ||
| 601 | d = ".openbsd.org"; | ||
| 602 | dl = strlen(".openbsd.org"); | ||
| 603 | if (!x509_constraints_sandns(d, dl, c, cl)) { | ||
| 604 | FAIL("constraint '%s' should have matched '%s'\n", | ||
| 605 | c, d); | ||
| 606 | failure = 1; | ||
| 607 | goto done; | ||
| 608 | } | ||
| 562 | done: | 609 | done: |
| 563 | return failure; | 610 | return failure; |
| 564 | } | 611 | } |
