Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- include/bcrypt.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/include/bcrypt.h b/include/bcrypt.h index 15c26c1fb0a..484dca0f0c4 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -254,6 +254,10 @@ typedef struct _BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO ULONG dwFlags; } BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO, *PBCRYPT_AUTHENTICATED_CIPHER_MODE_INFO;
+typedef struct _BCRYPT_KEY_BLOB { + ULONG Magic; +} BCRYPT_KEY_BLOB; + typedef struct _BCRYPT_ECCKEY_BLOB { ULONG dwMagic;
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/tests/Makefile.in | 6 ++ dlls/ncrypt/tests/ncrypt.c | 142 ++++++++++++++++++++++++++++++++++ include/ncrypt.h | 5 ++ 3 files changed, 153 insertions(+) create mode 100644 dlls/ncrypt/tests/Makefile.in create mode 100644 dlls/ncrypt/tests/ncrypt.c
diff --git a/dlls/ncrypt/tests/Makefile.in b/dlls/ncrypt/tests/Makefile.in new file mode 100644 index 00000000000..3ab100f849f --- /dev/null +++ b/dlls/ncrypt/tests/Makefile.in @@ -0,0 +1,6 @@ +EXTRADEFS = -DWINE_NO_LONG_TYPES +TESTDLL = ncrypt.dll +IMPORTS = advapi32 ncrypt bcrypt + +C_SRCS = \ + ncrypt.c diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c new file mode 100644 index 00000000000..39ee0f04254 --- /dev/null +++ b/dlls/ncrypt/tests/ncrypt.c @@ -0,0 +1,142 @@ +/* Unit test suite for ncrypt.dll + * + * Copyright 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 "wine/test.h" +#include "winbase.h" +#include "winnt.h" +#include "ncrypt.h" +#include "bcrypt.h" + +UCHAR rsa_key_blob[] = { + 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0xc7, 0x8f, 0xac, 0x2a, 0xce, 0xbf, 0xc9, 0x6c, 0x7b, + 0x85, 0x74, 0x71, 0xbb, 0xff, 0xbb, 0x9b, 0x20, 0x03, 0x79, 0x17, 0x34, + 0xe7, 0x26, 0x91, 0x5c, 0x1f, 0x1b, 0x03, 0x3d, 0x46, 0xdf, 0xb6, 0xf2, + 0x10, 0x55, 0xf0, 0x39, 0x55, 0x0a, 0xe3, 0x9c, 0x0c, 0x63, 0xc2, 0x14, + 0x03, 0x94, 0x51, 0x0d, 0xb4, 0x22, 0x09, 0xf2, 0x5c, 0xb2, 0xd1, 0xc3, + 0xac, 0x6f, 0xa8, 0xc4, 0xac, 0xb8, 0xbc, 0x59, 0xe7, 0xed, 0x77, 0x6e, + 0xb1, 0x80, 0x58, 0x7d, 0xb2, 0x94, 0x46, 0xe5, 0x00, 0xe2, 0xb7, 0x33, + 0x48, 0x7a, 0xd3, 0x78, 0xe9, 0x26, 0x01, 0xc7, 0x00, 0x7b, 0x41, 0x6d, + 0x94, 0x3a, 0xe1, 0x50, 0x2b, 0x9f, 0x6b, 0x1c, 0x08, 0xa3, 0xfc, 0x0a, + 0x44, 0x81, 0x09, 0x41, 0x80, 0x23, 0x7b, 0xf6, 0x3f, 0xaf, 0x91, 0xa1, + 0x87, 0x75, 0x33, 0x15, 0xb8, 0xde, 0x32, 0x30, 0xb4, 0x5e, 0xfd}; + +UCHAR rsa_key_blob_with_invalid_bit_length[] = { + 0x52, 0x53, 0x41, 0x31, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0xc7, 0x8f, 0xac, 0x2a, 0xce, 0xbf, 0xc9, 0x6c, 0x7b, + 0x85, 0x74, 0x71, 0xbb, 0xff, 0xbb, 0x9b, 0x20, 0x03, 0x79, 0x17, 0x34, + 0xe7, 0x26, 0x91, 0x5c, 0x1f, 0x1b, 0x03, 0x3d, 0x46, 0xdf, 0xb6, 0xf2, + 0x10, 0x55, 0xf0, 0x39, 0x55, 0x0a, 0xe3, 0x9c, 0x0c, 0x63, 0xc2, 0x14, + 0x03, 0x94, 0x51, 0x0d, 0xb4, 0x22, 0x09, 0xf2, 0x5c, 0xb2, 0xd1, 0xc3, + 0xac, 0x6f, 0xa8, 0xc4, 0xac, 0xb8, 0xbc, 0x59, 0xe7, 0xed, 0x77, 0x6e, + 0xb1, 0x80, 0x58, 0x7d, 0xb2, 0x94, 0x46, 0xe5, 0x00, 0xe2, 0xb7, 0x33, + 0x48, 0x7a, 0xd3, 0x78, 0xe9, 0x26, 0x01, 0xc7, 0x00, 0x7b, 0x41, 0x6d, + 0x94, 0x3a, 0xe1, 0x50, 0x2b, 0x9f, 0x6b, 0x1c, 0x08, 0xa3, 0xfc, 0x0a, + 0x44, 0x81, 0x09, 0x41, 0x80, 0x23, 0x7b, 0xf6, 0x3f, 0xaf, 0x91, 0xa1, + 0x87, 0x75, 0x33, 0x15, 0xb8, 0xde, 0x32, 0x30, 0xb4, 0x5e, 0xfd}; + +UCHAR rsa_key_blob_with_invalid_publicexp_size[] = { + 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0xc7, 0x8f, 0xac, 0x2a, 0xce, 0xbf, 0xc9, 0x6c, 0x7b, + 0x85, 0x74, 0x71, 0xbb, 0xff, 0xbb, 0x9b, 0x20, 0x03, 0x79, 0x17, 0x34, + 0xe7, 0x26, 0x91, 0x5c, 0x1f, 0x1b, 0x03, 0x3d, 0x46, 0xdf, 0xb6, 0xf2, + 0x10, 0x55, 0xf0, 0x39, 0x55, 0x0a, 0xe3, 0x9c, 0x0c, 0x63, 0xc2, 0x14, + 0x03, 0x94, 0x51, 0x0d, 0xb4, 0x22, 0x09, 0xf2, 0x5c, 0xb2, 0xd1, 0xc3, + 0xac, 0x6f, 0xa8, 0xc4, 0xac, 0xb8, 0xbc, 0x59, 0xe7, 0xed, 0x77, 0x6e, + 0xb1, 0x80, 0x58, 0x7d, 0xb2, 0x94, 0x46, 0xe5, 0x00, 0xe2, 0xb7, 0x33, + 0x48, 0x7a, 0xd3, 0x78, 0xe9, 0x26, 0x01, 0xc7, 0x00, 0x7b, 0x41, 0x6d, + 0x94, 0x3a, 0xe1, 0x50, 0x2b, 0x9f, 0x6b, 0x1c, 0x08, 0xa3, 0xfc, 0x0a, + 0x44, 0x81, 0x09, 0x41, 0x80, 0x23, 0x7b, 0xf6, 0x3f, 0xaf, 0x91, 0xa1, + 0x87, 0x75, 0x33, 0x15, 0xb8, 0xde, 0x32, 0x30, 0xb4, 0x5e, 0xfd}; + +/* RSA public key with invalid magic value. */ +UCHAR invalid_rsa_key_blob[] = { + 0x75, 0x59, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0xc7, 0x8f, 0xac, 0x2a, 0xce, 0xbf, 0xc9, 0x6c, 0x7b, + 0x85, 0x74, 0x71, 0xbb, 0xff, 0xbb, 0x9b, 0x20, 0x03, 0x79, 0x17, 0x34, + 0xe7, 0x26, 0x91, 0x5c, 0x1f, 0x1b, 0x03, 0x3d, 0x46, 0xdf, 0xb6, 0xf2, + 0x10, 0x55, 0xf0, 0x39, 0x55, 0x0a, 0xe3, 0x9c, 0x0c, 0x63, 0xc2, 0x14, + 0x03, 0x94, 0x51, 0x0d, 0xb4, 0x22, 0x09, 0xf2, 0x5c, 0xb2, 0xd1, 0xc3, + 0xac, 0x6f, 0xa8, 0xc4, 0xac, 0xb8, 0xbc, 0x59, 0xe7, 0xed, 0x77, 0x6e, + 0xb1, 0x80, 0x58, 0x7d, 0xb2, 0x94, 0x46, 0xe5, 0x00, 0xe2, 0xb7, 0x33, + 0x48, 0x7a, 0xd3, 0x78, 0xe9, 0x26, 0x01, 0xc7, 0x00, 0x7b, 0x41, 0x6d, + 0x94, 0x3a, 0xe1, 0x50, 0x2b, 0x9f, 0x6b, 0x1c, 0x08, 0xa3, 0xfc, 0x0a, + 0x44, 0x81, 0x09, 0x41, 0x80, 0x23, 0x7b, 0xf6, 0x3f, 0xaf, 0x91, 0xa1, + 0x87, 0x75, 0x33, 0x15, 0xb8, 0xde, 0x32, 0x30, 0xb4, 0x5e, 0xfd}; + +static void test_key_import_rsa(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 = NULL; + ncryptret = NCryptImportKey(prov, NULL, BCRYPT_RSAPUBLIC_BLOB, NULL, &key, rsa_key_blob, 155, 0); + ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret); + ok(key != NULL, "got null handle\n"); + NCryptFreeObject(key); + + key = NULL; + ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob, 155, 0); + ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret); + ok(key != NULL, "got null handle\n"); + NCryptFreeObject(key); + + key = NULL; + ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob, 155, 49); + ok(ncryptret == NTE_BAD_FLAGS, "got 0x%x\n", ncryptret); + ok(key == NULL, "expected null handle\n"); + + key = NULL; + ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, invalid_rsa_key_blob, 155, 0); + ok(ncryptret == NTE_INVALID_PARAMETER, "got 0x%x\n", ncryptret); + ok(key == NULL, "expected null handle\n"); + + key = NULL; + ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob_with_invalid_bit_length, 155, 0); + ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret); /* I'm not sure why, but this returns success */ + ok(key != NULL, "got null handle\n"); + NCryptFreeObject(key); + + key = NULL; + ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob_with_invalid_publicexp_size, 155, 0); + ok(ncryptret == NTE_BAD_DATA, "got 0x%x\n", ncryptret); + ok(key == NULL, "expected null handle\n"); + + key = NULL; + ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob, 40, 0); + ok(ncryptret == NTE_BAD_DATA, "got 0x%x\n", ncryptret); + ok(key == NULL, "expected null handle\n"); + + key = NULL; + ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob, 300, 0); + ok(ncryptret == NTE_BAD_DATA, "got 0x%x\n", ncryptret); + ok(key == NULL, "expected null handle\n"); + + NCryptFreeObject(prov); +} + +START_TEST(ncrypt) +{ + test_key_import_rsa(); +} diff --git a/include/ncrypt.h b/include/ncrypt.h index 111693f1d49..bfb4c0c325c 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -69,12 +69,17 @@ typedef ULONG_PTR NCRYPT_SECRET_HANDLE; #define NCRYPT_SCHANNEL_SIGNATURE_INTERFACE 0x00010003 #define NCRYPT_KEY_PROTECTION_INTERFACE 0x00010004
+#define NCRYPT_SILENT_FLAG 0x00000040L + SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, const WCHAR *, DWORD, DWORD); SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD); 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 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 NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
#ifdef __cplusplus
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=107784
Your paranoid android.
=== debian11 (32 bit report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (32 bit Arabic:Morocco report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (32 bit German report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (32 bit French report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (32 bit Hebrew:Israel report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (32 bit Hindi:India report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (32 bit Japanese:Japan report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (32 bit Chinese:China report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (32 bit WoW report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
=== debian11 (64 bit WoW report) ===
ncrypt: ncrypt.c:91: Test failed: got 0x80090029 ncrypt.c:95: Test failed: got 0x80090029 ncrypt.c:96: Test failed: got null handle ncrypt.c:101: Test failed: got 0x80090029 ncrypt.c:102: Test failed: got null handle ncrypt.c:107: Test failed: got 0x80090029 ncrypt.c:112: Test failed: got 0x80090029 ncrypt.c:117: Test failed: got 0x80090029 ncrypt.c:118: Test failed: got null handle ncrypt.c:123: Test failed: got 0x80090029 ncrypt.c:128: Test failed: got 0x80090029 ncrypt.c:133: Test failed: got 0x80090029
On Sat, 2022-02-12 at 18:49 -0300, Santino Mazza wrote:
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com
dlls/ncrypt/tests/Makefile.in | 6 ++  dlls/ncrypt/tests/ncrypt.c | 142 ++++++++++++++++++++++++++++++++++  include/ncrypt.h | 5 ++  3 files changed, 153 insertions(+)  create mode 100644 dlls/ncrypt/tests/Makefile.in  create mode 100644 dlls/ncrypt/tests/ncrypt.c
You also need to add an entry in configure.ac.
diff --git a/dlls/ncrypt/tests/Makefile.in b/dlls/ncrypt/tests/Makefile.in new file mode 100644 index 00000000000..3ab100f849f --- /dev/null +++ b/dlls/ncrypt/tests/Makefile.in @@ -0,0 +1,6 @@ +EXTRADEFS = -DWINE_NO_LONG_TYPES +TESTDLL = ncrypt.dll +IMPORTS = advapi32 ncrypt bcrypt
I would be better to build without -DWINE_NO_LONG_TYPES. The advapi32 and bcrypt imports are not needed.
+C_SRCS = \
- ncrypt.c
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c new file mode 100644 index 00000000000..39ee0f04254 --- /dev/null +++ b/dlls/ncrypt/tests/ncrypt.c @@ -0,0 +1,142 @@ +/* Unit test suite for ncrypt.dll
- Copyright 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 "wine/test.h" +#include "winbase.h" +#include "winnt.h" +#include "ncrypt.h" +#include "bcrypt.h"
...
+static void test_key_import_rsa(void) +{
- NCRYPT_PROV_HANDLE prov;
- SECURITY_STATUS ncryptret = NCryptOpenStorageProvider(&prov, NULL, 0);
- ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret);
The 'ncrypt' prefix doesn't add anything here. 'ret' or 'status' would be better.
- NCRYPT_KEY_HANDLE key = NULL;
NCRYPT_KEY_HANDLE is a ULONG_PTR which is an integer with the size of a pointer. You should initialize it with 0 and compare it against 0.
- ncryptret = NCryptImportKey(prov, NULL, BCRYPT_RSAPUBLIC_BLOB, NULL, &key, rsa_key_blob, 155, 0);
155 -> sizeof(rsa_key_blob)
- ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret);
- ok(key != NULL, "got null handle\n");
- NCryptFreeObject(key);
- key = NULL;
- ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob, 155, 0);
- ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret);
- ok(key != NULL, "got null handle\n");
- NCryptFreeObject(key);
- key = NULL;
- ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob, 155, 49);
- ok(ncryptret == NTE_BAD_FLAGS, "got 0x%x\n", ncryptret);
- ok(key == NULL, "expected null handle\n");
- key = NULL;
- ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, invalid_rsa_key_blob, 155, 0);
- ok(ncryptret == NTE_INVALID_PARAMETER, "got 0x%x\n", ncryptret);
- ok(key == NULL, "expected null handle\n");
- key = NULL;
- ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob_with_invalid_bit_length, 155, 0);
- ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret); /* I'm not sure why, but this returns success */
- ok(key != NULL, "got null handle\n");
- NCryptFreeObject(key);
- key = NULL;
- ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob_with_invalid_publicexp_size, 155, 0);
- ok(ncryptret == NTE_BAD_DATA, "got 0x%x\n", ncryptret);
- ok(key == NULL, "expected null handle\n");
- key = NULL;
- ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob, 40, 0);
- ok(ncryptret == NTE_BAD_DATA, "got 0x%x\n", ncryptret);
- ok(key == NULL, "expected null handle\n");
- key = NULL;
- ncryptret = NCryptImportKey(prov, NULL, BCRYPT_PUBLIC_KEY_BLOB, NULL, &key, rsa_key_blob, 300, 0);
- ok(ncryptret == NTE_BAD_DATA, "got 0x%x\n", ncryptret);
- ok(key == NULL, "expected null handle\n");
- NCryptFreeObject(prov);
+}
Tests must always pass on Wine so you need to add todo_wine statements where necessary.
diff --git a/include/ncrypt.h b/include/ncrypt.h index 111693f1d49..bfb4c0c325c 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -69,12 +69,17 @@ typedef ULONG_PTR NCRYPT_SECRET_HANDLE; Â #define NCRYPT_SCHANNEL_SIGNATURE_INTERFACE 0x00010003 Â #define NCRYPT_KEY_PROTECTION_INTERFACE 0x00010004
+#define NCRYPT_SILENT_FLAG 0x00000040L
You can drop the L suffix.
SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, const WCHAR *, DWORD, DWORD); Â SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD); Â 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 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 NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
Parameter names are not very useful here. Please keep these sorted.
On 2/14/22 03:56, Hans Leidekker wrote:>> Â SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, const WCHAR *, DWORD, DWORD);
SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD); Â 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 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 NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
Parameter names are not very useful here. Please keep these sorted.
I suppose it's a matter of taste, but for what it's worth, I tend to find them nice when calling functions, i.e. I can easily look up the signature in the header.
El lun, 14 feb 2022 a la(s) 14:52, Zebediah Figura (zfigura@codeweavers.com) escribió:
On 2/14/22 03:56, Hans Leidekker wrote:>> SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, const WCHAR *, DWORD, DWORD);
SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE, BYTE *,
DWORD, void *, BYTE *, DWORD, DWORD *, DWORD);
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 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 NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE
*, const WCHAR *, DWORD);
Parameter names are not very useful here. Please keep these sorted.
I suppose it's a matter of taste, but for what it's worth, I tend to find them nice when calling functions, i.e. I can easily look up the signature in the header.
I think for now I will leave it without the parameter names because that's how it was coded originally, but to be honest I also like to have parameter names in the signature for the intellisense.
Signed-off-by: Santino Mazza mazzasantino1206@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
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/tests/ncrypt.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c index 39ee0f04254..bacefa9d3b6 100644 --- a/dlls/ncrypt/tests/ncrypt.c +++ b/dlls/ncrypt/tests/ncrypt.c @@ -136,7 +136,29 @@ static void test_key_import_rsa(void) NCryptFreeObject(prov); }
+static void test_ncrypt_free_object(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); + ncryptret = NCryptFreeObject(key); + ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret); + + key = 0; + ncryptret = NCryptFreeObject(key); + ok(ncryptret == NTE_INVALID_HANDLE, "got 0x%x\n", ncryptret); + + key = malloc(1024); + ncryptret = NCryptFreeObject(key); + ok(ncryptret == NTE_INVALID_HANDLE, "got 0x%x\n", ncryptret); + free(key); +} + START_TEST(ncrypt) { test_key_import_rsa(); + test_ncrypt_free_object(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=107786
Your paranoid android.
=== debian11 (32 bit report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (32 bit Arabic:Morocco report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (32 bit German report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (32 bit French report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (32 bit Hebrew:Israel report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (32 bit Hindi:India report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (32 bit Japanese:Japan report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (32 bit Chinese:China report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (32 bit WoW report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
=== debian11 (64 bit WoW report) ===
ncrypt: ncrypt.c:148: Test failed: got 0x80090029 ncrypt.c:152: Test failed: got 0x80090029 ncrypt.c:156: Test failed: got 0x80090029
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/ncrypt_internal.c | 28 ++++++++++++++++++++++++++++ dlls/ncrypt/ncrypt_internal.h | 2 ++ dlls/ncrypt/ncrypt_main.c | 28 ++++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/dlls/ncrypt/ncrypt_internal.c b/dlls/ncrypt/ncrypt_internal.c index 370391d8171..2bbbd58af64 100644 --- a/dlls/ncrypt/ncrypt_internal.c +++ b/dlls/ncrypt/ncrypt_internal.c @@ -41,3 +41,31 @@ int allocate_key_object(struct ncrypt_object **keyobject) (*keyobject)->type = KEY; return ERROR_SUCCESS; } + +int free_key_object(struct ncrypt_object *keyobject) +{ + struct ncrypt_key_object *key = &keyobject->object.key; + switch (key->algtype) + { + case RSA: + { + free(key->payload.rsa_key.modulus); + free(key->payload.rsa_key.public_exp); + if (key->payload.rsa_key.type == PRIVATE) + { + free(key->payload.rsa_key.prime1); + free(key->payload.rsa_key.prime2); + } + } + break; + + default: + { + ERR("invalid key object 0x%x\n", keyobject); + return NTE_INVALID_HANDLE; + } + break; + } + + return ERROR_SUCCESS; +} diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index 52029521b3e..9ef5ce593be 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -41,6 +41,7 @@ enum key_algorithm_type
struct rsa_key { + enum asymmetric_key_type type; DWORD public_exp_size; BYTE *public_exp; DWORD modulus_size; @@ -91,6 +92,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);
diff --git a/dlls/ncrypt/ncrypt_main.c b/dlls/ncrypt/ncrypt_main.c index 69b0508b110..c567378c16b 100644 --- a/dlls/ncrypt/ncrypt_main.c +++ b/dlls/ncrypt/ncrypt_main.c @@ -90,8 +90,32 @@ SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf)
SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object) { - FIXME("(0x%lx): stub\n", object); - return NTE_NOT_SUPPORTED; + struct ncrypt_object *ncryptobj = (struct ncrypt_object *)object; + if (ncryptobj == NULL) { + ERR("invalid handle 0x%x\n", ncryptobj); + return NTE_INVALID_HANDLE; + } + + switch (ncryptobj->type) + { + case KEY: + { + int ret = free_key_object(ncryptobj); + if (ret != ERROR_SUCCESS) + return ret; + } + break; + + default: + { + ERR("invalid handle 0x%x\n", ncryptobj); + return NTE_INVALID_HANDLE; + } + break; + } + + free(ncryptobj); + return ERROR_SUCCESS; }
SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *property, PBYTE output,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=107787
Your paranoid android.
=== debian11 (64 bit WoW report) ===
ncrypt: Unhandled exception: page fault on read access to 0x0000000000000080 in 64-bit code (0x0000000062cc2294).
Signed-off-by: Santino Mazza mazzasantino1206@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 }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=107788
Your paranoid android.
=== debian11 (32 bit report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit Arabic:Morocco report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit German report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit French report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit Hebrew:Israel report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit Hindi:India report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit Japanese:Japan report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit Chinese:China report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit WoW report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x7ffc2000 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x7ffc2000 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (64 bit WoW report) ===
ncrypt: Unhandled exception: page fault on read access to 0xffffffffffffffff in 64-bit code (0x0000000062cc24c5).
Some applications crash when the storage provider its null.
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/ncrypt_internal.c | 13 +++++++++++++ dlls/ncrypt/ncrypt_internal.h | 1 + dlls/ncrypt/ncrypt_main.c | 8 +++++++- 3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/ncrypt/ncrypt_internal.c b/dlls/ncrypt/ncrypt_internal.c index 8895bf9ac8d..f52a6619dc9 100644 --- a/dlls/ncrypt/ncrypt_internal.c +++ b/dlls/ncrypt/ncrypt_internal.c @@ -42,6 +42,19 @@ int allocate_key_object(struct ncrypt_object **keyobject) return ERROR_SUCCESS; }
+int allocate_storage_provider_object(struct ncrypt_object **providerobject) +{ + *providerobject = malloc(sizeof(struct ncrypt_object)); + if (providerobject == NULL) + { + ERR("Error allocating memory.\n"); + return NTE_NO_MEMORY; + } + memset(*providerobject, 0, sizeof(struct ncrypt_object)); + (*providerobject)->type = STORAGE_PROVIDER; + return ERROR_SUCCESS; +} + int free_key_object(struct ncrypt_object *keyobject) { struct ncrypt_key_object *key = &keyobject->object.key; diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index 948704d320c..64ca7ed4c56 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -92,6 +92,7 @@ struct ncrypt_object };
int allocate_key_object(struct ncrypt_object **keyobject); +int allocate_storage_provider_object(struct ncrypt_object **providerobject); 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(struct ncrypt_object *obj, WCHAR *property_name, struct ncrypt_object_property *propertyout); diff --git a/dlls/ncrypt/ncrypt_main.c b/dlls/ncrypt/ncrypt_main.c index 24f0f50d588..3fe33f24a43 100644 --- a/dlls/ncrypt/ncrypt_main.c +++ b/dlls/ncrypt/ncrypt_main.c @@ -107,6 +107,12 @@ SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object) } break;
+ case STORAGE_PROVIDER: + { + // FIXME Stub + } + break; + default: { ERR("invalid handle 0x%x\n", ncryptobj); @@ -260,7 +266,7 @@ 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 ERROR_SUCCESS; + return allocate_storage_provider_object(provider); }
SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *property,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=107789
Your paranoid android.
=== debian11 (32 bit report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x8711e0 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x8711e0 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit Chinese:China report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x8711e0 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x8711e0 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (32 bit WoW report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x9811e0 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x9811e0 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
=== debian11 (64 bit WoW report) ===
ncrypt: ncrypt.c:171: Test failed: got 0x80090027 ncrypt.c:172: Test failed: got 0x0 ncrypt.c:176: Test failed: got 0x80090027 ncrypt.c:177: Test failed: got 0x0 ncrypt.c:178: Test failed: The string doesn't match with 'RSA'
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- include/ncrypt.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/include/ncrypt.h b/include/ncrypt.h index 8bcae4be0ab..51b21e100d6 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -71,6 +71,40 @@ typedef ULONG_PTR NCRYPT_SECRET_HANDLE;
#define NCRYPT_SILENT_FLAG 0x00000040L
+#define NCRYPT_NAME_PROPERTY L"Name" +#define NCRYPT_UNIQUE_NAME_PROPERTY L"Unique Name" +#define NCRYPT_ALGORITHM_PROPERTY L"Algorithm Name" +#define NCRYPT_LENGTH_PROPERTY L"Length" +#define NCRYPT_LENGTHS_PROPERTY L"Lengths" +#define NCRYPT_BLOCK_LENGTH_PROPERTY L"Block Length" +#define NCRYPT_UI_POLICY_PROPERTY L"UI Policy" +#define NCRYPT_EXPORT_POLICY_PROPERTY L"Export Policy" +#define NCRYPT_WINDOW_HANDLE_PROPERTY L"HWND Handle" +#define NCRYPT_USE_CONTEXT_PROPERTY L"Use Context" +#define NCRYPT_IMPL_TYPE_PROPERTY L"Impl Type" +#define NCRYPT_KEY_USAGE_PROPERTY L"Key Usage" +#define NCRYPT_KEY_TYPE_PROPERTY L"Key Type" +#define NCRYPT_VERSION_PROPERTY L"Version" +#define NCRYPT_SECURITY_DESCR_SUPPORT_PROPERTY L"Security Descr Support" +#define NCRYPT_SECURITY_DESCR_PROPERTY L"Security Descr" +#define NCRYPT_USE_COUNT_ENABLED_PROPERTY L"Enabled Use Count" +#define NCRYPT_USE_COUNT_PROPERTY L"Use Count" +#define NCRYPT_LAST_MODIFIED_PROPERTY L"Modified" +#define NCRYPT_MAX_NAME_LENGTH_PROPERTY L"Max Name Length" +#define NCRYPT_ALGORITHM_GROUP_PROPERTY L"Algorithm Group" +#define NCRYPT_PROVIDER_HANDLE_PROPERTY L"Provider Handle" +#define NCRYPT_PIN_PROPERTY L"SmartCardPin" +#define NCRYPT_READER_PROPERTY L"SmartCardReader" +#define NCRYPT_SMARTCARD_GUID_PROPERTY L"SmartCardGuid" +#define NCRYPT_CERTIFICATE_PROPERTY L"SmartCardKeyCertificate" +#define NCRYPT_PIN_PROMPT_PROPERTY L"SmartCardPinPrompt" +#define NCRYPT_USER_CERTSTORE_PROPERTY L"SmartCardUserCertStore" +#define NCRYPT_ROOT_CERTSTORE_PROPERTY L"SmartcardRootCertStore" +#define NCRYPT_SECURE_PIN_PROPERTY L"SmartCardSecurePin" +#define NCRYPT_ASSOCIATED_ECDH_KEY L"SmartCardAssociatedECDHKey" +#define NCRYPT_SCARD_PIN_ID L"SmartCardPinId" +#define NCRYPT_SCARD_PIN_INFO L"SmartCardPinInfo" + SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, const WCHAR *, DWORD, DWORD); SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD); SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD);
Add some of the properties of the key, like its algorithm group or the bit length.
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/ncrypt_internal.h | 1 + dlls/ncrypt/ncrypt_main.c | 4 ++++ dlls/ncrypt/tests/ncrypt.c | 13 +++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index 64ca7ed4c56..c47c1f22e89 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -42,6 +42,7 @@ enum key_algorithm_type struct rsa_key { enum asymmetric_key_type type; + DWORD bit_length; DWORD public_exp_size; BYTE *public_exp; DWORD modulus_size; diff --git a/dlls/ncrypt/ncrypt_main.c b/dlls/ncrypt/ncrypt_main.c index 3fe33f24a43..88389d1a02a 100644 --- a/dlls/ncrypt/ncrypt_main.c +++ b/dlls/ncrypt/ncrypt_main.c @@ -211,6 +211,7 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H
rsakey = &rsakeyobject->object.key; rsakey->algtype = RSA; + rsakey->payload.rsa_key.bit_length = rsaheader->BitLength; 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); @@ -231,6 +232,9 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H memcpy(rsakey->payload.rsa_key.public_exp, public_exp, rsaheader->cbPublicExp); memcpy(rsakey->payload.rsa_key.modulus, modulus, rsaheader->cbModulus);
+ set_object_property(rsakeyobject, NCRYPT_ALGORITHM_GROUP_PROPERTY, L"RSA", 8); + set_object_property(rsakeyobject, NCRYPT_LENGTH_PROPERTY, &rsakey->payload.rsa_key.bit_length, sizeof(DWORD)); + set_object_property(rsakeyobject, NCRYPT_PROVIDER_HANDLE_PROPERTY, &provider, sizeof(NCRYPT_PROV_HANDLE)); *key = (NCRYPT_KEY_HANDLE)rsakeyobject; } break; diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c index ccaa6003efa..ca6857fa8af 100644 --- a/dlls/ncrypt/tests/ncrypt.c +++ b/dlls/ncrypt/tests/ncrypt.c @@ -167,15 +167,24 @@ static void test_get_property(void) 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); + ncryptret = NCryptGetProperty(key, NCRYPT_ALGORITHM_GROUP_PROPERTY, 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); + ncryptret = NCryptGetProperty(key, NCRYPT_ALGORITHM_GROUP_PROPERTY, 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"); + + DWORD keylength; + ncryptret = NCryptGetProperty(key, NCRYPT_LENGTH_PROPERTY, NULL, 0, &size, 0); + ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret); + ok(size == sizeof(DWORD), "got 0x%x\n", size); + + ncryptret = NCryptGetProperty(key, NCRYPT_LENGTH_PROPERTY, &keylength, size, &size, 0); + ok(ncryptret == ERROR_SUCCESS, "got 0x%x\n", ncryptret); + ok(keylength == 1024, "got 0x%x\n", keylength); }
START_TEST(ncrypt)
With this change now some applications which uses ncrypt for signature validation work. For example, the visual studio installer (with dotnet and d3dcompiler from winetricks).
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/ncrypt/ncrypt.spec | 2 +- dlls/ncrypt/ncrypt_main.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec index 0e92609790c..bb914616373 100644 --- a/dlls/ncrypt/ncrypt.spec +++ b/dlls/ncrypt/ncrypt.spec @@ -101,7 +101,7 @@ @ stub NCryptUnprotectKey @ stub NCryptUnprotectSecret @ stub NCryptVerifyClaim -@ stub NCryptVerifySignature +@ stdcall NCryptVerifySignature(ptr ptr ptr long ptr long long) @ stub SslChangeNotify @ stub SslComputeClientAuthHash @ stub SslComputeEapKeyBlock diff --git a/dlls/ncrypt/ncrypt_main.c b/dlls/ncrypt/ncrypt_main.c index 88389d1a02a..01faecacb14 100644 --- a/dlls/ncrypt/ncrypt_main.c +++ b/dlls/ncrypt/ncrypt_main.c @@ -282,3 +282,12 @@ SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *prop struct ncrypt_object *ncryptobj = (struct ncrypt_object *)object; return set_object_property(ncryptobj, property, input, insize); } + +SECURITY_STATUS NCryptVerifySignature(NCRYPT_KEY_HANDLE key, VOID *padding_info, + BYTE *hash_value, DWORD hash_value_size, BYTE *signature, + DWORD signature_size, DWORD flags) +{ + FIXME("(%lx, %lx, %lx, %x, %lx, %x, %x): stub\n", key, padding_info, hash_value, hash_value_size, + signature, signature_size, flags); + return ERROR_SUCCESS; +}