ncrypt: Implement NCryptGetProperty and NCryptSetProperty.

Signed-off-by: Santino Mazza <mazzasantino1206@gmail.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Santino Mazza 2022-02-16 15:13:08 +01:00 committed by Alexandre Julliard
parent 24a4431f67
commit b8924d9da9
3 changed files with 123 additions and 7 deletions

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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
}