Hans Leidekker : wintrust: Implement CryptCATOpen and CryptCATClose.

Alexandre Julliard julliard at winehq.org
Mon Dec 22 10:19:53 CST 2008


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Mon Dec 22 14:19:50 2008 +0100

wintrust: Implement CryptCATOpen and CryptCATClose.

Based on work done by Maarten Lankhorst.

---

 dlls/wintrust/crypt.c |  172 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 169 insertions(+), 3 deletions(-)

diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c
index d68267c..4055c55 100644
--- a/dlls/wintrust/crypt.c
+++ b/dlls/wintrust/crypt.c
@@ -37,8 +37,21 @@
 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
 
 #define CATADMIN_MAGIC 0x43415441 /* 'CATA' */
+#define CRYPTCAT_MAGIC 0x43415443 /* 'CATC' */
 #define CATINFO_MAGIC  0x43415449 /* 'CATI' */
 
+struct cryptcat
+{
+    DWORD     magic;
+    HANDLE    msg;
+    DWORD     encoding;
+    CTL_INFO *inner;
+    DWORD     inner_len;
+    GUID      subject;
+    DWORD     attr_count;
+    CRYPTCATATTRIBUTE *attr;
+};
+
 struct catadmin
 {
     DWORD magic;
@@ -465,7 +478,21 @@ BOOL WINAPI CryptCATAdminRemoveCatalog(HCATADMIN hCatAdmin, LPCWSTR pwszCatalogF
  */
 BOOL WINAPI CryptCATClose(HANDLE hCatalog)
 {
-    FIXME("(%p) stub\n", hCatalog);
+    struct cryptcat *cc = hCatalog;
+
+    TRACE("(%p)\n", hCatalog);
+
+    if (!hCatalog || hCatalog == INVALID_HANDLE_VALUE || cc->magic != CRYPTCAT_MAGIC)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    HeapFree(GetProcessHeap(), 0, cc->attr);
+    HeapFree(GetProcessHeap(), 0, cc->inner);
+    CryptMsgClose(cc->msg);
+
+    cc->magic = 0;
+    HeapFree(GetProcessHeap(), 0, cc);
     return TRUE;
 }
 
@@ -478,15 +505,154 @@ CRYPTCATMEMBER *WINAPI CryptCATEnumerateMember(HANDLE hCatalog, CRYPTCATMEMBER*
     return NULL;
 }
 
+static CTL_INFO *decode_inner_content(HANDLE hmsg, DWORD encoding, DWORD *len)
+{
+    DWORD size;
+    LPSTR oid = NULL;
+    BYTE *buffer = NULL;
+    CTL_INFO *inner = NULL;
+
+    if (!CryptMsgGetParam(hmsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL, &size)) return NULL;
+    if (!(oid = HeapAlloc(GetProcessHeap(), 0, size)))
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        return NULL;
+    }
+    if (!CryptMsgGetParam(hmsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, oid, &size)) goto out;
+    if (!CryptMsgGetParam(hmsg, CMSG_CONTENT_PARAM, 0, NULL, &size)) goto out;
+    if (!(buffer = HeapAlloc(GetProcessHeap(), 0, size)))
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        goto out;
+    }
+    if (!CryptMsgGetParam(hmsg, CMSG_CONTENT_PARAM, 0, buffer, &size)) goto out;
+    if (!CryptDecodeObject(encoding, oid, buffer, size, 0, NULL, &size)) goto out;
+    if (!(inner = HeapAlloc(GetProcessHeap(), 0, size)))
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        goto out;
+    }
+    if (!CryptDecodeObject(encoding, oid, buffer, size, 0, inner, &size)) goto out;
+    *len = size;
+
+out:
+    HeapFree(GetProcessHeap(), 0, oid);
+    HeapFree(GetProcessHeap(), 0, buffer);
+    return inner;
+}
+
 /***********************************************************************
  *      CryptCATOpen  (WINTRUST.@)
  */
 HANDLE WINAPI CryptCATOpen(LPWSTR pwszFileName, DWORD fdwOpenFlags, HCRYPTPROV hProv,
                            DWORD dwPublicVersion, DWORD dwEncodingType)
 {
-    FIXME("(%s, %d, %ld, %d, %d) stub\n", debugstr_w(pwszFileName), fdwOpenFlags,
+    HANDLE file, hmsg;
+    BYTE *buffer = NULL;
+    DWORD size, flags = OPEN_EXISTING;
+    struct cryptcat *cc;
+
+    TRACE("%s, %x, %lx, %x, %x\n", debugstr_w(pwszFileName), fdwOpenFlags,
           hProv, dwPublicVersion, dwEncodingType);
-    return 0;
+
+    if (!pwszFileName)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return INVALID_HANDLE_VALUE;
+    }
+
+    if (!dwPublicVersion) dwPublicVersion = 0x00000100;
+    if (!dwEncodingType)  dwEncodingType  = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+
+    if (fdwOpenFlags & CRYPTCAT_OPEN_ALWAYS)    flags |= OPEN_ALWAYS;
+    if (fdwOpenFlags & CRYPTCAT_OPEN_CREATENEW) flags |= CREATE_NEW;
+
+    file = CreateFileW(pwszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, flags, 0, NULL);
+    if (file == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE;
+
+    size = GetFileSize(file, NULL);
+    if (!(buffer = HeapAlloc(GetProcessHeap(), 0, size)))
+    {
+        CloseHandle(file);
+        SetLastError(ERROR_OUTOFMEMORY);
+        return INVALID_HANDLE_VALUE;
+    }
+    if (!(hmsg = CryptMsgOpenToDecode(dwEncodingType, 0, 0, hProv, NULL, NULL)))
+    {
+        CloseHandle(file);
+        HeapFree(GetProcessHeap(), 0, buffer);
+        return INVALID_HANDLE_VALUE;
+    }
+    if (!ReadFile(file, buffer, size, &size, NULL) || !CryptMsgUpdate(hmsg, buffer, size, TRUE))
+    {
+        CloseHandle(file);
+        HeapFree(GetProcessHeap(), 0, buffer);
+        CryptMsgClose(hmsg);
+        return INVALID_HANDLE_VALUE;
+    }
+    HeapFree(GetProcessHeap(), 0, buffer);
+    CloseHandle(file);
+
+    size = sizeof(DWORD);
+    if (!(cc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cc))))
+    {
+        CryptMsgClose(hmsg);
+        SetLastError(ERROR_OUTOFMEMORY);
+        return INVALID_HANDLE_VALUE;
+    }
+
+    cc->msg = hmsg;
+    cc->encoding = dwEncodingType;
+    if (CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_COUNT_PARAM, 0, &cc->attr_count, &size))
+    {
+        DWORD i, sum = 0;
+        BYTE *p;
+
+        for (i = 0; i < cc->attr_count; i++)
+        {
+            if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, NULL, &size))
+            {
+                CryptMsgClose(hmsg);
+                return INVALID_HANDLE_VALUE;
+            }
+            sum += size;
+        }
+        if (!(cc->attr = HeapAlloc(GetProcessHeap(), 0, sizeof(*cc->attr) * cc->attr_count + sum)))
+        {
+            CryptMsgClose(hmsg);
+            SetLastError(ERROR_OUTOFMEMORY);
+            return INVALID_HANDLE_VALUE;
+        }
+        p = (BYTE *)(cc->attr + cc->attr_count);
+        for (i = 0; i < cc->attr_count; i++)
+        {
+            if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, NULL, &size))
+            {
+                CryptMsgClose(hmsg);
+                HeapFree(GetProcessHeap(), 0, cc->attr);
+                return INVALID_HANDLE_VALUE;
+            }
+            if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, p, &size))
+            {
+                CryptMsgClose(hmsg);
+                HeapFree(GetProcessHeap(), 0, cc->attr);
+                return INVALID_HANDLE_VALUE;
+            }
+            p += size;
+        }
+        cc->inner = decode_inner_content(hmsg, dwEncodingType, &cc->inner_len);
+        if (!cc->inner || !CryptSIPRetrieveSubjectGuid(pwszFileName, NULL, &cc->subject))
+        {
+            CryptMsgClose(hmsg);
+            HeapFree(GetProcessHeap(), 0, cc->attr);
+            HeapFree(GetProcessHeap(), 0, cc->inner);
+            HeapFree(GetProcessHeap(), 0, cc);
+            return INVALID_HANDLE_VALUE;
+        }
+        cc->magic = CRYPTCAT_MAGIC;
+        return cc;
+    }
+    return INVALID_HANDLE_VALUE;
 }
 
 /***********************************************************************




More information about the wine-cvs mailing list