Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/Makefile.in | 3 +- dlls/ncrypt/ncrypt_internal.c | 43 +++++++++++ dlls/ncrypt/ncrypt_internal.h | 95 +++++++++++++++++++++++ dlls/ncrypt/{main.c => ncrypt_main.c} | 104 +++++++++++++++++++++++--- dlls/ncrypt/tests/ncrypt.c | 2 - 5 files changed, 234 insertions(+), 13 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} (63%)
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..94c63ba2274 --- /dev/null +++ b/dlls/ncrypt/ncrypt_internal.h @@ -0,0 +1,95 @@ +/* + * 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 ncrypt_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 ncrypt_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); + +#endif // NCRYPT_INTERNAL_H diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/ncrypt_main.c similarity index 63% rename from dlls/ncrypt/main.c rename to dlls/ncrypt/ncrypt_main.c index f23b239d93f..717b67eae9f 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); + flags); return NTE_NOT_SUPPORTED; } diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c index b948665ebaa..eecd44a7ceb 100644 --- a/dlls/ncrypt/tests/ncrypt.c +++ b/dlls/ncrypt/tests/ncrypt.c @@ -86,7 +86,6 @@ UCHAR invalid_rsa_key_blob[] = {
static void test_key_import_rsa(void) { - todo_wine { NCRYPT_PROV_HANDLE prov; SECURITY_STATUS ret = NCryptOpenStorageProvider(&prov, NULL, 0); ok(ret == ERROR_SUCCESS, "got 0x%x\n", ret); @@ -124,7 +123,6 @@ static void test_key_import_rsa(void) ok(ret == NTE_BAD_DATA, "got 0x%x\n", ret);
NCryptFreeObject(prov); - } }
START_TEST(ncrypt)