Signed-off-by: Hans Leidekker hans@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");