Module: wine Branch: master Commit: 667aeb3ede3ddad63b387fad248b66c03690c5a6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=667aeb3ede3ddad63b387fad24...
Author: Juan Lang juan.lang@gmail.com Date: Thu Dec 16 10:31:47 2010 -0800
crypt32: Accept any matching CN when checking a certificate's name.
---
dlls/crypt32/chain.c | 19 ++++++++++--- dlls/crypt32/tests/chain.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index 1fb368b..d7c10b3 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -3343,13 +3343,24 @@ static BOOL match_dns_to_subject_dn(PCCERT_CONTEXT cert, LPCWSTR server_name) } else { - PCERT_RDN_ATTR attr; + DWORD i, j;
/* If the certificate isn't using a DN attribute in the name, make - * make sure the common name matches. + * make sure at least one common name matches. From RFC 2818, + * section 3.1: + * "If more than one identity of a given type is present in the + * certificate (e.g., more than one dNSName name, a match in any + * one of the set is considered acceptable.)" */ - if ((attr = CertFindRDNAttr(szOID_COMMON_NAME, name))) - matches = match_common_name(server_name, attr); + for (i = 0; !matches && i < name->cRDN; i++) + for (j = 0; !matches && j < name->rgRDN[i].cRDNAttr; j++) + { + PCERT_RDN_ATTR attr = &name->rgRDN[i].rgRDNAttr[j]; + + if (attr->pszObjId && !strcmp(szOID_COMMON_NAME, + attr->pszObjId)) + matches = match_common_name(server_name, attr); + } } LocalFree(name); } diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c index 11f297c..71be975 100644 --- a/dlls/crypt32/tests/chain.c +++ b/dlls/crypt32/tests/chain.c @@ -2568,6 +2568,39 @@ static const BYTE chain30_2[] = { 0x5e,0xe2,0x2b,0xf5,0xa1,0xee,0x02,0x7e,0x09,0x15,0xff,0xc9,0xf6,0xaf,0xf5, 0xcc,0xeb,0xfc,0xe7,0x3c,0x92,0xdb,0x31,0xab,0x1e,0xb8,0x9e,0xf0,0x5e,0xa3, 0x93,0xfe,0xab,0x26,0x7b,0x01,0xa8,0x98,0x88,0xbb,0xee }; +/* chain0_0 -> chain31_1: a chain whose end certificate has two CNs, a + * wildcard name "*.foo.com" and a non-wildcard name "foo.com". + */ +static const BYTE chain31_1[] = { +0x30,0x82,0x01,0xa2,0x30,0x82,0x01,0x0d,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x30,0x24,0x31,0x22,0x30,0x0e,0x06,0x03,0x55,0x04,0x03, +0x13,0x07,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d,0x30,0x10,0x06,0x03,0x55,0x04, +0x03,0x13,0x09,0x2a,0x2e,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d,0x30,0x81,0x9d, +0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81, +0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f, +0xe5,0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4, +0xc6,0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5, +0xa7,0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6, +0x8b,0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf, +0x6b,0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40, +0xfc,0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac, +0x85,0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23, +0xb2,0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98, +0x72,0xa3,0x02,0x03,0x01,0x00,0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0xa0,0x93,0x52,0x87,0x81,0xe2, +0xff,0x2a,0xc7,0xef,0x5f,0x3c,0xbc,0x88,0x99,0xc0,0x47,0x3e,0x13,0xe9,0x87, +0xfa,0x36,0xd7,0xb5,0xe8,0xdf,0x70,0xcc,0x36,0xe4,0x70,0x3c,0xcd,0xa2,0x0b, +0x31,0x6e,0x0a,0xb9,0x00,0xf0,0x4f,0xb6,0xc2,0xce,0xf4,0x33,0x1e,0xc0,0x29, +0xc0,0x73,0x0c,0xcf,0x28,0xa5,0x26,0x9d,0xc2,0xaf,0x85,0x30,0x81,0xbf,0xd1, +0x70,0x3f,0x69,0x15,0xc5,0x41,0x1d,0x8e,0xd4,0xfa,0x02,0xcd,0xba,0xf1,0xf2, +0x67,0xb5,0x45,0x29,0xad,0xe8,0x54,0x9a,0x0f,0x1a,0x8f,0xdf,0x16,0xf4,0xcb, +0x43,0x08,0xe5,0x78,0x2b,0x95,0xf3,0x75,0xb6,0x88,0xf0,0x6b,0x5c,0x5b,0x50, +0x04,0x91,0x3b,0x89,0x5a,0x60,0x1f,0xfc,0x36,0x53,0x32,0x36,0x0a,0x4d,0x03, +0x2c,0xd7 };
typedef struct _CONST_DATA_BLOB { @@ -3195,6 +3228,10 @@ static const CERT_TRUST_STATUS elementStatus30[] = { static const SimpleChainStatusCheck simpleStatus30[] = { { sizeof(elementStatus30) / sizeof(elementStatus30[0]), elementStatus30 }, }; +static CONST_DATA_BLOB chain31[] = { + { sizeof(chain0_0), chain0_0 }, + { sizeof(chain31_1), chain31_1 }, +}; static CONST_DATA_BLOB selfSignedChain[] = { { sizeof(selfSignedCert), selfSignedCert } }; @@ -4027,6 +4064,16 @@ static const ChainPolicyCheck invalidExtensionPolicyCheck = { { 0, CERT_E_CRITICAL, 0, 1, NULL}, &badDateNestingStatus, 0 };
+static const ChainPolicyCheck fooPolicyCheckWithMatchingName = { + { sizeof(chain31) / sizeof(chain31[0]), chain31 }, + { 0, 0, -1, -1, NULL}, NULL, 0 +}; + +static const ChainPolicyCheck fooPolicyCheckWithoutMatchingName = { + { sizeof(chain31) / sizeof(chain31[0]), chain31 }, + { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0 +}; + static const ChainPolicyCheck authenticodePolicyCheck[] = { { { sizeof(chain0) / sizeof(chain0[0]), chain0 }, { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, @@ -4324,6 +4371,9 @@ static void check_ssl_policy(void) 'w','i','n','e','h','q','.','o','r','g',0 }; WCHAR a_dot_b_dot_winehq_dot_org[] = { 'a','.','b','.', 'w','i','n','e','h','q','.','o','r','g',0 }; + WCHAR foo_dot_com[] = { 'f','o','o','.','c','o','m',0 }; + WCHAR afoo_dot_com[] = { 'a','f','o','o','.','c','o','m',0 }; + WCHAR a_dot_foo_dot_com[] = { 'a','.','f','o','o','.','c','o','m',0 }; HCERTSTORE testRoot; CERT_CHAIN_ENGINE_CONFIG engineConfig = { sizeof(engineConfig), 0 }; HCERTCHAINENGINE engine; @@ -4473,6 +4523,19 @@ static void check_ssl_policy(void) sslPolicyPara.pwszServerName = NULL; CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, invalidExtensionPolicyCheck, &oct2007, &policyPara); + /* Test chain31, which has two CNs, "*.foo.com" and "foo.com", against + * some names that match one of the CNs: + */ + sslPolicyPara.pwszServerName = foo_dot_com; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + fooPolicyCheckWithMatchingName, &oct2007, &policyPara); + sslPolicyPara.pwszServerName = a_dot_foo_dot_com; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + fooPolicyCheckWithMatchingName, &oct2007, &policyPara); + /* and against a name that doesn't match either CN: */ + sslPolicyPara.pwszServerName = afoo_dot_com; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + fooPolicyCheckWithoutMatchingName, &oct2007, &policyPara); }
static void testVerifyCertChainPolicy(void)