From da3eeb4bd5a7f61b8e4a155b9114a39d354dd7b3 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Fri, 28 Jul 2006 17:26:24 -0700 Subject: [PATCH] crypt32: Implement CryptHashPublicKeyInfo. --- dlls/crypt32/cert.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/crypt32/crypt32.spec | 2 +- dlls/crypt32/tests/cert.c | 33 +++++++++++++++++++++++++++++++++ include/wincrypt.h | 4 ++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 6297e722f0e..b131f11d704 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -1115,6 +1115,44 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid, return ret; } +BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV hCryptProv, ALG_ID Algid, + DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, + BYTE *pbComputedHash, DWORD *pcbComputedHash) +{ + BOOL ret = TRUE; + HCRYPTHASH hHash = 0; + + TRACE("(%ld, %d, %08lx, %ld, %p, %p, %p)\n", hCryptProv, Algid, dwFlags, + dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash); + + if (!hCryptProv) + hCryptProv = CRYPT_GetDefaultProvider(); + if (!Algid) + Algid = CALG_MD5; + if (ret) + { + BYTE *buf; + DWORD size = 0; + + ret = CryptEncodeObjectEx(dwCertEncodingType, X509_PUBLIC_KEY_INFO, + pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + if (ret) + { + ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); + if (ret) + { + ret = CryptHashData(hHash, buf, size, 0); + if (ret) + ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash, + pcbComputedHash, 0); + CryptDestroyHash(hHash); + } + LocalFree(buf); + } + } + return ret; +} + BOOL WINAPI CryptSignCertificate(HCRYPTPROV hCryptProv, DWORD dwKeySpec, DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned, DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index 1293816a636..56db08cfbc9 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -124,7 +124,7 @@ @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr) @ stdcall CryptHashCertificate(long long long ptr long ptr ptr) @ stub CryptHashMessage -@ stub CryptHashPublicKeyInfo +@ stdcall CryptHashPublicKeyInfo(long long long long ptr ptr ptr) @ stub CryptHashToBeSigned @ stub CryptImportPKCS8 @ stdcall CryptImportPublicKeyInfo(long long ptr ptr) diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index 49692e22eb9..5c23607fc54 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -1544,6 +1544,38 @@ static void testComparePublicKeyInfo(void) ok(!ret, "Expected keys not to compare\n"); } +static void testHashPublicKeyInfo(void) +{ + BOOL ret; + CERT_PUBLIC_KEY_INFO info = { { 0 } }; + DWORD len; + + /* Crash + ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL); + ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL); + */ + ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len); + ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, + "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError()); + ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len); + ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, + "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError()); + ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len); + ok(ret, "CryptHashPublicKeyInfo failed: %08lx\n", GetLastError()); + ok(len == 16, "Expected hash size 16, got %ld\n", len); + if (len == 16) + { + static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40, + 0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 }; + BYTE buf[16]; + + ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf, + &len); + ok(ret, "CryptHashPublicKeyInfo failed: %08lx\n", GetLastError()); + ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n"); + } +} + void testCompareCert(void) { CERT_INFO info1 = { 0 }, info2 = { 0 }; @@ -1827,6 +1859,7 @@ START_TEST(cert) testCompareCertName(); testCompareIntegerBlob(); testComparePublicKeyInfo(); + testHashPublicKeyInfo(); testCompareCert(); testVerifySubjectCert(); testAcquireCertPrivateKey(); diff --git a/include/wincrypt.h b/include/wincrypt.h index 6e8824937c6..f538aee7297 100644 --- a/include/wincrypt.h +++ b/include/wincrypt.h @@ -2936,6 +2936,10 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash); +BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV hCryptProv, ALG_ID Algid, + DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, + BYTE *pbComputedHash, DWORD *pcbComputedHash); + BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash); -- 2.11.4.GIT