Santino Mazza : ncrypt: Implement NCryptGetProperty and NCryptSetProperty.

Alexandre Julliard julliard at winehq.org
Wed Feb 16 15:30:25 CST 2022


Module: wine
Branch: master
Commit: b8924d9da989ae0f4d14e7d14c39c4e3bde0241e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b8924d9da989ae0f4d14e7d14c39c4e3bde0241e

Author: Santino Mazza <mazzasantino1206 at gmail.com>
Date:   Wed Feb 16 15:13:08 2022 +0100

ncrypt: Implement NCryptGetProperty and NCryptSetProperty.

Signed-off-by: Santino Mazza <mazzasantino1206 at gmail.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ncrypt/main.c         | 96 ++++++++++++++++++++++++++++++++++++++++++----
 dlls/ncrypt/tests/ncrypt.c | 32 ++++++++++++++++
 include/ncrypt.h           |  2 +
 3 files changed, 123 insertions(+), 7 deletions(-)

diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c
index fcf5bdbe3e7..a2253c44cb9 100644
--- a/dlls/ncrypt/main.c
+++ b/dlls/ncrypt/main.c
@@ -109,6 +109,7 @@ SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE handle)
 {
     struct object *object = (struct object *)handle;
     SECURITY_STATUS ret = ERROR_SUCCESS;
+    unsigned int i;
 
     TRACE("(%#Ix)\n", handle);
 
@@ -133,15 +134,46 @@ SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE handle)
         return NTE_INVALID_HANDLE;
     }
 
+    for (i = 0; i < object->num_properties; i++)
+    {
+        free(object->properties[i].key);
+        free(object->properties[i].value);
+    }
+    free(object->properties);
     free(object);
     return ret;
 }
 
-SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *property, PBYTE output,
+static const struct object_property *get_object_property(struct object *object, const WCHAR *name)
+{
+    unsigned int i;
+    for (i = 0; i < object->num_properties; i++)
+    {
+        const struct object_property *property = &object->properties[i];
+        if (!lstrcmpW(property->key, name)) return property;
+    }
+    return NULL;
+}
+
+SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE handle, const WCHAR *name, BYTE *output,
                                          DWORD outsize, DWORD *result, DWORD flags)
 {
-    FIXME("(0x%lx, %s, %p, %u, %p, 0x%08x): stub\n", object, wine_dbgstr_w(property), output, outsize, result, flags);
-    return NTE_NOT_SUPPORTED;
+    struct object *object = (struct object *)handle;
+    const struct object_property *property;
+
+    TRACE("(%#Ix, %s, %p, %u, %p, 0x%08x)\n", handle, wine_dbgstr_w(name), output, outsize, result, flags);
+    if (flags) FIXME("flags 0x%08x not supported\n", flags);
+
+    if (!(property = get_object_property(object, name))) return NTE_INVALID_PARAMETER;
+    if (!output)
+    {
+        *result = property->value_size;
+        return ERROR_SUCCESS;
+    }
+    if (outsize < property->value_size) return NTE_BUFFER_TOO_SMALL;
+
+    memcpy(output, property->value, property->value_size);
+    return ERROR_SUCCESS;
 }
 
 static struct object *allocate_object(enum object_type type)
@@ -278,9 +310,59 @@ SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *provider, c
     return ERROR_SUCCESS;
 }
 
-SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *property,
-                                         PBYTE input, DWORD insize, DWORD flags)
+static SECURITY_STATUS set_object_property(struct object *object, const WCHAR *name, BYTE *value, DWORD value_size)
 {
-    FIXME("(%lx, %s, %p, %u, 0x%08x): stub\n", object, wine_dbgstr_w(property), input, insize, flags);
-    return NTE_NOT_SUPPORTED;
+    struct object_property *property = &object->properties[object->num_properties];
+
+    FIXME("check duplicates\n");
+    if (!object->num_properties)
+    {
+        if (!(object->properties = malloc(sizeof(*property))))
+        {
+            ERR("Error allocating memory.");
+            return NTE_NO_MEMORY;
+        }
+        object->num_properties++;
+    }
+    else
+    {
+        struct object_property *tmp;
+        if (!(tmp = realloc(object->properties, sizeof(*property) * object->num_properties + 1)))
+        {
+            ERR("Error allocating memory.");
+            return NTE_NO_MEMORY;
+        }
+        object->properties = tmp;
+        object->num_properties++;
+    }
+
+    memset(property, 0, sizeof(*property));
+    if (!(property->key = malloc((lstrlenW(name) + 1) * sizeof(WCHAR))))
+    {
+        ERR("Error allocating memory.");
+        return NTE_NO_MEMORY;
+    }
+
+    lstrcpyW(property->key, name);
+    property->value_size = value_size;
+    if (!(property->value = malloc(value_size)))
+    {
+        ERR("Error allocating memory.");
+        free(property->key);
+        property->key = NULL;
+        return NTE_NO_MEMORY;
+    }
+
+    memcpy(property->value, value, value_size);
+    return ERROR_SUCCESS;
+}
+
+SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE handle, const WCHAR *name, BYTE *input, DWORD insize, DWORD flags)
+{
+    struct object *object = (struct object *)handle;
+
+    TRACE("(%#Ix, %s, %p, %u, 0x%08x)\n", handle, wine_dbgstr_w(name), input, insize, flags);
+    if (flags) FIXME("flags 0x%08x not supported\n", flags);
+
+    return set_object_property(object, name, input, insize);
 }
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c
index 430cb0ae52c..23205d989f0 100644
--- a/dlls/ncrypt/tests/ncrypt.c
+++ b/dlls/ncrypt/tests/ncrypt.c
@@ -159,10 +159,42 @@ static void test_ncrypt_free_object(void)
     ret = NCryptFreeObject((NCRYPT_KEY_HANDLE)buf);
     ok(ret == NTE_INVALID_HANDLE, "got %#lx\n", ret);
     free(buf);
+
+    NCryptFreeObject(prov);
+}
+
+static void test_get_property(void)
+{
+    NCRYPT_PROV_HANDLE prov;
+    NCRYPT_KEY_HANDLE key;
+    SECURITY_STATUS ret;
+    WCHAR value[4];
+    DWORD size;
+
+    ret = NCryptOpenStorageProvider(&prov, NULL, 0);
+    ok(ret == ERROR_SUCCESS, "got %#lx\n", ret);
+
+    ret = NCryptImportKey(prov, 0, BCRYPT_RSAPUBLIC_BLOB, NULL, &key, rsa_key_blob, sizeof(rsa_key_blob), 0);
+    ok(ret == ERROR_SUCCESS, "got %#lx\n", ret);
+
+    todo_wine {
+    ret = NCryptGetProperty(key, L"Algorithm Group", NULL, 0, &size, 0);
+    ok(ret == ERROR_SUCCESS, "got %#lx\n", ret);
+    ok(size == 8, "got %lu\n", size);
+
+    size = 0;
+    ret = NCryptGetProperty(key, L"Algorithm Group", (BYTE *)value, sizeof(value), &size, 0);
+    ok(ret == ERROR_SUCCESS, "got %#lx\n", ret);
+    ok(size == 8, "got %lu\n", size);
+    ok(!lstrcmpW(value, L"RSA"), "The string doesn't match with 'RSA'\n");
+    }
+
+    NCryptFreeObject(prov);
 }
 
 START_TEST(ncrypt)
 {
     test_key_import_rsa();
     test_ncrypt_free_object();
+    test_get_property();
 }
diff --git a/include/ncrypt.h b/include/ncrypt.h
index 84f1fedd0b9..5a8ba7e88fc 100644
--- a/include/ncrypt.h
+++ b/include/ncrypt.h
@@ -76,10 +76,12 @@ SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, B
 SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD);
 SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE, DWORD);
 SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE);
+SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE, const WCHAR *, BYTE *, DWORD, DWORD *, DWORD);
 SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE, const WCHAR *, NCryptBufferDesc *,
                                        NCRYPT_KEY_HANDLE *, BYTE *, DWORD, DWORD);
 SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, DWORD, DWORD);
 SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
+SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE, const WCHAR *, BYTE *, DWORD, DWORD);
 
 #ifdef __cplusplus
 }




More information about the wine-cvs mailing list