[PATCH v2 3/4] ncrypt: Implement NCryptIsAlgSupported.

Mohamad Al-Jaf mohamadaljaf at gmail.com
Wed Apr 6 02:19:54 CDT 2022


Microsoft Edge calls this function expecting an
implementation. With this, Internet browsing
works.

Signed-off-by: Mohamad Al-Jaf <mohamadaljaf at 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);
-- 
2.35.1




More information about the wine-devel mailing list