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