[PATCH v4 3/4] ncrypt: Implement NCryptFinalizeKey.

Hans Leidekker hans at codeweavers.com
Thu Mar 10 04:05:07 CST 2022


From: Santino Mazza <mazzasantino1206 at gmail.com>

v4: Map bcrypt return values.

Signed-off-by: Santino Mazza <mazzasantino1206 at gmail.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/ncrypt/main.c         | 43 +++++++++++++++++++++++++++++++++++---
 dlls/ncrypt/tests/ncrypt.c | 25 ++++++++++++++++++++++
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c
index f76d5885476..f7af49e6610 100644
--- a/dlls/ncrypt/main.c
+++ b/dlls/ncrypt/main.c
@@ -21,6 +21,8 @@
 #include <stdarg.h>
 #include <stdlib.h>
 
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "windef.h"
 #include "winbase.h"
 #include "ncrypt.h"
@@ -30,6 +32,17 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
 
+static SECURITY_STATUS map_ntstatus(NTSTATUS status)
+{
+    switch (status)
+    {
+    case STATUS_INVALID_HANDLE: return NTE_INVALID_HANDLE;
+    default:
+        FIXME("unhandled status %#lx\n", status);
+        return NTE_INTERNAL_ERROR;
+    }
+}
+
 static struct object *allocate_object(enum object_type type)
 {
     struct object *ret;
@@ -227,10 +240,34 @@ SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR *
     return NTE_NOT_SUPPORTED;
 }
 
-SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags)
+SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE handle, DWORD flags)
 {
-    FIXME("(%#Ix, %#lx): stub\n", key, flags);
-    return NTE_NOT_SUPPORTED;
+    struct object *object = (struct object *)handle;
+    DWORD key_length;
+    struct object_property *prop;
+    NTSTATUS status;
+
+    TRACE("(%#Ix, %#lx)\n", handle, flags);
+
+    if (!object || object->type != KEY) return NTE_INVALID_HANDLE;
+
+    if (!(prop = get_object_property(object, NCRYPT_LENGTH_PROPERTY))) return NTE_INVALID_HANDLE;
+    key_length = *(DWORD *)prop->value;
+    status = BCryptSetProperty(object->key.bcrypt_key, BCRYPT_KEY_LENGTH, (UCHAR *)&key_length, sizeof(key_length), 0);
+    if (status != STATUS_SUCCESS)
+    {
+        ERR("Error setting key length property\n");
+        return map_ntstatus(status);
+    }
+
+    status = BCryptFinalizeKeyPair(object->key.bcrypt_key, 0);
+    if (status != STATUS_SUCCESS)
+    {
+        ERR("Error finalizing key pair\n");
+        return map_ntstatus(status);
+    }
+
+    return ERROR_SUCCESS;
 }
 
 SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf)
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();
 }
-- 
2.30.2




More information about the wine-devel mailing list