Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- dlls/ncrypt/main.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index cc979a539d2..13909a2dd9e 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -40,6 +40,7 @@ static SECURITY_STATUS map_ntstatus(NTSTATUS status) case STATUS_INVALID_SIGNATURE: return NTE_BAD_SIGNATURE; case STATUS_SUCCESS: return ERROR_SUCCESS; case STATUS_INVALID_PARAMETER: return NTE_INVALID_PARAMETER; + case STATUS_NOT_SUPPORTED: return NTE_NOT_SUPPORTED; case NTE_BAD_DATA: return NTE_BAD_DATA; default: FIXME("unhandled status %#lx\n", status);
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- dlls/ncrypt/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 13909a2dd9e..e12284e0867 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -374,7 +374,7 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H } else if (flags) { - ERR("Invalid flags %#lx\n", flags); + WARN("Invalid flags %#lx\n", flags); return NTE_BAD_FLAGS; }
Signed-off-by: Hans Leidekker hans@codeweavers.com
Microsoft Edge calls this function expecting an implementation. With this, Internet browsing works.
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- v2: - Warn on invalid flags. - Use BCryptEnumAlgorithms to retrieve a list.
There seems to be an issue with the way BCryptEnumAlgorithms handles the first argument if bitwise operation is used. On Windows, it works without issue, but in Wine it crashes with an unhandled page fault.
I don't know if it's something I did wrong or if the function itself is at fault. I noticed there was no test for bitwise operation so I can't say for sure.
BCryptFreeBuffer is a stub and I tried to free the list through the standard free function as well as HeapFree, but neither changes the result. Also, the crash happens even after just calling it once.
Increasing the size of the malloc to an arbitrary number, like 50, prevents the crash but the function does not return the right list. Tried to debug it on my own but to no avail.
This is what I used as a parameter:
BCRYPT_CIPHER_OPERATION |\ BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION |\ BCRYPT_SIGNATURE_OPERATION |\ BCRYPT_SECRET_AGREEMENT_OPERATION
One last thing is that BCRYPT_RSA_SIGN_ALGORITHM would still need to be handled separately as it is not supported in Windows. --- dlls/ncrypt/main.c | 52 +++++++++++++++++++++++++++++++++++++++-- dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 1 + 3 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index e12284e0867..23f69c517e4 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -416,8 +416,56 @@ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H
SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const WCHAR *algid, DWORD flags) { - FIXME("(%#Ix, %s, %#lx): stub\n", provider, wine_dbgstr_w(algid), flags); - return NTE_NOT_SUPPORTED; + static const WCHAR *unsupported[9] = { BCRYPT_SHA256_ALGORITHM, + BCRYPT_SHA384_ALGORITHM, + BCRYPT_SHA512_ALGORITHM, + BCRYPT_SHA1_ALGORITHM, + BCRYPT_MD5_ALGORITHM, + BCRYPT_MD4_ALGORITHM, + BCRYPT_MD2_ALGORITHM, + BCRYPT_RSA_SIGN_ALGORITHM, + BCRYPT_RNG_ALGORITHM }; + BCRYPT_ALGORITHM_IDENTIFIER *list; + ULONG count; + NTSTATUS status; + int i; + + if (!provider) return NTE_INVALID_HANDLE; + if (!algid) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER); + if (flags == NCRYPT_SILENT_FLAG) + { + FIXME("Silent flag not implemented\n"); + } + else if (flags) + { + WARN("Invalid flags %#lx\n", flags); + return NTE_BAD_FLAGS; + } + + for (i = 0; i < ARRAY_SIZE(unsupported); i++) + { + if (!lstrcmpiW(unsupported[i], algid)) return NTE_NOT_SUPPORTED; + } + + status = BCryptEnumAlgorithms(0, &count, &list, 0); + if (status != STATUS_SUCCESS) + { + ERR("Error retrieving algorithm list %#lx\n", status); + return map_ntstatus(status); + } + + status = ERROR_NOT_SUPPORTED; + for (i = 0; i < count; i++) + { + if (!lstrcmpiW(list[i].pszName, algid)) + { + status = ERROR_SUCCESS; + break; + } + } + + BCryptFreeBuffer(list); + return map_ntstatus(status); }
BOOL WINAPI NCryptIsKeyHandle(NCRYPT_KEY_HANDLE hKey) diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec index bb914616373..60b367260d5 100644 --- a/dlls/ncrypt/ncrypt.spec +++ b/dlls/ncrypt/ncrypt.spec @@ -77,7 +77,7 @@ @ stdcall NCryptGetProperty(ptr wstr ptr long ptr long) @ stub NCryptGetProtectionDescriptorInfo @ stdcall NCryptImportKey(long long wstr ptr ptr ptr long long) -@ stub NCryptIsAlgSupported(long wstr long) +@ stdcall NCryptIsAlgSupported(long wstr long) @ stdcall NCryptIsKeyHandle(long) @ stub NCryptKeyDerivation @ stub NCryptNotifyChangeKey diff --git a/include/ncrypt.h b/include/ncrypt.h index c09a1ec8676..18198fdc5bb 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -118,6 +118,7 @@ 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 NCryptIsAlgSupported(NCRYPT_PROV_HANDLE, const WCHAR *, 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);
On Wed, 2022-04-06 at 03:19 -0400, Mohamad Al-Jaf wrote:
Microsoft Edge calls this function expecting an implementation. With this, Internet browsing works.
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com
v2: - Warn on invalid flags. - Use BCryptEnumAlgorithms to retrieve a list.
There seems to be an issue with the way BCryptEnumAlgorithms handles the first argument if bitwise operation is used. On Windows, it works without issue, but in Wine it crashes with an unhandled page fault.
I don't know if it's something I did wrong or if the function itself is at fault. I noticed there was no test for bitwise operation so I can't say for sure.
BCryptFreeBuffer is a stub and I tried to free the list through the standard free function as well as HeapFree, but neither changes the result. Also, the crash happens even after just calling it once.
Increasing the size of the malloc to an arbitrary number, like 50, prevents the crash but the function does not return the right list. Tried to debug it on my own but to no avail.
This is what I used as a parameter:
BCRYPT_CIPHER_OPERATION |\ BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION |\ BCRYPT_SIGNATURE_OPERATION |\ BCRYPT_SECRET_AGREEMENT_OPERATION
I've submitted patches for the bcrypt issues. Can you try again with those applied?
On Wed, Apr 6, 2022 at 4:50 AM Hans Leidekker hans@codeweavers.com wrote:
I've submitted patches for the bcrypt issues. Can you try again with those applied?
It runs and returns the correct list now. You work fast, well done. :) -- Kind regards, Mohamad
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- v2: - Remove todo_wine wrappers. --- dlls/ncrypt/tests/ncrypt.c | 109 +++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c index 7fb8b2cb4c5..a0bfcc0786b 100644 --- a/dlls/ncrypt/tests/ncrypt.c +++ b/dlls/ncrypt/tests/ncrypt.c @@ -465,6 +465,114 @@ static void test_verify_signature(void) NCryptFreeObject(prov); }
+static void test_NCryptIsAlgSupported(void) +{ + NCRYPT_PROV_HANDLE prov; + SECURITY_STATUS ret; + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(0, BCRYPT_RSA_ALGORITHM, 0); + ok(ret == NTE_INVALID_HANDLE, "expected NTE_INVALID_HANDLE, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, NULL, 0); + ok(ret == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER) || broken(ret == NTE_FAIL) /* win7 */, "got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_RSA_ALGORITHM, 20); + ok(ret == NTE_BAD_FLAGS, "expected NTE_BAD_FLAGS, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_RSA_ALGORITHM, 0); + ok(ret == ERROR_SUCCESS, "expected BCRYPT_RSA_ALGORITHM to be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_RSA_ALGORITHM, NCRYPT_SILENT_FLAG); + ok(ret == ERROR_SUCCESS, "expected BCRYPT_RSA_ALGORITHM to be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_3DES_ALGORITHM, 0); + ok(ret == ERROR_SUCCESS || broken(ret == NTE_NOT_SUPPORTED) /* win7 */, "expected BCRYPT_3DES_ALGORITHM to be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_AES_ALGORITHM, 0); + ok(ret == ERROR_SUCCESS || broken(ret == NTE_NOT_SUPPORTED) /* win7 */, "expected BCRYPT_AES_ALGORITHM to be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_ECDH_P256_ALGORITHM, 0); + ok(ret == ERROR_SUCCESS, "expected BCRYPT_ECDH_P256_ALGORITHM to be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_ECDSA_P256_ALGORITHM, 0); + ok(ret == ERROR_SUCCESS, "expected BCRYPT_ECDSA_P256_ALGORITHM to be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_ECDSA_P384_ALGORITHM, 0); + ok(ret == ERROR_SUCCESS, "expected BCRYPT_ECDSA_P384_ALGORITHM to be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_DSA_ALGORITHM, 0); + ok(ret == ERROR_SUCCESS, "expected BCRYPT_DSA_ALGORITHM to be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + /* Not Supported */ + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_SHA256_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_SHA256_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_SHA384_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_SHA384_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_SHA512_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_SHA512_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_SHA1_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_SHA1_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_MD5_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_MD5_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_MD4_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_MD4_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_MD2_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_MD2_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_RSA_SIGN_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_RSA_SIGN_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); + + NCryptOpenStorageProvider(&prov, NULL, 0); + ret = NCryptIsAlgSupported(prov, BCRYPT_RNG_ALGORITHM, 0); + ok(ret == NTE_NOT_SUPPORTED, "expected BCRYPT_RNG_ALGORITHM to not be supported, got %#lx\n", ret); + NCryptFreeObject(prov); +} + START_TEST(ncrypt) { test_key_import_rsa(); @@ -474,4 +582,5 @@ START_TEST(ncrypt) test_create_persisted_key(); test_finalize_key(); test_verify_signature(); + test_NCryptIsAlgSupported(); }