push 50b650a476c6f0df362ce67f063848f086de44d9
[wine/hacks.git] / dlls / advapi32 / tests / crypt.c
blob9fa532cb1d09f29f7732cb6a17015392a403c8dc
1 /*
2 * Unit tests for crypt functions
4 * Copyright (c) 2004 Michael Jung
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.
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.
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
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wincrypt.h"
26 #include "winerror.h"
27 #include "winreg.h"
29 #include "wine/test.h"
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
37 static HMODULE hadvapi32;
38 static BOOL (WINAPI *pCryptAcquireContextA)(HCRYPTPROV*,LPCSTR,LPCSTR,DWORD,DWORD);
39 static BOOL (WINAPI *pCryptEnumProviderTypesA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
40 static BOOL (WINAPI *pCryptEnumProvidersA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);
41 static BOOL (WINAPI *pCryptGetDefaultProviderA)(DWORD, DWORD*, DWORD, LPSTR, DWORD*);
42 static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV, DWORD);
43 static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD);
44 static BOOL (WINAPI *pCryptCreateHash)(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*);
45 static BOOL (WINAPI *pCryptDestroyHash)(HCRYPTHASH);
46 static BOOL (WINAPI *pCryptGenRandom)(HCRYPTPROV, DWORD, BYTE*);
47 static BOOL (WINAPI *pCryptContextAddRef)(HCRYPTPROV, DWORD*, DWORD dwFlags);
48 static BOOL (WINAPI *pCryptGenKey)(HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY*);
49 static BOOL (WINAPI *pCryptDestroyKey)(HCRYPTKEY);
50 static BOOL (WINAPI *pCryptDecrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*);
51 static BOOL (WINAPI *pCryptDeriveKey)(HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY*);
52 static BOOL (WINAPI *pCryptDuplicateHash)(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*);
53 static BOOL (WINAPI *pCryptDuplicateKey)(HCRYPTKEY, DWORD*, DWORD, HCRYPTKEY*);
54 static BOOL (WINAPI *pCryptEncrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*, DWORD);
55 static BOOL (WINAPI *pCryptExportKey)(HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, BYTE*, DWORD*);
56 static BOOL (WINAPI *pCryptGetHashParam)(HCRYPTHASH, DWORD, BYTE*, DWORD*, DWORD);
57 static BOOL (WINAPI *pCryptGetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD*, DWORD);
58 static BOOL (WINAPI *pCryptGetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD*, DWORD);
59 static BOOL (WINAPI *pCryptGetUserKey)(HCRYPTPROV, DWORD, HCRYPTKEY*);
60 static BOOL (WINAPI *pCryptHashData)(HCRYPTHASH, BYTE*, DWORD, DWORD);
61 static BOOL (WINAPI *pCryptHashSessionKey)(HCRYPTHASH, HCRYPTKEY, DWORD);
62 static BOOL (WINAPI *pCryptImportKey)(HCRYPTPROV, BYTE*, DWORD, HCRYPTKEY, DWORD, HCRYPTKEY*);
63 static BOOL (WINAPI *pCryptSignHashW)(HCRYPTHASH, DWORD, LPCWSTR, DWORD, BYTE*, DWORD*);
64 static BOOL (WINAPI *pCryptSetHashParam)(HCRYPTKEY, DWORD, BYTE*, DWORD);
65 static BOOL (WINAPI *pCryptSetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD);
66 static BOOL (WINAPI *pCryptSetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD);
67 static BOOL (WINAPI *pCryptVerifySignatureW)(HCRYPTHASH, BYTE*, DWORD, HCRYPTKEY, LPCWSTR, DWORD);
69 static void init_function_pointers(void)
71 hadvapi32 = GetModuleHandleA("advapi32.dll");
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");
105 static void init_environment(void)
107 HCRYPTPROV hProv;
109 /* Ensure that container "wine_test_keyset" does exist */
110 if (!pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
112 pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET);
114 pCryptReleaseContext(hProv, 0);
116 /* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */
117 if (!pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
119 pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
121 pCryptReleaseContext(hProv, 0);
123 /* Ensure that container "wine_test_bad_keyset" does not exist. */
124 if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
126 pCryptReleaseContext(hProv, 0);
127 pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
131 static void clean_up_environment(void)
133 HCRYPTPROV hProv;
135 /* Remove container "wine_test_keyset" */
136 if (pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
138 pCryptReleaseContext(hProv, 0);
139 pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
142 /* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */
143 if (pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
145 pCryptReleaseContext(hProv, 0);
146 pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
150 static void test_acquire_context(void)
152 BOOL result;
153 HCRYPTPROV hProv;
154 DWORD GLE;
156 /* Provoke all kinds of error conditions (which are easy to provoke).
157 * The order of the error tests seems to match Windows XP's rsaenh.dll CSP,
158 * but since this is likely to change between CSP versions, we don't check
159 * this. Please don't change the order of tests. */
160 result = pCryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
161 ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
163 result = pCryptAcquireContextA(&hProv, NULL, NULL, 1000, 0);
164 ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
166 result = pCryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0);
167 ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%d\n", GetLastError());
169 result = pCryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0);
170 ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%d\n", GetLastError());
172 result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0);
173 ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%d\n", GetLastError());
175 /* This test fails under Win2k SP4:
176 result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER
177 SetLastError(0xdeadbeef);
178 result = pCryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
179 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%d\n", result, GetLastError());
182 /* Last not least, try to really acquire a context. */
183 hProv = 0;
184 SetLastError(0xdeadbeef);
185 result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
186 GLE = GetLastError();
187 ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND ||
188 GLE == ERROR_SUCCESS ||
189 GLE == ERROR_RING2_STACK_IN_USE ||
190 GLE == NTE_FAIL ||
191 GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GLE);
193 if (hProv)
194 pCryptReleaseContext(hProv, 0);
196 /* Try again, witch an empty ("\0") szProvider parameter */
197 hProv = 0;
198 SetLastError(0xdeadbeef);
199 result = pCryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0);
200 GLE = GetLastError();
201 ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND ||
202 GLE == ERROR_SUCCESS ||
203 GLE == ERROR_RING2_STACK_IN_USE ||
204 GLE == NTE_FAIL ||
205 GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GetLastError());
207 if (hProv)
208 pCryptReleaseContext(hProv, 0);
211 static void test_incorrect_api_usage(void)
213 BOOL result;
214 HCRYPTPROV hProv, hProv2;
215 HCRYPTHASH hHash, hHash2;
216 HCRYPTKEY hKey, hKey2;
217 BYTE temp;
218 DWORD dwLen, dwTemp;
220 /* This is to document incorrect api usage in the
221 * "Uru - Ages beyond Myst Demo" installer as reported by Paul Vriens.
223 * The installer destroys a hash object after having released the context
224 * with which the hash was created. This is not allowed according to MSDN,
225 * since CryptReleaseContext destroys all hash and key objects belonging to
226 * the respective context. However, while wine used to crash, Windows is more
227 * robust here and returns an ERROR_INVALID_PARAMETER code.
230 result = pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv,
231 PROV_RSA_FULL, CRYPT_NEWKEYSET);
232 ok (result, "%08x\n", GetLastError());
233 if (!result) return;
235 result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
236 ok (result, "%d\n", GetLastError());
237 if (!result) return;
239 result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey);
240 ok (result, "%d\n", GetLastError());
241 if (!result) return;
243 result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
244 ok (result, "%d\n", GetLastError());
245 if (!result) return;
247 result = pCryptDestroyKey(hKey2);
248 ok (result, "%d\n", GetLastError());
250 dwTemp = CRYPT_MODE_ECB;
251 result = pCryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD));
252 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
254 result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL,
255 CRYPT_DELETEKEYSET);
256 ok (result, "%d\n", GetLastError());
257 if (!result) return;
259 result = pCryptReleaseContext(hProv, 0);
260 ok (result, "%d\n", GetLastError());
261 if (!result) return;
263 result = pCryptReleaseContext(hProv, 0);
264 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
266 result = pCryptGenRandom(hProv, 1, &temp);
267 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
269 #ifdef CRASHES_ON_NT40
270 result = pCryptContextAddRef(hProv, NULL, 0);
271 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
272 #endif
274 result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
275 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
277 dwLen = 1;
278 result = pCryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen);
279 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
281 dwLen = 1;
282 result = pCryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen, 1);
283 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
285 result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2);
286 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
288 #ifdef CRASHES_ON_NT40
289 result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2);
290 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
292 result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2);
293 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
294 #endif
296 dwLen = 1;
297 result = pCryptExportKey(hKey, (HCRYPTPROV)NULL, 0, 0, &temp, &dwLen);
298 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
300 result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
301 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
303 dwLen = 1;
304 result = pCryptGetHashParam(hHash, 0, &temp, &dwLen, 0);
305 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
307 dwLen = 1;
308 result = pCryptGetKeyParam(hKey, 0, &temp, &dwLen, 0);
309 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
311 dwLen = 1;
312 result = pCryptGetProvParam(hProv, 0, &temp, &dwLen, 0);
313 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
315 result = pCryptGetUserKey(hProv, 0, &hKey2);
316 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
318 result = pCryptHashData(hHash, &temp, 1, 0);
319 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
321 result = pCryptHashSessionKey(hHash, hKey, 0);
322 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
324 result = pCryptImportKey(hProv, &temp, 1, (HCRYPTKEY)NULL, 0, &hKey2);
325 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
327 dwLen = 1;
328 result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen);
329 ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
330 GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
332 result = pCryptSetKeyParam(hKey, 0, &temp, 1);
333 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
335 result = pCryptSetHashParam(hHash, 0, &temp, 1);
336 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
338 result = pCryptSetProvParam(hProv, 0, &temp, 1);
339 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
341 result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0);
342 ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
343 GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
345 result = pCryptDestroyHash(hHash);
346 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
348 result = pCryptDestroyKey(hKey);
349 ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
352 static const BYTE privKey[] = {
353 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
354 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
355 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
356 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
357 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
358 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
359 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
360 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
361 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
362 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
363 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
364 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
365 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
366 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
367 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
368 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
369 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
370 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
371 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
372 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
373 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
374 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
375 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
376 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
378 static void test_verify_sig(void)
380 BOOL ret;
381 HCRYPTPROV prov;
382 HCRYPTKEY key;
383 HCRYPTHASH hash;
384 BYTE bogus[] = { 0 };
386 SetLastError(0xdeadbeef);
387 ret = pCryptVerifySignatureW(0, NULL, 0, 0, NULL, 0);
388 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
389 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
390 ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL,
391 CRYPT_NEWKEYSET);
392 if (!ret && GetLastError() == NTE_EXISTS)
393 ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0);
394 ret = pCryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key);
395 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
396 ret = pCryptCreateHash(prov, CALG_MD5, 0, 0, &hash);
397 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
398 SetLastError(0xdeadbeef);
399 ret = pCryptVerifySignatureW(hash, NULL, 0, 0, NULL, 0);
400 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
401 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
402 SetLastError(0xdeadbeef);
403 ret = pCryptVerifySignatureW(0, NULL, 0, key, NULL, 0);
404 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
405 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
406 SetLastError(0xdeadbeef);
407 ret = pCryptVerifySignatureW(hash, NULL, 0, key, NULL, 0);
408 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
409 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
410 SetLastError(0xdeadbeef);
411 ret = pCryptVerifySignatureW(hash, NULL, sizeof(bogus), key, NULL, 0);
412 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
413 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
414 SetLastError(0xdeadbeef);
415 ret = pCryptVerifySignatureW(hash, bogus, 0, key, NULL, 0);
416 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
417 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
418 SetLastError(0xdeadbeef);
419 ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
420 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
421 "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
422 pCryptDestroyKey(key);
423 pCryptDestroyHash(hash);
424 pCryptReleaseContext(prov, 0);
427 static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName,
428 DWORD *pcbProvName, DWORD *pdwProvCount)
430 HKEY hKey;
431 HKEY subkey;
432 DWORD size = sizeof(DWORD);
434 if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))
435 return FALSE;
437 RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName,
438 NULL, NULL, NULL, NULL, NULL, NULL);
439 (*pcbProvName)++;
441 if (!(*pszProvName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbProvName))))
442 return FALSE;
444 RegEnumKeyEx(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
445 (*pcbProvName)++;
447 RegOpenKey(hKey, *pszProvName, &subkey);
448 RegQueryValueEx(subkey, "Type", NULL, NULL, (LPBYTE)pdwProvType, &size);
450 RegCloseKey(subkey);
451 RegCloseKey(hKey);
453 return TRUE;
456 static void test_enum_providers(void)
458 /* expected results */
459 CHAR *pszProvName = NULL;
460 DWORD cbName;
461 DWORD dwType;
462 DWORD provCount;
463 DWORD dwIndex = 0;
465 /* actual results */
466 CHAR *provider = NULL;
467 DWORD providerLen;
468 DWORD type;
469 DWORD count;
470 DWORD result;
471 DWORD notNull = 5;
472 DWORD notZeroFlags = 5;
474 if(!pCryptEnumProvidersA)
476 skip("CryptEnumProvidersA is not available\n");
477 return;
480 if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))
482 skip("Could not find providers in registry\n");
483 return;
486 /* check pdwReserved flag for NULL */
487 result = pCryptEnumProvidersA(dwIndex, &notNull, 0, &type, NULL, &providerLen);
488 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
490 /* check dwFlags == 0 */
491 result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);
492 ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d\n", GetLastError());
494 /* alloc provider to half the size required
495 * cbName holds the size required */
496 providerLen = cbName / 2;
497 if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))
498 return;
500 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
501 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
502 ERROR_MORE_DATA, GetLastError());
504 LocalFree(provider);
506 /* loop through the providers to get the number of providers
507 * after loop ends, count should be provCount + 1 so subtract 1
508 * to get actual number of providers */
509 count = 0;
510 while(pCryptEnumProvidersA(count++, NULL, 0, &type, NULL, &providerLen))
512 count--;
513 ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);
515 /* loop past the actual number of providers to get the error
516 * ERROR_NO_MORE_ITEMS */
517 for (count = 0; count < provCount + 1; count++)
518 result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen);
519 ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n",
520 ERROR_NO_MORE_ITEMS, GetLastError());
522 /* check expected versus actual values returned */
523 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, NULL, &providerLen);
524 ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);
525 if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))
526 return;
528 providerLen = 0xdeadbeef;
529 result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
530 ok(result, "expected TRUE, got %d\n", result);
531 ok(type==dwType, "expected %d, got %d\n", dwType, type);
532 if (pszProvName)
533 ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
534 ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
536 LocalFree(provider);
539 static BOOL FindProvTypesRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszTypeName,
540 DWORD *pcbTypeName, DWORD *pdwTypeCount)
542 HKEY hKey;
543 HKEY hSubKey;
544 PSTR ch;
546 if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
547 return FALSE;
549 if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, pcbTypeName, NULL,
550 NULL, NULL, NULL, NULL, NULL))
551 return FALSE;
552 (*pcbTypeName)++;
554 if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
555 return FALSE;
557 if (RegEnumKeyEx(hKey, dwIndex, *pszTypeName, pcbTypeName, NULL, NULL, NULL, NULL))
558 return FALSE;
559 (*pcbTypeName)++;
560 ch = *pszTypeName + strlen(*pszTypeName);
561 /* Convert "Type 000" to 0, etc/ */
562 *pdwProvType = *(--ch) - '0';
563 *pdwProvType += (*(--ch) - '0') * 10;
564 *pdwProvType += (*(--ch) - '0') * 100;
566 if (RegOpenKey(hKey, *pszTypeName, &hSubKey))
567 return FALSE;
569 if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
570 return FALSE;
572 if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
573 return FALSE;
575 if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
576 return FALSE;
578 RegCloseKey(hSubKey);
579 RegCloseKey(hKey);
581 return TRUE;
584 static void test_enum_provider_types(void)
586 /* expected values */
587 DWORD dwProvType;
588 LPSTR pszTypeName = NULL;
589 DWORD cbTypeName;
590 DWORD dwTypeCount;
592 /* actual values */
593 DWORD index = 0;
594 DWORD provType;
595 LPSTR typeName = NULL;
596 DWORD typeNameSize;
597 DWORD typeCount;
598 DWORD result;
599 DWORD notNull = 5;
600 DWORD notZeroFlags = 5;
602 if(!pCryptEnumProviderTypesA)
604 skip("CryptEnumProviderTypesA is not available\n");
605 return;
608 if (!FindProvTypesRegVals(index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
610 skip("Could not find provider types in registry\n");
611 return;
614 /* check pdwReserved for NULL */
615 result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
616 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
617 ERROR_INVALID_PARAMETER, GetLastError());
619 /* check dwFlags == zero */
620 result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
621 ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %i, got %d\n",
622 ERROR_INVALID_PARAMETER, GetLastError());
624 /* alloc provider type to half the size required
625 * cbTypeName holds the size required */
626 typeNameSize = cbTypeName / 2;
627 if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
628 return;
630 /* This test fails under Win2k SP4:
631 result = TRUE, GetLastError() == 0xdeadbeef
632 SetLastError(0xdeadbeef);
633 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
634 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%08lx\n",
635 result, GetLastError());
638 LocalFree(typeName);
640 /* loop through the provider types to get the number of provider types
641 * after loop ends, count should be dwTypeCount + 1 so subtract 1
642 * to get actual number of provider types */
643 typeCount = 0;
644 while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))
646 typeCount--;
647 ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);
649 /* loop past the actual number of provider types to get the error
650 * ERROR_NO_MORE_ITEMS */
651 for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
652 result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
653 ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n",
654 ERROR_NO_MORE_ITEMS, GetLastError());
657 /* check expected versus actual values returned */
658 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
659 ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
660 if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
661 return;
663 typeNameSize = 0xdeadbeef;
664 result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
665 ok(result, "expected TRUE, got %d\n", result);
666 ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
667 if (pszTypeName)
668 ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
669 ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
671 LocalFree(typeName);
674 static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
676 HKEY hKey;
677 PSTR keyname;
678 PSTR ptr;
679 DWORD user = dwFlags & CRYPT_USER_DEFAULT;
681 LPCSTR machinestr = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
682 LPCSTR userstr = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
684 keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(userstr) : strlen(machinestr)) + 1);
685 if (keyname)
687 user ? strcpy(keyname, userstr) : strcpy(keyname, machinestr);
688 ptr = keyname + strlen(keyname);
689 *(--ptr) = (dwProvType % 10) + '0';
690 *(--ptr) = ((dwProvType / 10) % 10) + '0';
691 *(--ptr) = (dwProvType / 100) + '0';
692 } else
693 return FALSE;
695 if (RegOpenKey((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
697 LocalFree(keyname);
698 return FALSE;
700 LocalFree(keyname);
702 if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
704 if (GetLastError() != ERROR_MORE_DATA)
705 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
706 return FALSE;
709 if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
710 return FALSE;
712 if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
714 if (GetLastError() != ERROR_MORE_DATA)
715 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
716 return FALSE;
719 RegCloseKey(hKey);
721 return TRUE;
724 static void test_get_default_provider(void)
726 /* expected results */
727 DWORD dwProvType = PROV_RSA_FULL;
728 DWORD dwFlags = CRYPT_MACHINE_DEFAULT;
729 LPSTR pszProvName = NULL;
730 DWORD cbProvName;
732 /* actual results */
733 DWORD provType = PROV_RSA_FULL;
734 DWORD flags = CRYPT_MACHINE_DEFAULT;
735 LPSTR provName = NULL;
736 DWORD provNameSize;
737 DWORD result;
738 DWORD notNull = 5;
740 if(!pCryptGetDefaultProviderA)
742 skip("CryptGetDefaultProviderA is not available\n");
743 return;
746 if(!FindDfltProvRegVals(dwProvType, dwFlags, &pszProvName, &cbProvName))
748 skip("Could not find default provider in registry\n");
749 return;
752 /* check pdwReserved for NULL */
753 result = pCryptGetDefaultProviderA(provType, &notNull, flags, provName, &provNameSize);
754 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
755 ERROR_INVALID_PARAMETER, GetLastError());
757 /* check for invalid flag */
758 flags = 0xdeadbeef;
759 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
760 ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %d, got %d\n",
761 NTE_BAD_FLAGS, GetLastError());
762 flags = CRYPT_MACHINE_DEFAULT;
764 /* check for invalid prov type */
765 provType = 0xdeadbeef;
766 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
767 ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE ||
768 GetLastError() == ERROR_INVALID_PARAMETER),
769 "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n",
770 result, GetLastError());
771 provType = PROV_RSA_FULL;
773 SetLastError(0);
775 /* alloc provName to half the size required
776 * cbProvName holds the size required */
777 provNameSize = cbProvName / 2;
778 if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
779 return;
781 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
782 ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
783 ERROR_MORE_DATA, GetLastError());
785 LocalFree(provName);
787 /* check expected versus actual values returned */
788 result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize);
789 ok(result && provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
790 provNameSize = cbProvName;
792 if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))
793 return;
795 provNameSize = 0xdeadbeef;
796 result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);
797 ok(result, "expected TRUE, got %d\n", result);
798 if(pszProvName)
799 ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName);
800 ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize);
802 LocalFree(provName);
805 static void test_set_provider_ex(void)
807 DWORD result;
808 DWORD notNull = 5;
810 /* results */
811 LPSTR pszProvName = NULL;
812 DWORD cbProvName;
814 if(!pCryptGetDefaultProviderA || !pCryptSetProviderExA)
816 skip("CryptGetDefaultProviderA and/or CryptSetProviderExA are not available\n");
817 return;
820 /* check pdwReserved for NULL */
821 result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);
822 ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
823 ERROR_INVALID_PARAMETER, GetLastError());
825 /* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */
826 SetLastError(0xdeadbeef);
827 result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT | CRYPT_DELETE_DEFAULT);
828 if (!result && (GetLastError() == ERROR_ACCESS_DENIED))
830 skip("Not enough rights to remove the default provider\n");
831 return;
833 ok(result, "%d\n", GetLastError());
835 result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
836 ok(result, "%d\n", GetLastError());
838 /* call CryptGetDefaultProvider to see if they match */
839 result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);
840 if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))
841 return;
843 result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);
844 ok(result && !strcmp(MS_DEF_PROV, pszProvName), "expected %s, got %s\n", MS_DEF_PROV, pszProvName);
845 ok(result && cbProvName==(strlen(MS_DEF_PROV) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV) + 1), cbProvName);
847 LocalFree(pszProvName);
850 START_TEST(crypt)
852 init_function_pointers();
853 if(pCryptAcquireContextA && pCryptReleaseContext) {
854 init_environment();
855 test_acquire_context();
856 test_incorrect_api_usage();
857 test_verify_sig();
858 clean_up_environment();
861 test_enum_providers();
862 test_enum_provider_types();
863 test_get_default_provider();
864 test_set_provider_ex();