dssenh: Implement CPGenKey.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
52ad894784
commit
90bb4fe34b
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
|
@ -309,27 +311,6 @@ BOOL WINAPI CPGetProvParam( HCRYPTPROV hprov, DWORD param, BYTE *data, DWORD *le
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI CPGenKey( HCRYPTPROV hprov, ALG_ID algid, DWORD flags, HCRYPTKEY *ret_key )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI CPDestroyKey( HCRYPTPROV hprov, HCRYPTKEY hkey )
|
||||
{
|
||||
struct key *key = (struct key *)hkey;
|
||||
|
||||
TRACE( "%p, %p\n", (void *)hprov, (void *)hkey );
|
||||
|
||||
if (key->magic != MAGIC_KEY)
|
||||
{
|
||||
SetLastError( NTE_BAD_KEY );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
destroy_key( key );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL store_key_pair( struct key *key, HKEY hkey, DWORD keyspec, DWORD flags )
|
||||
{
|
||||
const WCHAR *value;
|
||||
|
@ -378,6 +359,112 @@ static BOOL store_key_container_keys( struct container *container )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct key *duplicate_key( const struct key *key )
|
||||
{
|
||||
struct key *ret;
|
||||
|
||||
if (!(ret = create_key( key->algid, key->flags ))) return NULL;
|
||||
|
||||
if (BCryptDuplicateKey( key->handle, &ret->handle, NULL, 0, 0 ))
|
||||
{
|
||||
heap_free( ret );
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL generate_key( struct container *container, ALG_ID algid, DWORD bitlen, DWORD flags, HCRYPTKEY *ret_key )
|
||||
{
|
||||
struct key *key, *sign_key;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!(key = create_key( algid, flags ))) return FALSE;
|
||||
|
||||
if ((status = BCryptGenerateKeyPair( key->alg_handle, &key->handle, bitlen, 0 )))
|
||||
{
|
||||
ERR( "failed to generate key %08x\n", status );
|
||||
destroy_key( key );
|
||||
return FALSE;
|
||||
}
|
||||
if ((status = BCryptFinalizeKeyPair( key->handle, 0 )))
|
||||
{
|
||||
ERR( "failed to finalize key %08x\n", status );
|
||||
destroy_key( key );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (algid)
|
||||
{
|
||||
case AT_SIGNATURE:
|
||||
case CALG_DSS_SIGN:
|
||||
if (!(sign_key = duplicate_key( key )))
|
||||
{
|
||||
destroy_key( key );
|
||||
return FALSE;
|
||||
}
|
||||
destroy_key( container->sign_key );
|
||||
container->sign_key = sign_key;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME( "unhandled algorithm %08x\n", algid );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!store_key_container_keys( container ))
|
||||
{
|
||||
destroy_key( key );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*ret_key = (HCRYPTKEY)key;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI CPGenKey( HCRYPTPROV hprov, ALG_ID algid, DWORD flags, HCRYPTKEY *ret_key )
|
||||
{
|
||||
static const unsigned int supported_key_lengths[] = { 512, 768, 1024 };
|
||||
struct container *container = (struct container *)hprov;
|
||||
ULONG i, bitlen = HIWORD(flags) ? HIWORD(flags) : 1024;
|
||||
|
||||
TRACE( "%p, %08x, %08x, %p\n", (void *)hprov, algid, flags, ret_key );
|
||||
|
||||
if (container->magic != MAGIC_CONTAINER) return FALSE;
|
||||
|
||||
if (bitlen % 2)
|
||||
{
|
||||
SetLastError( STATUS_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(supported_key_lengths); i++)
|
||||
{
|
||||
if (bitlen == supported_key_lengths[i]) break;
|
||||
}
|
||||
if (i >= ARRAY_SIZE(supported_key_lengths))
|
||||
{
|
||||
SetLastError( NTE_BAD_FLAGS );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return generate_key( container, algid, bitlen, LOWORD(flags), ret_key );
|
||||
}
|
||||
|
||||
BOOL WINAPI CPDestroyKey( HCRYPTPROV hprov, HCRYPTKEY hkey )
|
||||
{
|
||||
struct key *key = (struct key *)hkey;
|
||||
|
||||
TRACE( "%p, %p\n", (void *)hprov, (void *)hkey );
|
||||
|
||||
if (key->magic != MAGIC_KEY)
|
||||
{
|
||||
SetLastError( NTE_BAD_KEY );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
destroy_key( key );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define MAGIC_DSS1 ('D' | ('S' << 8) | ('S' << 16) | ('1' << 24))
|
||||
#define MAGIC_DSS2 ('D' | ('S' << 8) | ('S' << 16) | ('2' << 24))
|
||||
|
||||
|
@ -493,20 +580,6 @@ BOOL WINAPI CPExportKey( HCRYPTPROV hprov, HCRYPTKEY hkey, HCRYPTKEY hexpkey, DW
|
|||
return !BCryptExportKey( key->handle, NULL, LEGACY_DSA_V2_PUBLIC_BLOB, data, *len, len, 0 );
|
||||
}
|
||||
|
||||
static struct key *duplicate_key( const struct key *key )
|
||||
{
|
||||
struct key *ret;
|
||||
|
||||
if (!(ret = create_key( key->algid, key->flags ))) return NULL;
|
||||
|
||||
if (BCryptDuplicateKey( key->handle, &ret->handle, NULL, 0, 0 ))
|
||||
{
|
||||
heap_free( ret );
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CPDuplicateKey( HCRYPTPROV hprov, HCRYPTKEY hkey, DWORD *reserved, DWORD flags, HCRYPTKEY *ret_key )
|
||||
{
|
||||
struct key *key = (struct key *)hkey, *ret;
|
||||
|
|
|
@ -184,14 +184,16 @@ struct keylength_test {
|
|||
BOOL expectedResult;
|
||||
DWORD expectedError;
|
||||
DWORD brokenError;
|
||||
int todo_result;
|
||||
int todo_error;
|
||||
};
|
||||
|
||||
static const struct keylength_test baseDSS_keylength[] = {
|
||||
/* AT_KEYEXCHANGE is not supported by the base DSS provider */
|
||||
{AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{AT_KEYEXCHANGE, 512 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{AT_KEYEXCHANGE, 1024 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 512 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 1024 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
/* min 512 max 1024 increment by 64 */
|
||||
{AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{AT_SIGNATURE, 512 << 16, TRUE},
|
||||
|
@ -200,15 +202,15 @@ static const struct keylength_test baseDSS_keylength[] = {
|
|||
{AT_SIGNATURE, 1024 << 16, TRUE},
|
||||
{AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
/* CALG_DH_EPHEM is not supported by the base DSS provider */
|
||||
{CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{CALG_DH_EPHEM, 512 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{CALG_DH_EPHEM, 1024 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 512 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 1024 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
/* CALG_DH_SF is not supported by the base DSS provider */
|
||||
{CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{CALG_DH_SF, 512 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{CALG_DH_SF, 1024 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_ALGID},
|
||||
{CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{CALG_DH_SF, 512 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{CALG_DH_SF, 1024 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
{CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_ALGID, 0, 0, 1},
|
||||
/* min 512 max 1024, increment by 64 */
|
||||
{CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DSS_SIGN, 512 << 16, TRUE},
|
||||
|
@ -221,10 +223,10 @@ static const struct keylength_test baseDSS_keylength[] = {
|
|||
static const struct keylength_test dssDH_keylength[] = {
|
||||
/* min 512 max 1024, increment by 64 */
|
||||
{AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{AT_KEYEXCHANGE, 512 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{AT_KEYEXCHANGE, 768 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 1024 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 512 << 16, TRUE, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 768 << 16, TRUE, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 1024 << 16, TRUE, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{AT_SIGNATURE, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{AT_SIGNATURE, 512 << 16, TRUE},
|
||||
|
@ -233,16 +235,16 @@ static const struct keylength_test dssDH_keylength[] = {
|
|||
{AT_SIGNATURE, 1024 << 16, TRUE},
|
||||
{AT_SIGNATURE, 1088 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_EPHEM, 512 << 16, TRUE},
|
||||
{CALG_DH_EPHEM, 513 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_EPHEM, 768 << 16, TRUE},
|
||||
{CALG_DH_EPHEM, 1024 << 16, TRUE},
|
||||
{CALG_DH_EPHEM, 512 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 768 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 1024 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 1088 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_SF, 512 << 16, TRUE},
|
||||
{CALG_DH_SF, 513 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_SF, 768 << 16, TRUE},
|
||||
{CALG_DH_SF, 1024 << 16, TRUE},
|
||||
{CALG_DH_SF, 512 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_SF, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
|
||||
{CALG_DH_SF, 768 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_SF, 1024 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_SF, 1088 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DSS_SIGN, 512 << 16, TRUE},
|
||||
|
@ -255,12 +257,12 @@ static const struct keylength_test dssDH_keylength[] = {
|
|||
static const struct keylength_test dssENH_keylength[] = {
|
||||
/* min 512 max 1024 (AT_KEYEXCHANGE, CALG_DH_EPHEM, CALG_DH_SF max 4096), increment by 64*/
|
||||
{AT_KEYEXCHANGE, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{AT_KEYEXCHANGE, 512 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{AT_KEYEXCHANGE, 768 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 1024 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 1088 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 2048 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 512 << 16, TRUE, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 768 << 16, TRUE, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 1024 << 16, TRUE, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 1088 << 16, TRUE, 0, 0, 1},
|
||||
{AT_KEYEXCHANGE, 2048 << 16, TRUE, 0, 0, 1},
|
||||
/* Keylength too large - test bot timeout.
|
||||
{AT_KEYEXCHANGE, 3072 << 16, TRUE},
|
||||
{AT_KEYEXCHANGE, 4096 << 16, TRUE}, */
|
||||
|
@ -272,20 +274,20 @@ static const struct keylength_test dssENH_keylength[] = {
|
|||
{AT_SIGNATURE, 1024 << 16, TRUE},
|
||||
{AT_SIGNATURE, 1032 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_EPHEM, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_EPHEM, 512 << 16, TRUE},
|
||||
{CALG_DH_EPHEM, 513 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_EPHEM, 768 << 16, TRUE},
|
||||
{CALG_DH_EPHEM, 1024 << 16, TRUE},
|
||||
{CALG_DH_EPHEM, 512 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 768 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 1024 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 1040 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_EPHEM, 1088 << 16, TRUE},
|
||||
{CALG_DH_EPHEM, 1088 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_EPHEM, 4160 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_SF, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_SF, 512 << 16, TRUE},
|
||||
{CALG_DH_SF, 513 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_SF, 768 << 16, TRUE},
|
||||
{CALG_DH_SF, 1024 << 16, TRUE},
|
||||
{CALG_DH_SF, 512 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_SF, 513 << 16, FALSE, NTE_BAD_FLAGS, 0, 0, 1},
|
||||
{CALG_DH_SF, 768 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_SF, 1024 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_SF, 1032 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DH_SF, 1088 << 16, TRUE},
|
||||
{CALG_DH_SF, 1088 << 16, TRUE, 0, 0, 1},
|
||||
{CALG_DH_SF, 4160 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DSS_SIGN, 448 << 16, FALSE, NTE_BAD_FLAGS},
|
||||
{CALG_DSS_SIGN, 512 << 16, TRUE},
|
||||
|
@ -307,16 +309,22 @@ static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *t
|
|||
result = CryptGenKey(hProv, tests[i].algid, tests[i].flags, &key);
|
||||
|
||||
/* success */
|
||||
if(tests[i].expectedResult)
|
||||
if (tests[i].expectedResult)
|
||||
{
|
||||
ok(result, "%d: Expected a key, got %08x\n", i, GetLastError());
|
||||
result = CryptDestroyKey(key);
|
||||
ok(result, "Expected no errors.\n");
|
||||
todo_wine_if (tests[i].todo_result) ok(result, "%d: got %08x\n", i, GetLastError());
|
||||
if (result)
|
||||
{
|
||||
result = CryptDestroyKey(key);
|
||||
ok(result, "%d: got %08x\n", i, GetLastError());
|
||||
}
|
||||
}
|
||||
else
|
||||
ok(!result && (GetLastError() == tests[i].expectedError ||
|
||||
broken(GetLastError() == tests[i].brokenError)),
|
||||
"%d: got %x.\n", i, GetLastError());
|
||||
{
|
||||
todo_wine_if (tests[i].todo_result) ok(!result, "%d: got %x\n", i, GetLastError());
|
||||
todo_wine_if (tests[i].todo_error)
|
||||
ok(GetLastError() == tests[i].expectedError ||
|
||||
broken(GetLastError() == tests[i].brokenError), "%d: got %08x\n", i, GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,12 +345,7 @@ static void test_keylength(void)
|
|||
ok(result, "Expected no errors.\n");
|
||||
|
||||
result = CryptGenKey(hProv, AT_SIGNATURE, 0, &key);
|
||||
todo_wine ok(result, "Expected no errors.\n");
|
||||
if (!result)
|
||||
{
|
||||
skip("skipping key length tests\n");
|
||||
return;
|
||||
}
|
||||
ok(result, "Expected no errors.\n");
|
||||
|
||||
result = CryptDestroyKey(key);
|
||||
ok(result, "Expected no errors.\n");
|
||||
|
|
Loading…
Reference in New Issue