~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/advapi32/tests/crypt.c

Version: ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  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 
 68 static void init_function_pointers(void)
 69 {
 70     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
 71 
 72     pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA");
 73     pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA");
 74     pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA");
 75     pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA");
 76     pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext");
 77     pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA");
 78     pCryptCreateHash = (void*)GetProcAddress(hadvapi32, "CryptCreateHash");
 79     pCryptDestroyHash = (void*)GetProcAddress(hadvapi32, "CryptDestroyHash");
 80     pCryptGenRandom = (void*)GetProcAddress(hadvapi32, "CryptGenRandom");
 81     pCryptContextAddRef = (void*)GetProcAddress(hadvapi32, "CryptContextAddRef");
 82     pCryptGenKey = (void*)GetProcAddress(hadvapi32, "CryptGenKey");
 83     pCryptDestroyKey = (void*)GetProcAddress(hadvapi32, "CryptDestroyKey");
 84     pCryptDecrypt = (void*)GetProcAddress(hadvapi32, "CryptDecrypt");
 85     pCryptDeriveKey = (void*)GetProcAddress(hadvapi32, "CryptDeriveKey");
 86     pCryptDuplicateHash = (void*)GetProcAddress(hadvapi32, "CryptDuplicateHash");
 87     pCryptDuplicateKey = (void*)GetProcAddress(hadvapi32, "CryptDuplicateKey");
 88     pCryptEncrypt = (void*)GetProcAddress(hadvapi32, "CryptEncrypt");
 89     pCryptExportKey = (void*)GetProcAddress(hadvapi32, "CryptExportKey");
 90     pCryptGetHashParam = (void*)GetProcAddress(hadvapi32, "CryptGetHashParam");
 91     pCryptGetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptGetKeyParam");
 92     pCryptGetProvParam = (void*)GetProcAddress(hadvapi32, "CryptGetProvParam");
 93     pCryptGetUserKey = (void*)GetProcAddress(hadvapi32, "CryptGetUserKey");
 94     pCryptHashData = (void*)GetProcAddress(hadvapi32, "CryptHashData");
 95     pCryptHashSessionKey = (void*)GetProcAddress(hadvapi32, "CryptHashSessionKey");
 96     pCryptImportKey = (void*)GetProcAddress(hadvapi32, "CryptImportKey");
 97     pCryptSignHashW = (void*)GetProcAddress(hadvapi32, "CryptSignHashW");
 98     pCryptSetHashParam = (void*)GetProcAddress(hadvapi32, "CryptSetHashParam");
 99     pCryptSetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptSetKeyParam");
100     pCryptSetProvParam = (void*)GetProcAddress(hadvapi32, "CryptSetProvParam");
101     pCryptVerifySignatureW = (void*)GetProcAddress(hadvapi32, "CryptVerifySignatureW");
102 }
103 
104 static void init_environment(void)
105 {
106         HCRYPTPROV hProv;
107         
108         /* Ensure that container "wine_test_keyset" does exist */
109         if (!pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
110         {
111                 pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET);
112         }
113         pCryptReleaseContext(hProv, 0);
114 
115         /* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */
116         if (!pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
117         {
118                 pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);
119         }
120         pCryptReleaseContext(hProv, 0);
121 
122         /* Ensure that container "wine_test_bad_keyset" does not exist. */
123         if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
124         {
125                 pCryptReleaseContext(hProv, 0);
126                 pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
127         }
128 }
129 
130 static void clean_up_environment(void)
131 {
132         HCRYPTPROV hProv;
133 
134         /* Remove container "wine_test_keyset" */
135         if (pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
136         {
137                 pCryptReleaseContext(hProv, 0);
138                 pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
139         }
140 
141         /* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */
142         if (pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))
143         {
144                 pCryptReleaseContext(hProv, 0);
145                 pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
146         }
147 }
148 
149 static void test_acquire_context(void)
150 {
151         BOOL result;
152         HCRYPTPROV hProv;
153         DWORD GLE;
154 
155         /* Provoke all kinds of error conditions (which are easy to provoke). 
156          * The order of the error tests seems to match Windows XP's rsaenh.dll CSP,
157          * but since this is likely to change between CSP versions, we don't check
158          * this. Please don't change the order of tests. */
159         result = pCryptAcquireContextA(&hProv, NULL, NULL, 0, 0);
160         ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
161         
162         result = pCryptAcquireContextA(&hProv, NULL, NULL, 1000, 0);
163         ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError());
164 
165         result = pCryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0);
166         ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%d\n", GetLastError());
167         
168         result = pCryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0);
169         ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%d\n", GetLastError());
170 
171         result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0);
172         ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%d\n", GetLastError());
173         
174         /* This test fails under Win2k SP4:
175            result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER
176         SetLastError(0xdeadbeef);
177         result = pCryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
178         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%d\n", result, GetLastError());
179         */
180         
181         /* Last not least, try to really acquire a context. */
182         hProv = 0;
183         SetLastError(0xdeadbeef);
184         result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);
185         GLE = GetLastError();
186         ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND   || 
187                       GLE == ERROR_SUCCESS            || 
188                       GLE == ERROR_RING2_STACK_IN_USE || 
189                       GLE == NTE_FAIL                 ||
190                       GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GLE);
191 
192         if (hProv) 
193                 pCryptReleaseContext(hProv, 0);
194 
195         /* Try again, witch an empty ("\0") szProvider parameter */
196         hProv = 0;
197         SetLastError(0xdeadbeef);
198         result = pCryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0);
199         GLE = GetLastError();
200         ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND   || 
201                       GLE == ERROR_SUCCESS            || 
202                       GLE == ERROR_RING2_STACK_IN_USE || 
203                       GLE == NTE_FAIL                 ||
204                       GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GetLastError());
205 
206         if (hProv) 
207                 pCryptReleaseContext(hProv, 0);
208 }
209 
210 static void test_incorrect_api_usage(void)
211 {
212     BOOL result;
213     HCRYPTPROV hProv, hProv2;
214     HCRYPTHASH hHash, hHash2;
215     HCRYPTKEY hKey, hKey2;
216     BYTE temp;
217     DWORD dwLen, dwTemp;
218 
219     /* This is to document incorrect api usage in the 
220      * "Uru - Ages beyond Myst Demo" installer as reported by Paul Vriens.
221      *
222      * The installer destroys a hash object after having released the context 
223      * with which the hash was created. This is not allowed according to MSDN, 
224      * since CryptReleaseContext destroys all hash and key objects belonging to 
225      * the respective context. However, while wine used to crash, Windows is more 
226      * robust here and returns an ERROR_INVALID_PARAMETER code.
227      */
228     
229     result = pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, 
230                                    PROV_RSA_FULL, CRYPT_NEWKEYSET);
231     ok (result, "%08x\n", GetLastError());
232     if (!result) return;
233 
234     result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
235     ok (result, "%d\n", GetLastError());
236     if (!result) return;
237 
238     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey);
239     ok (result, "%d\n", GetLastError());
240     if (!result) return;
241 
242     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
243     ok (result, "%d\n", GetLastError());
244     if (!result) return;
245 
246     result = pCryptDestroyKey(hKey2);
247     ok (result, "%d\n", GetLastError());
248 
249     dwTemp = CRYPT_MODE_ECB;    
250     result = pCryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD));
251     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
252     
253     result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL, 
254                                    CRYPT_DELETEKEYSET);
255     ok (result, "%d\n", GetLastError());
256     if (!result) return;
257     
258     result = pCryptReleaseContext(hProv, 0);
259     ok (result, "%d\n", GetLastError());
260     if (!result) return;
261 
262     result = pCryptReleaseContext(hProv, 0);
263     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
264 
265     result = pCryptGenRandom(hProv, 1, &temp);
266     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
267 
268 #ifdef CRASHES_ON_NT40
269     result = pCryptContextAddRef(hProv, NULL, 0);
270     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
271 #endif
272 
273     result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
274     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
275 
276     dwLen = 1;
277     result = pCryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen);
278     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
279 
280     dwLen = 1;
281     result = pCryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen, 1);
282     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
283 
284     result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2);
285     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
286 
287 #ifdef CRASHES_ON_NT40
288     result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2);
289     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
290 
291     result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2);
292     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
293 #endif
294 
295     dwLen = 1;
296     result = pCryptExportKey(hKey, (HCRYPTPROV)NULL, 0, 0, &temp, &dwLen);
297     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
298 
299     result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
300     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
301 
302     dwLen = 1;
303     result = pCryptGetHashParam(hHash, 0, &temp, &dwLen, 0);
304     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
305 
306     dwLen = 1;
307     result = pCryptGetKeyParam(hKey, 0, &temp, &dwLen, 0);
308     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
309 
310     dwLen = 1;
311     result = pCryptGetProvParam(hProv, 0, &temp, &dwLen, 0);
312     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
313     
314     result = pCryptGetUserKey(hProv, 0, &hKey2);
315     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
316 
317     result = pCryptHashData(hHash, &temp, 1, 0);
318     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
319 
320     result = pCryptHashSessionKey(hHash, hKey, 0);
321     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
322 
323     result = pCryptImportKey(hProv, &temp, 1, (HCRYPTKEY)NULL, 0, &hKey2);
324     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
325 
326     if (pCryptSignHashW)
327     {
328         dwLen = 1;
329         result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen);
330         ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
331             GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
332     }
333     else
334         skip("CryptSignHashW is not available\n");
335 
336     result = pCryptSetKeyParam(hKey, 0, &temp, 1);
337     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
338 
339     result = pCryptSetHashParam(hHash, 0, &temp, 1);
340     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
341 
342     result = pCryptSetProvParam(hProv, 0, &temp, 1);
343     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
344 
345     if (pCryptVerifySignatureW)
346     {
347         result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0);
348         ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER ||
349             GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError());
350     }
351     else
352         skip("CryptVerifySignatureW is not available\n");
353 
354     result = pCryptDestroyHash(hHash);
355     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
356     
357     result = pCryptDestroyKey(hKey);
358     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
359 }
360 
361 static const BYTE privKey[] = {
362  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
363  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
364  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
365  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
366  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
367  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
368  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
369  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
370  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
371  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
372  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
373  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
374  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
375  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
376  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
377  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
378  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
379  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
380  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
381  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
382  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
383  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
384  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
385  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
386 
387 static void test_verify_sig(void)
388 {
389         BOOL ret;
390         HCRYPTPROV prov;
391         HCRYPTKEY key;
392         HCRYPTHASH hash;
393         BYTE bogus[] = { 0 };
394 
395         if (!pCryptVerifySignatureW)
396         {
397                 skip("CryptVerifySignatureW is not available\n");
398                 return;
399         }
400 
401         SetLastError(0xdeadbeef);
402         ret = pCryptVerifySignatureW(0, NULL, 0, 0, NULL, 0);
403         if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
404         {
405                 skip("CryptVerifySignatureW is not implemented\n");
406                 return;
407         }
408         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
409          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
410         ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL,
411          CRYPT_NEWKEYSET);
412         if (!ret && GetLastError() == NTE_EXISTS)
413                 ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0);
414         ret = pCryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key);
415         ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
416         ret = pCryptCreateHash(prov, CALG_MD5, 0, 0, &hash);
417         ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
418         SetLastError(0xdeadbeef);
419         ret = pCryptVerifySignatureW(hash, NULL, 0, 0, NULL, 0);
420         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
421          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
422         SetLastError(0xdeadbeef);
423         ret = pCryptVerifySignatureW(0, NULL, 0, key, NULL, 0);
424         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
425          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
426         SetLastError(0xdeadbeef);
427         ret = pCryptVerifySignatureW(hash, NULL, 0, key, NULL, 0);
428         ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
429          GetLastError() == ERROR_INVALID_PARAMETER),
430          "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
431          GetLastError());
432         SetLastError(0xdeadbeef);
433         ret = pCryptVerifySignatureW(hash, NULL, sizeof(bogus), key, NULL, 0);
434         ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
435          GetLastError() == ERROR_INVALID_PARAMETER),
436          "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n",
437          GetLastError());
438         SetLastError(0xdeadbeef);
439         ret = pCryptVerifySignatureW(hash, bogus, 0, key, NULL, 0);
440         ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
441          "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
442         SetLastError(0xdeadbeef);
443         ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
444         ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
445          "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
446         pCryptDestroyKey(key);
447         pCryptDestroyHash(hash);
448         pCryptReleaseContext(prov, 0);
449 }
450 
451 static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName, 
452                             DWORD *pcbProvName, DWORD *pdwProvCount)
453 {
454         HKEY hKey;
455         HKEY subkey;
456         DWORD size = sizeof(DWORD);
457         
458         if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))
459                 return FALSE;
460         
461         RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName, 
462                                  NULL, NULL, NULL, NULL, NULL, NULL);
463         (*pcbProvName)++;
464         
465         if (!(*pszProvName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbProvName))))
466                 return FALSE;
467         
468         RegEnumKeyEx(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
469         (*pcbProvName)++;
470 
471         RegOpenKey(hKey, *pszProvName, &subkey);
472         RegQueryValueEx(subkey, "Type", NULL, NULL, (LPBYTE)pdwProvType, &size);
473         
474         RegCloseKey(subkey);
475         RegCloseKey(hKey);
476         
477         return TRUE;
478 }
479 
480 static void test_enum_providers(void)
481 {
482         /* expected results */
483         CHAR *pszProvName = NULL;
484         DWORD cbName;
485         DWORD dwType;
486         DWORD provCount;
487         DWORD dwIndex = 0;
488         
489         /* actual results */
490         CHAR *provider = NULL;
491         DWORD providerLen;
492         DWORD type;
493         DWORD count;
494         DWORD result;
495         DWORD notNull = 5;
496         DWORD notZeroFlags = 5;
497         
498         if(!pCryptEnumProvidersA)
499         {
500             skip("CryptEnumProvidersA is not available\n");
501             return;
502         }
503         
504         if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))
505         {
506             skip("Could not find providers in registry\n");
507             return;
508         }
509         
510         /* check pdwReserved flag for NULL */
511         result = pCryptEnumProvidersA(dwIndex, &notNull, 0, &type, NULL, &providerLen);
512         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
513         
514         /* check dwFlags == 0 */
515         result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);
516         ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d\n", GetLastError());
517         
518         /* alloc provider to half the size required
519          * cbName holds the size required */
520         providerLen = cbName / 2;
521         if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))
522                 return;
523 
524         result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
525         ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n",
526                 ERROR_MORE_DATA, GetLastError());
527 
528         LocalFree(provider);
529 
530         /* loop through the providers to get the number of providers 
531          * after loop ends, count should be provCount + 1 so subtract 1
532          * to get actual number of providers */
533         count = 0;
534         while(pCryptEnumProvidersA(count++, NULL, 0, &type, NULL, &providerLen))
535                 ;
536         count--;
537         ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);
538         
539         /* loop past the actual number of providers to get the error
540          * ERROR_NO_MORE_ITEMS */
541         for (count = 0; count < provCount + 1; count++)
542                 result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen);
543         ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n", 
544                         ERROR_NO_MORE_ITEMS, GetLastError());
545         
546         /* check expected versus actual values returned */
547         result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, NULL, &providerLen);
548         ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);
549         if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))
550                 return;
551                 
552         providerLen = 0xdeadbeef;
553         result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
554         ok(result, "expected TRUE, got %d\n", result);
555         ok(type==dwType, "expected %d, got %d\n", dwType, type);
556         if (pszProvName)
557             ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
558         ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
559 
560         LocalFree(provider);
561 }
562 
563 static BOOL FindProvTypesRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszTypeName, 
564                                  DWORD *pcbTypeName, DWORD *pdwTypeCount)
565 {
566         HKEY hKey;
567         HKEY hSubKey;
568         PSTR ch;
569         
570         if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
571                 return FALSE;
572         
573         if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, pcbTypeName, NULL,
574                         NULL, NULL, NULL, NULL, NULL))
575             return FALSE;
576         (*pcbTypeName)++;
577         
578         if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
579                 return FALSE;
580         
581         if (RegEnumKeyEx(hKey, dwIndex, *pszTypeName, pcbTypeName, NULL, NULL, NULL, NULL))
582             return FALSE;
583         (*pcbTypeName)++;
584         ch = *pszTypeName + strlen(*pszTypeName);
585         /* Convert "Type 000" to 0, etc/ */
586         *pdwProvType = *(--ch) - '';
587         *pdwProvType += (*(--ch) - '') * 10;
588         *pdwProvType += (*(--ch) - '') * 100;
589         
590         if (RegOpenKey(hKey, *pszTypeName, &hSubKey))
591             return FALSE;
592         
593         if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
594             return FALSE;
595 
596         if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
597                 return FALSE;
598         
599         if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
600             return FALSE;
601         
602         RegCloseKey(hSubKey);
603         RegCloseKey(hKey);
604         
605         return TRUE;
606 }
607 
608 static void test_enum_provider_types(void)
609 {
610         /* expected values */
611         DWORD dwProvType;
612         LPSTR pszTypeName = NULL;
613         DWORD cbTypeName;
614         DWORD dwTypeCount;
615         
616         /* actual values */
617         DWORD index = 0;
618         DWORD provType;
619         LPSTR typeName = NULL;
620         DWORD typeNameSize;
621         DWORD typeCount;
622         DWORD result;
623         DWORD notNull = 5;
624         DWORD notZeroFlags = 5;
625         
626         if(!pCryptEnumProviderTypesA)
627         {
628             skip("CryptEnumProviderTypesA is not available\n");
629             return;
630         }
631         
632         if (!FindProvTypesRegVals(index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
633         {
634             skip("Could not find provider types in registry\n");
635             return;
636         }
637         
638         /* check pdwReserved for NULL */
639         result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
640         ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n", 
641                 ERROR_INVALID_PARAMETER, GetLastError());
642         
643         /* check dwFlags == zero */
644         result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
645         ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %i, got %d\n",
646                 ERROR_INVALID_PARAMETER, GetLastError());
647         
648         /* alloc provider type to half the size required
649          * cbTypeName holds the size required */
650         typeNameSize = cbTypeName / 2;
651         if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
652                 return;
653 
654         /* This test fails under Win2k SP4:
655            result = TRUE, GetLastError() == 0xdeadbeef
656         SetLastError(0xdeadbeef);
657         result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
658         ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%08lx\n",
659                 result, GetLastError());
660         */
661         
662         LocalFree(typeName);
663         
664         /* loop through the provider types to get the number of provider types 
665          * after loop ends, count should be dwTypeCount + 1 so subtract 1
666          * to get actual number of provider types */
667         typeCount = 0;
668         while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))
669                 ;
670         typeCount--;
671         ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);
672         
673         /* loop past the actual number of provider types to get the error
674          * ERROR_NO_MORE_ITEMS */
675         for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
676                 result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
677         ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n", 
678                         ERROR_NO_MORE_ITEMS, GetLastError());
679         
680 
681         /* check expected versus actual values returned */
682         result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
683         ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
684         if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
685                 return;
686                 
687         typeNameSize = 0xdeadbeef;
688         result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
689         ok(result, "expected TRUE, got %d\n", result);
690         ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
691         if (pszTypeName)
692             ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
693         ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
694         
695         LocalFree(typeName);
696 }
697 
698 static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
699 {
700         HKEY hKey;
701         PSTR keyname;
702         PSTR ptr;
703         DWORD user = dwFlags & CRYPT_USER_DEFAULT;
704         
705         LPCSTR machinestr = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
706         LPCSTR userstr = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
707         
708         keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(userstr) : strlen(machinestr)) + 1);
709         if (keyname)
710         {
711                 user ? strcpy(keyname, userstr) : strcpy(keyname, machinestr);
712                 ptr = keyname + strlen(keyname);
713                 *(--ptr) = (dwProvType % 10) + '';
714                 *(--ptr) = ((dwProvType / 10) % 10) + '';
715                 *(--ptr) = (dwProvType / 100) + '';
716         } else
717                 return FALSE;
718         
719         if (RegOpenKey((dwFlags & CRYPT_USER_DEFAULT) ?  HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
720         {
721                 LocalFree(keyname);
722                 return FALSE;
723         }
724         LocalFree(keyname);
725         
726         if (RegQueryValueEx(hKey, "Name", NULL, NULL, (LPBYTE)*pszProvName, pcbProvName))
727         {
728                 if (GetLastError() != ERROR_MORE_DATA)
729                         SetLastError(