Juan Lang : crypt32: Output x.500 strings from CertNameToStrA/W.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jul 18 05:13:31 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 8d8520975fa0b1a6b9ec5198ae6b3524f77ef1c8
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=8d8520975fa0b1a6b9ec5198ae6b3524f77ef1c8

Author: Juan Lang <juan_lang at yahoo.com>
Date:   Mon Jul 17 11:50:20 2006 -0700

crypt32: Output x.500 strings from CertNameToStrA/W.

---

 dlls/crypt32/str.c       |  153 +++++++++++++++++++++++++++++++++++++---------
 dlls/crypt32/tests/str.c |    3 +
 2 files changed, 126 insertions(+), 30 deletions(-)

diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c
index a80301e..ef67a9a 100644
--- a/dlls/crypt32/str.c
+++ b/dlls/crypt32/str.c
@@ -109,6 +109,30 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dw
     return ret;
 }
 
+/* Adds the prefix prefix to the string pointed to by psz, followed by the
+ * character '='.  Copies no more than csz characters.  Returns the number of
+ * characters copied.  If psz is NULL, returns the number of characters that
+ * would be copied.
+ */
+static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz)
+{
+    DWORD chars = min(lstrlenA(prefix), csz);
+
+    TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz);
+
+    if (psz && chars)
+        memcpy(psz, prefix, chars);
+    csz -= chars;
+    if (csz > 1)
+    {
+        if (psz)
+            *(psz + chars) = '=';
+        chars++;
+        csz--;
+    }
+    return chars;
+}
+
 DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
  DWORD dwStrType, LPSTR psz, DWORD csz)
 {
@@ -152,25 +176,33 @@ DWORD WINAPI CertNameToStrA(DWORD dwCert
             for (j = 0; ret < csz && j < info->rgRDN[i].cRDNAttr; j++)
             {
                 DWORD chars;
+                char prefixBuf[10]; /* big enough for GivenName */
+                LPCSTR prefix = NULL;
 
                 if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
+                    prefix = info->rgRDN[i].rgRDNAttr[j].pszObjId;
+                else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR)
+                {
+                    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(
+                     CRYPT_OID_INFO_OID_KEY,
+                     info->rgRDN[i].rgRDNAttr[j].pszObjId,
+                     CRYPT_RDN_ATTR_OID_GROUP_ID);
+
+                    if (oidInfo)
+                    {
+                        WideCharToMultiByte(CP_ACP, 0, oidInfo->pwszName, -1,
+                         prefixBuf, sizeof(prefixBuf), NULL, NULL);
+                        prefix = prefixBuf;
+                    }
+                    else
+                        prefix = info->rgRDN[i].rgRDNAttr[j].pszObjId;
+                }
+                if (prefix)
                 {
                     /* - 1 is needed to account for the NULL terminator. */
-                    chars = min(
-                     lstrlenA(info->rgRDN[i].rgRDNAttr[j].pszObjId),
-                     csz - ret - 1);
-                    if (psz && chars)
-                        memcpy(psz + ret, info->rgRDN[i].rgRDNAttr[j].pszObjId,
-                         chars);
+                    chars = CRYPT_AddPrefixA(prefix, psz + ret, csz - ret - 1);
                     ret += chars;
                     csz -= chars;
-                    if (csz > 1)
-                    {
-                        if (psz)
-                            *(psz + ret) = '=';
-                        ret++;
-                        csz--;
-                    }
                 }
                 /* FIXME: handle quoting */
                 chars = CertRDNValueToStrA(
@@ -206,6 +238,60 @@ DWORD WINAPI CertNameToStrA(DWORD dwCert
     return ret;
 }
 
+/* Adds the prefix prefix to the wide-character string pointed to by psz,
+ * followed by the character '='.  Copies no more than csz characters.  Returns
+ * the number of characters copied.  If psz is NULL, returns the number of
+ * characters that would be copied.
+ * Assumes the characters in prefix are ASCII (not multibyte characters.)
+ */
+static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz)
+{
+    DWORD chars = min(lstrlenA(prefix), csz);
+
+    TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz);
+
+    if (psz && chars)
+    {
+        DWORD i;
+
+        for (i = 0; i < chars; i++)
+            *(psz + i) = prefix[i];
+    }
+    csz -= chars;
+    if (csz > 1)
+    {
+        if (psz)
+            *(psz + chars) = '=';
+        chars++;
+        csz--;
+    }
+    return chars;
+}
+
+/* Adds the prefix prefix to the string pointed to by psz, followed by the
+ * character '='.  Copies no more than csz characters.  Returns the number of
+ * characters copied.  If psz is NULL, returns the number of characters that
+ * would be copied.
+ */
+static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz)
+{
+    DWORD chars = min(lstrlenW(prefix), csz);
+
+    TRACE("(%s, %p, %ld)\n", debugstr_w(prefix), psz, csz);
+
+    if (psz && chars)
+        memcpy(psz, prefix, chars * sizeof(WCHAR));
+    csz -= chars;
+    if (csz > 1)
+    {
+        if (psz)
+            *(psz + chars) = '=';
+        chars++;
+        csz--;
+    }
+    return chars;
+}
+
 DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
  DWORD dwStrType, LPWSTR psz, DWORD csz)
 {
@@ -249,30 +335,37 @@ DWORD WINAPI CertNameToStrW(DWORD dwCert
             for (j = 0; ret < csz && j < info->rgRDN[i].cRDNAttr; j++)
             {
                 DWORD chars;
+                LPCSTR prefixA = NULL;
+                LPCWSTR prefixW = NULL;
 
                 if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
+                    prefixA = info->rgRDN[i].rgRDNAttr[j].pszObjId;
+                else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR)
+                {
+                    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(
+                     CRYPT_OID_INFO_OID_KEY,
+                     info->rgRDN[i].rgRDNAttr[j].pszObjId,
+                     CRYPT_RDN_ATTR_OID_GROUP_ID);
+
+                    if (oidInfo)
+                        prefixW = oidInfo->pwszName;
+                    else
+                        prefixA = info->rgRDN[i].rgRDNAttr[j].pszObjId;
+                }
+                if (prefixW)
+                {
+                    /* - 1 is needed to account for the NULL terminator. */
+                    chars = CRYPT_AddPrefixW(prefixW, psz + ret, csz - ret - 1);
+                    ret += chars;
+                    csz -= chars;
+                }
+                else if (prefixA)
                 {
                     /* - 1 is needed to account for the NULL terminator. */
-                    chars = min(
-                     lstrlenA(info->rgRDN[i].rgRDNAttr[j].pszObjId),
+                    chars = CRYPT_AddPrefixAToW(prefixA, psz + ret,
                      csz - ret - 1);
-                    if (psz && chars)
-                    {
-                        DWORD k;
-
-                        for (k = 0; k < chars; k++)
-                            *(psz + ret + k) =
-                             info->rgRDN[i].rgRDNAttr[j].pszObjId[k];
-                    }
                     ret += chars;
                     csz -= chars;
-                    if (csz > 1)
-                    {
-                        if (psz)
-                            *(psz + ret) = '=';
-                        ret++;
-                        csz--;
-                    }
                 }
                 /* FIXME: handle quoting */
                 chars = CertRDNValueToStrW(
diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c
index c7c2e97..abece9c 100644
--- a/dlls/crypt32/tests/str.c
+++ b/dlls/crypt32/tests/str.c
@@ -118,6 +118,7 @@ static char subjectStrSemicolon[] =
  "2.5.4.6=US; 2.5.4.8=Minnesota; 2.5.4.7=Minneapolis; 2.5.4.10=CodeWeavers; 2.5.4.11=Wine Development; 2.5.4.3=localhost; 1.2.840.113549.1.9.1=aric at codeweavers.com";
 static char subjectStrCRLF[] =
  "2.5.4.6=US\r\n2.5.4.8=Minnesota\r\n2.5.4.7=Minneapolis\r\n2.5.4.10=CodeWeavers\r\n2.5.4.11=Wine Development\r\n2.5.4.3=localhost\r\n1.2.840.113549.1.9.1=aric at codeweavers.com";
+static char x500SubjectStr[] = "C=US, S=Minnesota, L=Minneapolis, O=CodeWeavers, OU=Wine Development, CN=localhost, E=aric at codeweavers.com";
 static WCHAR issuerStrW[] = {
  'U','S',',',' ','M','i','n','n','e','s','o','t','a',',',' ','M','i','n','n',
  'e','a','p','o','l','i','s',',',' ','C','o','d','e','W','e','a','v','e','r',
@@ -349,6 +350,8 @@ static void test_CertNameToStrA(void)
         test_NameToStrConversionA(&context->pCertInfo->Subject,
          CERT_OID_NAME_STR | CERT_NAME_STR_CRLF_FLAG,
          subjectStrCRLF);
+        test_NameToStrConversionA(&context->pCertInfo->Subject,
+         CERT_X500_NAME_STR, x500SubjectStr);
 
         CertFreeCertificateContext(context);
     }




More information about the wine-cvs mailing list