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
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 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
);
68 static void init_function_pointers(void)
70 HMODULE hadvapi32
= GetModuleHandleA("advapi32.dll");
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");
104 static void init_environment(void)
108 /* Ensure that container "wine_test_keyset" does exist */
109 if (!pCryptAcquireContextA(&hProv
, szKeySet
, szRsaBaseProv
, PROV_RSA_FULL
, 0))
111 pCryptAcquireContextA(&hProv
, szKeySet
, szRsaBaseProv
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
113 pCryptReleaseContext(hProv
, 0);
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))
118 pCryptAcquireContextA(&hProv
, szKeySet
, NULL
, PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
120 pCryptReleaseContext(hProv
, 0);
122 /* Ensure that container "wine_test_bad_keyset" does not exist. */
123 if (pCryptAcquireContextA(&hProv
, szBadKeySet
, szRsaBaseProv
, PROV_RSA_FULL
, 0))
125 pCryptReleaseContext(hProv
, 0);
126 pCryptAcquireContextA(&hProv
, szBadKeySet
, szRsaBaseProv
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
130 static void clean_up_environment(void)
134 /* Remove container "wine_test_keyset" */
135 if (pCryptAcquireContextA(&hProv
, szKeySet
, szRsaBaseProv
, PROV_RSA_FULL
, 0))
137 pCryptReleaseContext(hProv
, 0);
138 pCryptAcquireContextA(&hProv
, szKeySet
, szRsaBaseProv
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
141 /* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */
142 if (pCryptAcquireContextA(&hProv
, szKeySet
, NULL
, PROV_RSA_FULL
, 0))
144 pCryptReleaseContext(hProv
, 0);
145 pCryptAcquireContextA(&hProv
, szKeySet
, NULL
, PROV_RSA_FULL
, CRYPT_DELETEKEYSET
);
149 static void test_acquire_context(void)
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());
162 result
= pCryptAcquireContextA(&hProv
, NULL
, NULL
, 1000, 0);
163 ok(!result
&& GetLastError()==NTE_BAD_PROV_TYPE
, "%d\n", GetLastError());
165 result
= pCryptAcquireContextA(&hProv
, NULL
, NULL
, NON_DEF_PROV_TYPE
, 0);
166 ok(!result
&& GetLastError()==NTE_PROV_TYPE_NOT_DEF
, "%d\n", GetLastError());
168 result
= pCryptAcquireContextA(&hProv
, szKeySet
, szNonExistentProv
, PROV_RSA_FULL
, 0);
169 ok(!result
&& GetLastError()==NTE_KEYSET_NOT_DEF
, "%d\n", GetLastError());
171 result
= pCryptAcquireContextA(&hProv
, szKeySet
, szRsaBaseProv
, NON_DEF_PROV_TYPE
, 0);
172 ok(!result
&& GetLastError()==NTE_PROV_TYPE_NO_MATCH
, "%d\n", GetLastError());
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());
181 /* Last not least, try to really acquire a context. */
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
||
190 GLE
== ERROR_NOT_LOGGED_ON
), "%d/%d\n", result
, GLE
);
193 pCryptReleaseContext(hProv
, 0);
195 /* Try again, witch an empty ("\0") szProvider parameter */
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
||
204 GLE
== ERROR_NOT_LOGGED_ON
), "%d/%d\n", result
, GetLastError());
207 pCryptReleaseContext(hProv
, 0);
210 static void test_incorrect_api_usage(void)
213 HCRYPTPROV hProv
, hProv2
;
214 HCRYPTHASH hHash
, hHash2
;
215 HCRYPTKEY hKey
, hKey2
;
219 /* This is to document incorrect api usage in the
220 * "Uru - Ages beyond Myst Demo" installer as reported by Paul Vriens.
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.
229 result
= pCryptAcquireContextA(&hProv
, szBadKeySet
, szRsaBaseProv
,
230 PROV_RSA_FULL
, CRYPT_NEWKEYSET
);
231 ok (result
, "%08x\n", GetLastError());
234 result
= pCryptCreateHash(hProv
, CALG_SHA
, 0, 0, &hHash
);
235 ok (result
, "%d\n", GetLastError());
238 result
= pCryptGenKey(hProv
, CALG_RC4
, 0, &hKey
);
239 ok (result
, "%d\n", GetLastError());
242 result
= pCryptGenKey(hProv
, CALG_RC4
, 0, &hKey2
);
243 ok (result
, "%d\n", GetLastError());
246 result
= pCryptDestroyKey(hKey2
);
247 ok (result
, "%d\n", GetLastError());
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());
253 result
= pCryptAcquireContextA(&hProv2
, szBadKeySet
, NULL
, PROV_RSA_FULL
,
255 ok (result
, "%d\n", GetLastError());
258 result
= pCryptReleaseContext(hProv
, 0);
259 ok (result
, "%d\n", GetLastError());
262 result
= pCryptReleaseContext(hProv
, 0);
263 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
265 result
= pCryptGenRandom(hProv
, 1, &temp
);
266 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
268 #ifdef CRASHES_ON_NT40
269 result
= pCryptContextAddRef(hProv
, NULL
, 0);
270 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
273 result
= pCryptCreateHash(hProv
, CALG_SHA
, 0, 0, &hHash2
);
274 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
277 result
= pCryptDecrypt(hKey
, (HCRYPTHASH
)NULL
, TRUE
, 0, &temp
, &dwLen
);
278 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
281 result
= pCryptEncrypt(hKey
, (HCRYPTHASH
)NULL
, TRUE
, 0, &temp
, &dwLen
, 1);
282 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
284 result
= pCryptDeriveKey(hProv
, CALG_RC4
, hHash
, 0, &hKey2
);
285 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
287 #ifdef CRASHES_ON_NT40
288 result
= pCryptDuplicateHash(hHash
, NULL
, 0, &hHash2
);
289 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
291 result
= pCryptDuplicateKey(hKey
, NULL
, 0, &hKey2
);
292 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
296 result
= pCryptExportKey(hKey
, (HCRYPTPROV
)NULL
, 0, 0, &temp
, &dwLen
);
297 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
299 result
= pCryptGenKey(hProv
, CALG_RC4
, 0, &hKey2
);
300 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
303 result
= pCryptGetHashParam(hHash
, 0, &temp
, &dwLen
, 0);
304 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
307 result
= pCryptGetKeyParam(hKey
, 0, &temp
, &dwLen
, 0);
308 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
311 result
= pCryptGetProvParam(hProv
, 0, &temp
, &dwLen
, 0);
312 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
314 result
= pCryptGetUserKey(hProv
, 0, &hKey2
);
315 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
317 result
= pCryptHashData(hHash
, &temp
, 1, 0);
318 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
320 result
= pCryptHashSessionKey(hHash
, hKey
, 0);
321 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
323 result
= pCryptImportKey(hProv
, &temp
, 1, (HCRYPTKEY
)NULL
, 0, &hKey2
);
324 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
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());
334 skip("CryptSignHashW is not available\n");
336 result
= pCryptSetKeyParam(hKey
, 0, &temp
, 1);
337 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
339 result
= pCryptSetHashParam(hHash
, 0, &temp
, 1);
340 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
342 result
= pCryptSetProvParam(hProv
, 0, &temp
, 1);
343 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
345 if (pCryptVerifySignatureW
)
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());
352 skip("CryptVerifySignatureW is not available\n");
354 result
= pCryptDestroyHash(hHash
);
355 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
357 result
= pCryptDestroyKey(hKey
);
358 ok (!result
&& GetLastError() == ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
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 };
387 static void test_verify_sig(void)
393 BYTE bogus
[] = { 0 };
395 if (!pCryptVerifySignatureW
)
397 skip("CryptVerifySignatureW is not available\n");
401 SetLastError(0xdeadbeef);
402 ret
= pCryptVerifySignatureW(0, NULL
, 0, 0, NULL
, 0);
403 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
405 skip("CryptVerifySignatureW is not implemented\n");
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
,
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",
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",
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);
451 static BOOL
FindProvRegVals(DWORD dwIndex
, DWORD
*pdwProvType
, LPSTR
*pszProvName
,
452 DWORD
*pcbProvName
, DWORD
*pdwProvCount
)
456 DWORD size
= sizeof(DWORD
);
458 if (RegOpenKey(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey
))
461 RegQueryInfoKey(hKey
, NULL
, NULL
, NULL
, pdwProvCount
, pcbProvName
,
462 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
465 if (!(*pszProvName
= ((LPSTR
)LocalAlloc(LMEM_ZEROINIT
, *pcbProvName
))))
468 RegEnumKeyEx(hKey
, dwIndex
, *pszProvName
, pcbProvName
, NULL
, NULL
, NULL
, NULL
);
471 RegOpenKey(hKey
, *pszProvName
, &subkey
);
472 RegQueryValueEx(subkey
, "Type", NULL
, NULL
, (LPBYTE
)pdwProvType
, &size
);
480 static void test_enum_providers(void)
482 /* expected results */
483 CHAR
*pszProvName
= NULL
;
490 CHAR
*provider
= NULL
;
496 DWORD notZeroFlags
= 5;
498 if(!pCryptEnumProvidersA
)
500 skip("CryptEnumProvidersA is not available\n");
504 if (!FindProvRegVals(dwIndex
, &dwType
, &pszProvName
, &cbName
, &provCount
))
506 skip("Could not find providers in registry\n");
510 /* check pdwReserved flag for NULL */
511 result
= pCryptEnumProvidersA(dwIndex
, ¬Null
, 0, &type
, NULL
, &providerLen
);
512 ok(!result
&& GetLastError()==ERROR_INVALID_PARAMETER
, "%d\n", GetLastError());
514 /* check dwFlags == 0 */
515 result
= pCryptEnumProvidersA(dwIndex
, NULL
, notZeroFlags
, &type
, NULL
, &providerLen
);
516 ok(!result
&& GetLastError()==NTE_BAD_FLAGS
, "%d\n", GetLastError());
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
))))
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());
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 */
534 while(pCryptEnumProvidersA(count
++, NULL
, 0, &type
, NULL
, &providerLen
))
537 ok(count
==provCount
, "expected %i, got %i\n", (int)provCount
, (int)count
);
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());
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
))))
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
);
557 ok(!strcmp(pszProvName
, provider
), "expected %s, got %s\n", pszProvName
, provider
);
558 ok(cbName
==providerLen
, "expected %d, got %d\n", cbName
, providerLen
);
563 static BOOL
FindProvTypesRegVals(DWORD dwIndex
, DWORD
*pdwProvType
, LPSTR
*pszTypeName
,
564 DWORD
*pcbTypeName
, DWORD
*pdwTypeCount
)
570 if (RegOpenKey(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey
))
573 if (RegQueryInfoKey(hKey
, NULL
, NULL
, NULL
, pdwTypeCount
, pcbTypeName
, NULL
,
574 NULL
, NULL
, NULL
, NULL
, NULL
))
578 if (!(*pszTypeName
= ((LPSTR
)LocalAlloc(LMEM_ZEROINIT
, *pcbTypeName
))))
581 if (RegEnumKeyEx(hKey
, dwIndex
, *pszTypeName
, pcbTypeName
, NULL
, NULL
, NULL
, NULL
))
584 ch
= *pszTypeName
+ strlen(*pszTypeName
);
585 /* Convert "Type 000" to 0, etc/ */
586 *pdwProvType
= *(--ch
) - '0';
587 *pdwProvType
+= (*(--ch
) - '0') * 10;
588 *pdwProvType
+= (*(--ch
) - '0') * 100;
590 if (RegOpenKey(hKey
, *pszTypeName
, &hSubKey
))
593 if (RegQueryValueEx(hSubKey
, "TypeName", NULL
, NULL
, NULL
, pcbTypeName
))
596 if (!(*pszTypeName
= ((LPSTR
)LocalAlloc(LMEM_ZEROINIT
, *pcbTypeName
))))
599 if (RegQueryValueEx(hSubKey
, "TypeName", NULL
, NULL
, (LPBYTE
)*pszTypeName
, pcbTypeName
))
602 RegCloseKey(hSubKey
);
608 static void test_enum_provider_types(void)
610 /* expected values */
612 LPSTR pszTypeName
= NULL
;
619 LPSTR typeName
= NULL
;
624 DWORD notZeroFlags
= 5;
626 if(!pCryptEnumProviderTypesA
)
628 skip("CryptEnumProviderTypesA is not available\n");
632 if (!FindProvTypesRegVals(index
, &dwProvType
, &pszTypeName
, &cbTypeName
, &dwTypeCount
))
634 skip("Could not find provider types in registry\n");
638 /* check pdwReserved for NULL */
639 result
= pCryptEnumProviderTypesA(index
, ¬Null
, 0, &provType
, typeName
, &typeNameSize
);
640 ok(!result
&& GetLastError()==ERROR_INVALID_PARAMETER
, "expected %i, got %d\n",
641 ERROR_INVALID_PARAMETER
, GetLastError());
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());
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
))))
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());
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 */
668 while(pCryptEnumProviderTypesA(typeCount
++, NULL
, 0, &provType
, NULL
, &typeNameSize
))
671 ok(typeCount
==dwTypeCount
, "expected %d, got %d\n", dwTypeCount
, typeCount
);
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());
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
))))
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
);
692 ok(!strcmp(pszTypeName
, typeName
), "expected %s, got %s\n", pszTypeName
, typeName
);
693 ok(typeNameSize
==cbTypeName
, "expected %d, got %d\n", cbTypeName
, typeNameSize
);
698 static BOOL
FindDfltProvRegVals(DWORD dwProvType
, DWORD dwFlags
, LPSTR
*pszProvName
, DWORD
*pcbProvName
)
703 DWORD user
= dwFlags
& CRYPT_USER_DEFAULT
;
705 LPCSTR machinestr
= "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
706 LPCSTR userstr
= "Software\\Microsoft\\Cryptography\\Provider Type XXX";
708 keyname
= LocalAlloc(LMEM_ZEROINIT
, (user
? strlen(userstr
) : strlen(machinestr
)) + 1);
711 user
? strcpy(keyname
, userstr
) : strcpy(keyname
, machinestr
);
712 ptr
= keyname
+ strlen(keyname
);
713 *(--ptr
) = (dwProvType
% 10) + '0';
714 *(--ptr
) = ((dwProvType
/ 10) % 10) + '0';
715 *(--ptr
) = (dwProvType
/ 100) + '0';
719 if (RegOpenKey((dwFlags
& CRYPT_USER_DEFAULT
) ? HKEY_CURRENT_USER
: HKEY_LOCAL_MACHINE
,keyname
, &hKey
))
726 if (RegQueryValueEx(hKey
, "Name", NULL
, NULL
, (LPBYTE
)*pszProvName
, pcbProvName
))
728 if (GetLastError() != ERROR_MORE_DATA
)
729 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
733 if (!(*pszProvName
= LocalAlloc(LMEM_ZEROINIT
, *pcbProvName
)))
736 if (RegQueryValueEx(hKey
, "Name", NULL
, NULL
, (LPBYTE
)*pszProvName
, pcbProvName
))
738 if (GetLastError() != ERROR_MORE_DATA
)
739 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
748 static void test_get_default_provider(void)
750 /* expected results */
751 DWORD dwProvType
= PROV_RSA_FULL
;
752 DWORD dwFlags
= CRYPT_MACHINE_DEFAULT
;
753 LPSTR pszProvName
= NULL
;
757 DWORD provType
= PROV_RSA_FULL
;
758 DWORD flags
= CRYPT_MACHINE_DEFAULT
;
759 LPSTR provName
= NULL
;
764 if(!pCryptGetDefaultProviderA
)
766 skip("CryptGetDefaultProviderA is not available\n");
770 if(!FindDfltProvRegVals(dwProvType
, dwFlags
, &pszProvName
, &cbProvName
))
772 skip("Could not find default provider in registry\n");
776 /* check pdwReserved for NULL */
777 result
= pCryptGetDefaultProviderA(provType
, ¬Null
, flags
, provName
, &provNameSize
);
778 ok(!result
&& GetLastError()==ERROR_INVALID_PARAMETER
, "expected %i, got %d\n",
779 ERROR_INVALID_PARAMETER
, GetLastError());
781 /* check for invalid flag */
783 result
= pCryptGetDefaultProviderA(provType
, NULL
, flags
, provName
, &provNameSize
);
784 ok(!result
&& GetLastError()==NTE_BAD_FLAGS
, "expected %d, got %d\n",
785 NTE_BAD_FLAGS
, GetLastError());
786 flags
= CRYPT_MACHINE_DEFAULT
;
788 /* check for invalid prov type */
789 provType
= 0xdeadbeef;
790 result
= pCryptGetDefaultProviderA(provType
, NULL
, flags
, provName
, &provNameSize
);
791 ok(!result
&& (GetLastError() == NTE_BAD_PROV_TYPE
||
792 GetLastError() == ERROR_INVALID_PARAMETER
),
793 "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n",
794 result
, GetLastError());
795 provType
= PROV_RSA_FULL
;
799 /* alloc provName to half the size required
800 * cbProvName holds the size required */
801 provNameSize
= cbProvName
/ 2;
802 if (!(provName
= LocalAlloc(LMEM_ZEROINIT
, provNameSize
)))
805 result
= pCryptGetDefaultProviderA(provType
, NULL
, flags
, provName
, &provNameSize
);
806 ok(!result
&& GetLastError()==ERROR_MORE_DATA
, "expected %i, got %d\n",
807 ERROR_MORE_DATA
, GetLastError());
811 /* check expected versus actual values returned */
812 result
= pCryptGetDefaultProviderA(provType
, NULL
, flags
, NULL
, &provNameSize
);
813 ok(result
&& provNameSize
==cbProvName
, "expected %d, got %d\n", cbProvName
, provNameSize
);
814 provNameSize
= cbProvName
;
816 if (!(provName
= LocalAlloc(LMEM_ZEROINIT
, provNameSize
)))
819 provNameSize
= 0xdeadbeef;
820 result
= pCryptGetDefaultProviderA(provType
, NULL
, flags
, provName
, &provNameSize
);
821 ok(result
, "expected TRUE, got %d\n", result
);
823 ok(!strcmp(pszProvName
, provName
), "expected %s, got %s\n", pszProvName
, provName
);
824 ok(provNameSize
==cbProvName
, "expected %d, got %d\n", cbProvName
, provNameSize
);
829 static void test_set_provider_ex(void)
835 LPSTR pszProvName
= NULL
;
838 if(!pCryptGetDefaultProviderA
|| !pCryptSetProviderExA
)
840 skip("CryptGetDefaultProviderA and/or CryptSetProviderExA are not available\n");
844 /* check pdwReserved for NULL */
845 result
= pCryptSetProviderExA(MS_DEF_PROV
, PROV_RSA_FULL
, ¬Null
, CRYPT_MACHINE_DEFAULT
);
846 ok(!result
&& GetLastError()==ERROR_INVALID_PARAMETER
, "expected %i, got %d\n",
847 ERROR_INVALID_PARAMETER
, GetLastError());
849 /* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */
850 SetLastError(0xdeadbeef);
851 result
= pCryptSetProviderExA(MS_DEF_PROV
, PROV_RSA_FULL
, NULL
, CRYPT_MACHINE_DEFAULT
| CRYPT_DELETE_DEFAULT
);
852 if (!result
&& (GetLastError() == ERROR_ACCESS_DENIED
))
854 skip("Not enough rights to remove the default provider\n");
857 ok(result
, "%d\n", GetLastError());
859 result
= pCryptSetProviderExA(MS_DEF_PROV
, PROV_RSA_FULL
, NULL
, CRYPT_MACHINE_DEFAULT
);
860 ok(result
, "%d\n", GetLastError());
862 /* call CryptGetDefaultProvider to see if they match */
863 result
= pCryptGetDefaultProviderA(PROV_RSA_FULL
, NULL
, CRYPT_MACHINE_DEFAULT
, NULL
, &cbProvName
);
864 if (!(pszProvName
= LocalAlloc(LMEM_ZEROINIT
, cbProvName
)))
867 result
= pCryptGetDefaultProviderA(PROV_RSA_FULL
, NULL
, CRYPT_MACHINE_DEFAULT
, pszProvName
, &cbProvName
);
868 ok(result
&& !strcmp(MS_DEF_PROV
, pszProvName
), "expected %s, got %s\n", MS_DEF_PROV
, pszProvName
);
869 ok(result
&& cbProvName
==(strlen(MS_DEF_PROV
) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV
) + 1), cbProvName
);
871 LocalFree(pszProvName
);
874 static void test_machine_guid(void)
876 char originalGuid
[40];
880 HCRYPTPROV hCryptProv
;
881 BOOL restoreGuid
= FALSE
, ret
;
883 r
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Cryptography",
884 0, KEY_ALL_ACCESS
, &key
);
885 if (r
!= ERROR_SUCCESS
)
887 skip("couldn't open HKLM\\Software\\Microsoft\\Cryptography\n");
890 /* Cache existing MachineGuid, and delete it */
891 size
= sizeof(originalGuid
);
892 r
= RegQueryValueExA(key
, "MachineGuid", NULL
, NULL
, (BYTE
*)originalGuid
,
894 if (r
== ERROR_SUCCESS
)
897 r
= RegDeleteValueA(key
, "MachineGuid");
898 ok(!r
, "RegDeleteValueA failed: %d\n", r
);
901 ok(r
== ERROR_FILE_NOT_FOUND
, "expected ERROR_FILE_NOT_FOUND, got %d\n",
903 /* Create and release a provider */
904 ret
= pCryptAcquireContextA(&hCryptProv
, szKeySet
, NULL
, PROV_RSA_FULL
, 0);
905 ok(ret
, "CryptAcquireContextA failed: %08x\n", GetLastError());
906 pCryptReleaseContext(hCryptProv
, 0);
909 RegSetValueExA(key
, "MachineGuid", 0, REG_SZ
, (const BYTE
*)originalGuid
,
910 strlen(originalGuid
)+1);
916 init_function_pointers();
917 if(pCryptAcquireContextA
&& pCryptReleaseContext
) {
919 test_acquire_context();
920 test_incorrect_api_usage();
923 clean_up_environment();
926 test_enum_providers();
927 test_enum_provider_types();
928 test_get_default_provider();
929 test_set_provider_ex();