Module: wine Branch: master Commit: c79aad51cd21e1da941dcc003379957065253715 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c79aad51cd21e1da941dcc0033...
Author: Juan Lang juan.lang@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 = {