Microsoft Edge calls this function expecting an implementation. With this, Internet browsing works.
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- v3: - Retrieve a list using bitwise operation in BCryptEnumAlgorithms. - Use proper NTSTATUS.
v4: - Return NTE_NOT_SUPPORTED for BCRYPT_RSA_SIGN_ALGORITHM after checking for bad flags.
Sorry, I only realized to test this behavior after submitting the patch. I thought there would be no point in checking if the flags are bad if the algorithm isn't even supported to begin with. --- dlls/ncrypt/main.c | 44 +++++++++++++++++++++++++++++++++++++++-- dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 1 + 3 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index e12284e0867..10cec633269 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -416,8 +416,48 @@ 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 ULONG supported = BCRYPT_CIPHER_OPERATION |\ + BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION |\ + BCRYPT_SIGNATURE_OPERATION |\ + BCRYPT_SECRET_AGREEMENT_OPERATION; + BCRYPT_ALGORITHM_IDENTIFIER *list; + ULONG i, count; + NTSTATUS status; + + TRACE("(%#Ix, %s, %#lx)\n", provider, wine_dbgstr_w(algid), flags); + + 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; + } + if (!lstrcmpiW(BCRYPT_RSA_SIGN_ALGORITHM, algid)) return NTE_NOT_SUPPORTED; + + status = BCryptEnumAlgorithms(supported, &count, &list, 0); + if (status != STATUS_SUCCESS) + { + ERR("Error retrieving algorithm list %#lx\n", status); + return map_ntstatus(status); + } + + status = STATUS_NOT_SUPPORTED; + for (i = 0; i < count; i++) + { + if (!lstrcmpiW(list[i].pszName, algid)) + { + status = STATUS_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);