[ADVAPI32_WINETEST] Sync with Wine Staging 3.3. CORE-14434
[reactos.git] / modules / rostests / winetests / advapi32 / crypt.c
1 /*
2 * Unit tests for crypt functions
3 *
4 * Copyright (c) 2004 Michael Jung
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
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wincrypt.h"
26 #include "winerror.h"
27 #include "winreg.h"
28
29 #include "wine/test.h"
30
31 static const char szRsaBaseProv[] = MS_DEF_PROV_A;
32 static const char szNonExistentProv[] = "Wine Nonexistent Cryptographic Provider v11.2";
33 static const char szKeySet[] = "wine_test_keyset";
34 static const char szBadKeySet[] = "wine_test_bad_keyset";
35 #define NON_DEF_PROV_TYPE 999
36
37 static BOOL (WINAPI *pCryptAcquireContextA)(HCRYPTPROV*,LPCSTR,LPCSTR,DWORD,DWORD);
38 static BOOL (WINAPI *pCryptEnumProviderTypesA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
39 static BOOL (WINAPI *pCryptEnumProvidersA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
40 static BOOL (WINAPI *pCryptGetDefaultProviderA)(DWORD, DWORD*, DWORD, LPSTR, DWORD*);
41 static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV, DWORD);
42 static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD);
43 static BOOL (WINAPI *pCryptCreateHash)(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*);
44 static BOOL (WINAPI *pCryptDestroyHash)(HCRYPTHASH);
45 static BOOL (WINAPI *pCryptGenRandom)(HCRYPTPROV, DWORD, BYTE*);
46 static BOOL (WINAPI *pCryptContextAddRef)(HCRYPTPROV, DWORD*, DWORD dwFlags);
47 static BOOL (WINAPI *pCryptGenKey)(HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY*);
48 static BOOL (WINAPI *pCryptDestroyKey)(HCRYPTKEY);
49 static BOOL (WINAPI *pCryptDecrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*);
50 static BOOL (WINAPI *pCryptDeriveKey)(HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY*);
51 static BOOL (WINAPI *pCryptDuplicateHash)(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
52 static BOOL (WINAPI *pCryptDuplicateKey)(HCRYPTKEY, DWORD*, DWORD, HCRYPTKEY*);
53 static BOOL (WINAPI *pCryptEncrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*, DWORD);
54 static BOOL (WINAPI *pCryptExportKey)(HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, BYTE*, DWORD*);
55 static BOOL (WINAPI *pCryptGetHashParam)(HCRYPTHASH, DWORD, BYTE*, DWORD*, DWORD);
56 static BOOL (WINAPI *pCryptGetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD*, DWORD);
57 static BOOL (WINAPI *pCryptGetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD*, DWORD);
58 static BOOL (WINAPI *pCryptGetUserKey)(HCRYPTPROV, DWORD, HCRYPTKEY*);
59 static BOOL (WINAPI *pCryptHashData)(HCRYPTHASH, BYTE*, DWORD, DWORD);
60 static BOOL (WINAPI *pCryptHashSessionKey)(HCRYPTHASH, HCRYPTKEY, DWORD);
61 static BOOL (WINAPI *pCryptImportKey)(HCRYPTPROV, BYTE*, DWORD, HCRYPTKEY, DWORD, HCRYPTKEY*);
62 static BOOL (WINAPI *pCryptSignHashW)(HCRYPTHASH, DWORD, LPCWSTR, DWORD, BYTE*, DWORD*);
63 static BOOL (WINAPI *pCryptSetHashParam)(HCRYPTKEY, DWORD, BYTE*, DWORD);
64 static BOOL (WINAPI *pCryptSetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD);
65 static BOOL (WINAPI *pCryptSetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD);
66 static BOOL (WINAPI *pCryptVerifySignatureW)(HCRYPTHASH, BYTE*, DWORD, HCRYPTKEY, LPCWSTR, DWORD);
67 static BOOLEAN (WINAPI *pSystemFunction036)(PVOID, ULONG);
68
69 static void init_function_pointers(void)
70 {
71 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
72
73 pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA");
74 pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA");
75 pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA");
76 pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA");
77 pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext");
78 pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA");
79 pCryptCreateHash = (void*)GetProcAddress(hadvapi32, "CryptCreateHash");
80 pCryptDestroyHash = (void*)GetProcAddress(hadvapi32, "CryptDestroyHash");
81 pCryptGenRandom = (void*)GetProcAddress(hadvapi32, "CryptGenRandom");
82 pCryptContextAddRef = (void*)GetProcAddress(hadvapi32, "CryptContextAddRef");
83 pCryptGenKey = (void*)GetProcAddress(hadvapi32, "CryptGenKey");
84 pCryptDestroyKey = (void*)GetProcAddress(hadvapi32, "CryptDestroyKey");
85 pCryptDecrypt = (void*)GetProcAddress(hadvapi32, "CryptDecrypt");
86 pCryptDeriveKey = (void*)GetProcAddress(hadvapi32, "CryptDeriveKey");
87 pCryptDuplicateHash = (void*)GetProcAddress(hadvapi32, "CryptDuplicateHash");
88 pCryptDuplicateKey = (void*)GetProcAddress(hadvapi32, "CryptDuplicateKey");
89 pCryptEncrypt = (void*)GetProcAddress(hadvapi32, "CryptEncrypt");
90 pCryptExportKey = (void*)GetProcAddress(hadvapi32, "CryptExportKey");
91 pCryptGetHashParam = (void*)GetProcAddress(hadvapi32, "CryptGetHashParam");
92 pCryptGetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptGetKeyParam");
93 pCryptGetProvParam = (void*)GetProcAddress(hadvapi32, "CryptGetProvParam");
94 pCryptGetUserKey = (void*)GetProcAddress(hadvapi32, "CryptGetUserKey");
95 pCryptHashData = (void*)GetProcAddress(hadvapi32, "CryptHashData");
96 pCryptHashSessionKey = (void*)GetProcAddress(hadvapi32, "CryptHashSessionKey");
97 pCryptImportKey = (void*)GetProcAddress(hadvapi32, "CryptImportKey");
98 pCryptSignHashW = (void*)GetProcAddress(hadvapi32, "CryptSignHashW");
99 pCryptSetHashParam = (void*)GetProcAddress(hadvapi32, "CryptSetHashParam");
100 pCryptSetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptSetKeyParam");
101 pCryptSetProvParam = (void*)GetProcAddress(hadvapi32, "CryptSetProvParam");
102 pCryptVerifySignatureW = (void*)GetProcAddress(hadvapi32, "CryptVerifySignatureW");
103 pSystemFunction036 = (void*)GetProcAddress(hadvapi32, "SystemFunction036");
104 }
105
106 static void init_environment(void)
107 {
108 HCRYPTPROV hProv;
109
110 /* Ensure that container "wine_test_keyset" does exist */
111 if (!pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
112 {
113 pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET);
114 }
115 pCryptReleaseContext(hProv, 0);
116
117 /* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */
118 if (!pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
119 {
120 pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
121 }
122 pCryptReleaseContext(hProv, 0);
123
124 /* Ensure that container "wine_test_bad_keyset" does not exist. */
125 if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
126 {
127 pCryptReleaseContext(hProv, 0);
128 pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
129 }
130 }
131
132 static void clean_up_environment(void)
133 {
134 HCRYPTPROV hProv;
135
136 /* Remove container "wine_test_keyset" */
137 if (pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
138 {
139 pCryptReleaseContext(hProv, 0);
140 pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
141 }
142
143 /* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */
144 if (pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
145 {
146 pCryptReleaseContext(hProv, 0);
147 pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
148 }
149
150 /* Remove container "wine_test_bad_keyset" */
151 if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
152 {
153 pCryptReleaseContext(hProv, 0);
154 pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
155 }
156 }
157
158 static void test_acquire_context(void)
159 {
160 BOOL result;
161 HCRYPTPROV hProv;
162 DWORD GLE;
163
164 /* Provoke all kinds of error conditions (which are easy to provoke).
165 * The order of the error tests seems to match Windows XP's rsaenh.dll CSP,
166 * but since this is likely to change between CSP versions, we don't check
167 * this. Please don't change the order of tests. */
168 result = pCryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
169 ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
170
171 result = pCryptAcquireContextA(&hProv, NULL, NULL, 1000, 0);
172 ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
173
174 result = pCryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0);
175 ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%d\n", GetLastError());
176
177 result = pCryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0);
178 ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%d\n", GetLastError());
179
180 result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0);
181 ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%d\n", GetLastError());
182
183 /* This test fails under Win2k SP4:
184 result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER
185 SetLastError(0xdeadbeef);
186 result = pCryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
187 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%d\n", result, GetLastError());
188 */
189
190 /* Last not least, try to really acquire a context. */
191 hProv = 0;
192 SetLastError(0xdeadbeef);
193 result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
194 GLE = GetLastError();
195 ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND ||
196 GLE == ERROR_SUCCESS ||
197 GLE == ERROR_RING2_STACK_IN_USE ||
198 GLE == NTE_FAIL ||
199 GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GLE);
200
201 if (hProv)
202 pCryptReleaseContext(hProv, 0);
203
204 /* Try again, witch an empty ("\0") szProvider parameter */
205 hProv = 0;
206 SetLastError(0xdeadbeef);
207 result = pCryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0);
208 GLE = GetLastError();
209 ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND ||
210 GLE == ERROR_SUCCESS ||
211 GLE == ERROR_RING2_STACK_IN_USE ||
212 GLE == NTE_FAIL ||
213 GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GetLastError());
214
215 if (hProv)
216 pCryptReleaseContext(hProv, 0);
217 }
218
219 static void test_incorrect_api_usage(void)
220 {
221 BOOL result;
222 HCRYPTPROV hProv, hProv2;
223 HCRYPTHASH hHash, hHash2;
224 HCRYPTKEY hKey, hKey2;
225 BYTE temp;
226 DWORD dwLen, dwTemp;
227
228 /* This is to document incorrect api usage in the
229 * "Uru - Ages beyond Myst Demo" installer as reported by Paul Vriens.
230 *
231 * The installer destroys a hash object after having released the context
232 * with which the hash was created. This is not allowed according to MSDN,
233 * since CryptReleaseContext destroys all hash and key objects belonging to
234 * the respective context. However, while wine used to crash, Windows is more
235 * robust here and returns an ERROR_INVALID_PARAMETER code.
236 */
237
238 result = pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv,
239 PROV_RSA_FULL, CRYPT_NEWKEYSET);
240 ok (result, "%08x\n", GetLastError());
241 if (!result) return;
242
243 result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
244 ok (result, "%d\n", GetLastError());
245 if (!result) return;
246 pCryptDestroyHash(hHash);
247
248 result = pCryptCreateHash(0, CALG_SHA, 0, 0, &hHash);
249 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
250
251 result = pCryptGenKey(0, CALG_RC4, 0, &hKey);
252 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
253
254 result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey);
255 ok (result, "%d\n", GetLastError());
256 if (!result) return;
257
258 result = pCryptDestroyKey(hKey);
259 ok (result, "%d\n", GetLastError());
260
261 result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
262 ok (result, "%d\n", GetLastError());
263 if (!result) return;
264
265 result = pCryptDestroyKey(hKey2);
266 ok (result, "%d\n", GetLastError());
267
268 dwTemp = CRYPT_MODE_ECB;
269 result = pCryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD));
270 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
271
272 result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL,
273 CRYPT_DELETEKEYSET);
274 ok (result, "%d\n", GetLastError());
275 if (!result) return;
276
277 result = pCryptReleaseContext(hProv, 0);
278 ok (result, "%d\n", GetLastError());
279 if (!result) return;
280
281 result = pCryptReleaseContext(hProv, 0);
282 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
283
284 result = pCryptGenRandom(hProv, 1, &temp);
285 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
286
287 #ifdef CRASHES_ON_NT40
288 result = pCryptContextAddRef(hProv, NULL, 0);
289 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
290 #endif
291
292 result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
293 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
294
295 dwLen = 1;
296 result = pCryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen);
297 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
298
299 dwLen = 1;
300 result = pCryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, 1);
301 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
302
303 result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2);
304 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
305
306 #ifdef CRASHES_ON_NT40
307 result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2);
308 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
309
310 result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2);
311 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
312 #endif
313
314 dwLen = 1;
315 result = pCryptExportKey(hKey, 0, 0, 0, &temp, &dwLen);
316 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
317
318 result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
319 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
320
321 dwLen = 1;
322 result = pCryptGetHashParam(hHash, 0, &temp, &dwLen, 0);
323 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
324
325 dwLen = 1;
326 result = pCryptGetKeyParam(hKey, 0, &temp, &dwLen, 0);
327 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
328
329 dwLen = 1;
330 result = pCryptGetProvParam(hProv, 0, &temp, &dwLen, 0);
331 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
332
333 result = pCryptGetUserKey(hProv, 0, &hKey2);
334 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
335
336 result = pCryptHashData(hHash, &temp, 1, 0);
337 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
338
339 result = pCryptHashSessionKey(hHash, hKey, 0);
340 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
341
342 result = pCryptImportKey(hProv, &temp, 1, 0, 0, &hKey2);
343 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
344
345 if (pCryptSignHashW)
346 {
347 dwLen = 1;
348 result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen);
349 ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
350 GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
351 }
352 else
353 win_skip("CryptSignHashW is not available\n");
354
355 result = pCryptSetKeyParam(hKey, 0, &temp, 1);
356 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
357
358 result = pCryptSetHashParam(hHash, 0, &temp, 1);
359 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
360
361 result = pCryptSetProvParam(hProv, 0, &temp, 1);
362 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
363
364 if (pCryptVerifySignatureW)
365 {
366 result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0);
367 ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
368 GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
369 }
370 else
371 win_skip("CryptVerifySignatureW is not available\n");
372
373 result = pCryptDestroyHash(hHash);
374 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
375
376 result = pCryptDestroyKey(hKey);
377 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
378 }
379
380 static const BYTE privKey[] = {
381 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
382 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
383 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
384 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
385 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
386 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
387 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
388 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
389 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
390 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
391 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
392 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
393 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
394 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
395 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
396 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
397 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
398 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
399 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
400 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
401 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
402 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
403 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
404 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
405
406 static void test_verify_sig(void)
407 {
408 BOOL ret;
409 HCRYPTPROV prov;
410 HCRYPTKEY key;
411 HCRYPTHASH hash;
412 BYTE bogus[] = { 0 };
413
414 if (!pCryptVerifySignatureW)
415 {
416 win_skip("CryptVerifySignatureW is not available\n");
417 return;
418 }
419
420 SetLastError(0xdeadbeef);
421 ret = pCryptVerifySignatureW(0, NULL, 0, 0, NULL, 0);
422 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
423 {
424 win_skip("CryptVerifySignatureW is not implemented\n");
425 return;
426 }
427 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
428 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
429 ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL,
430 CRYPT_NEWKEYSET);
431 if (!ret && GetLastError() == NTE_EXISTS)
432 ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0);
433 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
434 ret = pCryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key);
435 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
436 ret = pCryptCreateHash(prov, CALG_MD5, 0, 0, &hash);
437 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
438 SetLastError(0xdeadbeef);
439 ret = pCryptVerifySignatureW(hash, NULL, 0, 0, NULL, 0);
440 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
441 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
442 SetLastError(0xdeadbeef);
443 ret = pCryptVerifySignatureW(0, NULL, 0, key, NULL, 0);
444 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
445 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
446 SetLastError(0xdeadbeef);
447 ret = pCryptVerifySignatureW(hash, NULL, 0, key, NULL, 0);
448 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
449 GetLastError() == ERROR_INVALID_PARAMETER),
450 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
451 GetLastError());
452 SetLastError(0xdeadbeef);
453 ret = pCryptVerifySignatureW(hash, NULL, sizeof(bogus), key, NULL, 0);
454 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
455 GetLastError() == ERROR_INVALID_PARAMETER),
456 "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
457 GetLastError());
458 SetLastError(0xdeadbeef);
459 ret = pCryptVerifySignatureW(hash, bogus, 0, key, NULL, 0);
460 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
461 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
462 SetLastError(0xdeadbeef);
463 ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
464 ok(!ret &&
465 (GetLastError() == NTE_BAD_SIGNATURE ||
466 broken(GetLastError() == NTE_BAD_HASH_STATE /* older NT4 */)),
467 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
468 pCryptDestroyKey(key);
469 pCryptDestroyHash(hash);
470 pCryptReleaseContext(prov, 0);
471 }
472
473 static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName,
474 DWORD *pcbProvName, DWORD *pdwProvCount)
475 {
476 HKEY hKey;
477 HKEY subkey;
478 DWORD size = sizeof(DWORD);
479
480 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))
481 return FALSE;
482
483 RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName,
484 NULL, NULL, NULL, NULL, NULL, NULL);
485 (*pcbProvName)++;
486
487 if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
488 return FALSE;
489
490 RegEnumKeyExA(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
491 (*pcbProvName)++;
492
493 RegOpenKeyA(hKey, *pszProvName, &subkey);
494 RegQueryValueExA(subkey, "Type", NULL, NULL, (LPBYTE)pdwProvType, &size);
495
496 RegCloseKey(subkey);
497 RegCloseKey(hKey);
498
499 return TRUE;
500 }
501
502 static void test_enum_providers(void)
503 {
504 /* expected results */
505 CHAR *pszProvName = NULL;
506 DWORD cbName;
507 DWORD dwType;
508 DWORD provCount;
509 DWORD dwIndex = 0;
510
511 /* actual results */
512 CHAR *provider = NULL;
513 DWORD providerLen;
514 DWORD type;
515 DWORD count;
516 DWORD result;
517 DWORD notNull = 5;
518 DWORD notZeroFlags = 5;
519
520 if(!pCryptEnumProvidersA)
521 {
522 win_skip("CryptEnumProvidersA is not available\n");
523 return;
524 }
525
526 if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))
527 {
528 win_skip("Could not find providers in registry\n");
529 return;
530 }
531
532 /* check pdwReserved flag for NULL */
533 result = pCryptEnumProvidersA(dwIndex, &notNull, 0, &type, NULL, &providerLen);
534 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
535
536 /* check dwFlags == 0 */
537 result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);
538 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d\n", GetLastError());
539
540 /* alloc provider to half the size required
541 * cbName holds the size required */
542 providerLen = cbName / 2;
543 if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
544 return;
545
546 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
547 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
548 ERROR_MORE_DATA, GetLastError());
549
550 LocalFree(provider);
551
552 /* loop through the providers to get the number of providers
553 * after loop ends, count should be provCount + 1 so subtract 1
554 * to get actual number of providers */
555 count = 0;
556 while(pCryptEnumProvidersA(count++, NULL, 0, &type, NULL, &providerLen))
557 ;
558 count--;
559 ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);
560
561 /* loop past the actual number of providers to get the error
562 * ERROR_NO_MORE_ITEMS */
563 for (count = 0; count < provCount + 1; count++)
564 result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen);
565 ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n",
566 ERROR_NO_MORE_ITEMS, GetLastError());
567
568 /* check expected versus actual values returned */
569 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, NULL, &providerLen);
570 ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);
571 if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
572 return;
573
574 providerLen = -1;
575 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
576 ok(result, "expected TRUE, got %d\n", result);
577 ok(type==dwType, "expected %d, got %d\n", dwType, type);
578 if (pszProvName)
579 ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
580 ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
581
582 providerLen = -1000;
583 provider[0] = 0;
584 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
585 ok(result, "expected TRUE, got %d\n", result);
586 ok(type==dwType, "expected %d, got %d\n", dwType, type);
587 if (pszProvName)
588 ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
589 ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
590
591 LocalFree(pszProvName);
592 LocalFree(provider);
593 }
594
595 static BOOL FindProvTypesRegVals(DWORD *pdwIndex, DWORD *pdwProvType, LPSTR *pszTypeName,
596 DWORD *pcbTypeName, DWORD *pdwTypeCount)
597 {
598 HKEY hKey;
599 HKEY hSubKey;
600 PSTR ch;
601 LPSTR szName;
602 DWORD cbName;
603 BOOL ret = FALSE;
604
605 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
606 return FALSE;
607
608 if (RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pdwTypeCount, &cbName, NULL,
609 NULL, NULL, NULL, NULL, NULL))
610 goto cleanup;
611 cbName++;
612
613 if (!(szName = LocalAlloc(LMEM_ZEROINIT, cbName)))
614 goto cleanup;
615
616 while (!RegEnumKeyExA(hKey, *pdwIndex, szName, &cbName, NULL, NULL, NULL, NULL))
617 {
618 cbName++;
619 ch = szName + strlen(szName);
620 /* Convert "Type 000" to 0, etc/ */
621 *pdwProvType = *(--ch) - '0';
622 *pdwProvType += (*(--ch) - '0') * 10;
623 *pdwProvType += (*(--ch) - '0') * 100;
624
625 if (RegOpenKeyA(hKey, szName, &hSubKey))
626 break;
627
628 if (!RegQueryValueExA(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
629 {
630 if (!(*pszTypeName = LocalAlloc(LMEM_ZEROINIT, *pcbTypeName)))
631 break;
632
633 if (!RegQueryValueExA(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
634 {
635 ret = TRUE;
636 break;
637 }
638
639 LocalFree(*pszTypeName);
640 }
641
642 RegCloseKey(hSubKey);
643
644 (*pdwIndex)++;
645 }
646 RegCloseKey(hSubKey);
647 LocalFree(szName);
648
649 cleanup:
650 RegCloseKey(hKey);
651
652 return ret;
653 }
654
655 static void test_enum_provider_types(void)
656 {
657 /* expected values */
658 DWORD dwProvType = 0;
659 LPSTR pszTypeName = NULL;
660 DWORD cbTypeName;
661 DWORD dwTypeCount;
662
663 /* actual values */
664 DWORD index = 0;
665 DWORD provType;
666 LPSTR typeName = NULL;
667 DWORD typeNameSize;
668 DWORD typeCount;
669 DWORD result;
670 DWORD notNull = 5;
671 DWORD notZeroFlags = 5;
672
673 if(!pCryptEnumProviderTypesA)
674 {
675 win_skip("CryptEnumProviderTypesA is not available\n");
676 return;
677 }
678
679 if (!FindProvTypesRegVals(&index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
680 {
681 skip("Could not find provider types in registry\n");
682 return;
683 }
684
685 /* check pdwReserved for NULL */
686 result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
687 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n",
688 GetLastError());
689
690 /* check dwFlags == zero */
691 result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
692 ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected ERROR_INVALID_PARAMETER, got %d\n",
693 GetLastError());
694
695 /* This test fails under Win2k SP4:
696 * result = TRUE, GetLastError() == 0xdeadbeef */
697 if (0)
698 {
699 /* alloc provider type to half the size required
700 * cbTypeName holds the size required */
701 typeNameSize = cbTypeName / 2;
702 if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
703 goto cleanup;
704
705 SetLastError(0xdeadbeef);
706 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
707 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%d\n",
708 result, GetLastError());
709
710 LocalFree(typeName);
711 }
712
713 /* loop through the provider types to get the number of provider types
714 * after loop ends, count should be dwTypeCount + 1 so subtract 1
715 * to get actual number of provider types */
716 typeCount = 0;
717 while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))
718 ;
719 typeCount--;
720 ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);
721
722 /* loop past the actual number of provider types to get the error
723 * ERROR_NO_MORE_ITEMS */
724 for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
725 result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
726 ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n",
727 GetLastError());
728
729 /* check expected versus actual values returned */
730 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
731 ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
732 if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
733 goto cleanup;
734
735 typeNameSize = 0xdeadbeef;
736 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
737 ok(result, "expected TRUE, got %d\n", result);
738 ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
739 if (pszTypeName)
740 ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
741 ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
742
743 LocalFree(typeName);
744 cleanup:
745 LocalFree(pszTypeName);
746 }
747
748 static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
749 {
750 HKEY hKey;
751 PSTR keyname;
752 PSTR ptr;
753 DWORD user = dwFlags & CRYPT_USER_DEFAULT;
754
755 LPCSTR machinestr = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
756 LPCSTR userstr = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
757
758 keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(userstr) : strlen(machinestr)) + 1);
759 if (keyname)
760 {
761 user ? strcpy(keyname, userstr) : strcpy(keyname, machinestr);
762 ptr = keyname + strlen(keyname);
763 *(--ptr) = (dwProvType % 10) + '0';
764 *(--ptr) = ((dwProvType / 10) % 10) + '0';
765 *(--ptr) = (dwProvType / 100) + '0';
766 } else
767 return FALSE;
768
769 if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
770 {
771 LocalFree(keyname);
772 return FALSE;
773 }
774 LocalFree(keyname);
775
776 if (RegQueryValueExA(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
777 {
778 if (GetLastError() != ERROR_MORE_DATA)
779 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
780 return FALSE;
781 }
782
783 if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
784 return FALSE;
785
786 if (RegQueryValueExA(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
787 {
788 if (GetLastError() != ERROR_MORE_DATA)
789 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
790 return FALSE;
791 }
792
793 RegCloseKey(hKey);
794
795 return TRUE;
796 }
797
798 static void test_get_default_provider(void)
799 {
800 /* expected results */
801 DWORD dwProvType = PROV_RSA_FULL;
802 DWORD dwFlags = CRYPT_MACHINE_DEFAULT;
803 LPSTR pszProvName = NULL;
804 DWORD cbProvName;
805
806 /* actual results */
807 DWORD provType = PROV_RSA_FULL;
808 DWORD flags = CRYPT_MACHINE_DEFAULT;
809 LPSTR provName = NULL;
810 DWORD provNameSize;
811 DWORD result;
812 DWORD notNull = 5;
813
814 if(!pCryptGetDefaultProviderA)
815 {
816 win_skip("CryptGetDefaultProviderA is not available\n");
817 return;
818 }
819
820 if(!FindDfltProvRegVals(dwProvType, dwFlags, &pszProvName, &cbProvName))
821 {
822 skip("Could not find default provider in registry\n");
823 return;
824 }
825
826 /* check pdwReserved for NULL */
827 result = pCryptGetDefaultProviderA(provType, &notNull, flags, provName, &provNameSize);
828 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
829 ERROR_INVALID_PARAMETER, GetLastError());
830
831 /* check for invalid flag */
832 flags = 0xdeadbeef;
833 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
834 ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %d, got %d\n",
835 NTE_BAD_FLAGS, GetLastError());
836 flags = CRYPT_MACHINE_DEFAULT;
837
838 /* check for invalid prov type */
839 provType = 0xdeadbeef;
840 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
841 ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE ||
842 GetLastError() == ERROR_INVALID_PARAMETER),
843 "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n",
844 result, GetLastError());
845 provType = PROV_RSA_FULL;
846
847 SetLastError(0);
848
849 /* alloc provName to half the size required
850 * cbProvName holds the size required */
851 provNameSize = cbProvName / 2;
852 if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
853 return;
854
855 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
856 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
857 ERROR_MORE_DATA, GetLastError());
858
859 LocalFree(provName);
860
861 /* check expected versus actual values returned */
862 result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize);
863 ok(result && provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
864 provNameSize = cbProvName;
865
866 if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
867 return;
868
869 provNameSize = 0xdeadbeef;
870 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
871 ok(result, "expected TRUE, got %d\n", result);
872 if(pszProvName)
873 ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName);
874 ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
875
876 LocalFree(pszProvName);
877 LocalFree(provName);
878 }
879
880 static void test_set_provider_ex(void)
881 {
882 DWORD result;
883 DWORD notNull = 5;
884 LPSTR curProvName = NULL;
885 DWORD curlen;
886
887 /* results */
888 LPSTR pszProvName = NULL;
889 DWORD cbProvName;
890
891 if(!pCryptGetDefaultProviderA || !pCryptSetProviderExA)
892 {
893 win_skip("CryptGetDefaultProviderA and/or CryptSetProviderExA are not available\n");
894 return;
895 }
896
897 /* store the current one */
898 pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &curlen);
899 if (!(curProvName = LocalAlloc(LMEM_ZEROINIT, curlen)))
900 return;
901 result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, curProvName, &curlen);
902 ok(result, "%d\n", GetLastError());
903
904 /* check pdwReserved for NULL */
905 result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);
906 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
907 ERROR_INVALID_PARAMETER, GetLastError());
908
909 /* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */
910 SetLastError(0xdeadbeef);
911 result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT | CRYPT_DELETE_DEFAULT);
912 if (!result)
913 {
914 ok( GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == ERROR_INVALID_PARAMETER),
915 "wrong error %u\n", GetLastError() );
916 skip("Not enough rights to remove the default provider\n");
917 LocalFree(curProvName);
918 return;
919 }
920
921 result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
922 ok(result, "%d\n", GetLastError());
923
924 /* call CryptGetDefaultProvider to see if they match */
925 result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);
926 ok(result, "%d\n", GetLastError());
927 if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))
928 goto reset;
929
930 result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);
931 ok(result && !strcmp(MS_DEF_PROV_A, pszProvName), "expected %s, got %s\n", MS_DEF_PROV_A, pszProvName);
932 ok(result && cbProvName==(strlen(MS_DEF_PROV_A) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV_A) + 1), cbProvName);
933
934 LocalFree(pszProvName);
935
936 reset:
937 /* Set the provider back to its original */
938 result = pCryptSetProviderExA(curProvName, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
939 ok(result, "%d\n", GetLastError());
940 LocalFree(curProvName);
941 }
942
943 static void test_machine_guid(void)
944 {
945 char originalGuid[40];
946 LONG r;
947 HKEY key;
948 DWORD size;
949 HCRYPTPROV hCryptProv;
950 BOOL restoreGuid = FALSE, ret;
951
952 r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography",
953 0, KEY_ALL_ACCESS, &key);
954 if (r != ERROR_SUCCESS)
955 {
956 skip("couldn't open HKLM\\Software\\Microsoft\\Cryptography\n");
957 return;
958 }
959 /* Cache existing MachineGuid, and delete it */
960 size = sizeof(originalGuid);
961 r = RegQueryValueExA(key, "MachineGuid", NULL, NULL, (BYTE *)originalGuid,
962 &size);
963 if (r == ERROR_SUCCESS)
964 {
965 restoreGuid = TRUE;
966 r = RegDeleteValueA(key, "MachineGuid");
967 ok(!r || broken(r == ERROR_ACCESS_DENIED) /*win8*/, "RegDeleteValueA failed: %d\n", r);
968 if (r == ERROR_ACCESS_DENIED)
969 {
970 skip("broken virtualization on HKLM\\Software\\Microsoft\\Cryptography\n");
971 RegCloseKey(key);
972 return;
973 }
974 }
975 else
976 ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n",
977 r);
978 /* Create and release a provider */
979 ret = pCryptAcquireContextA(&hCryptProv, szKeySet, NULL, PROV_RSA_FULL, 0);
980 ok(ret || broken(!ret && GetLastError() == NTE_KEYSET_ENTRY_BAD /* NT4 */),
981 "CryptAcquireContextA failed: %08x\n", GetLastError());
982 pCryptReleaseContext(hCryptProv, 0);
983
984 if (restoreGuid)
985 RegSetValueExA(key, "MachineGuid", 0, REG_SZ, (const BYTE *)originalGuid,
986 strlen(originalGuid)+1);
987 RegCloseKey(key);
988 }
989
990 #define key_length 16
991
992 static const unsigned char key[key_length] =
993 { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
994 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
995
996 static void test_rc2_keylen(void)
997 {
998 struct KeyBlob
999 {
1000 BLOBHEADER header;
1001 DWORD key_size;
1002 BYTE key_data[2048];
1003 } key_blob;
1004
1005 HCRYPTPROV provider;
1006 HCRYPTKEY hkey = 0;
1007 BOOL ret;
1008
1009 SetLastError(0xdeadbeef);
1010 ret = pCryptAcquireContextA(&provider, NULL, NULL,
1011 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1012 ok(ret, "CryptAcquireContext error %u\n", GetLastError());
1013 if (ret)
1014 {
1015 key_blob.header.bType = PLAINTEXTKEYBLOB;
1016 key_blob.header.bVersion = CUR_BLOB_VERSION;
1017 key_blob.header.reserved = 0;
1018 key_blob.header.aiKeyAlg = CALG_RC2;
1019 key_blob.key_size = sizeof(key);
1020 memcpy(key_blob.key_data, key, key_length);
1021
1022 /* Importing a 16-byte key works with the default provider. */
1023 SetLastError(0xdeadbeef);
1024 ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1025 sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1026 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1027 /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
1028 ok(ret ||
1029 broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1030 "CryptImportKey error %08x\n", GetLastError());
1031
1032 if (ret)
1033 pCryptDestroyKey(hkey);
1034 pCryptReleaseContext(provider, 0);
1035 }
1036
1037 SetLastError(0xdeadbeef);
1038 ret = pCryptAcquireContextA(&provider, NULL, MS_DEF_PROV_A,
1039 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1040 ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
1041
1042 if (ret)
1043 {
1044 /* Importing a 16-byte key doesn't work with the base provider.. */
1045 SetLastError(0xdeadbeef);
1046 ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1047 sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1048 0, 0, &hkey);
1049 ok(!ret && (GetLastError() == NTE_BAD_DATA ||
1050 GetLastError() == NTE_BAD_LEN || /* Win7 */
1051 GetLastError() == NTE_BAD_TYPE || /* W2K */
1052 GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
1053 "unexpected error %08x\n", GetLastError());
1054 /* but importing an 56-bit (7-byte) key does.. */
1055 key_blob.key_size = 7;
1056 SetLastError(0xdeadbeef);
1057 ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1058 sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1059 0, 0, &hkey);
1060 ok(ret ||
1061 broken(!ret && GetLastError() == NTE_BAD_TYPE) || /* W2K */
1062 broken(!ret && GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
1063 "CryptAcquireContext error %08x\n", GetLastError());
1064 if (ret)
1065 pCryptDestroyKey(hkey);
1066 /* as does importing a 16-byte key with the base provider when
1067 * CRYPT_IPSEC_HMAC_KEY is specified.
1068 */
1069 key_blob.key_size = sizeof(key);
1070 SetLastError(0xdeadbeef);
1071 ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1072 sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1073 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1074 /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
1075 ok(ret ||
1076 broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1077 "CryptImportKey error %08x\n", GetLastError());
1078 if (ret)
1079 pCryptDestroyKey(hkey);
1080
1081 pCryptReleaseContext(provider, 0);
1082 }
1083
1084 key_blob.key_size = sizeof(key);
1085 SetLastError(0xdeadbeef);
1086 ret = pCryptAcquireContextA(&provider, NULL, NULL,
1087 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1088 ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
1089
1090 if (ret)
1091 {
1092 /* Importing a 16-byte key also works with the default provider when
1093 * CRYPT_IPSEC_HMAC_KEY is specified.
1094 */
1095 SetLastError(0xdeadbeef);
1096 ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1097 sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1098 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1099 ok(ret ||
1100 broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1101 "CryptImportKey error %08x\n", GetLastError());
1102 if (ret)
1103 pCryptDestroyKey(hkey);
1104
1105 /* There is no apparent limit to the size of the input key when
1106 * CRYPT_IPSEC_HMAC_KEY is specified.
1107 */
1108 key_blob.key_size = sizeof(key_blob.key_data);
1109 SetLastError(0xdeadbeef);
1110 ret = pCryptImportKey(provider, (BYTE*)&key_blob,
1111 sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
1112 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
1113 ok(ret ||
1114 broken(!ret && GetLastError() == NTE_BAD_FLAGS),
1115 "CryptImportKey error %08x\n", GetLastError());
1116 if (ret)
1117 pCryptDestroyKey(hkey);
1118
1119 pCryptReleaseContext(provider, 0);
1120 }
1121 }
1122
1123 static void test_SystemFunction036(void)
1124 {
1125 BOOL ret;
1126 int test;
1127
1128 if (!pSystemFunction036)
1129 {
1130 win_skip("SystemFunction036 is not available\n");
1131 return;
1132 }
1133
1134 ret = pSystemFunction036(NULL, 0);
1135 ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1136
1137 /* Test crashes on Windows. */
1138 if (0)
1139 {
1140 SetLastError(0xdeadbeef);
1141 ret = pSystemFunction036(NULL, 5);
1142 trace("ret = %d, GetLastError() = %d\n", ret, GetLastError());
1143 }
1144
1145 ret = pSystemFunction036(&test, 0);
1146 ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1147
1148 ret = pSystemFunction036(&test, sizeof(int));
1149 ok(ret == TRUE, "Expected SystemFunction036 to return TRUE, got %d\n", ret);
1150 }
1151
1152 static void test_container_sd(void)
1153 {
1154 HCRYPTPROV prov;
1155 SECURITY_DESCRIPTOR *sd;
1156 DWORD len, err;
1157 BOOL ret;
1158
1159 ret = CryptAcquireContextA(&prov, "winetest", "Microsoft Enhanced Cryptographic Provider v1.0",
1160 PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET);
1161 ok(ret, "got %u\n", GetLastError());
1162
1163 len = 0;
1164 SetLastError(0xdeadbeef);
1165 ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, NULL, &len, OWNER_SECURITY_INFORMATION);
1166 err = GetLastError();
1167 ok(ret, "got %u\n", err);
1168 ok(err == ERROR_INSUFFICIENT_BUFFER || broken(err == ERROR_INVALID_PARAMETER), "got %u\n", err);
1169 ok(len, "expected len > 0\n");
1170
1171 sd = HeapAlloc(GetProcessHeap(), 0, len);
1172 ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, (BYTE *)sd, &len, OWNER_SECURITY_INFORMATION);
1173 ok(ret, "got %u\n", GetLastError());
1174 HeapFree(GetProcessHeap(), 0, sd);
1175
1176 ret = CryptReleaseContext(prov, 0);
1177 ok(ret, "got %u\n", GetLastError());
1178
1179 ret = CryptAcquireContextA(&prov, "winetest", "Microsoft Enhanced Cryptographic Provider v1.0",
1180 PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_DELETEKEYSET);
1181 ok(ret, "got %u\n", GetLastError());
1182 }
1183
1184 START_TEST(crypt)
1185 {
1186 init_function_pointers();
1187 if (pCryptAcquireContextA && pCryptReleaseContext)
1188 {
1189 test_rc2_keylen();
1190 init_environment();
1191 test_acquire_context();
1192 test_incorrect_api_usage();
1193 test_verify_sig();
1194 test_machine_guid();
1195 test_container_sd();
1196 clean_up_environment();
1197 }
1198
1199 test_enum_providers();
1200 test_enum_provider_types();
1201 test_get_default_provider();
1202 test_set_provider_ex();
1203 test_SystemFunction036();
1204 }