Juan Lang : crypt32: Implement CertIsRDNAttrsInCertificateName.

Alexandre Julliard julliard at winehq.org
Tue Nov 17 09:28:18 CST 2009


Module: wine
Branch: master
Commit: 440c702ce413861f8a030e728ee6bceee255b513
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=440c702ce413861f8a030e728ee6bceee255b513

Author: Juan Lang <juan.lang at gmail.com>
Date:   Mon Nov 16 17:08:03 2009 -0800

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 656c547..f91adc1 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 186691f..4a1c449 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());
 }




More information about the wine-cvs mailing list