Microsoft Edge calls this function expecting an implementation. Without it, Internet browsing does not work.
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- If you want to test this patch in Microsoft Edge, you have to wait a few minutes after opening it before it becomes usable. --- dlls/ncrypt/main.c | 24 ++++++++++++++++++++++-- dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 1 + 3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index cc979a539d2..912f7ef643e 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -415,8 +415,28 @@ 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; + NCRYPT_KEY_HANDLE key; + SECURITY_STATUS 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) + { + ERR("Invalid flags %#lx\n", flags); + return NTE_BAD_FLAGS; + } + + status = NCryptCreatePersistedKey(provider, &key, algid, NULL, 0, 0); + NCryptFinalizeKey(key, 0); + NCryptFreeObject(key); + NCryptFreeObject(provider); + return 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);
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- dlls/ncrypt/tests/ncrypt.c | 127 +++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+)
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c index 7fb8b2cb4c5..8763afe835d 100644 --- a/dlls/ncrypt/tests/ncrypt.c +++ b/dlls/ncrypt/tests/ncrypt.c @@ -465,6 +465,132 @@ 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); + + todo_wine + { + 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); + } + + todo_wine + { + 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); + } + + todo_wine + { + 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); + } + + todo_wine + { + 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); + } + + todo_wine + { + 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); + } + + todo_wine + { + 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 +600,5 @@ START_TEST(ncrypt) test_create_persisted_key(); test_finalize_key(); test_verify_signature(); + test_NCryptIsAlgSupported(); }
On Tue, 2022-04-05 at 01:23 -0400, Mohamad Al-Jaf wrote:
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index cc979a539d2..912f7ef643e 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -415,8 +415,28 @@ 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;
- NCRYPT_KEY_HANDLE key;
- SECURITY_STATUS 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)
- {
ERR("Invalid flags %#lx\n", flags);
return NTE_BAD_FLAGS;
- }
We don't ERR on invalid user input.
- status = NCryptCreatePersistedKey(provider, &key, algid, NULL, 0, 0);
- NCryptFinalizeKey(key, 0);
- NCryptFreeObject(key);
- NCryptFreeObject(provider);
- return status;
}
I think it would better to implement this on top of BCryptEnumAlgorithms(). Also note that you can't free provider here, it's owned by the caller.
On Tue, Apr 5, 2022, 07:38 Hans Leidekker hans@codeweavers.com wrote:
We don't ERR on invalid user input.
Sorry, I didn't know, this was based on the existing code in ncrypt.
I think it would better to implement this on top of
BCryptEnumAlgorithms().
Also note that you can't free provider here, it's > owned by the caller.
This is actually what I had originally and I used a for loop to iterate through the list to see if the algid matches. But doing this provider was not used. I thought this would be considered incorrect. I'm not sure what to do with provider.
On Tue, 2022-04-05 at 10:56 -0400, Mohamad Al-Jaf wrote:
On Tue, Apr 5, 2022, 07:38 Hans Leidekker hans@codeweavers.com wrote:
We don't ERR on invalid user input.
Sorry, I didn't know, this was based on the existing code in ncrypt.
I think it would better to implement this on top of BCryptEnumAlgorithms(). Also note that you can't free provider here, it's > owned by the caller.
This is actually what I had originally and I used a for loop to iterate through the list to see if the algid matches. But doing this provider was not used. I thought this would be considered incorrect. I'm not sure what to do with provider.
It's okay to ignore the provider since we don't really support it yet.