Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/bcrypt/bcrypt_main.c | 6 ++++++ dlls/bcrypt/tests/bcrypt.c | 20 +++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 7353cae26eb..75ee96f56c7 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -701,6 +701,12 @@ static NTSTATUS set_key_property( struct key *key, const WCHAR *prop, UCHAR *val return STATUS_NOT_IMPLEMENTED; } } + else if (!wcscmp( prop, BCRYPT_KEY_LENGTH )) + { + if(size < sizeof(DWORD)) return STATUS_INVALID_PARAMETER; + key->u.a.bitlen = *(DWORD*)value; + return STATUS_SUCCESS; + }
FIXME( "unsupported key property %s\n", debugstr_w(prop) ); return STATUS_NOT_IMPLEMENTED; diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c index 95addc1ab16..9230726969b 100644 --- a/dlls/bcrypt/tests/bcrypt.c +++ b/dlls/bcrypt/tests/bcrypt.c @@ -672,6 +672,7 @@ static void test_BCryptGenerateSymmetricKey(void) BCRYPT_KEY_LENGTHS_STRUCT key_lengths; ULONG size, len, i; NTSTATUS ret; + DWORD keylen;
ret = BCryptOpenAlgorithmProvider(&aes, BCRYPT_AES_ALGORITHM, NULL, 0); ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); @@ -706,6 +707,13 @@ static void test_BCryptGenerateSymmetricKey(void) sizeof(BCRYPT_CHAIN_MODE_CBC), 0); ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
+ todo_wine + { + keylen = 512; + ret = BCryptSetProperty(aes, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0); + ok(ret == STATUS_NOT_SUPPORTED, "got %#lx\n", ret); + } + size = 0; memset(mode, 0, sizeof(mode)); ret = BCryptGetProperty(key, BCRYPT_CHAINING_MODE, mode, sizeof(mode), &size, 0); @@ -2005,6 +2013,7 @@ static void test_RSA(void) ULONG len, size, size2, schemes; NTSTATUS ret; BYTE *buf; + DWORD keylen;
ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0); if (ret) @@ -2052,12 +2061,21 @@ static void test_RSA(void) ok(!ret, "BCryptDestroyKey failed: %#lx\n", ret);
/* sign/verify with export/import round-trip */ - ret = BCryptGenerateKeyPair(alg, &key, 512, 0); + ret = BCryptGenerateKeyPair(alg, &key, 1024, 0); + ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); + + keylen = 512; + ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, 2, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret); + ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0); ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
ret = BCryptFinalizeKeyPair(key, 0); ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
+ ret = BCryptSetProperty(key, BCRYPT_KEY_LENGTH, (UCHAR *)&keylen, sizeof(keylen), 0); + ok(ret == STATUS_SUCCESS, "got %#lx\n", ret); + pad.pszAlgId = BCRYPT_SHA1_ALGORITHM; memset(sig, 0, sizeof(sig)); ret = BCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/Makefile.in | 1 + dlls/ncrypt/main.c | 101 +++++++++++++--------------------- dlls/ncrypt/ncrypt_internal.h | 28 +--------- 3 files changed, 42 insertions(+), 88 deletions(-)
diff --git a/dlls/ncrypt/Makefile.in b/dlls/ncrypt/Makefile.in index ad3ed409961..f46aecae66b 100644 --- a/dlls/ncrypt/Makefile.in +++ b/dlls/ncrypt/Makefile.in @@ -1,5 +1,6 @@ IMPORTLIB = ncrypt MODULE = ncrypt.dll +IMPORTS = bcrypt
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 68d9d884618..1f0ff3f5752 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -88,20 +88,14 @@ SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf)
static SECURITY_STATUS free_key_object(struct key *key) { - switch (key->alg) - { - case RSA: - { - free(key->rsa.modulus); - free(key->rsa.public_exp); - free(key->rsa.prime1); - free(key->rsa.prime2); - break; - } - default: - WARN("invalid key %p\n", key); - return NTE_INVALID_HANDLE; - } + NTSTATUS ret; + + ret = BCryptDestroyKey(key->bcrypt_key); + if(ret != ERROR_SUCCESS) return NTE_INVALID_HANDLE; + + ret = BCryptCloseAlgorithmProvider(key->alg_prov, 0); + if(ret != ERROR_SUCCESS) return NTE_INVALID_HANDLE; + return ERROR_SUCCESS; }
@@ -246,6 +240,7 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H BYTE *data, DWORD datasize, DWORD flags) { BCRYPT_KEY_BLOB *header = (BCRYPT_KEY_BLOB *)data; + struct object *key_object;
TRACE("(%#Ix, %#Ix, %s, %p, %p, %p, %lu, %#lx): stub\n", provider, decrypt_key, wine_dbgstr_w(type), params, handle, data, datasize, flags); @@ -270,70 +265,50 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H return NTE_BAD_FLAGS; }
- switch (header->Magic) + if (!(key_object = allocate_object(KEY))) + { + ERR("Error allocating memory\n"); + return NTE_NO_MEMORY; + } + + switch(header->Magic) { + case BCRYPT_RSAFULLPRIVATE_MAGIC: + case BCRYPT_RSAPRIVATE_MAGIC: case BCRYPT_RSAPUBLIC_MAGIC: { - DWORD expected_size; - struct object *object; - struct key *key; - BYTE *public_exp, *modulus; - BCRYPT_RSAKEY_BLOB *rsaheader = (BCRYPT_RSAKEY_BLOB *)data; - - if (datasize < sizeof(*rsaheader)) + NTSTATUS ret; + BCRYPT_RSAKEY_BLOB *rsablob = (BCRYPT_RSAKEY_BLOB *)data; + ret = BCryptOpenAlgorithmProvider(&key_object->key.alg_prov, BCRYPT_RSA_ALGORITHM, NULL, 0); + if (ret != ERROR_SUCCESS) { - ERR("Invalid buffer size.\n"); - return NTE_BAD_DATA; + ERR("Error opening algorithm provider\n"); + free(key_object); + return NTE_INTERNAL_ERROR; } - - expected_size = sizeof(*rsaheader) + rsaheader->cbPublicExp + rsaheader->cbModulus; - if (datasize != expected_size) + ret = BCryptImportKeyPair(key_object->key.alg_prov, NULL, type, &key_object->key.bcrypt_key, data, datasize, 0); + if (ret != ERROR_SUCCESS) { - ERR("Invalid buffer size.\n"); + WARN("Error importing keypair with bcrypt %#lx\n", ret); + BCryptCloseAlgorithmProvider(key_object->key.alg_prov, 0); + free(key_object); return NTE_BAD_DATA; }
- if (!(object = allocate_object(KEY))) - { - ERR("Error allocating memory.\n"); - return NTE_NO_MEMORY; - } - - key = &object->key; - key->alg = RSA; - key->rsa.bit_length = rsaheader->BitLength; - key->rsa.public_exp_size = rsaheader->cbPublicExp; - key->rsa.modulus_size = rsaheader->cbModulus; - if (!(key->rsa.public_exp = malloc(rsaheader->cbPublicExp))) - { - ERR("Error allocating memory.\n"); - free(object); - return NTE_NO_MEMORY; - } - if (!(key->rsa.modulus = malloc(rsaheader->cbModulus))) - { - ERR("Error allocating memory.\n"); - free(key->rsa.public_exp); - free(object); - return NTE_NO_MEMORY; - } - - public_exp = &data[sizeof(*rsaheader)]; /* The public exp is after the header. */ - modulus = &public_exp[rsaheader->cbPublicExp]; /* The modulus is after the public exponent. */ - memcpy(key->rsa.public_exp, public_exp, rsaheader->cbPublicExp); - memcpy(key->rsa.modulus, modulus, rsaheader->cbModulus); - - set_object_property(object, NCRYPT_ALGORITHM_GROUP_PROPERTY, (BYTE *)L"RSA", sizeof(L"RSA")); - set_object_property(object, NCRYPT_LENGTH_PROPERTY, (BYTE *)&key->rsa.bit_length, sizeof(key->rsa.bit_length)); - set_object_property(object, NCRYPT_PROVIDER_HANDLE_PROPERTY, (BYTE *)&provider, sizeof(provider)); - *handle = (NCRYPT_KEY_HANDLE)object; + set_object_property(key_object, NCRYPT_PROVIDER_HANDLE_PROPERTY, (BYTE *)&provider, sizeof(NCRYPT_PROV_HANDLE)); + set_object_property(key_object, NCRYPT_ALGORITHM_GROUP_PROPERTY, (BYTE *)BCRYPT_RSA_ALGORITHM, sizeof(BCRYPT_RSA_ALGORITHM)); + set_object_property(key_object, NCRYPT_LENGTH_PROPERTY, (BYTE *)&rsablob->BitLength, sizeof(rsablob->BitLength)); break; } default: - FIXME("Unhandled key magic %#lx.\n", header->Magic); + { + FIXME("Unhandled key magic %#lx\n", header->Magic); + free(key_object); return NTE_INVALID_PARAMETER; } + }
+ *handle = (NCRYPT_KEY_HANDLE)key_object; return ERROR_SUCCESS; }
diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index 3966dd73ed6..05f2f6835de 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -16,34 +16,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-enum key_algorithm -{ - DH, - DSA, - ECC, - RSA, -}; - -struct rsa_key -{ - DWORD bit_length; - DWORD public_exp_size; - BYTE *public_exp; - DWORD modulus_size; - BYTE *modulus; - DWORD prime1_size; - BYTE *prime1; - DWORD prime2_size; - BYTE *prime2; -}; +#include <bcrypt.h>
struct key { - enum key_algorithm alg; - union - { - struct rsa_key rsa; - }; + BCRYPT_ALG_HANDLE alg_prov; + BCRYPT_KEY_HANDLE bcrypt_key; };
struct storage_provider
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/tests/ncrypt.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c index d1bcbbcab2a..cf434054428 100644 --- a/dlls/ncrypt/tests/ncrypt.c +++ b/dlls/ncrypt/tests/ncrypt.c @@ -291,6 +291,13 @@ static void test_create_persisted_key(void)
NCryptFinalizeKey(key, 0); NCryptFreeObject(key); + + key = 0; + ret = NCryptCreatePersistedKey(prov, &key, BCRYPT_AES_ALGORITHM, NULL, 0, 0); + ok(ret == ERROR_SUCCESS || broken(ret == NTE_NOT_SUPPORTED) /* win 7 */, "got %#lx\n", ret); + if (ret == NTE_NOT_SUPPORTED) win_skip("broken, symmetric keys not supported.\n"); + else ok(key, "got null handle\n"); + NCryptFreeObject(prov); } }
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/main.c | 62 ++++++++++++++++++++++++++++++----- dlls/ncrypt/ncrypt_internal.h | 6 ++++ dlls/ncrypt/tests/ncrypt.c | 8 +++-- 3 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 1f0ff3f5752..d4248e76c45 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -30,14 +30,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
-SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key, - const WCHAR *algid, const WCHAR *name, DWORD keyspec, DWORD flags) -{ - FIXME("(%#Ix, %p, %s, %s, %#lx, %#lx): stub\n", provider, key, wine_dbgstr_w(algid), - wine_dbgstr_w(name), keyspec, flags); - return NTE_NOT_SUPPORTED; -} - SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD insize, void *padding, BYTE *output, DWORD outsize, DWORD *result, DWORD flags) { @@ -357,6 +349,60 @@ SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE handle, const WCHAR *name return set_object_property(object, name, input, insize); }
+SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key, + const WCHAR *algid, const WCHAR *name, DWORD keyspec, DWORD flags) +{ + struct object *key_object; + TRACE("(%#Ix, %p, %s, %s, %#lx, %#lx)\n", provider, key, wine_dbgstr_w(algid), + wine_dbgstr_w(name), keyspec, flags); + + if (!provider) return NTE_INVALID_HANDLE; + if (!algid) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER); + if (name) FIXME("Persistant keys not supported\n"); + + if (!(key_object = allocate_object(KEY))) + { + ERR("Error allocating memory\n"); + return NTE_NO_MEMORY; + } + + if (!lstrcmpiW(algid, BCRYPT_RSA_ALGORITHM)) + { + NTSTATUS ret = BCryptOpenAlgorithmProvider(&key_object->key.alg_prov, BCRYPT_RSA_ALGORITHM, NULL, 0); + DWORD default_bitlength = 1024; + + if (ret != ERROR_SUCCESS) + { + ERR("Error opening algorithm provider\n"); + free(key_object); + return NTE_INTERNAL_ERROR; + } + + ret = BCryptGenerateKeyPair(key_object->key.alg_prov, &key_object->key.bcrypt_key, 1024, 0); + if (ret != ERROR_SUCCESS) + { + ERR("Error generating key pair\n"); + BCryptCloseAlgorithmProvider(key_object->key.alg_prov, 0); + free(key_object); + return NTE_INTERNAL_ERROR; + } + + key_object->key.type = ASYMMETRIC; + set_object_property(key_object, NCRYPT_PROVIDER_HANDLE_PROPERTY, (BYTE *)&provider, sizeof(NCRYPT_PROV_HANDLE)); + set_object_property(key_object, NCRYPT_ALGORITHM_GROUP_PROPERTY, (BYTE *)BCRYPT_RSA_ALGORITHM, sizeof(BCRYPT_RSA_ALGORITHM)); + set_object_property(key_object, NCRYPT_LENGTH_PROPERTY, (BYTE *)&default_bitlength, sizeof(default_bitlength)); + } + else + { + FIXME("Algorithm not handled %s\n", wine_dbgstr_w(algid)); + free(key_object); + return NTE_NOT_SUPPORTED; + } + + *key = (NCRYPT_KEY_HANDLE)key_object; + return ERROR_SUCCESS; +} + SECURITY_STATUS WINAPI NCryptVerifySignature(NCRYPT_KEY_HANDLE handle, void *padding, BYTE *hash, DWORD hash_size, BYTE *signature, DWORD signature_size, DWORD flags) { diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index 05f2f6835de..f480667b29e 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -18,8 +18,14 @@
#include <bcrypt.h>
+enum key_type { + SYMMETRIC, + ASYMMETRIC +}; + struct key { + enum key_type type; BCRYPT_ALG_HANDLE alg_prov; BCRYPT_KEY_HANDLE bcrypt_key; }; diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c index cf434054428..ec69b236ac9 100644 --- a/dlls/ncrypt/tests/ncrypt.c +++ b/dlls/ncrypt/tests/ncrypt.c @@ -229,6 +229,7 @@ static void test_set_property(void) { ret = NCryptSetProperty(key, NCRYPT_NAME_PROPERTY, (BYTE *)L"Key name", sizeof(L"Key name"), 0); ok(ret == NTE_NOT_SUPPORTED, "got %#lx\n", ret); + } NCryptFreeObject(key);
key = 0; @@ -240,6 +241,8 @@ static void test_set_property(void) ret = NCryptSetProperty(key, NCRYPT_LENGTH_PROPERTY, (BYTE *)&keylength, sizeof(keylength), 0); ok(ret == ERROR_SUCCESS, "got %#lx\n", ret);
+ todo_wine + { ret = NCryptSetProperty(key, NCRYPT_NAME_PROPERTY, (BYTE *)L"Key name", sizeof(L"Key name"), 0); ok(ret == NTE_NOT_SUPPORTED, "got %#lx\n", ret);
@@ -261,7 +264,6 @@ static void test_create_persisted_key(void) ret = NCryptOpenStorageProvider(&prov, NULL, 0); ok(ret == ERROR_SUCCESS, "got %#lx\n", ret);
- todo_wine { key = 0; ret = NCryptCreatePersistedKey(0, &key, BCRYPT_RSA_ALGORITHM, NULL, 0, 0); ok(ret == NTE_INVALID_HANDLE, "got %#lx\n", ret); @@ -292,14 +294,16 @@ static void test_create_persisted_key(void) NCryptFinalizeKey(key, 0); NCryptFreeObject(key);
+ todo_wine + { key = 0; ret = NCryptCreatePersistedKey(prov, &key, BCRYPT_AES_ALGORITHM, NULL, 0, 0); ok(ret == ERROR_SUCCESS || broken(ret == NTE_NOT_SUPPORTED) /* win 7 */, "got %#lx\n", ret); if (ret == NTE_NOT_SUPPORTED) win_skip("broken, symmetric keys not supported.\n"); else ok(key, "got null handle\n"); + }
NCryptFreeObject(prov); - } }
START_TEST(ncrypt)
On Mon, 2022-03-07 at 20:57 -0300, Santino Mazza wrote:
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com
dlls/ncrypt/main.c | 62 ++++++++++++++++++++++++++++++----- dlls/ncrypt/ncrypt_internal.h | 6 ++++ dlls/ncrypt/tests/ncrypt.c | 8 +++-- 3 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 1f0ff3f5752..d4248e76c45 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -30,14 +30,6 @@
[...]
-SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key,
const WCHAR *algid, const WCHAR *name, DWORD keyspec, DWORD flags)
-{
- FIXME("(%#Ix, %p, %s, %s, %#lx, %#lx): stub\n", provider, key, wine_dbgstr_w(algid),
wine_dbgstr_w(name), keyspec, flags);
- return NTE_NOT_SUPPORTED;
-}
SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD insize, void *padding, BYTE *output, DWORD outsize, DWORD *result, DWORD flags) { @@ -357,6 +349,60 @@ SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE handle, const WCHAR *name return set_object_property(object, name, input, insize); }
+SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key,
const WCHAR *algid, const WCHAR *name, DWORD keyspec, DWORD flags)
+{
- struct object *key_object;
- TRACE("(%#Ix, %p, %s, %s, %#lx, %#lx)\n", provider, key, wine_dbgstr_w(algid),
wine_dbgstr_w(name), keyspec, flags);
- if (!provider) return NTE_INVALID_HANDLE;
- if (!algid) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER);
- if (name) FIXME("Persistant keys not supported\n");
- if (!(key_object = allocate_object(KEY)))
- {
ERR("Error allocating memory\n");
return NTE_NO_MEMORY;
- }
- if (!lstrcmpiW(algid, BCRYPT_RSA_ALGORITHM))
- {
NTSTATUS ret = BCryptOpenAlgorithmProvider(&key_object->key.alg_prov, BCRYPT_RSA_ALGORITHM, NULL, 0);
DWORD default_bitlength = 1024;
This could use a test to confirm that 1024 is the default.
if (ret != ERROR_SUCCESS)
{
ERR("Error opening algorithm provider\n");
free(key_object);
return NTE_INTERNAL_ERROR;
}
ret = BCryptGenerateKeyPair(key_object->key.alg_prov, &key_object->key.bcrypt_key, 1024, 0);
if (ret != ERROR_SUCCESS)
{
ERR("Error generating key pair\n");
BCryptCloseAlgorithmProvider(key_object->key.alg_prov, 0);
free(key_object);
return NTE_INTERNAL_ERROR;
}
key_object->key.type = ASYMMETRIC;
set_object_property(key_object, NCRYPT_PROVIDER_HANDLE_PROPERTY, (BYTE *)&provider, sizeof(NCRYPT_PROV_HANDLE));
set_object_property(key_object, NCRYPT_ALGORITHM_GROUP_PROPERTY, (BYTE *)BCRYPT_RSA_ALGORITHM, sizeof(BCRYPT_RSA_ALGORITHM));
set_object_property(key_object, NCRYPT_LENGTH_PROPERTY, (BYTE *)&default_bitlength, sizeof(default_bitlength));
- }
- else
- {
FIXME("Algorithm not handled %s\n", wine_dbgstr_w(algid));
free(key_object);
return NTE_NOT_SUPPORTED;
- }
- *key = (NCRYPT_KEY_HANDLE)key_object;
- return ERROR_SUCCESS;
+}
There's no reason to move this function. It also has so much in common with NCryptImportKey() that they should share a helper.
SECURITY_STATUS WINAPI NCryptVerifySignature(NCRYPT_KEY_HANDLE handle, void *padding, BYTE *hash, DWORD hash_size, BYTE *signature, DWORD signature_size, DWORD flags) { diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index 05f2f6835de..f480667b29e 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -18,8 +18,14 @@
#include <bcrypt.h>
+enum key_type {
- SYMMETRIC,
- ASYMMETRIC
+};
struct key {
- enum key_type type;
It would be better to store an algorithm id from which the symmetric/asymmetric distinction can be derived.
El mar, 8 mar 2022 a la(s) 07:16, Hans Leidekker (hans@codeweavers.com) escribió:
+SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE
provider, NCRYPT_KEY_HANDLE *key,
const WCHAR *algid,
const WCHAR *name, DWORD keyspec, DWORD flags)
+{
- struct object *key_object;
- TRACE("(%#Ix, %p, %s, %s, %#lx, %#lx)\n", provider, key,
wine_dbgstr_w(algid),
wine_dbgstr_w(name), keyspec, flags);
- if (!provider) return NTE_INVALID_HANDLE;
- if (!algid) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER);
- if (name) FIXME("Persistant keys not supported\n");
- if (!(key_object = allocate_object(KEY)))
- {
ERR("Error allocating memory\n");
return NTE_NO_MEMORY;
- }
- if (!lstrcmpiW(algid, BCRYPT_RSA_ALGORITHM))
- {
NTSTATUS ret =
BCryptOpenAlgorithmProvider(&key_object->key.alg_prov, BCRYPT_RSA_ALGORITHM, NULL, 0);
DWORD default_bitlength = 1024;
This could use a test to confirm that 1024 is the default.
This is already tested at dlls/ncrypt/tests/ncrypt.c:292
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/main.c | 48 ++++++++++++++++++++++++++++++----- dlls/ncrypt/ncrypt_internal.h | 1 + dlls/ncrypt/tests/ncrypt.c | 25 ++++++++++++++++++ 3 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index d4248e76c45..81dca4196e0 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -66,12 +66,6 @@ SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR * return NTE_NOT_SUPPORTED; }
-SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags) -{ - FIXME("(%#Ix, %#lx): stub\n", key, flags); - return NTE_NOT_SUPPORTED; -} - SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf) { FIXME("(%p): stub\n", buf); @@ -403,6 +397,48 @@ SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCR return ERROR_SUCCESS; }
+SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags) +{ + struct object *key_object = (struct object*)key; + DWORD key_length; + struct object_property *prop; + NTSTATUS ret; + + TRACE("(%#Ix, %#lx): stub\n", key, flags); + + if (!key) return NTE_INVALID_HANDLE; + if (key_object->key.finalized_key) return NTE_INVALID_HANDLE; + + if (key_object->key.type == ASYMMETRIC) + { + prop = get_object_property(key_object, NCRYPT_LENGTH_PROPERTY); + if (!prop) return NTE_INVALID_HANDLE; + + key_length = *(DWORD *)prop->value; + BCryptSetProperty(key_object->key.bcrypt_key, BCRYPT_KEY_LENGTH, (UCHAR*)&key_length, sizeof(key_length), 0); + + ret = BCryptFinalizeKeyPair(key_object->key.bcrypt_key, 0); + if (ret != ERROR_SUCCESS) + { + ERR("Error finalizing key pair\n"); + return NTE_INTERNAL_ERROR; + } + } + else if (key_object->key.type == SYMMETRIC) + { + FIXME("Symmetric keys not implemented\n"); + return NTE_NOT_SUPPORTED; + } + else + { + ERR("Got handle with invalid key type"); + return NTE_INVALID_HANDLE; + } + + key_object->key.finalized_key = 1; + return ERROR_SUCCESS; +} + SECURITY_STATUS WINAPI NCryptVerifySignature(NCRYPT_KEY_HANDLE handle, void *padding, BYTE *hash, DWORD hash_size, BYTE *signature, DWORD signature_size, DWORD flags) { diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index f480667b29e..bf7570ed591 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -25,6 +25,7 @@ enum key_type {
struct key { + DWORD finalized_key; enum key_type type; BCRYPT_ALG_HANDLE alg_prov; BCRYPT_KEY_HANDLE bcrypt_key; diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c index ec69b236ac9..fc951fef80a 100644 --- a/dlls/ncrypt/tests/ncrypt.c +++ b/dlls/ncrypt/tests/ncrypt.c @@ -306,6 +306,30 @@ static void test_create_persisted_key(void) NCryptFreeObject(prov); }
+static void test_finalize_key(void) +{ + NCRYPT_PROV_HANDLE prov; + NCRYPT_KEY_HANDLE key; + SECURITY_STATUS ret; + + ret = NCryptOpenStorageProvider(&prov, NULL, 0); + ok(ret == ERROR_SUCCESS, "got %#lx\n", ret); + + ret = NCryptCreatePersistedKey(prov, &key, BCRYPT_RSA_ALGORITHM, NULL, 0, 0); + ok(ret == ERROR_SUCCESS, "got %#lx\n", ret); + + ret = NCryptFinalizeKey(key, 0); + ok(ret == ERROR_SUCCESS, "got %#lx\n", ret); + + ret = NCryptFinalizeKey(key, 0); + ok(ret == NTE_INVALID_HANDLE, "got %#lx\n", ret); + + ret = NCryptFinalizeKey(0, 0); + ok(ret == NTE_INVALID_HANDLE, "got %#lx\n", ret); + + NCryptFreeObject(key); +} + START_TEST(ncrypt) { test_key_import_rsa(); @@ -313,4 +337,5 @@ START_TEST(ncrypt) test_get_property(); test_set_property(); test_create_persisted_key(); + test_finalize_key(); }
On Mon, 2022-03-07 at 20:57 -0300, Santino Mazza wrote:
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com
dlls/ncrypt/main.c | 48 ++++++++++++++++++++++++++++++----- dlls/ncrypt/ncrypt_internal.h | 1 + dlls/ncrypt/tests/ncrypt.c | 25 ++++++++++++++++++ 3 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index d4248e76c45..81dca4196e0 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -66,12 +66,6 @@ SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR * return NTE_NOT_SUPPORTED; } -SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags) -{
- FIXME("(%#Ix, %#lx): stub\n", key, flags);
- return NTE_NOT_SUPPORTED;
-}
SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf) { FIXME("(%p): stub\n", buf); @@ -403,6 +397,48 @@ SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCR return ERROR_SUCCESS; }
+SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags) +{
- struct object *key_object = (struct object*)key;
- DWORD key_length;
- struct object_property *prop;
- NTSTATUS ret;
- TRACE("(%#Ix, %#lx): stub\n", key, flags);
- if (!key) return NTE_INVALID_HANDLE;
- if (key_object->key.finalized_key) return NTE_INVALID_HANDLE;
- if (key_object->key.type == ASYMMETRIC)
- {
prop = get_object_property(key_object, NCRYPT_LENGTH_PROPERTY);
if (!prop) return NTE_INVALID_HANDLE;
key_length = *(DWORD *)prop->value;
BCryptSetProperty(key_object->key.bcrypt_key, BCRYPT_KEY_LENGTH, (UCHAR*)&key_length, sizeof(key_length), 0);
ret = BCryptFinalizeKeyPair(key_object->key.bcrypt_key, 0);
if (ret != ERROR_SUCCESS)
{
ERR("Error finalizing key pair\n");
return NTE_INTERNAL_ERROR;
}
- }
- else if (key_object->key.type == SYMMETRIC)
- {
FIXME("Symmetric keys not implemented\n");
return NTE_NOT_SUPPORTED;
- }
- else
- {
ERR("Got handle with invalid key type");
return NTE_INVALID_HANDLE;
- }
- key_object->key.finalized_key = 1;
- return ERROR_SUCCESS;
+}
There's no need to move this function. Do you really need finalized_key? If BCryptFinalizeKeyPair() fails when called a second time we should implement that and rely on it here.