[PATCH 3/5] dssenh: Implement CPSignHash.

Hans Leidekker hans at codeweavers.com
Wed Oct 14 04:03:55 CDT 2020


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/dssenh/main.c         | 34 +++++++++++++++++++++++++++++++++-
 dlls/dssenh/tests/dssenh.c | 12 +++++++-----
 2 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/dlls/dssenh/main.c b/dlls/dssenh/main.c
index b575689ab1f..da269807bf9 100644
--- a/dlls/dssenh/main.c
+++ b/dlls/dssenh/main.c
@@ -718,10 +718,42 @@ BOOL WINAPI CPDeriveKey( HCRYPTPROV hprov, ALG_ID algid, HCRYPTHASH hhash, DWORD
     return FALSE;
 }
 
+static DWORD get_signature_length( DWORD algid )
+{
+    switch (algid)
+    {
+    case AT_SIGNATURE:
+    case CALG_DSS_SIGN: return 40;
+    default:
+        FIXME( "unhandled algorithm %u\n", algid );
+        return 0;
+    }
+}
+
+#define MAX_HASH_LEN 20
 BOOL WINAPI CPSignHash( HCRYPTPROV hprov, HCRYPTHASH hhash, DWORD keyspec, const WCHAR *desc, DWORD flags, BYTE *sig,
                         DWORD *siglen )
 {
-    return FALSE;
+    struct container *container = (struct container *)hprov;
+    struct hash *hash = (struct hash *)hhash;
+    UCHAR hashval[MAX_HASH_LEN];
+    ULONG len, hashlen = sizeof(hashval);
+
+    TRACE( "%p, %p, %u, %s, %08x, %p, %p\n", (void *)hprov, (void *)hhash, keyspec, debugstr_w(desc), flags, sig,
+           siglen );
+
+    if (container->magic != MAGIC_CONTAINER || !container->sign_key) return FALSE;
+    if (hash->magic != MAGIC_HASH) return FALSE;
+
+    if (!(len = get_signature_length( container->sign_key->algid ))) return FALSE;
+    if (!CPGetHashParam( hprov, hhash, HP_HASHVAL, hashval, &hashlen, 0 )) return FALSE;
+    if (*siglen < len)
+    {
+        *siglen = len;
+        return TRUE;
+    }
+
+    return !BCryptSignHash( container->sign_key->handle, NULL, hashval, hashlen, sig, *siglen, siglen, 0 );
 }
 
 BOOL WINAPI CPVerifySignature( HCRYPTPROV hprov, HCRYPTHASH hhash, const BYTE *sig, DWORD siglen, HCRYPTKEY hpubkey,
diff --git a/dlls/dssenh/tests/dssenh.c b/dlls/dssenh/tests/dssenh.c
index 6ad15225924..c2ab37d288b 100644
--- a/dlls/dssenh/tests/dssenh.c
+++ b/dlls/dssenh/tests/dssenh.c
@@ -889,12 +889,8 @@ static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *t
         ok(!memcmp(hashValue1, hashValue2, hashLen2), "Hashes were not identical.\n");
 
         /* Sign hash 1 */
+        signLen1 = 0;
         result = CryptSignHashA(hHash1, AT_SIGNATURE, NULL, 0, NULL, &signLen1);
-        if (!result)
-        {
-            skip("skipping sign tests\n");
-            return;
-        }
         ok(result, "Failed to get signature length, got %x\n", GetLastError());
         ok(signLen1 == 40, "Expected a 40-byte signature, got %d\n", signLen1);
 
@@ -902,6 +898,7 @@ static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *t
         ok(result, "Failed to sign hash, got %x\n", GetLastError());
 
         /* Sign hash 2 */
+        signLen2 = 0;
         result = CryptSignHashA(hHash2, AT_SIGNATURE, NULL, 0, NULL, &signLen2);
         ok(result, "Failed to get signature length, got %x\n", GetLastError());
         ok(signLen2 == 40, "Expected a 40-byte signature, got %d\n", signLen2);
@@ -943,6 +940,11 @@ static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *t
 
         /* Verify signed hash 1 */
         result = CryptVerifySignatureA(hHash1, signValue1, sizeof(signValue1), pubKey, NULL, 0);
+        if (!result)
+        {
+            skip("skipping sign tests\n");
+            return;
+        }
         ok(result, "Failed to verify signature, got %x\n", GetLastError());
 
         result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
-- 
2.28.0




More information about the wine-devel mailing list