crypt32: Test/correct CertGetNameString with NULL pvTypePara

Juan Lang juan.lang at gmail.com
Thu Sep 8 13:14:08 CDT 2011


Oops, meant to send to wine-patches.  Fix for bug 23287.
--Juan
-------------- next part --------------
From 1114085290c2ada360a02bae154b7167a0f2b0ca Mon Sep 17 00:00:00 2001
From: Juan Lang <juan.lang at gmail.com>
Date: Thu, 8 Sep 2011 11:10:08 -0700
Subject: [PATCH 2/2] Test/correct CertGetNameString with NULL pvTypePara

---
 dlls/crypt32/str.c       |   18 ++++-
 dlls/crypt32/tests/str.c |  162 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 176 insertions(+), 4 deletions(-)

diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c
index 7444575..6d406d2 100644
--- a/dlls/crypt32/str.c
+++ b/dlls/crypt32/str.c
@@ -1209,8 +1209,11 @@ static DWORD cert_get_name_from_rdn_attr(DWORD encodingType,
     if (CryptDecodeObjectEx(encodingType, X509_NAME, name->pbData,
      name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo, &bytes))
     {
-        PCERT_RDN_ATTR nameAttr = CertFindRDNAttr(oid, nameInfo);
+        PCERT_RDN_ATTR nameAttr;
 
+        if (!oid)
+            oid = szOID_RSA_emailAddr;
+        nameAttr = CertFindRDNAttr(oid, nameInfo);
         if (nameAttr)
             ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value,
              pszNameString, cchNameString);
@@ -1229,6 +1232,9 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
     TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType,
      dwFlags, pvTypePara, pszNameString, cchNameString);
 
+    if (!pCertContext)
+        goto done;
+
     if (dwFlags & CERT_NAME_ISSUER_FLAG)
     {
         name = &pCertContext->pCertInfo->Issuer;
@@ -1268,9 +1274,12 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
         break;
     }
     case CERT_NAME_RDN_TYPE:
+    {
+        DWORD type = pvTypePara ? *(DWORD *)pvTypePara : 0;
+
         if (name->cbData)
             ret = CertNameToStrW(pCertContext->dwCertEncodingType, name,
-             *(DWORD *)pvTypePara, pszNameString, cchNameString);
+             type, pszNameString, cchNameString);
         else
         {
             CERT_ALT_NAME_INFO *info;
@@ -1279,12 +1288,12 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
 
             if (entry)
                 ret = CertNameToStrW(pCertContext->dwCertEncodingType,
-                 &entry->u.DirectoryName, *(DWORD *)pvTypePara, pszNameString,
-                 cchNameString);
+                 &entry->u.DirectoryName, type, pszNameString, cchNameString);
             if (info)
                 LocalFree(info);
         }
         break;
+    }
     case CERT_NAME_ATTR_TYPE:
         ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType,
          name, pvTypePara, pszNameString, cchNameString);
@@ -1413,6 +1422,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
         FIXME("unimplemented for type %d\n", dwType);
         ret = 0;
     }
+done:
     if (!ret)
     {
         if (!pszNameString)
diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c
index cbfdf4d..1443597 100644
--- a/dlls/crypt32/tests/str.c
+++ b/dlls/crypt32/tests/str.c
@@ -199,6 +199,8 @@ typedef BOOL (WINAPI *CertStrToNameAFunc)(DWORD dwCertEncodingType,
 typedef BOOL (WINAPI *CertStrToNameWFunc)(DWORD dwCertEncodingType,
  LPCWSTR pszX500, DWORD dwStrType, void *pvReserved, BYTE *pbEncoded,
  DWORD *pcbEncoded, LPCWSTR *ppszError);
+typedef DWORD (WINAPI *CertGetNameStringAFunc)(PCCERT_CONTEXT cert, DWORD type,
+ DWORD flags, void *typePara, LPSTR str, DWORD cch);
 
 static HMODULE dll;
 static CertNameToStrAFunc pCertNameToStrA;
@@ -208,6 +210,7 @@ static CertRDNValueToStrAFunc pCertRDNValueToStrA;
 static CertRDNValueToStrWFunc pCertRDNValueToStrW;
 static CertStrToNameAFunc pCertStrToNameA;
 static CertStrToNameWFunc pCertStrToNameW;
+static CertGetNameStringAFunc pCertGetNameStringA;
 
 static void test_CertRDNValueToStrA(void)
 {
@@ -933,6 +936,162 @@ static void test_CertStrToNameW(void)
     }
 }
 
+static void test_CertGetNameStringA(void)
+{
+    PCCERT_CONTEXT context;
+
+    if (!pCertGetNameStringA)
+    {
+        win_skip("CertGetNameStringA is not available\n");
+        return;
+    }
+
+    context = CertCreateCertificateContext(X509_ASN_ENCODING, cert,
+     sizeof(cert));
+    ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
+     GetLastError());
+    if (context)
+    {
+        static const char aric[] = "aric at codeweavers.com";
+        static const char localhost[] = "localhost";
+        DWORD len, type;
+        LPSTR str;
+
+        /* Bad string types/types missing from the cert */
+        len = pCertGetNameStringA(NULL, 0, 0, NULL, NULL, 0);
+        ok(len == 1, "expected 1, got %d\n", len);
+        len = pCertGetNameStringA(context, 0, 0, NULL, NULL, 0);
+        ok(len == 1, "expected 1, got %d\n", len);
+        len = pCertGetNameStringA(context, CERT_NAME_URL_TYPE, 0, NULL, NULL,
+         0);
+        ok(len == 1, "expected 1, got %d\n", len);
+
+        len = pCertGetNameStringA(context, CERT_NAME_EMAIL_TYPE, 0, NULL, NULL,
+         0);
+        ok(len == strlen(aric) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_EMAIL_TYPE, 0, NULL,
+             str, len);
+            ok(!strcmp(str, aric), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+
+        len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, NULL, NULL,
+         0);
+        ok(len == strlen(issuerStr) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, NULL,
+             str, len);
+            ok(!strcmp(str, issuerStr), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+        type = 0;
+        len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, &type, NULL,
+         0);
+        ok(len == strlen(issuerStr) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, &type,
+             str, len);
+            ok(!strcmp(str, issuerStr), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+        type = CERT_OID_NAME_STR;
+        len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, &type, NULL,
+         0);
+        ok(len == strlen(subjectStr) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, &type,
+             str, len);
+            ok(!strcmp(str, subjectStr), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+
+        len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0, NULL, NULL,
+         0);
+        ok(len == strlen(aric) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0, NULL,
+             str, len);
+            ok(!strcmp(str, aric), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+        len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0,
+         (void *)szOID_RSA_emailAddr, NULL, 0);
+        ok(len == strlen(aric) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0,
+             (void *)szOID_RSA_emailAddr, str, len);
+            ok(!strcmp(str, aric), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+        len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0,
+         (void *)szOID_COMMON_NAME, NULL, 0);
+        ok(len == strlen(localhost) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0,
+             (void *)szOID_COMMON_NAME, str, len);
+            ok(!strcmp(str, localhost), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+
+        len = pCertGetNameStringA(context, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
+         NULL, NULL, 0);
+        ok(len == strlen(localhost) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_SIMPLE_DISPLAY_TYPE,
+             0, NULL, str, len);
+            ok(!strcmp(str, localhost), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+
+        len = pCertGetNameStringA(context, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0,
+         NULL, NULL, 0);
+        ok(len == strlen(localhost) + 1, "unexpected length %d\n", len);
+        str = HeapAlloc(GetProcessHeap(), 0, len);
+        if (str)
+        {
+            len = pCertGetNameStringA(context, CERT_NAME_FRIENDLY_DISPLAY_TYPE,
+             0, NULL, str, len);
+            ok(!strcmp(str, localhost), "unexpected value %s\n", str);
+            HeapFree(GetProcessHeap(), 0, str);
+        }
+
+        len = pCertGetNameStringA(context, CERT_NAME_DNS_TYPE, 0, NULL, NULL,
+         0);
+        ok(len == strlen(localhost) + 1 || broken(len == 1) /* NT4 */,
+         "unexpected length %d\n", len);
+        if (len > 1)
+        {
+            str = HeapAlloc(GetProcessHeap(), 0, len);
+            if (str)
+            {
+                len = pCertGetNameStringA(context, CERT_NAME_DNS_TYPE, 0, NULL,
+                 str, len);
+                ok(!strcmp(str, localhost), "unexpected value %s\n", str);
+                HeapFree(GetProcessHeap(), 0, str);
+            }
+        }
+
+        CertFreeCertificateContext(context);
+    }
+}
+
 START_TEST(str)
 {
     dll = GetModuleHandleA("Crypt32.dll");
@@ -947,6 +1106,8 @@ START_TEST(str)
      "CryptDecodeObject");
     pCertStrToNameA = (CertStrToNameAFunc)GetProcAddress(dll,"CertStrToNameA");
     pCertStrToNameW = (CertStrToNameWFunc)GetProcAddress(dll,"CertStrToNameW");
+    pCertGetNameStringA = (CertGetNameStringAFunc)GetProcAddress(dll,
+     "CertGetNameStringA");
 
     test_CertRDNValueToStrA();
     test_CertRDNValueToStrW();
@@ -954,4 +1115,5 @@ START_TEST(str)
     test_CertNameToStrW();
     test_CertStrToNameA();
     test_CertStrToNameW();
+    test_CertGetNameStringA();
 }
-- 
1.7.3.1


More information about the wine-patches mailing list