[PATCH 06/10] ncrypt: Implement NCryptGetProperty and NCryptSetProperty.

Santino Mazza mazzasantino1206 at gmail.com
Sat Feb 12 15:49:50 CST 2022


Signed-off-by: Santino Mazza <mazzasantino1206 at gmail.com>
---
 dlls/ncrypt/ncrypt_internal.c | 63 +++++++++++++++++++++++++++++++++++
 dlls/ncrypt/ncrypt_internal.h |  4 +--
 dlls/ncrypt/ncrypt_main.c     | 36 ++++++++++++++++----
 dlls/ncrypt/tests/ncrypt.c    | 22 ++++++++++++
 include/ncrypt.h              |  2 ++
 5 files changed, 118 insertions(+), 9 deletions(-)

diff --git a/dlls/ncrypt/ncrypt_internal.c b/dlls/ncrypt/ncrypt_internal.c
index 2bbbd58af64..8895bf9ac8d 100644
--- a/dlls/ncrypt/ncrypt_internal.c
+++ b/dlls/ncrypt/ncrypt_internal.c
@@ -69,3 +69,66 @@ int free_key_object(struct ncrypt_object *keyobject)
 
     return ERROR_SUCCESS;
 }
+
+int set_object_property(struct ncrypt_object *obj, WCHAR *property_name, BYTE *value, DWORD value_size)
+{
+    if (obj->number_of_properties == 0)
+    {
+        obj->properties = malloc(sizeof(struct ncrypt_object_property));
+        if (obj->properties == NULL)
+        {
+            ERR("Error allocating memory.");
+            return NTE_NO_MEMORY;
+        }
+        obj->number_of_properties++;
+    }
+    else
+    {
+        obj->number_of_properties++;
+        obj->properties = realloc(obj->properties, sizeof(struct ncrypt_object_property) * obj->number_of_properties);
+        if (obj->properties == NULL)
+        {
+            ERR("Error allocating memory.");
+            return NTE_NO_MEMORY;
+        }
+    }
+
+    struct ncrypt_object_property property;
+    property.key = malloc((lstrlenW(property_name) + 1) * 2);
+    if (property.key == NULL)
+    {
+        ERR("Error allocating memory.");
+        return NTE_NO_MEMORY;
+    }
+    lstrcpyW(property.key, property_name);
+    property.value_size = value_size;
+    property.value = malloc(value_size);
+    if (property.value == NULL)
+    {
+        ERR("Error allocating memory.");
+        return NTE_NO_MEMORY;
+    }
+    memcpy(property.value, value, value_size);
+
+    memcpy(&obj->properties[obj->number_of_properties - 1], &property, sizeof(struct ncrypt_object_property));
+
+    return ERROR_SUCCESS;
+}
+
+int get_object_property(struct ncrypt_object *obj, WCHAR *property_name, struct ncrypt_object_property *propertyout)
+{
+    if (obj->number_of_properties == 0)
+        return NTE_INVALID_PARAMETER;
+
+    for (int i = 0; i < obj->number_of_properties; ++i)
+    {
+        struct ncrypt_object_property *property = &obj->properties[i];
+        if (lstrcmpW(property->key, property_name) == 0)
+        {
+            memcpy(propertyout, property, sizeof(struct ncrypt_object_property));
+            return ERROR_SUCCESS;
+        }
+    }
+
+    return NTE_INVALID_PARAMETER;
+}
diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h
index 9ef5ce593be..948704d320c 100644
--- a/dlls/ncrypt/ncrypt_internal.h
+++ b/dlls/ncrypt/ncrypt_internal.h
@@ -93,7 +93,7 @@ struct ncrypt_object
 
 int allocate_key_object(struct ncrypt_object **keyobject);
 int free_key_object(struct ncrypt_object *keyobject);
-int set_object_property(struct ncrypt_object *obj, WCHAR property_name, BYTE *value, DWORD value_size);
-int get_object_property_value(struct ncrypt_object *obj, WCHAR property_name, BYTE *buf, DWORD buffer_size);
+int set_object_property(struct ncrypt_object *obj, WCHAR *property_name, BYTE *value, DWORD value_size);
+int get_object_property(struct ncrypt_object *obj, WCHAR *property_name, struct ncrypt_object_property *propertyout);
 
 #endif // NCRYPT_INTERNAL_H
diff --git a/dlls/ncrypt/ncrypt_main.c b/dlls/ncrypt/ncrypt_main.c
index c567378c16b..24f0f50d588 100644
--- a/dlls/ncrypt/ncrypt_main.c
+++ b/dlls/ncrypt/ncrypt_main.c
@@ -91,7 +91,8 @@ SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf)
 SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object)
 {
     struct ncrypt_object *ncryptobj = (struct ncrypt_object *)object;
-    if (ncryptobj == NULL) {
+    if (ncryptobj == NULL)
+    {
         ERR("invalid handle 0x%x\n", ncryptobj);
         return NTE_INVALID_HANDLE;
     }
@@ -114,21 +115,40 @@ SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object)
     break;
     }
 
+    free(ncryptobj->properties);
     free(ncryptobj);
     return ERROR_SUCCESS;
 }
 
-SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *property, PBYTE output,
+SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *property, 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,
+    FIXME("(0x%lx, %s, %p, %u, %p, 0x%08x): semi-stub\n", object, wine_dbgstr_w(property), output, outsize,
           result, flags);
-    return NTE_NOT_SUPPORTED;
+
+    struct ncrypt_object *ncryptobj = (struct ncrypt_object *)object;
+    struct ncrypt_object_property prop;
+    int ret = get_object_property(ncryptobj, property, &prop);
+
+    if (ret != ERROR_SUCCESS)
+        return ret;
+
+    if (output == NULL)
+    {
+        *result = prop.value_size;
+        return ERROR_SUCCESS;
+    }
+
+    if (outsize < prop.value_size)
+        return NTE_BUFFER_TOO_SMALL;
+
+    memcpy(output, prop.value, prop.value_size);
+    return ERROR_SUCCESS;
 }
 
 SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE decrypt_key,
                                        const WCHAR *type, NCryptBufferDesc *params, NCRYPT_KEY_HANDLE *key,
-                                       PBYTE data, DWORD datasize, DWORD flags)
+                                       BYTE *data, DWORD datasize, DWORD flags)
 {
     BCRYPT_KEY_BLOB *keyheader = (BCRYPT_KEY_BLOB *)data;
 
@@ -244,9 +264,11 @@ SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *provider, c
 }
 
 SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *property,
-                                         PBYTE input, DWORD insize, DWORD flags)
+                                         BYTE *input, DWORD insize, DWORD flags)
 {
     FIXME("(%lx, %s, %p, %u, 0x%08x): semi-stub\n", object, wine_dbgstr_w(property), input, insize,
           flags);
-    return NTE_NOT_SUPPORTED;
+
+    struct ncrypt_object *ncryptobj = (struct ncrypt_object *)object;
+    return set_object_property(ncryptobj, property, input, insize);
 }
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c
index bacefa9d3b6..ccaa6003efa 100644
--- a/dlls/ncrypt/tests/ncrypt.c
+++ b/dlls/ncrypt/tests/ncrypt.c
@@ -157,8 +157,30 @@ static void test_ncrypt_free_object(void)
     free(key);
 }
 
+static void test_get_property(void)
+{
+    NCRYPT_PROV_HANDLE prov;
+    SECURITY_STATUS ncryptret = NCryptOpenStorageProvider(&prov, NULL, 0);
+    ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret);
+
+    NCRYPT_KEY_HANDLE key;
+    ncryptret = NCryptImportKey(prov, (NCRYPT_KEY_HANDLE)NULL, BCRYPT_RSAPUBLIC_BLOB, NULL, &key, rsa_key_blob, 155, 0);
+
+    DWORD size;
+    ncryptret = NCryptGetProperty(key, L"Algorithm Group", NULL, 0, &size, 0);
+    ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret);
+    ok(size == 8, "got 0x%x\n", size);
+
+    WCHAR value[8];
+    ncryptret = NCryptGetProperty(key, L"Algorithm Group", value, 8, &size, 0);
+    ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret);
+    ok(size == 8, "got 0x%x\n", size);
+    ok(lstrcmpW(value, L"RSA") == 0, "The string doesn't match with 'RSA'\n");
+}
+
 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 620dfa52d66..8bcae4be0ab 100644
--- a/include/ncrypt.h
+++ b/include/ncrypt.h
@@ -80,6 +80,8 @@ SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, co
 SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE,const WCHAR *, NCryptBufferDesc *, NCRYPT_KEY_HANDLE *,
                                        PBYTE, DWORD, DWORD);
 SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
+SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE, const WCHAR *, BYTE *, DWORD, DWORD);
+SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE, const WCHAR *, BYTE *, DWORD, DWORD *, DWORD);
 
 #ifdef __cplusplus
 }
-- 
2.25.1




More information about the wine-devel mailing list