Module: wine
Branch: master
Commit: c79aad51cd21e1da941dcc003379957065253715
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c79aad51cd21e1da941dcc003…
Author: Juan Lang <juan.lang(a)gmail.com>
Date: Thu May 20 08:52:43 2010 -0700
crypt32: Implement wildcard domain name matching in subject alternative names.
---
dlls/crypt32/chain.c | 26 +++++++++++++++++++++++++-
dlls/crypt32/tests/chain.c | 2 +-
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index d324314..e951ef8 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -3035,7 +3035,31 @@ static BOOL match_dns_to_subject_alt_name(PCERT_EXTENSION ext,
{
TRACE_(chain)("dNSName: %s\n", debugstr_w(
subjectName->rgAltEntry[i].u.pwszDNSName));
- if (!strcmpiW(server_name,
+ if (subjectName->rgAltEntry[i].u.pwszDNSName[0] == '*')
+ {
+ LPCWSTR server_name_dot;
+
+ /* Matching a wildcard: a wildcard matches a single name
+ * component, which is terminated by a dot. RFC 1034
+ * doesn't define whether multiple wildcards are allowed,
+ * but I will assume that they are not until proven
+ * otherwise. RFC 1034 also states that 'the "*" label
+ * always matches at least one whole label and sometimes
+ * more, but always whole labels.' Native crypt32 does not
+ * match more than one label with a wildcard, so I do the
+ * same here. Thus, a wildcard only accepts the first
+ * label, then requires an exact match of the remaining
+ * string.
+ */
+ server_name_dot = strchrW(server_name, '.');
+ if (server_name_dot)
+ {
+ if (!strcmpiW(server_name_dot,
+ subjectName->rgAltEntry[i].u.pwszDNSName + 1))
+ matches = TRUE;
+ }
+ }
+ else if (!strcmpiW(server_name,
subjectName->rgAltEntry[i].u.pwszDNSName))
matches = TRUE;
}
diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c
index 0484aa1..a59a95a 100644
--- a/dlls/crypt32/tests/chain.c
+++ b/dlls/crypt32/tests/chain.c
@@ -3818,7 +3818,7 @@ static const ChainPolicyCheck opensslPolicyCheckWithoutMatchingName = {
static const ChainPolicyCheck winehqPolicyCheckWithMatchingName = {
{ sizeof(chain29) / sizeof(chain29[0]), chain29 },
- { 0, 0, -1, -1, NULL}, NULL, TODO_ERROR
+ { 0, 0, -1, -1, NULL}, NULL, 0
};
static const ChainPolicyCheck winehqPolicyCheckWithoutMatchingName = {