Hans Leidekker : dssenh: Implement CPDuplicateHash.
Alexandre Julliard
julliard at winehq.org
Mon Oct 12 15:20:51 CDT 2020
Module: wine
Branch: master
Commit: bf83b89dabbd7a2fc612529d26d5552a54a1b147
URL: https://source.winehq.org/git/wine.git/?a=commit;h=bf83b89dabbd7a2fc612529d26d5552a54a1b147
Author: Hans Leidekker <hans at codeweavers.com>
Date: Mon Oct 12 16:11:09 2020 +0200
dssenh: Implement CPDuplicateHash.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dssenh/dssenh.spec | 2 +-
dlls/dssenh/main.c | 31 +++++++++++++++++++++++++++
dlls/dssenh/tests/dssenh.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/dlls/dssenh/dssenh.spec b/dlls/dssenh/dssenh.spec
index 2d93a98796..a045a7e04e 100644
--- a/dlls/dssenh/dssenh.spec
+++ b/dlls/dssenh/dssenh.spec
@@ -4,7 +4,7 @@
@ stdcall CPDeriveKey(ptr long ptr long ptr)
@ stdcall CPDestroyHash(ptr ptr)
@ stdcall CPDestroyKey(ptr ptr)
-@ stub CPDuplicateHash
+@ stdcall CPDuplicateHash(ptr ptr ptr long ptr)
@ stub CPDuplicateKey
@ stub CPEncrypt
@ stdcall CPExportKey(ptr ptr ptr long long ptr ptr)
diff --git a/dlls/dssenh/main.c b/dlls/dssenh/main.c
index e9b676e735..d40dedf41b 100644
--- a/dlls/dssenh/main.c
+++ b/dlls/dssenh/main.c
@@ -563,6 +563,37 @@ BOOL WINAPI CPDestroyHash( HCRYPTPROV hprov, HCRYPTHASH hhash )
return TRUE;
}
+static struct hash *duplicate_hash( const struct hash *hash )
+{
+ struct hash *ret;
+
+ if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
+
+ ret->magic = hash->magic;
+ ret->len = hash->len;
+ if (BCryptDuplicateHash( hash->handle, &ret->handle, NULL, 0, 0 ))
+ {
+ heap_free( ret );
+ return NULL;
+ }
+ memcpy( ret->value, hash->value, sizeof(hash->value) );
+ ret->finished = hash->finished;
+ return ret;
+}
+
+BOOL WINAPI CPDuplicateHash( HCRYPTPROV hprov, HCRYPTHASH hhash, DWORD *reserved, DWORD flags, HCRYPTHASH *ret_hash )
+{
+ struct hash *hash = (struct hash *)hhash, *ret;
+
+ TRACE( "%p, %p, %p, %08x, %p\n", (void *)hprov, (void *)hhash, reserved, flags, ret_hash );
+
+ if (hash->magic != MAGIC_HASH) return FALSE;
+
+ if (!(ret = duplicate_hash( hash ))) return FALSE;
+ *ret_hash = (HCRYPTHASH)ret;
+ return TRUE;
+}
+
BOOL WINAPI CPHashData( HCRYPTPROV hprov, HCRYPTHASH hhash, const BYTE *data, DWORD len, DWORD flags )
{
struct hash *hash = (struct hash *)hhash;
diff --git a/dlls/dssenh/tests/dssenh.c b/dlls/dssenh/tests/dssenh.c
index d4a231562e..704b3685c3 100644
--- a/dlls/dssenh/tests/dssenh.c
+++ b/dlls/dssenh/tests/dssenh.c
@@ -1413,6 +1413,58 @@ static void test_key_exchange(void)
ok(result, "Failed to release CSP provider.\n");
}
+static void test_duplicate_hash(void)
+{
+ static const char expected[] =
+ {0xb9,0x7b,0xed,0xd4,0x7b,0xd8,0xa0,0xcd,0x6c,0xba,0xce,0xe9,0xb1,0x36,0xbb,0x00,0x27,0xe3,0x95,0x21};
+ HCRYPTPROV hprov;
+ HCRYPTHASH hhash, hhash2;
+ BYTE buf[20];
+ DWORD len;
+ BOOL result;
+
+ result = CryptAcquireContextA(&hprov, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, CRYPT_VERIFYCONTEXT);
+ ok(result, "got %08x\n", GetLastError());
+
+ result = CryptCreateHash(hprov, CALG_SHA, 0, 0, &hhash);
+ ok(result, "got %08x\n", GetLastError());
+
+ result = CryptHashData(hhash, (const BYTE *)"winetest", sizeof("winetest"), 0);
+ ok(result, "got %08x\n", GetLastError());
+
+ len = sizeof(buf);
+ result = CryptGetHashParam(hhash, HP_HASHVAL, buf, &len, 0);
+ ok(result, "got %08x\n", GetLastError());
+ ok(!memcmp(buf, expected, sizeof(expected)), "wrong data\n");
+
+ SetLastError(0xdeadbeef);
+ result = CryptHashData(hhash, (const BYTE *)"winetest", sizeof("winetest"), 0);
+ ok(!result, "success\n");
+ todo_wine ok(GetLastError() == NTE_BAD_HASH_STATE, "got %08x\n", GetLastError());
+
+ result = CryptDuplicateHash(hhash, NULL, 0, &hhash2);
+ ok(result, "got %08x\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ result = CryptHashData(hhash2, (const BYTE *)"winetest", sizeof("winetest"), 0);
+ ok(!result, "success\n");
+ todo_wine ok(GetLastError() == NTE_BAD_HASH_STATE, "got %08x\n", GetLastError());
+
+ len = sizeof(buf);
+ result = CryptGetHashParam(hhash2, HP_HASHVAL, buf, &len, 0);
+ ok(result, "got %08x\n", GetLastError());
+ ok(!memcmp(buf, expected, sizeof(expected)), "wrong data\n");
+
+ result = CryptDestroyHash(hhash2);
+ ok(result, "got %08x\n", GetLastError());
+
+ result = CryptDestroyHash(hhash);
+ ok(result, "got %08x\n", GetLastError());
+
+ result = CryptReleaseContext(hprov, 0);
+ ok(result, "got %08x\n", GetLastError());
+}
+
START_TEST(dssenh)
{
test_acquire_context();
@@ -1422,4 +1474,5 @@ START_TEST(dssenh)
test_cipher_modes(ciphermode_data, ARRAY_SIZE(ciphermode_data));
test_verify_signature();
test_key_exchange();
+ test_duplicate_hash();
}
More information about the wine-cvs
mailing list