Add support for generating SHA-256 hashes via CryptCATAdminCalcHashFromFileHandle2, which in turn requires CryptCATAdminAcquireContext2 in order to be able to specify the hashing algorithm.
From: Elias Norberg elias@aisle.se
--- dlls/wintrust/crypt.c | 64 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 12 deletions(-)
diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c index b2c5e31e87f..381c6375a9a 100644 --- a/dlls/wintrust/crypt.c +++ b/dlls/wintrust/crypt.c @@ -58,6 +58,9 @@ struct catadmin DWORD magic; WCHAR path[MAX_PATH]; HANDLE find; + ALG_ID alg; + const WCHAR *providerName; + DWORD providerType; };
struct catinfo @@ -97,6 +100,29 @@ static HCATINFO create_catinfo(const WCHAR *filename) */ BOOL WINAPI CryptCATAdminAcquireContext(HCATADMIN *catAdmin, const GUID *sys, DWORD dwFlags) +{ + TRACE("%p %s %lx\n", catAdmin, debugstr_guid(sys), dwFlags); + return CryptCATAdminAcquireContext2(catAdmin, sys, NULL, NULL, dwFlags); +} + +/*********************************************************************** + * CryptCATAdminAcquireContext2 (WINTRUST.@) + * Get a catalog administrator context handle. + * + * PARAMS + * catAdmin [O] Pointer to the context handle. + * sys [I] Pointer to a GUID for the needed subsystem. + * algorithm [I] String of hashing algorithm to use for catalog (SHA1/SHA256). + * policy [I] Pointer to policy structure for checking strong signatures. + * dwFlags [I] Reserved. + * + * RETURNS + * Success: TRUE. catAdmin contains the context handle. + * Failure: FALSE. + * + */ +BOOL WINAPI CryptCATAdminAcquireContext2(HCATADMIN *catAdmin, const GUID *sys, const WCHAR *algorithm, + const CERT_STRONG_SIGN_PARA *policy, DWORD dwFlags) { static const WCHAR catroot[] = {'\','c','a','t','r','o','o','t',0}; @@ -110,20 +136,45 @@ BOOL WINAPI CryptCATAdminAcquireContext(HCATADMIN *catAdmin,
WCHAR catroot_dir[MAX_PATH]; struct catadmin *ca; + ALG_ID alg; + const WCHAR *providerName; + DWORD providerType;
- TRACE("%p %s %lx\n", catAdmin, debugstr_guid(sys), dwFlags); + TRACE("%p %s %s %p %lx\n", catAdmin, debugstr_guid(sys), debugstr_w(algorithm), policy, dwFlags);
if (!catAdmin || dwFlags) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } + + if (policy != NULL) { + FIXME("strong policy parameter is unimplemented\n"); + } + + if (algorithm == NULL || wcscmp(algorithm, BCRYPT_SHA1_ALGORITHM) == 0) { + alg = CALG_SHA1; + providerName = MS_DEF_PROV_W; + providerType = PROV_RSA_FULL; + } else if (wcscmp(algorithm, BCRYPT_SHA256_ALGORITHM) == 0) { + alg = CALG_SHA_256; + providerName = MS_ENH_RSA_AES_PROV_W; + providerType = PROV_RSA_AES; + } else { + SetLastError(NTE_BAD_ALGID); + return FALSE; + } + if (!(ca = malloc(sizeof(*ca)))) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; }
+ ca->alg = alg; + ca->providerName = providerName; + ca->providerType = providerType; + GetSystemDirectoryW(catroot_dir, MAX_PATH); lstrcatW(catroot_dir, catroot);
@@ -146,17 +197,6 @@ BOOL WINAPI CryptCATAdminAcquireContext(HCATADMIN *catAdmin, return TRUE; }
-/*********************************************************************** - * CryptCATAdminAcquireContext2 (WINTRUST.@) - */ -BOOL WINAPI CryptCATAdminAcquireContext2(HCATADMIN *catAdmin, const GUID *sys, const WCHAR *algorithm, - const CERT_STRONG_SIGN_PARA *policy, DWORD flags) -{ - FIXME("%p %s %s %p %lx stub\n", catAdmin, debugstr_guid(sys), debugstr_w(algorithm), policy, flags); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - /*********************************************************************** * CryptCATAdminAddCatalog (WINTRUST.@) */
From: Elias Norberg elias@aisle.se
--- dlls/wintrust/tests/crypt.c | 130 ++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
diff --git a/dlls/wintrust/tests/crypt.c b/dlls/wintrust/tests/crypt.c index ca246776046..06aa9bc0514 100644 --- a/dlls/wintrust/tests/crypt.c +++ b/dlls/wintrust/tests/crypt.c @@ -99,6 +99,7 @@ static const BYTE test_catalog[] = { };
static BOOL (WINAPI * pCryptCATAdminAcquireContext)(HCATADMIN*, const GUID*, DWORD); +static BOOL (WINAPI * pCryptCATAdminAcquireContext2)(HCATADMIN*, const GUID*, const WCHAR *, const CERT_STRONG_SIGN_PARA *, DWORD); static BOOL (WINAPI * pCryptCATAdminReleaseContext)(HCATADMIN, DWORD); static BOOL (WINAPI * pCryptCATAdminCalcHashFromFileHandle)(HANDLE hFile, DWORD*, BYTE*, DWORD); static HCATINFO (WINAPI * pCryptCATAdminAddCatalog)(HCATADMIN, PWSTR, PWSTR, DWORD); @@ -130,6 +131,7 @@ static void InitFunctionPtrs(void) }
WINTRUST_GET_PROC(CryptCATAdminAcquireContext) + WINTRUST_GET_PROC(CryptCATAdminAcquireContext2) WINTRUST_GET_PROC(CryptCATAdminReleaseContext) WINTRUST_GET_PROC(CryptCATAdminCalcHashFromFileHandle) WINTRUST_GET_PROC(CryptCATAdminAddCatalog) @@ -303,6 +305,133 @@ static void test_context(void) } }
+static void test_context2(void) +{ + BOOL ret; + HCATADMIN hca; + static GUID unknown = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; /* WINTRUST.DLL */ + static const WCHAR unknown_alg[] = {'A', 'L', 'G', '-', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\0'}; + CHAR dummydir[MAX_PATH]; + DWORD attrs; + + /* See comments in test_context() for information about which directories CryptCATAdminAcquireContext creates + * Note that CryptCATAdminReleaseContext is primarily tested in test_context(). + */ + + /* All NULL */ + SetLastError(0xdeadbeef); + ret = pCryptCATAdminAcquireContext2(NULL, NULL, NULL, NULL, 0); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + + /* NULL GUID */ + ret = pCryptCATAdminAcquireContext2(&hca, NULL, NULL, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(hca != NULL, "Expected a context handle, got NULL\n"); + + /* Release context again */ + SetLastError(0xdeadbeef); + ret = pCryptCATAdminReleaseContext(hca, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + + /* NULL context handle and dummy GUID */ + SetLastError(0xdeadbeef); + ret = pCryptCATAdminAcquireContext2(NULL, &dummy, NULL, NULL, 0); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + + /* Correct context handle and dummy GUID + * + * The tests run in the past unfortunately made sure that some directories were created. + * + * FIXME: + * We don't want to mess too much with these for now so we should delete only the ones + * that shouldn't be there like the deadbeef ones. We first have to figure out if it's + * safe to remove files and directories from CatRoot/CatRoot2. + */ + + ret = pCryptCATAdminAcquireContext2(&hca, &dummy, NULL, NULL, 0); + ok(ret || GetLastError() == ERROR_ACCESS_DENIED, "CryptCATAdminAcquireContext failed %lu\n", GetLastError()); + if (!ret && GetLastError() == ERROR_ACCESS_DENIED) + { + win_skip("Not running as administrator\n"); + return; + } + ok(hca != NULL, "Expected a context handle, got NULL\n"); + + attrs = GetFileAttributesA(catroot); + ok(attrs != INVALID_FILE_ATTRIBUTES, "Expected the CatRoot directory to exist\n"); + + /* Windows creates the GUID directory in capitals */ + lstrcpyA(dummydir, catroot); + lstrcatA(dummydir, "\{DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF}"); + attrs = GetFileAttributesA(dummydir); + ok(attrs != INVALID_FILE_ATTRIBUTES, + "Expected CatRoot\{DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF} directory to exist\n"); + + /* Only present on XP or higher. */ + attrs = GetFileAttributesA(catroot2); + if (attrs != INVALID_FILE_ATTRIBUTES) + { + lstrcpyA(dummydir, catroot2); + lstrcatA(dummydir, "\{DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF}"); + attrs = GetFileAttributesA(dummydir); + ok(attrs != INVALID_FILE_ATTRIBUTES, + "Expected CatRoot2\{DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF} directory to exist\n"); + } + + ret = pCryptCATAdminReleaseContext(hca, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + + /* Correct context handle and GUID */ + ret = pCryptCATAdminAcquireContext2(&hca, &unknown, NULL, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(hca != NULL, "Expected a context handle, got NULL\n"); + + ret = pCryptCATAdminReleaseContext(hca, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + + hca = (void *) 0xdeadbeef; + SetLastError(0xdeadbeef); + /* Flags is documented as unused, but the parameter is checked since win8 */ + ret = pCryptCATAdminAcquireContext2(&hca, &unknown, NULL, NULL, 1); + ok((!ret && (GetLastError() == ERROR_INVALID_PARAMETER) && (hca == (void *) 0xdeadbeef)) || + broken(ret && hca != NULL && hca != (void *) 0xdeadbeef), + "Expected FALSE and ERROR_INVALID_PARAMETER with untouched handle, got %d and %lu with %p\n", + ret, GetLastError(), hca); + + if (ret && hca) + { + SetLastError(0xdeadbeef); + ret = pCryptCATAdminReleaseContext(hca, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + } + + /* Specify SHA-1 algorithm */ + + ret = pCryptCATAdminAcquireContext2(&hca, &unknown, BCRYPT_SHA1_ALGORITHM, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(hca != NULL, "Expected a context handle, got NULL\n"); + + ret = pCryptCATAdminReleaseContext(hca, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + + /* Specify SHA-256 algorithm */ + ret = pCryptCATAdminAcquireContext2(&hca, &unknown, BCRYPT_SHA256_ALGORITHM, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(hca != NULL, "Expected a context handle, got NULL\n"); + + ret = pCryptCATAdminReleaseContext(hca, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + + /* Set unknown algorithm - should fall back to default */ + ret = pCryptCATAdminAcquireContext2(&hca, &unknown, unknown_alg, NULL, 0); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == NTE_BAD_ALGID, "Expected NTE_BAD_ALGID, got %ld\n", GetLastError()); +} + /* TODO: Check whether SHA-1 is the algorithm that's always used */ static void test_calchash(void) { @@ -1361,6 +1490,7 @@ START_TEST(crypt) GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
test_context(); + test_context2(); test_calchash(); test_CryptCATOpen(); /* Parameter checking only */
From: Elias Norberg elias@aisle.se
--- dlls/wintrust/crypt.c | 84 +++++++++++++++++++++++++++++++------ dlls/wintrust/wintrust.spec | 2 +- 2 files changed, 73 insertions(+), 13 deletions(-)
diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c index 381c6375a9a..5f08a371780 100644 --- a/dlls/wintrust/crypt.c +++ b/dlls/wintrust/crypt.c @@ -328,28 +328,47 @@ done: return ret; }
-/*********************************************************************** - * CryptCATAdminCalcHashFromFileHandle (WINTRUST.@) - */ -BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD *pcbHash, BYTE *pbHash, DWORD dwFlags) +static BOOL catadmin_calc_hash_from_filehandle(HCATADMIN catAdmin, HANDLE hFile, DWORD *pcbHash, + BYTE *pbHash, DWORD dwFlags) { BOOL ret = FALSE; - - TRACE("%p %p %p %lx\n", hFile, pcbHash, pbHash, dwFlags); + struct catadmin *ca = catAdmin; + ALG_ID alg = CALG_SHA1; + const WCHAR *providerName = MS_DEF_PROV_W; + DWORD providerType = PROV_RSA_FULL; + DWORD hashLength = 20;
if (!hFile || !pcbHash || dwFlags) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - if (*pcbHash < 20) - { - *pcbHash = 20; + + if (ca && ca->magic == CATADMIN_MAGIC) { + alg = ca->alg; + providerName = ca->providerName; + providerType = ca->providerType; + } + + switch (alg) { + case CALG_SHA1: + hashLength = 20; + break; + case CALG_SHA_256: + hashLength = 32; + break; + default: + FIXME("unsupported algorithm %x\n", alg); + return FALSE; + } + + if (*pcbHash < hashLength) { + *pcbHash = hashLength; SetLastError(ERROR_INSUFFICIENT_BUFFER); return TRUE; }
- *pcbHash = 20; + *pcbHash = hashLength; if (pbHash) { HCRYPTPROV prov; @@ -362,13 +381,13 @@ BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD *pcbHash, BY SetLastError(ERROR_OUTOFMEMORY); return FALSE; } - ret = CryptAcquireContextW(&prov, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ret = CryptAcquireContextW(&prov, NULL, providerName, providerType, CRYPT_VERIFYCONTEXT); if (!ret) { free(buffer); return FALSE; } - ret = CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash); + ret = CryptCreateHash(prov, alg, 0, 0, &hash); if (!ret) { free(buffer); @@ -392,6 +411,47 @@ BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD *pcbHash, BY return ret; }
+/*********************************************************************** + * CryptCATAdminCalcHashFromFileHandle (WINTRUST.@) + */ +BOOL WINAPI CryptCATAdminCalcHashFromFileHandle(HANDLE hFile, DWORD *pcbHash, BYTE *pbHash, DWORD dwFlags) +{ + TRACE("%p %p %p %lx\n", hFile, pcbHash, pbHash, dwFlags); + return catadmin_calc_hash_from_filehandle(NULL, hFile, pcbHash, pbHash, dwFlags); +} + +/*********************************************************************** + * CryptCATAdminCalcHashFromFileHandle2 (WINTRUST.@) + * + * Calculate hash for a specific file using a catalog administrator context. + * + * PARAMS + * catAdmin [I] Catalog administrator context handle. + * hFile [I] Handle for the file to hash. + * pcbHash [I] Pointer to the length of the hash. + * pbHash [O] Pointer to the buffer that will store that hash + * dwFlags [I] Reserved. + * + * RETURNS + * Success: TRUE. If pcbHash is too small, LastError will be set to ERROR_INSUFFICIENT_BUFFER. + * pbHash contains the computed hash, if supplied. + * Failure: FALSE. + * + */ +BOOL WINAPI CryptCATAdminCalcHashFromFileHandle2(HCATADMIN catAdmin, HANDLE hFile, DWORD *pcbHash, + BYTE *pbHash, DWORD dwFlags) +{ + TRACE("%p %p %p %p %lx\n", catAdmin, hFile, pcbHash, pbHash, dwFlags); + + if (!catAdmin || ((struct catadmin *)catAdmin)->magic != CATADMIN_MAGIC) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + return catadmin_calc_hash_from_filehandle(catAdmin, hFile, pcbHash, pbHash, dwFlags); +} + + /*********************************************************************** * CryptCATAdminEnumCatalogFromHash (WINTRUST.@) */ diff --git a/dlls/wintrust/wintrust.spec b/dlls/wintrust/wintrust.spec index 06db4a1159e..79e9bd32a75 100644 --- a/dlls/wintrust/wintrust.spec +++ b/dlls/wintrust/wintrust.spec @@ -7,7 +7,7 @@ @ stdcall CryptCATAdminAcquireContext2(ptr ptr wstr ptr long) @ stdcall CryptCATAdminAddCatalog(long wstr wstr long) @ stdcall CryptCATAdminCalcHashFromFileHandle(long ptr ptr long) -#@ stub CryptCATAdminCalcHashFromFileHandle2 +@ stdcall CryptCATAdminCalcHashFromFileHandle2(ptr ptr ptr ptr long) @ stdcall CryptCATAdminEnumCatalogFromHash(long ptr long long ptr) @ stub CryptCATAdminPauseServiceForBackup @ stdcall CryptCATAdminReleaseCatalogContext(long long long)
From: Elias Norberg elias@aisle.se
--- dlls/wintrust/tests/crypt.c | 157 ++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+)
diff --git a/dlls/wintrust/tests/crypt.c b/dlls/wintrust/tests/crypt.c index 06aa9bc0514..7631b33a342 100644 --- a/dlls/wintrust/tests/crypt.c +++ b/dlls/wintrust/tests/crypt.c @@ -102,6 +102,7 @@ static BOOL (WINAPI * pCryptCATAdminAcquireContext)(HCATADMIN*, const GUID*, DWO static BOOL (WINAPI * pCryptCATAdminAcquireContext2)(HCATADMIN*, const GUID*, const WCHAR *, const CERT_STRONG_SIGN_PARA *, DWORD); static BOOL (WINAPI * pCryptCATAdminReleaseContext)(HCATADMIN, DWORD); static BOOL (WINAPI * pCryptCATAdminCalcHashFromFileHandle)(HANDLE hFile, DWORD*, BYTE*, DWORD); +static BOOL (WINAPI * pCryptCATAdminCalcHashFromFileHandle2)(HCATADMIN, HANDLE hFile, DWORD*, BYTE*, DWORD); static HCATINFO (WINAPI * pCryptCATAdminAddCatalog)(HCATADMIN, PWSTR, PWSTR, DWORD); static BOOL (WINAPI * pCryptCATAdminRemoveCatalog)(HCATADMIN, LPCWSTR, DWORD); static BOOL (WINAPI * pCryptCATAdminReleaseCatalogContext)(HCATADMIN, HCATINFO, DWORD); @@ -134,6 +135,7 @@ static void InitFunctionPtrs(void) WINTRUST_GET_PROC(CryptCATAdminAcquireContext2) WINTRUST_GET_PROC(CryptCATAdminReleaseContext) WINTRUST_GET_PROC(CryptCATAdminCalcHashFromFileHandle) + WINTRUST_GET_PROC(CryptCATAdminCalcHashFromFileHandle2) WINTRUST_GET_PROC(CryptCATAdminAddCatalog) WINTRUST_GET_PROC(CryptCATAdminRemoveCatalog) WINTRUST_GET_PROC(CryptCATAdminReleaseCatalogContext) @@ -528,6 +530,160 @@ static void test_calchash(void) DeleteFileA(temp); }
+static void test_calchash2(void) +{ + BOOL ret; + HCATADMIN hca_sha1, hca_sha256; + HANDLE file; + DWORD hashsize = 0; + BYTE* hash; + BYTE expectedhash_sha1[20] = {0x3a,0xa1,0x19,0x08,0xec,0xa6,0x0d,0x2e,0x7e,0xcc,0x7a,0xca,0xf5,0xb8,0x2e,0x62,0x6a,0xda,0xf0,0x19}; + BYTE expectedhash_sha256[32] = { 0x8a, 0xfd, 0x8c, 0xec, 0xdd, 0xe3, 0x0b, 0xaa, 0x2f, 0x1c, 0x3f, 0x61, 0xaf, 0xdf, 0x24, 0x84, 0x99, 0x8b, 0xe3, 0xcf, 0xda, 0xff, 0x0c, 0x5e, 0xa8, 0x68, 0xe8, 0xea, 0x94, 0x1e, 0x90, 0xe2}; + CHAR temp[MAX_PATH]; + DWORD written; + int i; + + /* All NULL */ + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(NULL, NULL, NULL, NULL, 0); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + + /* NULL catadmin, NULL filehandle, rest is legal */ + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(NULL, NULL, &hashsize, NULL, 0); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + + /* Correct filehandle, rest is NULL */ + file = CreateFileA(selfname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(NULL, file, NULL, NULL, 0); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + CloseHandle(file); + + /* Correct catadmin, rest is NULL */ + ret = pCryptCATAdminAcquireContext2(&hca_sha1, NULL, BCRYPT_SHA1_ALGORITHM, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha1, NULL, NULL, NULL, 0); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + + /* All OK, but dwFlags set to 1 */ + file = CreateFileA(selfname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha1, file, &hashsize, NULL, 1); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + CloseHandle(file); + + /* All OK, requesting the size of SHA1 hash */ + file = CreateFileA(selfname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed %lu\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha1, file, &hashsize, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(hashsize == 20," Expected a hash size of 20, got %ld\n", hashsize); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + CloseHandle(file); + + /* All OK, retrieve the SHA1 hash + * Double the hash buffer to see what happens to the size parameter + */ + file = CreateFileA(selfname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + hashsize *= 2; + hash = HeapAlloc(GetProcessHeap(), 0, hashsize); + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha1, file, &hashsize, hash, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(hashsize == 20," Expected a hash size of 20, got %ld\n", hashsize); + ok(GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); + CloseHandle(file); + HeapFree(GetProcessHeap(), 0, hash); + + /* Do the same test with a file created and filled by ourselves (and we thus + * have a known hash for). + */ + GetTempFileNameA(CURR_DIR, "hsh", 0, temp); + file = CreateFileA(temp, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + WriteFile(file, "Text in this file is needed to create a know hash", 49, &written, NULL); + CloseHandle(file); + + /* All OK, first request the size and then retrieve the SHA1 hash */ + file = CreateFileA(temp, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + hashsize = 0; + pCryptCATAdminCalcHashFromFileHandle2(hca_sha1, file, &hashsize, NULL, 0); + hash = HeapAlloc(GetProcessHeap(), 0, hashsize); + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha1, file, &hashsize, hash, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); + ok(hashsize == sizeof(expectedhash_sha1) && + !memcmp(hash, expectedhash_sha1, sizeof(expectedhash_sha1)), + "Hashes didn't match\n"); + CloseHandle(file); + HeapFree(GetProcessHeap(), 0, hash); + pCryptCATAdminReleaseContext(hca_sha1, 0); + + ret = pCryptCATAdminAcquireContext2(&hca_sha256, NULL, BCRYPT_SHA256_ALGORITHM, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + + /* All OK, requesting the size of the SHA-256 hash */ + file = CreateFileA(selfname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed %lu\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha256, file, &hashsize, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(hashsize == 32," Expected a hash size of 32, got %ld\n", hashsize); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + CloseHandle(file); + + /* All OK, retrieve the SHA1 hash + * Double the hash buffer to see what happens to the size parameter + */ + file = CreateFileA(selfname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + hashsize *= 2; + hash = HeapAlloc(GetProcessHeap(), 0, hashsize); + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha256, file, &hashsize, hash, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(hashsize == 32," Expected a hash size of 32, got %ld\n", hashsize); + ok(GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); + CloseHandle(file); + HeapFree(GetProcessHeap(), 0, hash); + + /* All OK, first request the size and then retrieve the SHA256 hash */ + file = CreateFileA(temp, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + hashsize = 0; + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha256, file, &hashsize, NULL, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + hash = HeapAlloc(GetProcessHeap(), 0, hashsize); + SetLastError(0xdeadbeef); + ret = pCryptCATAdminCalcHashFromFileHandle2(hca_sha256, file, &hashsize, hash, 0); + ok(ret, "Expected success, got FALSE with %ld\n", GetLastError()); + ok(GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); + ok(hashsize == sizeof(expectedhash_sha256) && + !memcmp(hash, expectedhash_sha256, sizeof(expectedhash_sha256)), + "Hashes didn't match\n"); + CloseHandle(file); + HeapFree(GetProcessHeap(), 0, hash); + pCryptCATAdminReleaseContext(hca_sha256, 0); + DeleteFileA(temp); +} + static void test_CryptCATOpen(void) { WCHAR filename[MAX_PATH], temp_path[MAX_PATH]; @@ -1492,6 +1648,7 @@ START_TEST(crypt) test_context(); test_context2(); test_calchash(); + test_calchash2(); test_CryptCATOpen(); /* Parameter checking only */ test_CryptCATCDF_params();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149734
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: win.c:4073: Test succeeded inside todo block: Expected active window 0000000005D40144, got 0000000005D40144. win.c:4074: Test succeeded inside todo block: Expected focus window 0000000005D40144, got 0000000005D40144.
winmm: mci: Timeout