dssenh: Implement CPDuplicateHash.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2020-10-12 16:11:09 +02:00 committed by Alexandre Julliard
parent b5e931d83c
commit bf83b89dab
3 changed files with 85 additions and 1 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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();
}