[PATCH v3 1/2] ncrypt: Implement NCryptCreatePersistedKey.
Santino Mazza
mazzasantino1206 at gmail.com
Wed Mar 9 19:41:55 CST 2022
Signed-off-by: Santino Mazza <mazzasantino1206 at gmail.com>
---
dlls/ncrypt/main.c | 109 +++++++++++++++++++++++++++-------
dlls/ncrypt/ncrypt_internal.h | 21 +++++++
dlls/ncrypt/tests/ncrypt.c | 8 ++-
3 files changed, 114 insertions(+), 24 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c
index 8ace3e55731..1cc09cdfc97 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)
{
@@ -229,6 +221,45 @@ static SECURITY_STATUS set_object_property(struct object *object, const WCHAR *n
return ERROR_SUCCESS;
}
+static struct object *create_key_object(enum algid algid, NCRYPT_PROV_HANDLE provider)
+{
+ struct object *key_object;
+ NTSTATUS ret;
+
+ if (!(key_object = allocate_object(KEY)))
+ {
+ ERR("Error allocating memory\n");
+ return NULL;
+ }
+
+ switch(algid)
+ {
+ case RSA:
+ {
+ ret = BCryptOpenAlgorithmProvider(&key_object->key.bcrypt_alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
+ if (ret != ERROR_SUCCESS)
+ {
+ ERR("Error opening algorithm provider\n");
+ free(key_object);
+ return NULL;
+ }
+
+ key_object->key.algid = RSA;
+ set_object_property(key_object, NCRYPT_ALGORITHM_GROUP_PROPERTY, (BYTE *)BCRYPT_RSA_ALGORITHM, sizeof(BCRYPT_RSA_ALGORITHM));
+ break;
+ }
+ default:
+ {
+ ERR("Invalid algid %#x\n", algid);
+ free(key_object);
+ return NULL;
+ }
+ }
+
+ set_object_property(key_object, NCRYPT_PROVIDER_HANDLE_PROPERTY, (BYTE *)&provider, sizeof(provider));
+ return key_object;
+}
+
SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE decrypt_key,
const WCHAR *type, NCryptBufferDesc *params, NCRYPT_KEY_HANDLE *handle,
BYTE *data, DWORD datasize, DWORD flags)
@@ -259,12 +290,6 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H
return NTE_BAD_FLAGS;
}
- if (!(object = allocate_object(KEY)))
- {
- ERR("Error allocating memory\n");
- return NTE_NO_MEMORY;
- }
-
switch(header->Magic)
{
case BCRYPT_RSAFULLPRIVATE_MAGIC:
@@ -273,13 +298,13 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H
{
NTSTATUS ret;
BCRYPT_RSAKEY_BLOB *rsablob = (BCRYPT_RSAKEY_BLOB *)data;
- ret = BCryptOpenAlgorithmProvider(&object->key.bcrypt_alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
- if (ret != ERROR_SUCCESS)
+
+ if (!(object = create_key_object(RSA, provider)))
{
- ERR("Error opening algorithm provider\n");
- free(object);
- return NTE_INTERNAL_ERROR;
+ ERR("Error allocating memory\n");
+ return NTE_NO_MEMORY;
}
+
ret = BCryptImportKeyPair(object->key.bcrypt_alg, NULL, type, &object->key.bcrypt_key, data, datasize, 0);
if (ret != ERROR_SUCCESS)
{
@@ -289,14 +314,11 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H
return NTE_BAD_DATA;
}
- set_object_property(object, NCRYPT_PROVIDER_HANDLE_PROPERTY, (BYTE *)&provider, sizeof(provider));
- set_object_property(object, NCRYPT_ALGORITHM_GROUP_PROPERTY, (BYTE *)BCRYPT_RSA_ALGORITHM, sizeof(BCRYPT_RSA_ALGORITHM));
set_object_property(object, NCRYPT_LENGTH_PROPERTY, (BYTE *)&rsablob->BitLength, sizeof(rsablob->BitLength));
break;
}
default:
FIXME("Unhandled key magic %#lx\n", header->Magic);
- free(object);
return NTE_INVALID_PARAMETER;
}
@@ -304,6 +326,49 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H
return ERROR_SUCCESS;
}
+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 (!lstrcmpiW(algid, BCRYPT_RSA_ALGORITHM))
+ {
+ NTSTATUS ret;
+ DWORD default_bitlength = 1024;
+
+ if (!(key_object = create_key_object(RSA, provider)))
+ {
+ ERR("Error allocating memory\n");
+ return NTE_NO_MEMORY;
+ }
+
+ ret = BCryptGenerateKeyPair(key_object->key.bcrypt_alg, &key_object->key.bcrypt_key, 1024, 0);
+ if (ret != ERROR_SUCCESS)
+ {
+ ERR("Error generating key pair\n");
+ BCryptCloseAlgorithmProvider(key_object->key.bcrypt_alg, 0);
+ free(key_object);
+ return NTE_INTERNAL_ERROR;
+ }
+
+ 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));
+ return NTE_NOT_SUPPORTED;
+ }
+
+ *key = (NCRYPT_KEY_HANDLE)key_object;
+ return ERROR_SUCCESS;
+}
+
SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const WCHAR *algid, DWORD flags)
{
FIXME("(%#Ix, %s, %#lx): stub\n", provider, wine_dbgstr_w(algid), flags);
diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h
index e5884c8871a..fb4dcd290b6 100644
--- a/dlls/ncrypt/ncrypt_internal.h
+++ b/dlls/ncrypt/ncrypt_internal.h
@@ -18,8 +18,29 @@
#include <bcrypt.h>
+enum algid
+{
+ AES,
+ DES,
+ DESX,
+ DH,
+ DSA,
+ ECDH,
+ ECDH_P256,
+ ECDH_P384,
+ ECDH_P521,
+ ECDSA,
+ ECDSA_P256,
+ ECDSA_P384,
+ ECDSA_P521,
+ RC2,
+ RSA,
+ PBKDF2,
+};
+
struct key
{
+ enum algid algid;
BCRYPT_ALG_HANDLE bcrypt_alg;
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)
--
2.32.0
More information about the wine-devel
mailing list