ole32: Remove 'recursive registry key delete' function.
[wine] / dlls / wintrust / tests / crypt.c
1 /* Unit test suite for wintrust crypt functions
2  *
3  * Copyright 2007 Paul Vriens
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  *
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #include "windows.h"
25 #include "mscat.h"
26
27 #include "wine/test.h"
28
29 static char selfname[MAX_PATH];
30
31 static CHAR CURR_DIR[MAX_PATH];
32
33 static HMODULE hWintrust = 0;
34
35 static BOOL (WINAPI * pCryptCATAdminAcquireContext)(HCATADMIN*, const GUID*, DWORD);
36 static BOOL (WINAPI * pCryptCATAdminReleaseContext)(HCATADMIN, DWORD);
37 static BOOL (WINAPI * pCryptCATAdminCalcHashFromFileHandle)(HANDLE hFile, DWORD*, BYTE*, DWORD);
38
39 #define WINTRUST_GET_PROC(func) \
40     p ## func = (void*)GetProcAddress(hWintrust, #func); \
41     if(!p ## func) { \
42       trace("GetProcAddress(%s) failed\n", #func); \
43     }
44
45 static BOOL InitFunctionPtrs(void)
46 {
47     hWintrust = LoadLibraryA("wintrust.dll");
48
49     if(!hWintrust)
50     {
51         skip("Could not load wintrust.dll\n");
52         return FALSE;
53     }
54
55     WINTRUST_GET_PROC(CryptCATAdminAcquireContext)
56     WINTRUST_GET_PROC(CryptCATAdminReleaseContext)
57     WINTRUST_GET_PROC(CryptCATAdminCalcHashFromFileHandle)
58
59     return TRUE;
60 }
61
62 static void test_context(void)
63 {
64     BOOL ret;
65     HCATADMIN hca;
66     static GUID dummy   = { 0xdeadbeef, 0xdead, 0xbeef, { 0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef }};
67     static GUID unknown = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; /* WINTRUST.DLL */
68
69     if (!pCryptCATAdminAcquireContext || !pCryptCATAdminReleaseContext)
70     {
71         skip("CryptCATAdminAcquireContext and/or CryptCATAdminReleaseContext are not available\n");
72         return;
73     }
74
75     /* All NULL */
76     SetLastError(0xdeadbeef);
77     ret = pCryptCATAdminAcquireContext(NULL, NULL, 0);
78     todo_wine
79     {
80     ok(!ret, "Expected failure\n");
81     ok(GetLastError() == ERROR_INVALID_PARAMETER,
82        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
83     }
84
85     /* NULL GUID */
86     SetLastError(0xdeadbeef);
87     ret = pCryptCATAdminAcquireContext(&hca, NULL, 0);
88     ok(ret, "Expected success\n");
89     ok(GetLastError() == ERROR_SUCCESS ||
90        GetLastError() == 0xdeadbeef /* Vista */,
91        "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
92     ok(hca != NULL, "Expected a context handle, got NULL\n");
93
94     /* All NULL */
95     SetLastError(0xdeadbeef);
96     ret = pCryptCATAdminReleaseContext(NULL, 0);
97     todo_wine
98     {
99     ok(!ret, "Expected failure\n");
100     ok(GetLastError() == ERROR_INVALID_PARAMETER,
101        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
102     }
103
104     /* Proper release */
105     SetLastError(0xdeadbeef);
106     ret = pCryptCATAdminReleaseContext(hca, 0);
107     ok(ret, "Expected success\n");
108     ok(GetLastError() == 0xdeadbeef,
109        "Expected no change in last error, got %d\n", GetLastError());
110
111     /* Try to release a second time */
112     SetLastError(0xdeadbeef);
113     ret = pCryptCATAdminReleaseContext(hca, 0);
114     todo_wine
115     {
116     ok(!ret, "Expected failure\n");
117     ok(GetLastError() == ERROR_INVALID_PARAMETER,
118        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
119     }
120
121     /* NULL context handle and dummy GUID */
122     SetLastError(0xdeadbeef);
123     ret = pCryptCATAdminAcquireContext(NULL, &dummy, 0);
124     todo_wine
125     {
126     ok(!ret, "Expected failure\n");
127     ok(GetLastError() == ERROR_INVALID_PARAMETER,
128        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
129     }
130
131     /* Correct context handle and dummy GUID */
132     SetLastError(0xdeadbeef);
133     ret = pCryptCATAdminAcquireContext(&hca, &dummy, 0);
134     ok(ret, "Expected success\n");
135     ok(GetLastError() == ERROR_SUCCESS ||
136        GetLastError() == 0xdeadbeef /* Vista */,
137        "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
138     ok(hca != NULL, "Expected a context handle, got NULL\n");
139
140     ret = pCryptCATAdminReleaseContext(hca, 0);
141     ok(ret, "Expected success\n");
142
143     /* Correct context handle and GUID */
144     SetLastError(0xdeadbeef);
145     ret = pCryptCATAdminAcquireContext(&hca, &unknown, 0);
146     ok(ret, "Expected success\n");
147     ok(GetLastError() == ERROR_SUCCESS ||
148        GetLastError() == 0xdeadbeef /* Vista */,
149        "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
150     ok(hca != NULL, "Expected a context handle, got NULL\n");
151
152     ret = pCryptCATAdminReleaseContext(hca, 0);
153     ok(ret, "Expected success\n");
154
155     /* Flags not equal to 0 */
156     SetLastError(0xdeadbeef);
157     ret = pCryptCATAdminAcquireContext(&hca, &unknown, 1);
158     ok(ret, "Expected success\n");
159     ok(GetLastError() == ERROR_SUCCESS ||
160        GetLastError() == 0xdeadbeef /* Vista */,
161        "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
162     ok(hca != NULL, "Expected a context handle, got NULL\n");
163
164     ret = pCryptCATAdminReleaseContext(hca, 0);
165     ok(ret, "Expected success\n");
166 }
167
168 /* TODO: Check whether SHA-1 is the algorithm that's always used */
169 static void test_calchash(void)
170 {
171     BOOL ret;
172     HANDLE file;
173     DWORD hashsize = 0;
174     BYTE* hash;
175     BYTE expectedhash[20] = {0x3a,0xa1,0x19,0x08,0xec,0xa6,0x0d,0x2e,0x7e,0xcc,0x7a,0xca,0xf5,0xb8,0x2e,0x62,0x6a,0xda,0xf0,0x19};
176     CHAR temp[MAX_PATH];
177     DWORD written;
178
179     if (!pCryptCATAdminCalcHashFromFileHandle)
180     {
181         skip("CryptCATAdminCalcHashFromFileHandle is not available\n");
182         return;
183     }
184     
185     /* All NULL */
186     SetLastError(0xdeadbeef);
187     ret = pCryptCATAdminCalcHashFromFileHandle(NULL, NULL, NULL, 0);
188     todo_wine
189     {
190     ok(!ret, "Expected failure\n");
191     ok(GetLastError() == ERROR_INVALID_PARAMETER,
192        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
193     }
194
195     /* NULL filehandle, rest is legal */
196     SetLastError(0xdeadbeef);
197     ret = pCryptCATAdminCalcHashFromFileHandle(NULL, &hashsize, NULL, 0);
198     todo_wine
199     {
200     ok(!ret, "Expected failure\n");
201     ok(GetLastError() == ERROR_INVALID_PARAMETER,
202        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
203     }
204
205     /* Correct filehandle, rest is NULL */
206     file = CreateFileA(selfname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
207     SetLastError(0xdeadbeef);
208     ret = pCryptCATAdminCalcHashFromFileHandle(file, NULL, NULL, 0);
209     todo_wine
210     {
211     ok(!ret, "Expected failure\n");
212     ok(GetLastError() == ERROR_INVALID_PARAMETER,
213        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
214     }
215     CloseHandle(file);
216
217     /* All OK, but dwFlags set to 1 */
218     file = CreateFileA(selfname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
219     SetLastError(0xdeadbeef);
220     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, NULL, 1);
221     todo_wine
222     {
223     ok(!ret, "Expected failure\n");
224     ok(GetLastError() == ERROR_INVALID_PARAMETER,
225        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
226     }
227     CloseHandle(file);
228
229     /* All OK, requesting the size of the hash */
230     file = CreateFileA(selfname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
231     SetLastError(0xdeadbeef);
232     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, NULL, 0);
233     ok(ret, "Expected success\n");
234     todo_wine
235     {
236     ok(hashsize == 20," Expected a hash size of 20, got %d\n", hashsize);
237     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
238        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
239     }
240     CloseHandle(file);
241
242     /* All OK, retrieve the hash
243      * Double the hash buffer to see what happens to the size parameter
244      */
245     file = CreateFileA(selfname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
246     hashsize *= 2;
247     hash = HeapAlloc(GetProcessHeap(), 0, hashsize);
248     SetLastError(0xdeadbeef);
249     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, hash, 0);
250     ok(ret, "Expected success\n");
251     todo_wine
252     {
253     ok(hashsize == 20," Expected a hash size of 20, got %d\n", hashsize);
254     ok(GetLastError() == ERROR_SUCCESS,
255        "Expected ERROR_SUCCESS, got %d\n", GetLastError());
256     }
257     CloseHandle(file);
258     HeapFree(GetProcessHeap(), 0, hash);
259
260     /* Do the same test with a file created and filled by ourselves (and we thus
261      * have a known hash for).
262      */
263     GetTempFileNameA(CURR_DIR, "hsh", 0, temp); 
264     file = CreateFileA(temp, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
265     WriteFile(file, "Text in this file is needed to create a know hash", 49, &written, NULL);
266     CloseHandle(file);
267
268     /* All OK, first request the size and then retrieve the hash */
269     file = CreateFileA(temp, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
270     hashsize = 0;
271     pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, NULL, 0);
272     hash = HeapAlloc(GetProcessHeap(), 0, hashsize);
273     SetLastError(0xdeadbeef);
274     ret = pCryptCATAdminCalcHashFromFileHandle(file, &hashsize, hash, 0);
275     ok(ret, "Expected success\n");
276     todo_wine
277     {
278     ok(GetLastError() == ERROR_SUCCESS,
279        "Expected ERROR_SUCCESS, got %d\n", GetLastError());
280     ok(!memcmp(hash, expectedhash, sizeof(expectedhash)), "Hashes didn't match\n");
281     }
282     CloseHandle(file);
283
284     HeapFree(GetProcessHeap(), 0, hash);
285     DeleteFileA(temp);
286 }
287
288 START_TEST(crypt)
289 {
290     int myARGC;
291     char** myARGV;
292
293     if(!InitFunctionPtrs())
294         return;
295
296     myARGC = winetest_get_mainargs(&myARGV);
297     strcpy(selfname, myARGV[0]);
298
299     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
300    
301     test_context();
302     test_calchash();
303
304     FreeLibrary(hWintrust);
305 }