Juan Lang : cryptui: Show the certificate extensions in the details page.

Alexandre Julliard julliard at winehq.org
Thu Dec 18 08:08:42 CST 2008


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Wed Dec 17 08:55:09 2008 -0800

cryptui: Show the certificate extensions in the details page.

---

 dlls/cryptui/main.c |  152 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 149 insertions(+), 3 deletions(-)

diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c
index fbc2b99..993e953 100644
--- a/dlls/cryptui/main.c
+++ b/dlls/cryptui/main.c
@@ -1261,10 +1261,156 @@ static void add_v1_fields(HWND hwnd, struct detail_data *data)
         add_v1_field(hwnd, data, &v1_fields[i]);
 }
 
+static WCHAR *crypt_format_extension(PCERT_EXTENSION ext, DWORD formatStrType)
+{
+    WCHAR *str = NULL;
+    DWORD size;
+
+    if (CryptFormatObject(X509_ASN_ENCODING, 0, formatStrType, NULL,
+     ext->pszObjId, ext->Value.pbData, ext->Value.cbData, NULL, &size))
+    {
+        str = HeapAlloc(GetProcessHeap(), 0, size);
+        CryptFormatObject(X509_ASN_ENCODING, 0, formatStrType, NULL,
+         ext->pszObjId, ext->Value.pbData, ext->Value.cbData, str, &size);
+    }
+    return str;
+}
+
+static WCHAR *field_format_extension_hex_with_ascii(PCERT_EXTENSION ext)
+{
+    WCHAR *str = NULL;
+
+    if (ext->Value.cbData)
+    {
+        /* The output is formatted as:
+         * <hex bytes>  <ascii bytes>\n
+         * where <hex bytes> is a string of up to 8 bytes, output as %02x,
+         * and <ascii bytes> is the ASCII equivalent of each byte, or '.' if
+         * the byte is not printable.
+         * So, for example, the extension value consisting of the following
+         * bytes:
+         *   0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,
+         *   0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67
+         * is output as:
+         *   30 14 31 12 30 10 06 03  0.1.0...
+         *   55 04 03 13 09 4a 75 61  U....Jua
+         *   6e 20 4c 61 6e 67        n Lang
+         * The allocation size therefore requires:
+         * - 4 characters per character in an 8-byte line
+         *   (2 for the hex format, one for the space, one for the ASCII value)
+         * - 3 more characters per 8-byte line (two spaces and a newline)
+         * - 1 character for the terminating nul
+         * FIXME: should use a fixed-width font for this
+         */
+        DWORD lines = (ext->Value.cbData + 7) / 8;
+
+        str = HeapAlloc(GetProcessHeap(), 0,
+         (lines * 8 * 4 + lines * 3 + 1) * sizeof(WCHAR));
+        if (str)
+        {
+            static const WCHAR fmt[] = { '%','0','2','x',' ',0 };
+            DWORD i, j;
+            WCHAR *ptr;
+
+            for (i = 0, ptr = str; i < ext->Value.cbData; i += 8)
+            {
+                /* Output as hex bytes first */
+                for (j = i; j < min(i + 8, ext->Value.cbData); j++, ptr += 3)
+                    sprintfW(ptr, fmt, ext->Value.pbData[j]);
+                /* Pad the hex output with spaces for alignment */
+                if (j == ext->Value.cbData && j % 8)
+                {
+                    static const WCHAR pad[] = { ' ',' ',' ' };
+
+                    for (; j % 8; j++, ptr += sizeof(pad) / sizeof(pad[0]))
+                        memcpy(ptr, pad, sizeof(pad));
+                }
+                /* The last sprintfW included a space, so just insert one
+                 * more space between the hex bytes and the ASCII output
+                 */
+                *ptr++ = ' ';
+                /* Output as ASCII bytes */
+                for (j = i; j < min(i + 8, ext->Value.cbData); j++, ptr++)
+                {
+                    if (isprintW(ext->Value.pbData[j]) &&
+                     !isspaceW(ext->Value.pbData[j]))
+                        *ptr = ext->Value.pbData[j];
+                    else
+                        *ptr = '.';
+                }
+                *ptr++ = '\n';
+            }
+            *ptr++ = '\0';
+        }
+    }
+    return str;
+}
+
+static WCHAR *field_format_detailed_extension(PCCERT_CONTEXT cert, void *param)
+{
+    PCERT_EXTENSION ext = param;
+    LPWSTR str = crypt_format_extension(ext,
+     CRYPT_FORMAT_STR_MULTI_LINE | CRYPT_FORMAT_STR_NO_HEX);
+
+    if (!str)
+        str = field_format_extension_hex_with_ascii(ext);
+    return str;
+}
+
+static void add_cert_extension_detail(HWND hwnd, struct detail_data *data,
+ PCERT_EXTENSION ext)
+{
+    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+     ext->pszObjId, 0);
+    LPWSTR val = crypt_format_extension(ext, 0);
+
+    if (oidInfo)
+        add_field_and_value_to_list(hwnd, data, (LPWSTR)oidInfo->pwszName,
+         val, field_format_detailed_extension, ext);
+    else
+    {
+        DWORD len = strlen(ext->pszObjId);
+        LPWSTR oidW = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
+
+        if (oidW)
+        {
+            DWORD i;
+
+            for (i = 0; i <= len; i++)
+                oidW[i] = ext->pszObjId[i];
+            add_field_and_value_to_list(hwnd, data, oidW, val,
+             field_format_detailed_extension, ext);
+            HeapFree(GetProcessHeap(), 0, oidW);
+        }
+    }
+    HeapFree(GetProcessHeap(), 0, val);
+}
+
+static void add_all_extensions(HWND hwnd, struct detail_data *data)
+{
+    DWORD i;
+    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;
+
+    for (i = 0; i < cert->pCertInfo->cExtension; i++)
+        add_cert_extension_detail(hwnd, data, &cert->pCertInfo->rgExtension[i]);
+}
+
+static void add_critical_extensions(HWND hwnd, struct detail_data *data)
+{
+    DWORD i;
+    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;
+
+    for (i = 0; i < cert->pCertInfo->cExtension; i++)
+        if (cert->pCertInfo->rgExtension[i].fCritical)
+            add_cert_extension_detail(hwnd, data,
+             &cert->pCertInfo->rgExtension[i]);
+}
+
 static void add_all_fields(HWND hwnd, struct detail_data *data)
 {
     add_v1_fields(hwnd, data);
-    FIXME("add extensions and properties\n");
+    add_all_extensions(hwnd, data);
+    FIXME("add properties\n");
 }
 
 struct selection_list_item
@@ -1276,8 +1422,8 @@ struct selection_list_item
 const struct selection_list_item listItems[] = {
  { IDS_FIELDS_ALL, add_all_fields },
  { IDS_FIELDS_V1, add_v1_fields },
- { IDS_FIELDS_EXTENSIONS, NULL },
- { IDS_FIELDS_CRITICAL_EXTENSIONS, NULL },
+ { IDS_FIELDS_EXTENSIONS, add_all_extensions },
+ { IDS_FIELDS_CRITICAL_EXTENSIONS, add_critical_extensions },
  { IDS_FIELDS_PROPERTIES, NULL },
 };
 




More information about the wine-cvs mailing list