Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/dssenh/main.c | 143 ++++++++++++++++++++++++++++---------
dlls/dssenh/tests/dssenh.c | 109 ++++++++++++++--------------
2 files changed, 164 insertions(+), 88 deletions(-)
diff --git a/dlls/dssenh/main.c b/dlls/dssenh/main.c
index 752189d15bb..5ad0ef1505d 100644
--- a/dlls/dssenh/main.c
+++ b/dlls/dssenh/main.c
@@ -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;
diff --git a/dlls/dssenh/tests/dssenh.c b/dlls/dssenh/tests/dssenh.c
index c2ab37d288b..4f401254f52 100644
--- a/dlls/dssenh/tests/dssenh.c
+++ b/dlls/dssenh/tests/dssenh.c
@@ -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");
--
2.28.0