From 440c702ce413861f8a030e728ee6bceee255b513 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Mon, 16 Nov 2009 17:08:03 -0800 Subject: [PATCH] crypt32: Implement CertIsRDNAttrsInCertificateName. --- dlls/crypt32/cert.c | 78 +++++++++++++++++++++++++++++++++++++-- dlls/crypt32/tests/cert.c | 15 -------- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 656c547c42d..f91adc1e02b 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -1832,12 +1832,84 @@ PCERT_RDN_ATTR WINAPI CertFindRDNAttr(LPCSTR pszObjId, PCERT_NAME_INFO pName) return ret; } +static BOOL find_matching_rdn_attr(DWORD dwFlags, const CERT_NAME_INFO *name, + const CERT_RDN_ATTR *attr) +{ + DWORD i, j; + BOOL match = FALSE; + + for (i = 0; !match && i < name->cRDN; i++) + { + for (j = 0; j < name->rgRDN[i].cRDNAttr; j++) + { + if (!strcmp(name->rgRDN[i].rgRDNAttr[j].pszObjId, + attr->pszObjId) && + name->rgRDN[i].rgRDNAttr[j].dwValueType == + attr->dwValueType) + { + if (dwFlags & CERT_UNICODE_IS_RDN_ATTRS_FLAG) + { + LPCWSTR nameStr = + (LPCWSTR)name->rgRDN[i].rgRDNAttr[j].Value.pbData; + LPCWSTR attrStr = (LPCWSTR)attr->Value.pbData; + + if (dwFlags & CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG) + match = !strncmpiW(nameStr, attrStr, + attr->Value.cbData / sizeof(WCHAR)); + else + match = !strncmpW(nameStr, attrStr, + attr->Value.cbData / sizeof(WCHAR)); + TRACE("%s : %s => %d\n", + debugstr_wn(nameStr, attr->Value.cbData / sizeof(WCHAR)), + debugstr_wn(attrStr, attr->Value.cbData / sizeof(WCHAR)), + match); + } + else + { + LPCSTR nameStr = + (LPCSTR)name->rgRDN[i].rgRDNAttr[j].Value.pbData; + LPCSTR attrStr = (LPCSTR)attr->Value.pbData; + + if (dwFlags & CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG) + match = !strncasecmp(nameStr, attrStr, + attr->Value.cbData); + else + match = !strncmp(nameStr, attrStr, attr->Value.cbData); + TRACE("%s : %s => %d\n", + debugstr_an(nameStr, attr->Value.cbData), + debugstr_an(attrStr, attr->Value.cbData), match); + } + } + } + } + return match; +} + BOOL WINAPI CertIsRDNAttrsInCertificateName(DWORD dwCertEncodingType, DWORD dwFlags, PCERT_NAME_BLOB pCertName, PCERT_RDN pRDN) { - FIXME("(%08x, %08x, %p, %p): stub\n", dwCertEncodingType, dwFlags, - pCertName, pRDN); - return FALSE; + CERT_NAME_INFO *name; + LPCSTR type; + DWORD size; + BOOL ret; + + TRACE("(%08x, %08x, %p, %p)\n", dwCertEncodingType, dwFlags, pCertName, + pRDN); + + type = dwFlags & CERT_UNICODE_IS_RDN_ATTRS_FLAG ? X509_UNICODE_NAME : + X509_NAME; + if ((ret = CryptDecodeObjectEx(dwCertEncodingType, type, pCertName->pbData, + pCertName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &name, &size))) + { + DWORD i; + + for (i = 0; ret && i < pRDN->cRDNAttr; i++) + ret = find_matching_rdn_attr(dwFlags, name, &pRDN->rgRDNAttr[i]); + if (!ret) + SetLastError(CRYPT_E_NO_MATCH); + LocalFree(name); + } + return ret; } LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify, diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index 186691f2222..4a1c449a777 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -2662,18 +2662,15 @@ static void testIsRDNAttrsInCertificateName(void) } SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(0, 0, &name, NULL); - todo_wine ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError()); attr[0].pszObjId = oid_1_2_3; rdn.rgRDNAttr = attr; rdn.cRDNAttr = 1; SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); attr[0].pszObjId = oid_common_name; @@ -2681,28 +2678,24 @@ static void testIsRDNAttrsInCertificateName(void) attr[0].Value.cbData = strlen(juan); attr[0].Value.pbData = (BYTE *)juan; ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError()); /* Again, spaces are not removed for name comparison. */ attr[0].Value.cbData = strlen(juan_with_leading_space); attr[0].Value.pbData = (BYTE *)juan_with_leading_space; SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); attr[0].Value.cbData = strlen(juan_with_intermediate_space); attr[0].Value.pbData = (BYTE *)juan_with_intermediate_space; SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); attr[0].Value.cbData = strlen(juan_with_trailing_space); attr[0].Value.pbData = (BYTE *)juan_with_trailing_space; SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); /* The lower case name isn't matched unless a case insensitive match is @@ -2712,12 +2705,10 @@ static void testIsRDNAttrsInCertificateName(void) attr[0].Value.pbData = (BYTE *)juan_lower_case; SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG, &name, &rdn); - todo_wine ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError()); /* The values don't match unless they have the same RDN type */ attr[0].dwValueType = CERT_RDN_UNICODE_STRING; @@ -2725,13 +2716,11 @@ static void testIsRDNAttrsInCertificateName(void) attr[0].Value.pbData = (BYTE *)juanW; SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, CERT_UNICODE_IS_RDN_ATTRS_FLAG, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); attr[0].dwValueType = CERT_RDN_IA5_STRING; @@ -2739,7 +2728,6 @@ static void testIsRDNAttrsInCertificateName(void) attr[0].Value.pbData = (BYTE *)juan; SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); /* All attributes must be present */ @@ -2753,20 +2741,17 @@ static void testIsRDNAttrsInCertificateName(void) rdn.cRDNAttr = 2; SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); /* Order also matters */ name.pbData = cnThenO; name.cbData = sizeof(cnThenO); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError()); name.pbData = oThenCN; name.cbData = sizeof(oThenCN); SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, &rdn); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NO_MATCH, "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError()); }