diff options
-rw-r--r-- | x509_name_match.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/x509_name_match.c b/x509_name_match.c index ddfee3eb..50c7368a 100644 --- a/x509_name_match.c +++ b/x509_name_match.c @@ -26,15 +26,20 @@ int name_match(const char *p1, const char *p2) { if (strspn(p2, dom) == strlen(p2)) wildcard_ok = 0; + /* If we decided above that wildcarding is still OK, + * try a wildcard match first - providing that + * the wildcard is for a full component, + * i. e. starts with "*." */ if (wildcard_ok && p1[0] == '*' && p1[1] == '.') { size_t l1, l2; int number_dots = 0; const char *tmp; + /* skip over the asterisk */ ++p1; + /* make sure CAs don't wildcard top-level domains by requiring there * are at least two dots in wildcarded X.509 CN/SANs */ - for(tmp = p1; *tmp; tmp += strcspn(tmp, ".")) { if (*tmp == '.') { ++number_dots; @@ -42,15 +47,28 @@ int name_match(const char *p1, const char *p2) { } } + /* If there are at least 2 dots, do the wildcard match. + * Match from the end by incrementing the p2 pointer by the + * length difference between remainder of pattern and string to + * be matched. */ if (number_dots >= 2) { l1 = strlen(p1); l2 = strlen(p2); if (l2 > l1) p2 += l2 - l1; + /* FALLTHROUGH */ } } + /* Now to the match. Either wildcards are forbidden or not found, + * then it's a case-insensitive full-string match, or wildcards are + * permitted and found and we've bumped the start-string pointers + * sufficiently. */ return (0 == strcasecmp(p1, p2)); + + /* XXX open issue: do we need to deal with trailing dots in patterns + * or domains? A trailing dot is an anchor that prevents resolver + * "search"es to DNS, so might cause false mismatches. */ } #ifdef TEST |