wintrust: Test and implement SoftpubLoadMessage.
[wine] / dlls / wintrust / tests / softpub.c
1 /*
2  * wintrust softpub functions tests
3  *
4  * Copyright 2007 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 #include <assert.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winerror.h>
26 #include <wintrust.h>
27 #include <softpub.h>
28 #include <mssip.h>
29 #include <winuser.h>
30
31 #include "wine/test.h"
32
33 /* Just in case we're being built with borked headers, redefine function
34  * pointers to have the correct calling convention.
35  */
36 typedef void   *(WINAPI *SAFE_MEM_ALLOC)(DWORD);
37 typedef void    (WINAPI *SAFE_MEM_FREE)(void *);
38 typedef BOOL    (WINAPI *SAFE_ADD_STORE)(CRYPT_PROVIDER_DATA *,
39  HCERTSTORE);
40 typedef BOOL    (WINAPI *SAFE_ADD_SGNR)(CRYPT_PROVIDER_DATA *,
41  BOOL, DWORD, struct _CRYPT_PROVIDER_SGNR *);
42 typedef BOOL    (WINAPI *SAFE_ADD_CERT)(CRYPT_PROVIDER_DATA *,
43  DWORD, BOOL, DWORD, PCCERT_CONTEXT);
44 typedef BOOL    (WINAPI *SAFE_ADD_PRIVDATA)(CRYPT_PROVIDER_DATA *,
45  CRYPT_PROVIDER_PRIVDATA *);
46 typedef HRESULT (WINAPI *SAFE_PROVIDER_INIT_CALL)(CRYPT_PROVIDER_DATA *);
47 typedef HRESULT (WINAPI *SAFE_PROVIDER_OBJTRUST_CALL)(CRYPT_PROVIDER_DATA *);
48 typedef HRESULT (WINAPI *SAFE_PROVIDER_SIGTRUST_CALL)(CRYPT_PROVIDER_DATA *);
49 typedef HRESULT (WINAPI *SAFE_PROVIDER_CERTTRUST_CALL)(CRYPT_PROVIDER_DATA *);
50 typedef HRESULT (WINAPI *SAFE_PROVIDER_FINALPOLICY_CALL)(CRYPT_PROVIDER_DATA *);
51 typedef HRESULT (WINAPI *SAFE_PROVIDER_TESTFINALPOLICY_CALL)(
52  CRYPT_PROVIDER_DATA *);
53 typedef HRESULT (WINAPI *SAFE_PROVIDER_CLEANUP_CALL)(CRYPT_PROVIDER_DATA *);
54 typedef BOOL    (WINAPI *SAFE_PROVIDER_CERTCHKPOLICY_CALL)(
55  CRYPT_PROVIDER_DATA *, DWORD, BOOL, DWORD);
56
57 typedef struct _SAFE_PROVIDER_FUNCTIONS
58 {
59     DWORD                              cbStruct;
60     SAFE_MEM_ALLOC                     pfnAlloc;
61     SAFE_MEM_FREE                      pfnFree;
62     SAFE_ADD_STORE                     pfnAddStore2Chain;
63     SAFE_ADD_SGNR                      pfnAddSgnr2Chain;
64     SAFE_ADD_CERT                      pfnAddCert2Chain;
65     SAFE_ADD_PRIVDATA                  pfnAddPrivData2Chain;
66     SAFE_PROVIDER_INIT_CALL            pfnInitialize;
67     SAFE_PROVIDER_OBJTRUST_CALL        pfnObjectTrust;
68     SAFE_PROVIDER_SIGTRUST_CALL        pfnSignatureTrust;
69     SAFE_PROVIDER_CERTTRUST_CALL       pfnCertificateTrust;
70     SAFE_PROVIDER_FINALPOLICY_CALL     pfnFinalPolicy;
71     SAFE_PROVIDER_CERTCHKPOLICY_CALL   pfnCertCheckPolicy;
72     SAFE_PROVIDER_TESTFINALPOLICY_CALL pfnTestFinalPolicy;
73     struct _CRYPT_PROVUI_FUNCS        *psUIpfns;
74     SAFE_PROVIDER_CLEANUP_CALL         pfnCleanupPolicy;
75 } SAFE_PROVIDER_FUNCTIONS;
76
77 static void testInitialize(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
78 {
79     HRESULT ret;
80     CRYPT_PROVIDER_DATA data = { 0 };
81     WINTRUST_DATA wintrust_data = { 0 };
82
83     if (!funcs->pfnInitialize)
84     {
85         skip("missing pfnInitialize\n");
86         return;
87     }
88
89     /* Crashes
90     ret = funcs->pfnInitialize(NULL);
91      */
92     memset(&data, 0, sizeof(data));
93     ret = funcs->pfnInitialize(&data);
94     ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
95     data.padwTrustStepErrors =
96      funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
97     /* Without wintrust data set, crashes when padwTrustStepErrors is set */
98     data.pWintrustData = &wintrust_data;
99     if (data.padwTrustStepErrors)
100     {
101         /* Apparently, cdwTrustStepErrors does not need to be set. */
102         ret = funcs->pfnInitialize(&data);
103         ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
104         data.cdwTrustStepErrors = 1;
105         ret = funcs->pfnInitialize(&data);
106         ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
107         memset(data.padwTrustStepErrors, 0xba,
108          TRUSTERROR_MAX_STEPS * sizeof(DWORD));
109         ret = funcs->pfnInitialize(&data);
110         ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
111         data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] = 0;
112         ret = funcs->pfnInitialize(&data);
113         ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
114         funcs->pfnFree(data.padwTrustStepErrors);
115     }
116 }
117
118 static const BYTE v1CertWithPubKey[] = {
119 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
120 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
121 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
122 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
123 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
124 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
125 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
126 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
127 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
128 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
129 0x01,0x01 };
130
131 static void testObjTrust(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
132 {
133     HRESULT ret;
134     CRYPT_PROVIDER_DATA data = { 0 };
135     WINTRUST_DATA wintrust_data = { 0 };
136     WINTRUST_CERT_INFO certInfo = { sizeof(WINTRUST_CERT_INFO), 0 };
137     WINTRUST_FILE_INFO fileInfo = { sizeof(WINTRUST_FILE_INFO), 0 };
138
139     if (!funcs->pfnObjectTrust)
140     {
141         skip("missing pfnObjectTrust\n");
142         return;
143     }
144
145     /* Crashes
146     ret = funcs->pfnObjectTrust(NULL);
147      */
148     data.pWintrustData = &wintrust_data;
149     data.padwTrustStepErrors =
150      funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
151     if (data.padwTrustStepErrors)
152     {
153         static const WCHAR notepad[] = { '\\','n','o','t','e','p','a','d','.',
154          'e','x','e',0 };
155         WCHAR notepadPath[MAX_PATH];
156         PROVDATA_SIP provDataSIP = { 0 };
157         static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
158          0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
159
160         ret = funcs->pfnObjectTrust(&data);
161         ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
162         ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
163          ERROR_INVALID_PARAMETER,
164          "Expected ERROR_INVALID_PARAMETER, got %08x\n",
165          data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
166         wintrust_data.pCert = &certInfo;
167         wintrust_data.dwUnionChoice = WTD_CHOICE_CERT;
168         ret = funcs->pfnObjectTrust(&data);
169         ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
170         certInfo.psCertContext = (PCERT_CONTEXT)CertCreateCertificateContext(
171          X509_ASN_ENCODING, v1CertWithPubKey, sizeof(v1CertWithPubKey));
172         ret = funcs->pfnObjectTrust(&data);
173         ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
174         CertFreeCertificateContext(certInfo.psCertContext);
175         certInfo.psCertContext = NULL;
176         wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
177         wintrust_data.pFile = NULL;
178         ret = funcs->pfnObjectTrust(&data);
179         ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
180         ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
181          ERROR_INVALID_PARAMETER,
182          "Expected ERROR_INVALID_PARAMETER, got %08x\n",
183          data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
184         wintrust_data.pFile = &fileInfo;
185         /* Crashes
186         ret = funcs->pfnObjectTrust(&data);
187          */
188         GetWindowsDirectoryW(notepadPath, MAX_PATH);
189         lstrcatW(notepadPath, notepad);
190         fileInfo.pcwszFilePath = notepadPath;
191         /* pfnObjectTrust now crashes unless both pPDSip and psPfns are set */
192         data.pPDSip = &provDataSIP;
193         data.psPfns = (CRYPT_PROVIDER_FUNCTIONS *)funcs;
194         ret = funcs->pfnObjectTrust(&data);
195         ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
196         ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
197          TRUST_E_NOSIGNATURE, "Expected TRUST_E_NOSIGNATURE, got %08x\n",
198          data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
199         ok(!memcmp(&provDataSIP.gSubject, &unknown, sizeof(unknown)),
200          "Unexpected subject GUID\n");
201         ok(provDataSIP.pSip != NULL, "Expected a SIP\n");
202         ok(provDataSIP.psSipSubjectInfo != NULL, "Expected a subject info\n");
203         funcs->pfnFree(data.padwTrustStepErrors);
204     }
205 }
206
207 START_TEST(softpub)
208 {
209     static GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
210     SAFE_PROVIDER_FUNCTIONS funcs = { sizeof(SAFE_PROVIDER_FUNCTIONS), 0 };
211     BOOL ret;
212
213     ret = WintrustLoadFunctionPointers(&generic_verify_v2,
214      (CRYPT_PROVIDER_FUNCTIONS *)&funcs);
215     if (!ret)
216         skip("WintrustLoadFunctionPointers failed\n");
217     else
218     {
219         testInitialize(&funcs, &generic_verify_v2);
220         testObjTrust(&funcs, &generic_verify_v2);
221     }
222 }