[PATCH 03/10] ncrypt: Implement NCryptImportKey function.
Santino Mazza
mazzasantino1206 at gmail.com
Sat Feb 12 15:49:47 CST 2022
Signed-off-by: Santino Mazza <mazzasantino1206 at gmail.com>
---
dlls/ncrypt/Makefile.in | 3 +-
dlls/ncrypt/ncrypt_internal.c | 43 +++++++++++
dlls/ncrypt/ncrypt_internal.h | 97 +++++++++++++++++++++++
dlls/ncrypt/{main.c => ncrypt_main.c} | 106 +++++++++++++++++++++++---
include/ncrypt.h | 5 +-
5 files changed, 239 insertions(+), 15 deletions(-)
create mode 100644 dlls/ncrypt/ncrypt_internal.c
create mode 100644 dlls/ncrypt/ncrypt_internal.h
rename dlls/ncrypt/{main.c => ncrypt_main.c} (62%)
diff --git a/dlls/ncrypt/Makefile.in b/dlls/ncrypt/Makefile.in
index b8c7b6e242c..13a58204bdf 100644
--- a/dlls/ncrypt/Makefile.in
+++ b/dlls/ncrypt/Makefile.in
@@ -4,4 +4,5 @@ MODULE = ncrypt.dll
EXTRADLLFLAGS = -Wb,--prefer-native
C_SRCS = \
- main.c
+ ncrypt_internal.c \
+ ncrypt_main.c
diff --git a/dlls/ncrypt/ncrypt_internal.c b/dlls/ncrypt/ncrypt_internal.c
new file mode 100644
index 00000000000..370391d8171
--- /dev/null
+++ b/dlls/ncrypt/ncrypt_internal.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021 Santino Mazza
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+
+#include "ncrypt_internal.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
+
+int allocate_key_object(struct ncrypt_object **keyobject)
+{
+ *keyobject = malloc(sizeof(struct ncrypt_object));
+ if (keyobject == NULL)
+ {
+ ERR("Error allocating memory.\n");
+ return NTE_NO_MEMORY;
+ }
+ memset(*keyobject, 0, sizeof(struct ncrypt_object));
+ (*keyobject)->type = KEY;
+ return ERROR_SUCCESS;
+}
diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h
new file mode 100644
index 00000000000..52029521b3e
--- /dev/null
+++ b/dlls/ncrypt/ncrypt_internal.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021 Santino Mazza
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef NCRYPT_INTERNAL_H
+#define NCRYPT_INTERNAL_H
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+
+enum asymmetric_key_type
+{
+ PUBLIC,
+ PRIVATE,
+};
+
+enum key_algorithm_type
+{
+ DH,
+ DSA,
+ ECC,
+ RSA,
+};
+
+struct rsa_key
+{
+ DWORD public_exp_size;
+ BYTE *public_exp;
+ DWORD modulus_size;
+ BYTE *modulus;
+ DWORD prime1_size;
+ BYTE *prime1;
+ DWORD prime2_size;
+ BYTE *prime2;
+};
+
+struct ncrypt_key_object
+{
+ enum key_algorithm_type algtype;
+ union
+ {
+ struct rsa_key rsa_key;
+ } payload;
+};
+
+struct ncrypt_storage_provider_object
+{
+ // FIXME Stub
+};
+
+enum ncrypt_object_type
+{
+ KEY,
+ STORAGE_PROVIDER,
+};
+
+struct ncrypt_object_property
+{
+ WCHAR *key;
+ DWORD value_size;
+ VOID *value;
+};
+
+struct ncrypt_object
+{
+ enum ncrypt_object_type type;
+ DWORD number_of_properties;
+ struct ncrypt_object_property *properties;
+ union
+ {
+ struct ncrypt_key_object key;
+ struct ncrypt_storage_provider_object storage_provider;
+ } object;
+};
+
+int allocate_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);
+
+#endif // NCRYPT_INTERNAL_H
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/ncrypt_main.c
similarity index 62%
rename from dlls/ncrypt/main.c
rename to dlls/ncrypt/ncrypt_main.c
index f23b239d93f..69b0508b110 100644
--- a/dlls/ncrypt/main.c
+++ b/dlls/ncrypt/ncrypt_main.c
@@ -19,10 +19,13 @@
*/
#include <stdarg.h>
+#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "ncrypt.h"
+#include "bcrypt.h"
+#include "ncrypt_internal.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
@@ -32,7 +35,7 @@ SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCR
DWORD flags)
{
FIXME("(0x%lx, %p, %s, %s, 0x%08x, 0x%08x): stub\n", provider, key, wine_dbgstr_w(algid),
- wine_dbgstr_w(name), keyspec, flags);
+ wine_dbgstr_w(name), keyspec, flags);
return NTE_NOT_SUPPORTED;
}
@@ -40,7 +43,7 @@ SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD i
BYTE *output, DWORD outsize, DWORD *result, DWORD flags)
{
FIXME("(0x%lx, %p, %u, %p, %p, %u, %p, 0x%08x): stub\n", key, input, insize, padding,
- output, outsize, result, flags);
+ output, outsize, result, flags);
return NTE_NOT_SUPPORTED;
}
@@ -54,7 +57,7 @@ SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD i
BYTE *output, DWORD outsize, DWORD *result, DWORD flags)
{
FIXME("(0x%lx, %p, %u, %p, %p, %u, %p, 0x%08x): stub\n", key, input, insize, padding,
- output, outsize, result, flags);
+ output, outsize, result, flags);
return NTE_NOT_SUPPORTED;
}
@@ -95,7 +98,7 @@ SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *prop
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);
+ result, flags);
return NTE_NOT_SUPPORTED;
}
@@ -103,10 +106,91 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H
const WCHAR *type, NCryptBufferDesc *params, NCRYPT_KEY_HANDLE *key,
PBYTE data, DWORD datasize, DWORD flags)
{
- FIXME("(0x%lx, 0x%lx, %s, %p, %p, %p, %u, 0x%08x): stub\n", provider, decrypt_key,
- wine_dbgstr_w(type), params,
- key, data, datasize, flags);
- return NTE_NOT_SUPPORTED;
+ BCRYPT_KEY_BLOB *keyheader = (BCRYPT_KEY_BLOB *)data;
+
+ if (decrypt_key != 0)
+ {
+ FIXME("Key blob decryption not implemented\n");
+ return NTE_NOT_SUPPORTED;
+ }
+
+ if (params != NULL)
+ {
+ FIXME("Parameter information not implemented\n");
+ return NTE_NOT_SUPPORTED;
+ }
+
+ if (flags == NCRYPT_SILENT_FLAG)
+ {
+ FIXME("Silent flag not implemented\n");
+ }
+ else if (flags != 0)
+ {
+ ERR("Invalid flags 0x%x\n", flags);
+ return NTE_BAD_FLAGS;
+ }
+
+ switch (keyheader->Magic)
+ {
+ case BCRYPT_RSAPUBLIC_MAGIC:
+ {
+ int ret;
+ DWORD expected_size;
+ struct ncrypt_object *rsakeyobject;
+ struct ncrypt_key_object *rsakey;
+ BYTE *public_exp;
+ BYTE *modulus;
+ BCRYPT_RSAKEY_BLOB *rsaheader = (BCRYPT_RSAKEY_BLOB *)data;
+
+ if (datasize < sizeof(BCRYPT_RSAKEY_BLOB))
+ {
+ ERR("Invalid buffer size.\n");
+ return NTE_BAD_DATA;
+ }
+
+ expected_size = sizeof(BCRYPT_RSAKEY_BLOB) + rsaheader->cbPublicExp + rsaheader->cbModulus;
+ if (datasize != expected_size)
+ {
+ ERR("Invalid buffer size.\n");
+ return NTE_BAD_DATA;
+ }
+
+ ret = allocate_key_object(&rsakeyobject);
+ if (ret != ERROR_SUCCESS)
+ return ret;
+
+ rsakey = &rsakeyobject->object.key;
+ rsakey->algtype = RSA;
+ rsakey->payload.rsa_key.public_exp_size = rsaheader->cbPublicExp;
+ rsakey->payload.rsa_key.modulus_size = rsaheader->cbModulus;
+ rsakey->payload.rsa_key.public_exp = malloc(rsaheader->cbPublicExp);
+ if (rsakey->payload.rsa_key.public_exp == NULL)
+ {
+ ERR("Error allocating memory.\n");
+ return NTE_NO_MEMORY;
+ }
+ rsakey->payload.rsa_key.modulus = malloc(rsaheader->cbModulus);
+ if (rsakey->payload.rsa_key.modulus == NULL)
+ {
+ ERR("Error allocating memory.\n");
+ return NTE_NO_MEMORY;
+ }
+
+ public_exp = &data[sizeof(BCRYPT_RSAKEY_BLOB)]; /* The public exp its after the header. */
+ modulus = &public_exp[rsaheader->cbPublicExp]; /* The modulus its after the public exp. */
+ memcpy(rsakey->payload.rsa_key.public_exp, public_exp, rsaheader->cbPublicExp);
+ memcpy(rsakey->payload.rsa_key.modulus, modulus, rsaheader->cbModulus);
+
+ *key = (NCRYPT_KEY_HANDLE)rsakeyobject;
+ }
+ break;
+
+ default:
+ ERR("Invalid key magic %x\n", keyheader->Magic);
+ return NTE_INVALID_PARAMETER;
+ }
+
+ return ERROR_SUCCESS;
}
SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const WCHAR *algid,
@@ -132,13 +216,13 @@ SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HAN
SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *provider, const WCHAR *name, DWORD flags)
{
FIXME("(%p, %s, %u): stub\n", provider, wine_dbgstr_w(name), flags);
- return NTE_NOT_SUPPORTED;
+ return ERROR_SUCCESS;
}
SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *property,
PBYTE input, DWORD insize, DWORD flags)
{
- FIXME("(%lx, %s, %p, %u, 0x%08x): stub\n", object, wine_dbgstr_w(property), input, insize,
- flags);
+ FIXME("(%lx, %s, %p, %u, 0x%08x): semi-stub\n", object, wine_dbgstr_w(property), input, insize,
+ flags);
return NTE_NOT_SUPPORTED;
}
diff --git a/include/ncrypt.h b/include/ncrypt.h
index bfb4c0c325c..620dfa52d66 100644
--- a/include/ncrypt.h
+++ b/include/ncrypt.h
@@ -77,9 +77,8 @@ SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, B
SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE, DWORD);
SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE);
SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, DWORD, DWORD);
-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);
+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);
#ifdef __cplusplus
--
2.25.1
More information about the wine-devel
mailing list