My first patch, I could use a review. Thanks.
--- dlls/crypt32/cert.c | 59 +++++++++++++++++++++++++++++++++++++++ dlls/crypt32/crypt32.spec | 1 + include/wincrypt.h | 4 +++ 3 files changed, 64 insertions(+)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 2d4ce8c10c..82d06e2e33 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -2213,6 +2213,65 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, return ret; }
+BOOL WINAPI CryptHashCertificate2(LPCWSTR pwszCNGHashAlgid, DWORD dwFlags, + void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, + DWORD *pcbComputedHash) +{ + BCRYPT_HASH_HANDLE hash = NULL; + BCRYPT_ALG_HANDLE alg = NULL; + NTSTATUS status; + DWORD hash_len; + DWORD hash_len_size; + + TRACE("(%s, %08x, %p, %p, %d, %p, %p)\n", debugstr_w(pwszCNGHashAlgid), + dwFlags, pvReserved, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash); + + if (pcbComputedHash == NULL) + { + status = STATUS_INVALID_PARAMETER; + goto done; + } + + if ((status = BCryptOpenAlgorithmProvider(&alg, pwszCNGHashAlgid, NULL, 0))) + goto done; + + if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0))) + goto done; + + if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)&hash_len, sizeof(hash_len), &hash_len_size, 0))) + goto done; + + if (pbComputedHash == NULL) + { + *pcbComputedHash = hash_len; + goto done; + } + + if (*pcbComputedHash < hash_len) + { + status = STATUS_INVALID_PARAMETER; + goto done; + } + else + { + *pcbComputedHash = hash_len; + } + + if ((status = BCryptHashData(hash, (BYTE *)pbEncoded, cbEncoded, 0))) + goto done; + + if ((status = BCryptFinishHash(hash, pbComputedHash, hash_len, 0))) + { + goto done; + } + +done: + if (hash) BCryptDestroyHash(hash); + if (alg) BCryptCloseAlgorithmProvider(alg, 0); + if (status) SetLastError(RtlNtStatusToDosError(status)); + return status == 0; +} + BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash) diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index fc32570b52..fa507dfc65 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -136,6 +136,7 @@ @ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr) @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr) @ stdcall CryptHashCertificate(long long long ptr long ptr ptr) +@ stdcall CryptHashCertificate2(wstr long ptr ptr long ptr ptr) @ stdcall CryptHashMessage(ptr long long ptr ptr ptr ptr ptr ptr) @ stdcall CryptHashPublicKeyInfo(long long long long ptr ptr ptr) @ stdcall CryptHashToBeSigned(ptr long ptr long ptr ptr) diff --git a/include/wincrypt.h b/include/wincrypt.h index a1b1305902..cbc76d7f10 100644 --- a/include/wincrypt.h +++ b/include/wincrypt.h @@ -4379,6 +4379,10 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash);
+BOOL WINAPI CryptHashCertificate2(LPCWSTR pwszCNGHashAlgid, DWORD dwFlags, + void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, + DWORD *pcbComputedHash); + BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash);
--- dlls/crypt32/tests/cert.c | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+)
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index f653741ea7..ddda156cc5 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -1784,6 +1784,70 @@ static void testCryptHashCert(void) ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n"); }
+static void testCryptHashCert2(void) +{ + static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, + 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, + 0x09 }; + static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee, + 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8, + 0xa2 }; + static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:"; + BOOL ret; + BYTE hash[20]; + DWORD hashLen; + const WCHAR SHA1[] = { 'S', 'H', 'A', '1', '\0' }; + const WCHAR invalidAlgorithm[] = { 'I', 'H', 'A', '9', '9', '\0' }; + + /* Test empty hash */ + hashLen = sizeof(hash); + ret = CryptHashCertificate2(SHA1, 0, NULL, NULL, 0, hash, &hashLen); + ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError()); + ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen); + ok(!memcmp(hash, emptyHash, sizeof(emptyHash)), "Unexpected hash of nothing\n"); + + /* Test known hash */ + hashLen = sizeof(hash); + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), hash, &hashLen); + ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError()); + ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen); + ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n"); + + /* Test null hash size pointer just sets hash size */ + hashLen = 0; + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), NULL, &hashLen); + ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError()); + ok(hashLen == sizeof(hash), "Hash size not set correctly (%d)\n", hashLen); + + /* Test invalid algorithm ID */ + hashLen = sizeof(hash); + ret = CryptHashCertificate2(NULL, 0, NULL, toHash, sizeof(toHash), hash, &hashLen); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER (%d), got %d\n", ERROR_INVALID_PARAMETER, GetLastError()); + + /* Test invalid algorithm */ + hashLen = sizeof(hash); + ret = CryptHashCertificate2(invalidAlgorithm, 0, NULL, toHash, sizeof(toHash), hash, &hashLen); + ok(!ret && GetLastError() == ERROR_INVALID_FUNCTION, + "Expected ERROR_INVALID_FUNCTION (%d), got %d\n", ERROR_INVALID_FUNCTION, GetLastError()); + + /* Test hash buffer too small */ + hashLen = sizeof(hash) / 2; + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), hash, &hashLen); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER (%d), got %d\n", ERROR_INVALID_PARAMETER, GetLastError()); + + /* Test hashLen null with hash */ + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), hash, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER (%d), got %d\n", ERROR_INVALID_PARAMETER, GetLastError()); + + /* Test hashLen null with no hash */ + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), NULL, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER (%d), got %d\n", ERROR_INVALID_PARAMETER, GetLastError()); +} + static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen, const BYTE *sig, unsigned int sigLen) { @@ -4074,6 +4138,7 @@ START_TEST(cert) testLinkCert();
testCryptHashCert(); + testCryptHashCert2(); testCertSigs(); testSignAndEncodeCert(); testCreateSelfSignCert();
On Wed, Jan 23, 2019 at 1:26 PM Orhan 'aib' Kavrakoğlu aibok42@gmail.com wrote:
You need to sign off this patch as well.
dlls/crypt32/tests/cert.c | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+)
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index f653741ea7..ddda156cc5 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -1784,6 +1784,70 @@ static void testCryptHashCert(void) ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n"); }
+static void testCryptHashCert2(void) +{
- static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b,
0x4b,
0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8,
0x07,
0x09 };
- static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46,
0xee,
0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52,
0xa8,
0xa2 };
- static const BYTE toHash[] =
"abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
- BOOL ret;
- BYTE hash[20];
- DWORD hashLen;
- const WCHAR SHA1[] = { 'S', 'H', 'A', '1', '\0' };
- const WCHAR invalidAlgorithm[] = { 'I', 'H', 'A', '9', '9', '\0' };
- /* Test empty hash */
- hashLen = sizeof(hash);
- ret = CryptHashCertificate2(SHA1, 0, NULL, NULL, 0, hash, &hashLen);
- ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError());
- ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n",
hashLen);
- ok(!memcmp(hash, emptyHash, sizeof(emptyHash)), "Unexpected hash of
nothing\n");
- /* Test known hash */
- hashLen = sizeof(hash);
- ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash),
hash, &hashLen);
- ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError());
- ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n",
hashLen);
- ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
- /* Test null hash size pointer just sets hash size */
- hashLen = 0;
- ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash),
NULL, &hashLen);
- ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError());
- ok(hashLen == sizeof(hash), "Hash size not set correctly (%d)\n",
hashLen);
- /* Test invalid algorithm ID */
- hashLen = sizeof(hash);
- ret = CryptHashCertificate2(NULL, 0, NULL, toHash, sizeof(toHash),
hash, &hashLen);
- ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER (%d), got %d\n",
ERROR_INVALID_PARAMETER, GetLastError());
- /* Test invalid algorithm */
- hashLen = sizeof(hash);
- ret = CryptHashCertificate2(invalidAlgorithm, 0, NULL, toHash,
sizeof(toHash), hash, &hashLen);
- ok(!ret && GetLastError() == ERROR_INVALID_FUNCTION,
"Expected ERROR_INVALID_FUNCTION (%d), got %d\n",
ERROR_INVALID_FUNCTION, GetLastError());
- /* Test hash buffer too small */
- hashLen = sizeof(hash) / 2;
- ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash),
hash, &hashLen);
- ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER (%d), got %d\n",
ERROR_INVALID_PARAMETER, GetLastError());
- /* Test hashLen null with hash */
- ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash),
hash, NULL);
- ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER (%d), got %d\n",
ERROR_INVALID_PARAMETER, GetLastError());
- /* Test hashLen null with no hash */
- ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash),
NULL, NULL);
- ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER (%d), got %d\n",
ERROR_INVALID_PARAMETER, GetLastError()); +}
static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen, const BYTE *sig, unsigned int sigLen) { @@ -4074,6 +4138,7 @@ START_TEST(cert) testLinkCert();
testCryptHashCert();
- testCryptHashCert2(); testCertSigs(); testSignAndEncodeCert(); testCreateSelfSignCert();
-- 2.19.1
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=46494
Your paranoid android.
=== build (build log) ===
error: corrupt patch at line 142 Task: Patch failed to apply
=== debian9 (build log) ===
error: corrupt patch at line 142 Task: Patch failed to apply
=== debian9 (build log) ===
error: corrupt patch at line 142 Task: Patch failed to apply
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=46489
Your paranoid android.
=== wxppro (32 bit report) ===
crypt32: cert: Timeout
=== w2003std (32 bit report) ===
crypt32: cert: Timeout
=== wvistau64 (32 bit report) ===
crypt32: 0890:cert: unhandled exception c0000005 at 76139B3D
=== wvistau64_zh_CN (32 bit report) ===
crypt32: 0bbc:cert: unhandled exception c0000005 at 75169B3D
=== wvistau64_fr (32 bit report) ===
crypt32: 072c:cert: unhandled exception c0000005 at 75B79B3D
=== wvistau64_he (32 bit report) ===
crypt32: 0bdc:cert: unhandled exception c0000005 at 75AC9B3D
=== w2008s64 (32 bit report) ===
crypt32: 0870:cert: unhandled exception c0000005 at 75809B3D
=== w7u (32 bit report) ===
crypt32: 0ccc:cert: unhandled exception c0000005 at 76189B69
=== w7pro64 (32 bit report) ===
crypt32: 0ad8:cert: unhandled exception c0000005 at 750A9B69
=== w8 (32 bit report) ===
crypt32: 0db4:cert: unhandled exception c0000005 at 77389EAA
=== w8adm (32 bit report) ===
crypt32: 012c:cert: unhandled exception c0000005 at 77389EAA
=== w864 (32 bit report) ===
crypt32: 0a28:cert: unhandled exception c0000005 at 758F9EAA
=== w1064 (32 bit report) ===
crypt32: 0764:cert: unhandled exception c0000005 at 75478658
=== wvistau64 (64 bit report) ===
crypt32: 0890:cert: unhandled exception c0000005 at 000007FEFDA01342
=== w2008s64 (64 bit report) ===
crypt32: 0870:cert: unhandled exception c0000005 at 000007FEFE3A1342
=== w7pro64 (64 bit report) ===
crypt32: 0aec:cert: unhandled exception c0000005 at 000007FEFDEC12B9
=== w864 (64 bit report) ===
crypt32: 074c:cert: unhandled exception c0000005 at 00007FFB25311A31
=== w1064 (64 bit report) ===
crypt32: 0b6c:cert: unhandled exception c0000005 at 00007FFC3B693C60
On Wed, Jan 23, 2019 at 1:26 PM Orhan 'aib' Kavrakoğlu aibok42@gmail.com wrote:
My first patch, I could use a review. Thanks.
You need to sign off the patch.
dlls/crypt32/cert.c | 59 +++++++++++++++++++++++++++++++++++++++ dlls/crypt32/crypt32.spec | 1 + include/wincrypt.h | 4 +++ 3 files changed, 64 insertions(+)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 2d4ce8c10c..82d06e2e33 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -2213,6 +2213,65 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, return ret; }
+BOOL WINAPI CryptHashCertificate2(LPCWSTR pwszCNGHashAlgid, DWORD dwFlags,
- void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE
*pbComputedHash,
- DWORD *pcbComputedHash)
+{
- BCRYPT_HASH_HANDLE hash = NULL;
- BCRYPT_ALG_HANDLE alg = NULL;
- NTSTATUS status;
- DWORD hash_len;
- DWORD hash_len_size;
- TRACE("(%s, %08x, %p, %p, %d, %p, %p)\n",
debugstr_w(pwszCNGHashAlgid),
dwFlags, pvReserved, pbEncoded, cbEncoded, pbComputedHash,
pcbComputedHash);
- if (pcbComputedHash == NULL)
- {
status = STATUS_INVALID_PARAMETER;
goto done;
- }
- if ((status = BCryptOpenAlgorithmProvider(&alg, pwszCNGHashAlgid,
NULL, 0)))
goto done;
- if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0)))
goto done;
- if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE
*)&hash_len, sizeof(hash_len), &hash_len_size, 0)))
goto done;
- if (pbComputedHash == NULL)
- {
*pcbComputedHash = hash_len;
goto done;
- }
- if (*pcbComputedHash < hash_len)
- {
status = STATUS_INVALID_PARAMETER;
goto done;
- }
- else
- {
*pcbComputedHash = hash_len;
- }
- if ((status = BCryptHashData(hash, (BYTE *)pbEncoded, cbEncoded, 0)))
goto done;
- if ((status = BCryptFinishHash(hash, pbComputedHash, hash_len, 0)))
- {
goto done;
- }
+done:
- if (hash) BCryptDestroyHash(hash);
- if (alg) BCryptCloseAlgorithmProvider(alg, 0);
- if (status) SetLastError(RtlNtStatusToDosError(status));
- return status == 0;
+}
BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash) diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index fc32570b52..fa507dfc65 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -136,6 +136,7 @@ @ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr) @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr) @ stdcall CryptHashCertificate(long long long ptr long ptr ptr) +@ stdcall CryptHashCertificate2(wstr long ptr ptr long ptr ptr) @ stdcall CryptHashMessage(ptr long long ptr ptr ptr ptr ptr ptr) @ stdcall CryptHashPublicKeyInfo(long long long long ptr ptr ptr) @ stdcall CryptHashToBeSigned(ptr long ptr long ptr ptr) diff --git a/include/wincrypt.h b/include/wincrypt.h index a1b1305902..cbc76d7f10 100644 --- a/include/wincrypt.h +++ b/include/wincrypt.h @@ -4379,6 +4379,10 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash);
+BOOL WINAPI CryptHashCertificate2(LPCWSTR pwszCNGHashAlgid, DWORD dwFlags,
- void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE
*pbComputedHash,
- DWORD *pcbComputedHash);
BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash); -- 2.19.1
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=46493
Your paranoid android.
=== debian9 (build log) ===
error: corrupt patch at line 142 Task: Patch failed to apply
=== debian9 (build log) ===
error: corrupt patch at line 142 Task: Patch failed to apply
Signed-off-by: Orhan Kavrakoğlu aibok42@gmail.com --- dlls/crypt32/cert.c | 59 +++++++++++++++++++++++++++++++++++++++ dlls/crypt32/crypt32.spec | 1 + include/wincrypt.h | 4 +++ 3 files changed, 64 insertions(+)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 2d4ce8c10c..82d06e2e33 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -2213,6 +2213,65 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, return ret; }
+BOOL WINAPI CryptHashCertificate2(LPCWSTR pwszCNGHashAlgid, DWORD dwFlags, + void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, + DWORD *pcbComputedHash) +{ + BCRYPT_HASH_HANDLE hash = NULL; + BCRYPT_ALG_HANDLE alg = NULL; + NTSTATUS status; + DWORD hash_len; + DWORD hash_len_size; + + TRACE("(%s, %08x, %p, %p, %d, %p, %p)\n", debugstr_w(pwszCNGHashAlgid), + dwFlags, pvReserved, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash); + + if (pcbComputedHash == NULL) + { + status = STATUS_INVALID_PARAMETER; + goto done; + } + + if ((status = BCryptOpenAlgorithmProvider(&alg, pwszCNGHashAlgid, NULL, 0))) + goto done; + + if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0))) + goto done; + + if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)&hash_len, sizeof(hash_len), &hash_len_size, 0))) + goto done; + + if (pbComputedHash == NULL) + { + *pcbComputedHash = hash_len; + goto done; + } + + if (*pcbComputedHash < hash_len) + { + status = STATUS_INVALID_PARAMETER; + goto done; + } + else + { + *pcbComputedHash = hash_len; + } + + if ((status = BCryptHashData(hash, (BYTE *)pbEncoded, cbEncoded, 0))) + goto done; + + if ((status = BCryptFinishHash(hash, pbComputedHash, hash_len, 0))) + { + goto done; + } + +done: + if (hash) BCryptDestroyHash(hash); + if (alg) BCryptCloseAlgorithmProvider(alg, 0); + if (status) SetLastError(RtlNtStatusToDosError(status)); + return status == 0; +} + BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash) diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index fc32570b52..fa507dfc65 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -136,6 +136,7 @@ @ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr) @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr) @ stdcall CryptHashCertificate(long long long ptr long ptr ptr) +@ stdcall CryptHashCertificate2(wstr long ptr ptr long ptr ptr) @ stdcall CryptHashMessage(ptr long long ptr ptr ptr ptr ptr ptr) @ stdcall CryptHashPublicKeyInfo(long long long long ptr ptr ptr) @ stdcall CryptHashToBeSigned(ptr long ptr long ptr ptr) diff --git a/include/wincrypt.h b/include/wincrypt.h index a1b1305902..cbc76d7f10 100644 --- a/include/wincrypt.h +++ b/include/wincrypt.h @@ -4379,6 +4379,10 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash);
+BOOL WINAPI CryptHashCertificate2(LPCWSTR pwszCNGHashAlgid, DWORD dwFlags, + void *pvReserved, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, + DWORD *pcbComputedHash); + BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash);
Signed-off-by: Orhan Kavrakoğlu aibok42@gmail.com --- dlls/crypt32/tests/cert.c | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+)
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index f653741ea7..ddda156cc5 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -1784,6 +1784,70 @@ static void testCryptHashCert(void) ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n"); }
+static void testCryptHashCert2(void) +{ + static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, + 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, + 0x09 }; + static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee, + 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8, + 0xa2 }; + static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:"; + BOOL ret; + BYTE hash[20]; + DWORD hashLen; + const WCHAR SHA1[] = { 'S', 'H', 'A', '1', '\0' }; + const WCHAR invalidAlgorithm[] = { 'I', 'H', 'A', '9', '9', '\0' }; + + /* Test empty hash */ + hashLen = sizeof(hash); + ret = CryptHashCertificate2(SHA1, 0, NULL, NULL, 0, hash, &hashLen); + ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError()); + ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen); + ok(!memcmp(hash, emptyHash, sizeof(emptyHash)), "Unexpected hash of nothing\n"); + + /* Test known hash */ + hashLen = sizeof(hash); + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), hash, &hashLen); + ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError()); + ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen); + ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n"); + + /* Test null hash size pointer just sets hash size */ + hashLen = 0; + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), NULL, &hashLen); + ok(ret, "CryptHashCertificate2 failed: %08x\n", GetLastError()); + ok(hashLen == sizeof(hash), "Hash size not set correctly (%d)\n", hashLen); + + /* Test invalid algorithm ID */ + hashLen = sizeof(hash); + ret = CryptHashCertificate2(NULL, 0, NULL, toHash, sizeof(toHash), hash, &hashLen); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER (%d), got %d\n", ERROR_INVALID_PARAMETER, GetLastError()); + + /* Test invalid algorithm */ + hashLen = sizeof(hash); + ret = CryptHashCertificate2(invalidAlgorithm, 0, NULL, toHash, sizeof(toHash), hash, &hashLen); + ok(!ret && GetLastError() == ERROR_INVALID_FUNCTION, + "Expected ERROR_INVALID_FUNCTION (%d), got %d\n", ERROR_INVALID_FUNCTION, GetLastError()); + + /* Test hash buffer too small */ + hashLen = sizeof(hash) / 2; + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), hash, &hashLen); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER (%d), got %d\n", ERROR_INVALID_PARAMETER, GetLastError()); + + /* Test hashLen null with hash */ + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), hash, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER (%d), got %d\n", ERROR_INVALID_PARAMETER, GetLastError()); + + /* Test hashLen null with no hash */ + ret = CryptHashCertificate2(SHA1, 0, NULL, toHash, sizeof(toHash), NULL, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER (%d), got %d\n", ERROR_INVALID_PARAMETER, GetLastError()); +} + static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen, const BYTE *sig, unsigned int sigLen) { @@ -4074,6 +4138,7 @@ START_TEST(cert) testLinkCert();
testCryptHashCert(); + testCryptHashCert2(); testCertSigs(); testSignAndEncodeCert(); testCreateSelfSignCert();
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=46614
Your paranoid android.
=== wxppro (32 bit report) ===
crypt32: cert: Timeout
=== w2003std (32 bit report) ===
crypt32: cert: Timeout
=== wvistau64 (32 bit report) ===
crypt32: 0890:cert: unhandled exception c0000005 at 76139B3D
=== wvistau64_zh_CN (32 bit report) ===
crypt32: 0bb8:cert: unhandled exception c0000005 at 75169B3D
=== wvistau64_fr (32 bit report) ===
crypt32: 072c:cert: unhandled exception c0000005 at 75B79B3D
=== wvistau64_he (32 bit report) ===
crypt32: 0bd8:cert: unhandled exception c0000005 at 75AC9B3D
=== w2008s64 (32 bit report) ===
crypt32: 0870:cert: unhandled exception c0000005 at 75809B3D
=== w7u (32 bit report) ===
crypt32: 0138:cert: unhandled exception c0000005 at 76189B69
=== w7pro64 (32 bit report) ===
crypt32: 0ad4:cert: unhandled exception c0000005 at 750A9B69
=== w8 (32 bit report) ===
crypt32: 0d54:cert: unhandled exception c0000005 at 77389EAA
=== w8adm (32 bit report) ===
crypt32: 0fd8:cert: unhandled exception c0000005 at 77389EAA
=== w864 (32 bit report) ===
crypt32: 060c:cert: unhandled exception c0000005 at 758F9EAA
=== w1064 (32 bit report) ===
crypt32: 0830:cert: unhandled exception c0000005 at 75478658
=== wvistau64 (64 bit report) ===
crypt32: 0890:cert: unhandled exception c0000005 at 000007FEFDA01342
=== w2008s64 (64 bit report) ===
crypt32: 0870:cert: unhandled exception c0000005 at 000007FEFE3A1342
=== w7pro64 (64 bit report) ===
crypt32: 0ad4:cert: unhandled exception c0000005 at 000007FEFDEC12B9
=== w864 (64 bit report) ===
crypt32: 0a20:cert: unhandled exception c0000005 at 00007FFB25311A31
=== w1064 (64 bit report) ===
crypt32: 0eb8:cert: unhandled exception c0000005 at 00007FFC3B693C60