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