[WINTRUST]
[reactos.git] / reactos / dll / win32 / wintrust / crypt.c
index c41a56b..b59bfdd 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include <stdarg.h>
-#include <stdio.h>
-#include "windef.h"
-#include "winbase.h"
-#include "wintrust.h"
-#include "mscat.h"
-#include "mssip.h"
-#include "imagehlp.h"
-#include "winternl.h"
-
-#include "wine/debug.h"
-#include "wine/unicode.h"
+#include "wintrust_priv.h"
+
+#include <imagehlp.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
 
@@ -113,7 +104,7 @@ BOOL WINAPI CryptCATAdminAcquireContext(HCATADMIN *catAdmin,
 
     TRACE("%p %s %x\n", catAdmin, debugstr_guid(sys), dwFlags);
 
-    if (!catAdmin)
+    if (!catAdmin || dwFlags)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
@@ -858,7 +849,6 @@ HANDLE WINAPI CryptCATOpen(LPWSTR pwszFileName, DWORD fdwOpenFlags, HCRYPTPROV h
         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;
@@ -910,6 +900,7 @@ HANDLE WINAPI CryptCATOpen(LPWSTR pwszFileName, DWORD fdwOpenFlags, HCRYPTPROV h
             if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, NULL, &size))
             {
                 CryptMsgClose(hmsg);
+                HeapFree(GetProcessHeap(), 0, cc);
                 return INVALID_HANDLE_VALUE;
             }
             sum += size;
@@ -917,6 +908,7 @@ HANDLE WINAPI CryptCATOpen(LPWSTR pwszFileName, DWORD fdwOpenFlags, HCRYPTPROV h
         if (!(cc->attr = HeapAlloc(GetProcessHeap(), 0, sizeof(*cc->attr) * cc->attr_count + sum)))
         {
             CryptMsgClose(hmsg);
+            HeapFree(GetProcessHeap(), 0, cc);
             SetLastError(ERROR_OUTOFMEMORY);
             return INVALID_HANDLE_VALUE;
         }
@@ -927,12 +919,14 @@ HANDLE WINAPI CryptCATOpen(LPWSTR pwszFileName, DWORD fdwOpenFlags, HCRYPTPROV h
             {
                 CryptMsgClose(hmsg);
                 HeapFree(GetProcessHeap(), 0, cc->attr);
+                HeapFree(GetProcessHeap(), 0, cc);
                 return INVALID_HANDLE_VALUE;
             }
             if (!CryptMsgGetParam(hmsg, CMSG_ATTR_CERT_PARAM, i, p, &size))
             {
                 CryptMsgClose(hmsg);
                 HeapFree(GetProcessHeap(), 0, cc->attr);
+                HeapFree(GetProcessHeap(), 0, cc);
                 return INVALID_HANDLE_VALUE;
             }
             p += size;
@@ -949,6 +943,7 @@ HANDLE WINAPI CryptCATOpen(LPWSTR pwszFileName, DWORD fdwOpenFlags, HCRYPTPROV h
         cc->magic = CRYPTCAT_MAGIC;
         return cc;
     }
+    HeapFree(GetProcessHeap(), 0, cc);
     return INVALID_HANDLE_VALUE;
 }
 
@@ -1017,16 +1012,27 @@ static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo,
 {
     BOOL ret;
     WIN_CERTIFICATE *pCert = NULL;
+    HANDLE file;
 
     TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
           pcbSignedDataMsg, pbSignedDataMsg);
+
+    if(pSubjectInfo->hFile && pSubjectInfo->hFile!=INVALID_HANDLE_VALUE)
+        file = pSubjectInfo->hFile;
+    else
+    {
+        file = CreateFileW(pSubjectInfo->pwsFileName, GENERIC_READ,
+                FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+        if(file == INVALID_HANDLE_VALUE)
+            return FALSE;
+    }
  
     if (!pbSignedDataMsg)
     {
         WIN_CERTIFICATE cert;
 
         /* app hasn't passed buffer, just get the length */
-        ret = ImageGetCertificateHeader(pSubjectInfo->hFile, dwIndex, &cert);
+        ret = ImageGetCertificateHeader(file, dwIndex, &cert);
         if (ret)
         {
             switch (cert.wCertificateType)
@@ -1045,7 +1051,7 @@ static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo,
     {
         DWORD len = 0;
 
-        ret = ImageGetCertificateData(pSubjectInfo->hFile, dwIndex, NULL, &len);
+        ret = ImageGetCertificateData(file, dwIndex, NULL, &len);
         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
             goto error;
         pCert = HeapAlloc(GetProcessHeap(), 0, len);
@@ -1054,10 +1060,10 @@ static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo,
             ret = FALSE;
             goto error;
         }
-        ret = ImageGetCertificateData(pSubjectInfo->hFile, dwIndex, pCert,
-         &len);
+        ret = ImageGetCertificateData(file, dwIndex, pCert, &len);
         if (!ret)
             goto error;
+        pCert->dwLength -= FIELD_OFFSET(WIN_CERTIFICATE, bCertificate);
         if (*pcbSignedDataMsg < pCert->dwLength)
         {
             *pcbSignedDataMsg = pCert->dwLength;
@@ -1067,6 +1073,7 @@ static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo,
         else
         {
             memcpy(pbSignedDataMsg, pCert->bCertificate, pCert->dwLength);
+            *pcbSignedDataMsg = pCert->dwLength;
             switch (pCert->wCertificateType)
             {
             case WIN_CERT_TYPE_X509:
@@ -1084,10 +1091,48 @@ static BOOL WINTRUST_GetSignedMsgFromPEFile(SIP_SUBJECTINFO *pSubjectInfo,
         }
     }
 error:
+    if(pSubjectInfo->hFile != file)
+        CloseHandle(file);
     HeapFree(GetProcessHeap(), 0, pCert);
     return ret;
 }
 
+static BOOL WINTRUST_PutSignedMsgToPEFile(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType,
+        DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg)
+{
+    WIN_CERTIFICATE *cert;
+    HANDLE file;
+    DWORD size;
+    BOOL ret;
+
+    if(pSubjectInfo->hFile && pSubjectInfo->hFile!=INVALID_HANDLE_VALUE)
+        file = pSubjectInfo->hFile;
+    else
+    {
+        file = CreateFileW(pSubjectInfo->pwsFileName, GENERIC_READ|GENERIC_WRITE,
+                FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+        if(file == INVALID_HANDLE_VALUE)
+            return FALSE;
+    }
+
+    /* int aligned WIN_CERTIFICATE structure with cbSignedDataMsg+1 bytes of data */
+    size = FIELD_OFFSET(WIN_CERTIFICATE, bCertificate[cbSignedDataMsg+4]) & (~3);
+    cert = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+    if(!cert)
+        return FALSE;
+
+    cert->dwLength = size;
+    cert->wRevision = WIN_CERT_REVISION_2_0;
+    cert->wCertificateType = WIN_CERT_TYPE_PKCS_SIGNED_DATA;
+    memcpy(cert->bCertificate, pbSignedDataMsg, cbSignedDataMsg);
+    ret = ImageAddCertificate(file, cert, pdwIndex);
+
+    HeapFree(GetProcessHeap(), 0, cert);
+    if(file != pSubjectInfo->hFile)
+        CloseHandle(file);
+    return ret;
+}
+
 /* structure offsets */
 #define cfhead_Signature         (0x00)
 #define cfhead_CabinetSize       (0x08)
@@ -1297,23 +1342,31 @@ static BOOL WINTRUST_GetSignedMsgFromCatFile(SIP_SUBJECTINFO *pSubjectInfo,
     return ret;
 }
 
+/* GUIDs used by CryptSIPGetSignedDataMsg and CryptSIPPutSignedDataMsg */
+static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
+    0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
+static const GUID cabGUID = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,
+    0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
+static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,
+     0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
+
 /***********************************************************************
  *      CryptSIPGetSignedDataMsg  (WINTRUST.@)
  */
 BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType,
                                        DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg)
 {
-    static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
-     0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
-    static const GUID cabGUID = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,
-     0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
-    static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,
-     0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
     BOOL ret;
 
     TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
           pcbSignedDataMsg, pbSignedDataMsg);
 
+    if(!pSubjectInfo)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
     if (!memcmp(pSubjectInfo->pgSubjectType, &unknown, sizeof(unknown)))
         ret = WINTRUST_GetSignedMsgFromPEFile(pSubjectInfo, pdwEncodingType,
          dwIndex, pcbSignedDataMsg, pbSignedDataMsg);
@@ -1338,11 +1391,23 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn
  *      CryptSIPPutSignedDataMsg  (WINTRUST.@)
  */
 BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType,
-                                       DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg)
+        DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg)
 {
-    FIXME("(%p %d %p %d %p) stub\n", pSubjectInfo, pdwEncodingType, pdwIndex,
+    TRACE("(%p %d %p %d %p)\n", pSubjectInfo, pdwEncodingType, pdwIndex,
           cbSignedDataMsg, pbSignedDataMsg);
+
+    if(!pSubjectInfo) {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if(!memcmp(pSubjectInfo->pgSubjectType, &unknown, sizeof(unknown)))
+        return WINTRUST_PutSignedMsgToPEFile(pSubjectInfo, pdwEncodingType,
+                pdwIndex, cbSignedDataMsg, pbSignedDataMsg);
+    else
+        FIXME("unimplemented for subject type %s\n",
+                debugstr_guid(pSubjectInfo->pgSubjectType));
+
     return FALSE;
 }