From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/Makefile.in | 2 + dlls/ncrypt/main.c | 127 +++++++++++++++++++++++++++++++++++++++- dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 7 +++ 4 files changed, 135 insertions(+), 3 deletions(-)
diff --git a/dlls/ncrypt/Makefile.in b/dlls/ncrypt/Makefile.in index c387c35d854..dc9d3fbdc28 100644 --- a/dlls/ncrypt/Makefile.in +++ b/dlls/ncrypt/Makefile.in @@ -1,5 +1,7 @@ MODULE = ncrypt.dll
+IMPORTS = advapi32 + EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index c0cc05c43ca..86bc9190717 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -23,7 +23,9 @@ #include "windef.h" #include "winbase.h" #include "ncrypt.h" +#include "winreg.h" #include "wine/debug.h" +#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
@@ -89,6 +91,123 @@ SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR * return NTE_NOT_SUPPORTED; }
+SECURITY_STATUS WINAPI NCryptEnumStorageProviders(DWORD *providerCount, NCryptProviderName **providerList, DWORD flags) +{ + HKEY hKey; + HKEY hSubKey; + SECURITY_STATUS ret; + LSTATUS status; + DWORD maxKeyLen; + DWORD i; + WCHAR providerName[MAX_PATH]; + WCHAR providerKSReg[MAX_PATH]; + DWORD providerNameLength; + NCryptProviderName *outList; + DWORD outCount; + DWORD numKeys; + void *allocBuffer; + void *reAllocBuffer; + DWORD allocSize; + DWORD totalNamesSize; + + TRACE("(%p, %p, 0x%08x)\n", providerCount, providerList, flags); + + if (flags) + { + FIXME("Ignoring flags: 0x%08x - Not implemented\n", flags); + } + + ret = ERROR_SUCCESS; + outList = NULL; + outCount = 0; + allocSize = 0; + + status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\CurrentControlSet\Control\Cryptography\Providers", 0, KEY_READ, &hKey); + if (status != ERROR_SUCCESS) + { + ERR("Failed to open 'HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Providers' error code: 0x%08x\n", status); + return NTE_NOT_SUPPORTED; /* FIXME: what should be returned here? */ + } + + status = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numKeys, &maxKeyLen, NULL, NULL, NULL, NULL, NULL, NULL); + if (status != ERROR_SUCCESS) + { + ERR("Failed to query info on 'HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Providers' error code: 0x%08x\n", status); + ret = NTE_NOT_SUPPORTED; /* FIXME: what should be returned here? */ + goto cleanup; + } + + + for (i = 0; i < numKeys; ++i) + { + providerNameLength = MAX_PATH; + status = RegEnumKeyExW(hKey, i, providerName, &providerNameLength, NULL, NULL, NULL, NULL); + if (status != ERROR_SUCCESS) + { + ERR("Failed to enumerate sub keys of 'HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Providers' error code: 0x%08x\n", status); + ret = NTE_NOT_SUPPORTED; /* FIXME: what should be returned here? */ + goto cleanup; + } + + + /* This registry key should exist if the provider supports key storage */ + swprintf(providerKSReg, MAX_PATH - 1, L"%s\UM\00010001", providerName); + status = RegOpenKeyExW(hKey, providerKSReg, 0, KEY_READ, &hSubKey); + if (status != ERROR_SUCCESS) + { + /* Provider doesn't support key storage, skip it */ + continue; + } + RegCloseKey(hSubKey); + + allocSize += sizeof(NCryptProviderName) + (providerNameLength + 1) * sizeof(WCHAR); + if (!outCount++) + { + allocBuffer = heap_alloc(allocSize); + if (!allocBuffer) + { + ERR("Out of memory!\n"); + ret = NTE_NO_MEMORY; + goto cleanup; + } + totalNamesSize = 0; + } + else + { + reAllocBuffer = heap_realloc(allocBuffer, allocSize); + if (!reAllocBuffer) + { + ERR("Out of memory during realloc!\n"); + heap_free(allocBuffer); + ret = NTE_NO_MEMORY; + goto cleanup; + } + /* Shift the wstrings that contain the names over by the size of one struct */ + memmove((BYTE*)allocBuffer + outCount * sizeof(NCryptProviderName), (BYTE*)allocBuffer + (outCount - 1) * sizeof(NCryptProviderName), totalNamesSize); + } + + + + outList = allocBuffer; + outList[outCount - 1].pszName = (WCHAR*)((BYTE*)allocBuffer + outCount * sizeof(NCryptProviderName) + totalNamesSize); + outList[outCount - 1].pszComment = NULL; + + wcscpy(outList[outCount - 1].pszName, providerName); + totalNamesSize += (providerNameLength + 1) * sizeof(WCHAR); + } + + +cleanup: + if (ret == ERROR_SUCCESS) + { + *providerCount = outCount; + *providerList = outList; + } + + RegCloseKey(hKey); + return ret; +} + SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags) { FIXME("(0x%lx, 0x%08x): stub\n", key, flags); @@ -97,8 +216,12 @@ SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags)
SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf) { - FIXME("(%p): stub\n", buf); - return NTE_NOT_SUPPORTED; + /* FIXME: How do we tell which provider should be called? + How do we update refCounts of referenced objects? */ + FIXME("(%p): semi-stub\n", buf); + + heap_free(buf); + return ERROR_SUCCESS; }
SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object) diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec index 2b5a4fca420..2e6765c91ff 100644 --- a/dlls/ncrypt/ncrypt.spec +++ b/dlls/ncrypt/ncrypt.spec @@ -69,7 +69,7 @@ @ stdcall NCryptEncrypt(long ptr long ptr ptr long ptr long) @ stdcall NCryptEnumAlgorithms(long long ptr ptr long) @ stdcall NCryptEnumKeys(long wstr ptr ptr long) -@ stub NCryptEnumStorageProviders +@ stdcall NCryptEnumStorageProviders(ptr ptr long) @ stub NCryptExportKey @ stdcall NCryptFinalizeKey(long long) @ stdcall NCryptFreeBuffer(ptr) diff --git a/include/ncrypt.h b/include/ncrypt.h index 111693f1d49..9110c1ef6a4 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -58,6 +58,11 @@ typedef struct NCryptKeyName { DWORD dwFlags; } NCryptKeyName;
+typedef struct _NCryptProviderName { + LPWSTR pszName; + LPWSTR pszComment; +} NCryptProviderName; + typedef ULONG_PTR NCRYPT_HANDLE; typedef ULONG_PTR NCRYPT_PROV_HANDLE; typedef ULONG_PTR NCRYPT_KEY_HANDLE; @@ -72,7 +77,9 @@ typedef ULONG_PTR NCRYPT_SECRET_HANDLE; 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 NCryptEnumStorageProviders(DWORD *, NCryptProviderName **, DWORD); SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE, DWORD); +SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID); SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE); SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, DWORD, DWORD); SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
From: Ariel Darshan abdaandroid@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48733 Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 125 +++++++++++++++++++++++++++++++++- dlls/ncrypt/ncrypt_internal.h | 92 +++++++++++++++++++++++++ include/bcrypt.h | 6 ++ 3 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 dlls/ncrypt/ncrypt_internal.h
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 86bc9190717..8a8d8d0ed13 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -2,6 +2,7 @@ * New cryptographic library (ncrypt.dll) * * Copyright 2016 Alex Henrie + * Copyright 2020 Ariel Darshan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,6 +27,7 @@ #include "winreg.h" #include "wine/debug.h" #include "wine/heap.h" +#include "ncrypt_internal.h"
WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
@@ -264,8 +266,60 @@ 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; + NCryptProviderName *providerNames; + DWORD providerCount; + DWORD i; + BOOL isKSP; + LSTATUS lstatus; + SECURITY_STATUS secStatus; + WCHAR registryPath[MAX_PATH]; + WCHAR dllName[MAX_PATH]; + DWORD dllNameLen; + + TRACE("(%p, %s, %u)\n", provider, wine_dbgstr_w(name), flags); + + + secStatus = NCryptEnumStorageProviders(&providerCount, &providerNames, 0); + if (secStatus != ERROR_SUCCESS) + { + return secStatus; + } + + isKSP = FALSE; + for (i = 0; i < providerCount; ++i) + { + if (!wcscmp(providerNames[i].pszName, name)) + { + isKSP = TRUE; + break; + } + } + + secStatus = NCryptFreeBuffer(providerNames); + if (secStatus != ERROR_SUCCESS) + { + WARN("Failed to free providers list\n"); + } + + if (!isKSP) + { + ERR("provider not found: %s\n", wine_dbgstr_w(name)); + return NTE_INVALID_PARAMETER; + } + + + + dllNameLen = MAX_PATH; + swprintf(registryPath, MAX_PATH, L"SYSTEM\CurrentControlSet\Control\Cryptography\Providers\%s\UM", name); + + lstatus = RegGetValueW(HKEY_LOCAL_MACHINE, registryPath, L"Image", RRF_RT_REG_SZ, NULL, dllName, &dllNameLen); + if (lstatus != ERROR_SUCCESS) + { + ERR("Couldn't find image for provider: %s\n", wine_dbgstr_w(name)); + return NTE_INVALID_PARAMETER; + } + + return open_provider(provider, name, dllName, flags); }
SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *property, @@ -275,3 +329,70 @@ SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *prop flags); return NTE_NOT_SUPPORTED; } + +static SECURITY_STATUS open_provider(NCRYPT_PROV_HANDLE *providerInstance, const WCHAR *name, const WCHAR *dllName, DWORD flags) +{ + unsigned int size; + void *buffer; + struct ncrypt_provider_instance *ret; + HMODULE hDLL; + getInterfaceFn getKeyStorageInterface; + SECURITY_STATUS status; + NCRYPT_KEY_STORAGE_FUNCTION_TABLE *functionTable; + NCRYPT_PROV_HANDLE kspHandle; + + hDLL = LoadLibraryW(dllName); + if (!hDLL) + { + ERR("Failed to load provider dll: %s. error code: 0x%08x\n", wine_dbgstr_w(dllName), GetLastError()); + return NTE_PROV_DLL_NOT_FOUND; + } + + getKeyStorageInterface = (getInterfaceFn) GetProcAddress(hDLL, "GetKeyStorageInterface"); + if (!getKeyStorageInterface) + { + ERR("Failed to locate the 'GetKeyStorageInterface' export in dll: %s. error code: 0x%08x\n", wine_dbgstr_w(dllName), GetLastError()); + FreeLibrary(hDLL); + return NTE_PROVIDER_DLL_FAIL; + } + + /* FIXME: What should flags be? */ + status = getKeyStorageInterface(name, &functionTable, 0); + if (status != ERROR_SUCCESS) + { + ERR("Failed to get key storage interface from dll: %s\n", wine_dbgstr_w(dllName)); + FreeLibrary(hDLL); + return status; + } + + status = functionTable->OpenProvider(&kspHandle, name, flags); + if (status != ERROR_SUCCESS) + { + ERR("OpenProvider failed in dll: %s\n", wine_dbgstr_w(dllName)); + FreeLibrary(hDLL); + return status; + } + + /* Allocate both structure and name in the same call */ + size = sizeof(struct ncrypt_provider_instance) + (wcslen(name) + 1) * sizeof(WCHAR); + + buffer = heap_alloc(size); + if (!buffer) + { + ERR("Out of memory!\n"); + FreeLibrary(hDLL); + return NTE_NO_MEMORY; + } + + ret = (struct ncrypt_provider_instance*)buffer; + ret->sType = NCRYPT_OBJ_TYPE_PROVIDER; + ret->refCount = 1; + ret->kspDLL = hDLL; + memcpy(&ret->functions, functionTable, sizeof(NCRYPT_KEY_STORAGE_FUNCTION_TABLE)); + ret->kspHandle = kspHandle; + ret->name = (WCHAR*)((char*)buffer + sizeof(struct ncrypt_provider_instance)); + wcscpy(ret->name, name); + + *providerInstance = provider2handle(ret); + return ERROR_SUCCESS; +} diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h new file mode 100644 index 00000000000..e5c9a946f2c --- /dev/null +++ b/dlls/ncrypt/ncrypt_internal.h @@ -0,0 +1,92 @@ +/* + * Common definitions + * + * Copyright 2020 Ariel Darshan + * + * 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__ +#define __NCRYPT_INTERNAL__ + +#include "bcrypt.h" + +typedef struct _NCRYPT_KEY_STORAGE_FUNCTION_TABLE +{ + BCRYPT_INTERFACE_VERSION version; + SECURITY_STATUS(*OpenProvider)(NCRYPT_PROV_HANDLE *outProvider, LPCWSTR name, DWORD flags); + SECURITY_STATUS(*OpenKey)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *outKey, LPCWSTR keyName, DWORD legacyKeySpec, DWORD flags); + SECURITY_STATUS(*CreatePersistedKey)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE* outKey, LPCWSTR algId, LPCWSTR keyName, DWORD legacyKeySpec, DWORD flags); + SECURITY_STATUS(*GetProviderProperty)(NCRYPT_PROV_HANDLE provider, LPCWSTR propertyName, BYTE *output, DWORD outputSize, DWORD *result, DWORD flags); + SECURITY_STATUS(*GetKeyProperty)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE key, LPCWSTR propertyName, BYTE* output, DWORD outputSize, DWORD* result, DWORD flags); + SECURITY_STATUS(*SetProviderProperty)(NCRYPT_PROV_HANDLE provider, LPCWSTR propertyName, BYTE* input, DWORD inputSize, DWORD flags); + SECURITY_STATUS(*SetKeyProperty)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE key, LPCWSTR propertyName, BYTE* input, DWORD inputSize, DWORD flags); + SECURITY_STATUS(*FinalizeKey)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE key, DWORD flags); + SECURITY_STATUS(*DeleteKey)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE key, DWORD flags); + SECURITY_STATUS(*FreeProvider)(NCRYPT_PROV_HANDLE provider); + SECURITY_STATUS(*FreeKey)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE key); + SECURITY_STATUS(*FreeBuffer)(void *buffer); + SECURITY_STATUS(*Encrypt)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE key, BYTE *input, DWORD inputSize, void *paddingInfo, BYTE *output, DWORD outputSize, DWORD *result, DWORD flags); + SECURITY_STATUS(*Decrypt)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE key, BYTE* input, DWORD inputSize, void *paddingInfo, BYTE* output, DWORD outputSize, DWORD* result, DWORD flags); + SECURITY_STATUS(*IsAlgSupported)(NCRYPT_PROV_HANDLE provider, LPCWSTR algId, DWORD flags); + SECURITY_STATUS(*EnumAlgorithms)(NCRYPT_PROV_HANDLE provider, DWORD algOperations, DWORD *algCount, NCryptAlgorithmName **algList, DWORD flags); + SECURITY_STATUS(*EnumKeys)(NCRYPT_PROV_HANDLE provider, LPCWSTR scope, NCryptKeyName **keyName, void **enumState, DWORD flags); + SECURITY_STATUS(*ImportKey)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE decryptKey, LPCWSTR blobType, NCryptBufferDesc *parameterList, NCRYPT_KEY_HANDLE *outKey, BYTE *data, DWORD dataSize, DWORD flags); + SECURITY_STATUS(*ExportKey)(NCRYPT_KEY_HANDLE key, NCRYPT_KEY_HANDLE encryptKey, LPCWSTR blobType, NCryptBufferDesc *parameterList, BYTE *output, DWORD outputSize, DWORD *result, DWORD flags); + SECURITY_STATUS(*SignHash)(NCRYPT_KEY_HANDLE key, void *paddingInfo, BYTE *hashValue, DWORD hashSize, BYTE *outSig, DWORD outSigSize, DWORD *result, DWORD flags); + SECURITY_STATUS(*VerifySignature)(NCRYPT_KEY_HANDLE key, void *paddingInfo, BYTE *hashValue, DWORD hashSize, BYTE *signature, DWORD signatureSize, DWORD flags); + SECURITY_STATUS(*PromptUser)(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE key, LPCWSTR operation, DWORD flags); + SECURITY_STATUS(*NotifyChangeKey)(NCRYPT_PROV_HANDLE provider, HANDLE *event, DWORD flags); + SECURITY_STATUS(*SecretAgreement)(NCRYPT_KEY_HANDLE privateKey, NCRYPT_KEY_HANDLE publicKey, NCRYPT_SECRET_HANDLE *agreedSecret, DWORD flags); + SECURITY_STATUS(*DeriveKey)(NCRYPT_SECRET_HANDLE sharedSecret, LPCWSTR kdf, NCryptBufferDesc *parameterList, BYTE *outKey, DWORD outKeySize, DWORD *result, DWORD flags); + SECURITY_STATUS(*FreeSecret)(NCRYPT_PROV_HANDLE provider, NCRYPT_SECRET_HANDLE sharedSecret); + +}NCRYPT_KEY_STORAGE_FUNCTION_TABLE; + +typedef NTSTATUS(*getInterfaceFn)(LPCWSTR providerName, NCRYPT_KEY_STORAGE_FUNCTION_TABLE **outFunctionTable, DWORD dwFlags); + + +#define NCRYPT_OBJ_TYPE_PROVIDER 0x44440001 +#define NCRYPT_OBJ_TYPE_KEY 0x44440002 +#define NCRYPT_OBJ_TYPE_HASH 0x44440003 +#define NCRYPT_OBJ_TYPE_SECRET 0x44440004 + +struct ncrypt_base_object +{ + DWORD sType; +}; + +struct ncrypt_provider_instance +{ + DWORD sType; + DWORD refCount; + HMODULE kspDLL; + NCRYPT_KEY_STORAGE_FUNCTION_TABLE functions; + NCRYPT_PROV_HANDLE kspHandle; + WCHAR *name; +}; + + +#define handle2baseObject(x) ((struct ncrypt_base_object*)(x)) +#define baseObject2handle(x) ((NCRYPT_HANDLE)(x)) + +#define handle2provider(x) ((struct ncrypt_provider_instance*)(x)) +#define provider2handle(x) ((NCRYPT_PROV_HANDLE)(x)) + + + +static SECURITY_STATUS open_provider(NCRYPT_PROV_HANDLE *providerInstance ,const WCHAR *name, const WCHAR *dllName, DWORD flags); + +#endif /* __NCRYPT_INTERNAL__ */ diff --git a/include/bcrypt.h b/include/bcrypt.h index a099f2f4b0e..4d3f59c3462 100644 --- a/include/bcrypt.h +++ b/include/bcrypt.h @@ -221,6 +221,12 @@ static const WCHAR BCRYPT_KDF_RAW_SECRET[] = {'T','R','U','N','C','A','T','E',0} #define BCRYPT_SUPPORTED_PAD_OAEP 0x00000008 #define BCRYPT_SUPPORTED_PAD_PSS 0x00000010
+typedef struct _BCRYPT_INTERFACE_VERSION +{ + USHORT MajorVersion; + USHORT MinorVersion; +}BCRYPT_INTERFACE_VERSION, *PBCRYPT_INTERFACE_VERSION; + typedef struct _BCRYPT_ALGORITHM_IDENTIFIER { LPWSTR pszName;
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 65 +++++++++++++++++++++++++++++++++-- dlls/ncrypt/ncrypt_internal.h | 15 ++++++++ 2 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 8a8d8d0ed13..c7546cce897 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -51,9 +51,23 @@ SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCR const WCHAR *algid, const WCHAR *name, DWORD keyspec, DWORD flags) { - FIXME("(0x%lx, %p, %s, %s, 0x%08x, 0x%08x): stub\n", provider, key, wine_dbgstr_w(algid), + struct ncrypt_provider_instance *providerInstance; + struct ncrypt_key_instance *outKeyInstance; + + TRACE("(0x%lx, %p, %s, %s, 0x%08x, 0x%08x)\n", provider, key, wine_dbgstr_w(algid), wine_dbgstr_w(name), keyspec, flags); - return NTE_NOT_SUPPORTED; + if (!provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(provider); + outKeyInstance = create_key(provider, name); + if (!outKeyInstance) + { + return NTE_NO_MEMORY; + } + *key = (NCRYPT_KEY_HANDLE)outKeyInstance; + return providerInstance->functions.CreatePersistedKey(providerInstance->kspHandle, &outKeyInstance->kspHandle, algid, name, keyspec, flags); }
SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD insize, void *padding, @@ -396,3 +410,50 @@ static SECURITY_STATUS open_provider(NCRYPT_PROV_HANDLE *providerInstance, const *providerInstance = provider2handle(ret); return ERROR_SUCCESS; } + +static struct ncrypt_key_instance* create_key(NCRYPT_PROV_HANDLE provider, const WCHAR *name) +{ + unsigned int size; + void *buffer; + struct ncrypt_key_instance *ret; + + size = sizeof(struct ncrypt_key_instance); + + if (name) + { + /* Allocate both structure and name in the same call */ + size += (wcslen(name) + 1) * sizeof(WCHAR); + } + + buffer = heap_alloc(size); + if (!buffer) + { + return NULL; + } + + ret = (struct ncrypt_key_instance *) buffer; + ret->sType = NCRYPT_OBJ_TYPE_KEY; + ret->provider = ref_provider(provider); + + if (name) + { + ret->name = (WCHAR*)((char*)buffer + sizeof(struct ncrypt_key_instance)); + wcscpy(ret->name, name); + } + else + { + ret->name = NULL; + } + + return ret; +} + +static NCRYPT_PROV_HANDLE ref_provider(NCRYPT_PROV_HANDLE provider) +{ + struct ncrypt_provider_instance *providerInstance; + + providerInstance = handle2provider(provider); + providerInstance->refCount++; + + return provider; +} diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index e5c9a946f2c..3a87727cb1e 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -78,15 +78,30 @@ struct ncrypt_provider_instance WCHAR *name; };
+struct ncrypt_key_instance +{ + DWORD sType; + NCRYPT_PROV_HANDLE provider; + NCRYPT_KEY_HANDLE kspHandle; + WCHAR *name; +}; +
#define handle2baseObject(x) ((struct ncrypt_base_object*)(x)) #define baseObject2handle(x) ((NCRYPT_HANDLE)(x))
+#define handle2key(x) ((struct ncrypt_key_instance*)(x)) +#define key2handle(x) ((NCRYPT_KEY_HANDLE)(x)) + #define handle2provider(x) ((struct ncrypt_provider_instance*)(x)) #define provider2handle(x) ((NCRYPT_PROV_HANDLE)(x))
static SECURITY_STATUS open_provider(NCRYPT_PROV_HANDLE *providerInstance ,const WCHAR *name, const WCHAR *dllName, DWORD flags); +static struct ncrypt_key_instance* create_key(NCRYPT_PROV_HANDLE provider, const WCHAR *name); +static NCRYPT_PROV_HANDLE ref_provider(NCRYPT_PROV_HANDLE provider); +static SECURITY_STATUS free_provider(NCRYPT_HANDLE provider); +static SECURITY_STATUS free_key(NCRYPT_HANDLE key);
#endif /* __NCRYPT_INTERNAL__ */
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 108 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index c7546cce897..27313438279 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -242,8 +242,25 @@ SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf)
SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object) { - FIXME("(0x%lx): stub\n", object); - return NTE_NOT_SUPPORTED; + /* FIXME: implement for secret and hash handles */ + struct ncrypt_base_object *obj; + + TRACE("(0x%lx)\n", object); + + obj = handle2baseObject(object); + + switch(obj->sType) + { + case NCRYPT_OBJ_TYPE_PROVIDER: + return free_provider(object); + + case NCRYPT_OBJ_TYPE_KEY: + return free_key(object); + + default: + FIXME("Object type not implemented: 0x%08x\n", obj->sType); + return NTE_NOT_SUPPORTED; + } }
SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *property, PBYTE output, @@ -457,3 +474,90 @@ static NCRYPT_PROV_HANDLE ref_provider(NCRYPT_PROV_HANDLE provider)
return provider; } + +static SECURITY_STATUS free_provider(NCRYPT_HANDLE provider) +{ + struct ncrypt_provider_instance *providerInstance; + SECURITY_STATUS ret; + BOOL success; + + if (!provider) + { + return NTE_INVALID_HANDLE; + } + + providerInstance = handle2provider(provider); + + if (providerInstance->refCount) + { + providerInstance->refCount--; + } + + if (!providerInstance->refCount) + { + if (providerInstance->kspHandle) + { + ret = providerInstance->functions.FreeProvider(providerInstance->kspHandle); + if (ret != ERROR_SUCCESS) + { + ERR("FreeProvider failed\n"); + return ret; + } + providerInstance->kspHandle = 0; + } + + if (providerInstance->kspDLL) + { + success = FreeLibrary(providerInstance->kspDLL); + if (!success) + { + ERR("Failed to free dll: 0x%08x\n", GetLastError()); + return NTE_INTERNAL_ERROR; + } + providerInstance->kspDLL = NULL; + } + heap_free(providerInstance); + } + return ERROR_SUCCESS; +} + +static SECURITY_STATUS free_key(NCRYPT_HANDLE key) +{ + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance *providerInstance; + SECURITY_STATUS ret; + + + if (!key) + { + return NTE_INVALID_HANDLE; + } + + keyInstance = handle2key(key); + providerInstance = handle2provider(keyInstance->provider); + + + if (keyInstance->kspHandle) + { + ret = providerInstance->functions.FreeKey(providerInstance->kspHandle, keyInstance->kspHandle); + if (ret != ERROR_SUCCESS) + { + ERR("FreeKey failed in the key storage provider\n"); + return ret; + } + keyInstance->kspHandle = 0; + } + + if (keyInstance->provider) + { + ret = free_provider(keyInstance->provider); + if (ret != ERROR_SUCCESS) + { + return ret; + } + keyInstance->provider = 0; + } + + heap_free(keyInstance); + return ERROR_SUCCESS; +}
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 10 ++++++++++ dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 27313438279..003add36502 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -288,6 +288,16 @@ SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const W return NTE_NOT_SUPPORTED; }
+BOOL WINAPI NCryptIsKeyHandle(NCRYPT_HANDLE object) +{ + struct ncrypt_base_object *obj; + + TRACE("(0x%lx)\n", object); + + obj = handle2baseObject(object); + return obj->sType == NCRYPT_OBJ_TYPE_KEY; +} + SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key, const WCHAR *name, DWORD keyspec, DWORD flags) { diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec index 2e6765c91ff..b13354e4bef 100644 --- a/dlls/ncrypt/ncrypt.spec +++ b/dlls/ncrypt/ncrypt.spec @@ -78,7 +78,7 @@ @ stub NCryptGetProtectionDescriptorInfo @ stdcall NCryptImportKey(long long wstr ptr ptr ptr long long) @ stub NCryptIsAlgSupported(long wstr long) -@ stub NCryptIsKeyHandle +@ stdcall NCryptIsKeyHandle(long) @ stub NCryptKeyDerivation @ stub NCryptNotifyChangeKey @ stdcall NCryptOpenKey(long ptr wstr long long) diff --git a/include/ncrypt.h b/include/ncrypt.h index 9110c1ef6a4..b78fa3aeae7 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -81,6 +81,7 @@ SECURITY_STATUS WINAPI NCryptEnumStorageProviders(DWORD *, NCryptProviderName ** SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE, DWORD); SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID); SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE); +BOOL WINAPI NCryptIsKeyHandle(NCRYPT_HANDLE); SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, DWORD, DWORD); SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 003add36502..4189132c395 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -73,9 +73,24 @@ SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCR SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD insize, void *padding, 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, + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance *providerInstance; + + TRACE("(0x%lx, %p, %u, %p, %p, %u, %p, 0x%08x)\n", key, input, insize, padding, output, outsize, result, flags); - return NTE_NOT_SUPPORTED; + if (!key) + { + return NTE_INVALID_HANDLE; + } + keyInstance = handle2key(key); + + if (!keyInstance->provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(keyInstance->provider); + + return providerInstance->functions.Decrypt(providerInstance->kspHandle, keyInstance->kspHandle, input, insize, padding, output, outsize, result, flags); }
SECURITY_STATUS WINAPI NCryptDeleteKey(NCRYPT_KEY_HANDLE key, DWORD flags) @@ -87,9 +102,25 @@ SECURITY_STATUS WINAPI NCryptDeleteKey(NCRYPT_KEY_HANDLE key, DWORD flags) SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD insize, void *padding, 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, + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance *providerInstance; + + TRACE("(0x%lx, %p, %u, %p, %p, %u, %p, 0x%08x)\n", key, input, insize, padding, output, outsize, result, flags); - return NTE_NOT_SUPPORTED; + + if (!key) + { + return NTE_INVALID_HANDLE; + } + keyInstance = handle2key(key); + + if (!keyInstance->provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(keyInstance->provider); + + return providerInstance->functions.Encrypt(providerInstance->kspHandle, keyInstance->kspHandle, input, insize, padding, output, outsize, result, flags); }
SECURITY_STATUS WINAPI NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE provider, DWORD alg_ops,
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 30 ++++++++++++++++++++++++++++-- include/ncrypt.h | 1 + 2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 4189132c395..63687850b55 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -95,8 +95,34 @@ SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD i
SECURITY_STATUS WINAPI NCryptDeleteKey(NCRYPT_KEY_HANDLE key, DWORD flags) { - FIXME("(0x%lx, 0x%08x): stub\n", key, flags); - return NTE_NOT_SUPPORTED; + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance *providerInstance; + SECURITY_STATUS ret; + + TRACE("(0x%lx, 0x%08x)", key, flags); + + if (!key) + { + return NTE_INVALID_HANDLE; + } + keyInstance = handle2key(key); + + if (!keyInstance->provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(keyInstance->provider); + + ret = providerInstance->functions.DeleteKey(providerInstance->kspHandle, keyInstance->kspHandle, flags); + if (ret != ERROR_SUCCESS) + { + return ret; + } + keyInstance->kspHandle = 0; + + free_key(key); + + return ret; }
SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD insize, void *padding, diff --git a/include/ncrypt.h b/include/ncrypt.h index b78fa3aeae7..22f9c67ebb6 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -76,6 +76,7 @@ typedef ULONG_PTR NCRYPT_SECRET_HANDLE;
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 NCryptDeleteKey(NCRYPT_KEY_HANDLE, DWORD); SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD); SECURITY_STATUS WINAPI NCryptEnumStorageProviders(DWORD *, NCryptProviderName **, DWORD); SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE, DWORD);
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 44 ++++++++++++++++++++++++++++++++++++++++---- include/ncrypt.h | 2 ++ 2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 63687850b55..606cd1b8401 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -153,15 +153,51 @@ SECURITY_STATUS WINAPI NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE provider, DWORD a DWORD *alg_count, NCryptAlgorithmName **alg_list, DWORD flags) { - FIXME("(0x%lx, 0x%08x, %p, %p, 0x%08x): stub\n", provider, alg_ops, alg_count, alg_list, flags); - return NTE_NOT_SUPPORTED; + struct ncrypt_provider_instance *providerInstance; + + TRACE("(0x%lx, 0x%08x, %p, %p, 0x%08x)\n", provider, alg_ops, alg_count, alg_list, flags); + + if (!provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(provider); + return providerInstance->functions.EnumAlgorithms(providerInstance->kspHandle, alg_ops, alg_count, alg_list, flags); }
SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR *scope, NCryptKeyName **key_name, PVOID *enum_state, DWORD flags) { - FIXME("(0x%lx, %p, %p, %p, 0x%08x): stub\n", provider, scope, key_name, enum_state, flags); - return NTE_NOT_SUPPORTED; + struct ncrypt_provider_instance *providerInstance; + SECURITY_STATUS ret; + BOOL firstRound; + + TRACE("(0x%lx, %p, %p, %p, 0x%08x)\n", provider, scope, key_name, enum_state, flags); + + if (!provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(provider); + + firstRound = (*enum_state == NULL); + + ret = providerInstance->functions.EnumKeys(providerInstance->kspHandle, scope, key_name, enum_state, flags); + + if (firstRound && *enum_state) + { + /* FIXME: enum_state must be freed with NCryptFreeBuffer, which as it seems should in turn + call the FreeBuffer function that is in the KSP DLL, so provider should live until after that happens */ + providerInstance->refCount++; + } + + if (ret == ERROR_SUCCESS && *key_name) + { + /* FIXME: key_name must be freed with NCryptFreeBuffer, which as it seems should in turn + call the FreeBuffer function that is in the KSP DLL, so provider should live until after that happens */ + providerInstance->refCount++; + } + return ret; }
SECURITY_STATUS WINAPI NCryptEnumStorageProviders(DWORD *providerCount, NCryptProviderName **providerList, DWORD flags) diff --git a/include/ncrypt.h b/include/ncrypt.h index 22f9c67ebb6..2906d47b023 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -78,6 +78,8 @@ SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_H SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD); SECURITY_STATUS WINAPI NCryptDeleteKey(NCRYPT_KEY_HANDLE, DWORD); SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, BYTE *, DWORD, DWORD *, DWORD); +SECURITY_STATUS WINAPI NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE, DWORD, DWORD *, NCryptAlgorithmName **, DWORD); +SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE, const WCHAR *, NCryptKeyName **, PVOID *, DWORD); SECURITY_STATUS WINAPI NCryptEnumStorageProviders(DWORD *, NCryptProviderName **, DWORD); SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE, DWORD); SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID);
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 54 +++++++++++++++++++++++++++++++++++++++-- dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 2 ++ 3 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 606cd1b8401..a183eb00bb3 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -317,6 +317,32 @@ cleanup: return ret; }
+SECURITY_STATUS WINAPI NCryptExportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE enc_key, const WCHAR *blobType, + NCryptBufferDesc *parameterList, PBYTE output, DWORD outsize, DWORD *result, DWORD flags) +{ + struct ncrypt_provider_instance *providerInstance; + struct ncrypt_key_instance *encryptKeyInstance; + NCRYPT_KEY_HANDLE kspEncryptKeyHandle; + + TRACE("(0x%lx, 0x%lx, %s, %p, %p, 0x%08x, %p, 0x%08x)\n", provider, enc_key, wine_dbgstr_w(blobType), + parameterList, output, outsize, result, flags); + + if (!provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(provider); + + kspEncryptKeyHandle = 0; + if (enc_key) + { + encryptKeyInstance = handle2key(enc_key); + kspEncryptKeyHandle = encryptKeyInstance->kspHandle; + } + + return providerInstance->functions.ExportKey(providerInstance->kspHandle, kspEncryptKeyHandle, blobType, parameterList, output, outsize, result, flags); +} + SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags) { FIXME("(0x%lx, 0x%08x): stub\n", key, flags); @@ -368,10 +394,34 @@ 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, + struct ncrypt_provider_instance *providerInstance; + struct ncrypt_key_instance *decryptKeyInstance; + struct ncrypt_key_instance *outKeyInstance; + NCRYPT_KEY_HANDLE kspDecryptKeyHandle; + + TRACE("(0x%lx, 0x%lx, %s, %p, %p, %p, %u, 0x%08x)\n", provider, decrypt_key, wine_dbgstr_w(type), params, key, data, datasize, flags); - return NTE_NOT_SUPPORTED; + if (!provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(provider); + + kspDecryptKeyHandle = 0; + if (decrypt_key) + { + decryptKeyInstance = handle2key(decrypt_key); + kspDecryptKeyHandle = decryptKeyInstance->kspHandle; + } + + outKeyInstance = create_key(provider, NULL); + if (!outKeyInstance) + { + return NTE_NO_MEMORY; + } + *key = (NCRYPT_KEY_HANDLE)outKeyInstance; + return providerInstance->functions.ImportKey(providerInstance->kspHandle, kspDecryptKeyHandle, type, params, &outKeyInstance->kspHandle, data, datasize, flags); }
SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const WCHAR *algid, diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec index b13354e4bef..3a47f12cfa1 100644 --- a/dlls/ncrypt/ncrypt.spec +++ b/dlls/ncrypt/ncrypt.spec @@ -70,7 +70,7 @@ @ stdcall NCryptEnumAlgorithms(long long ptr ptr long) @ stdcall NCryptEnumKeys(long wstr ptr ptr long) @ stdcall NCryptEnumStorageProviders(ptr ptr long) -@ stub NCryptExportKey +@ stdcall NCryptExportKey(long long ptr ptr ptr long ptr long) @ stdcall NCryptFinalizeKey(long long) @ stdcall NCryptFreeBuffer(ptr) @ stdcall NCryptFreeObject(long) diff --git a/include/ncrypt.h b/include/ncrypt.h index 2906d47b023..3edc069352f 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -81,9 +81,11 @@ SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE, BYTE *, DWORD, void *, B SECURITY_STATUS WINAPI NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE, DWORD, DWORD *, NCryptAlgorithmName **, DWORD); SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE, const WCHAR *, NCryptKeyName **, PVOID *, DWORD); SECURITY_STATUS WINAPI NCryptEnumStorageProviders(DWORD *, NCryptProviderName **, DWORD); +SECURITY_STATUS WINAPI NCryptExportKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE, const WCHAR *, NCryptBufferDesc *, PBYTE, DWORD, DWORD *, DWORD); SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE, DWORD); SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID); SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE); +SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE, const WCHAR *, NCryptBufferDesc *, NCRYPT_KEY_HANDLE *, PBYTE, DWORD, DWORD); BOOL WINAPI NCryptIsKeyHandle(NCRYPT_HANDLE); SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, DWORD, DWORD); SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index a183eb00bb3..d940a49c1e4 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -345,8 +345,25 @@ SECURITY_STATUS WINAPI NCryptExportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_H
SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags) { - FIXME("(0x%lx, 0x%08x): stub\n", key, flags); - return NTE_NOT_SUPPORTED; + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance *providerInstance; + + TRACE("(0x%lx, 0x%08x)\n", key, flags); + + + if (!key) + { + return NTE_INVALID_HANDLE; + } + keyInstance = handle2key(key); + + if (!keyInstance->provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(keyInstance->provider); + + return providerInstance->functions.FinalizeKey(providerInstance->kspHandle, keyInstance->kspHandle, flags); }
SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf)
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 59 ++++++++++++++++++++++++++++++++++++++++++---- include/ncrypt.h | 2 ++ 2 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index d940a49c1e4..e574743430a 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -402,9 +402,35 @@ SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object) SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *property, PBYTE 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, + struct ncrypt_base_object *obj; + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance *providerInstance; + + TRACE("(0x%lx, %s, %p, %u, %p, 0x%08x)\n", object, wine_dbgstr_w(property), output, outsize, result, flags); - return NTE_NOT_SUPPORTED; + + if (!object) + { + return NTE_INVALID_HANDLE; + } + + obj = handle2baseObject(object); + + switch(obj->sType) + { + case NCRYPT_OBJ_TYPE_PROVIDER: + providerInstance = handle2provider(object); + return providerInstance->functions.GetProviderProperty(providerInstance->kspHandle, property, output, outsize, result, flags); + + case NCRYPT_OBJ_TYPE_KEY: + keyInstance = handle2key(object); + providerInstance = handle2provider(keyInstance->provider); + return providerInstance->functions.GetKeyProperty(providerInstance->kspHandle, keyInstance->kspHandle, property, output, outsize, result, flags); + + default: + FIXME("Object type not implemented: 0x%08x\n", obj->sType); + return NTE_NOT_SUPPORTED; + } }
SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE decrypt_key, @@ -526,9 +552,34 @@ 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) { - FIXME("(%lx, %s, %p, %u, 0x%08x): stub\n", object, wine_dbgstr_w(property), input, insize, + struct ncrypt_base_object *obj; + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance *providerInstance; + + TRACE("(%lx, %s, %p, %u, 0x%08x)\n", object, wine_dbgstr_w(property), input, insize, flags); - return NTE_NOT_SUPPORTED; + if (!object) + { + return NTE_INVALID_HANDLE; + } + + obj = handle2baseObject(object); + + switch(obj->sType) + { + case NCRYPT_OBJ_TYPE_PROVIDER: + providerInstance = handle2provider(object); + return providerInstance->functions.SetProviderProperty(providerInstance->kspHandle, property, input, insize, flags); + + case NCRYPT_OBJ_TYPE_KEY: + keyInstance = handle2key(object); + providerInstance = handle2provider(keyInstance->provider); + return providerInstance->functions.SetKeyProperty(providerInstance->kspHandle, keyInstance->kspHandle, property, input, insize, flags); + + default: + FIXME("Object type not implemented: 0x%08x\n", obj->sType); + return NTE_NOT_SUPPORTED; + } }
static SECURITY_STATUS open_provider(NCRYPT_PROV_HANDLE *providerInstance, const WCHAR *name, const WCHAR *dllName, DWORD flags) diff --git a/include/ncrypt.h b/include/ncrypt.h index 3edc069352f..d4ace11c6e8 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -85,10 +85,12 @@ SECURITY_STATUS WINAPI NCryptExportKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE, co SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE, DWORD); SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID); SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE); +SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE, const WCHAR *, PBYTE, DWORD, DWORD *, DWORD); SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE, const WCHAR *, NCryptBufferDesc *, NCRYPT_KEY_HANDLE *, PBYTE, DWORD, DWORD); BOOL WINAPI NCryptIsKeyHandle(NCRYPT_HANDLE); 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 *, PBYTE, DWORD, DWORD);
#ifdef __cplusplus }
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 12 ++++++++++-- dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index e574743430a..2772da1d8fb 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -470,8 +470,16 @@ 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("(0x%lx, %s, 0x%08x): stub\n", provider, wine_dbgstr_w(algid), flags); - return NTE_NOT_SUPPORTED; + struct ncrypt_provider_instance *providerInstance; + + TRACE("(0x%lx, %s, 0x%08x)\n", provider, wine_dbgstr_w(algid), flags); + + if (!provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(provider); + return providerInstance->functions.IsAlgSupported(providerInstance->kspHandle, algid, flags); }
BOOL WINAPI NCryptIsKeyHandle(NCRYPT_HANDLE object) diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec index 3a47f12cfa1..cc566313cd1 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 d4ace11c6e8..ce82603b673 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -87,6 +87,7 @@ SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID); SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE); SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE, const WCHAR *, PBYTE, DWORD, DWORD *, DWORD); SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE, const WCHAR *, NCryptBufferDesc *, NCRYPT_KEY_HANDLE *, PBYTE, DWORD, DWORD); +SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE, const WCHAR *, DWORD); BOOL WINAPI NCryptIsKeyHandle(NCRYPT_HANDLE); SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, const WCHAR *, DWORD, DWORD); SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD);
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 2772da1d8fb..23cf6896405 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -495,8 +495,25 @@ BOOL WINAPI NCryptIsKeyHandle(NCRYPT_HANDLE object) SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key, const WCHAR *name, DWORD keyspec, DWORD flags) { - FIXME("(0x%lx, %p, %s, 0x%08x, 0x%08x): stub\n", provider, key, wine_dbgstr_w(name), keyspec, flags); - return NTE_NOT_SUPPORTED; + struct ncrypt_provider_instance *providerInstance; + struct ncrypt_key_instance *outKeyInstance; + + TRACE("(0x%lx, %p, %s, 0x%08x, 0x%08x)\n", provider, key, wine_dbgstr_w(name), keyspec, flags); + + if (!provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(provider); + + outKeyInstance = create_key(provider, name); + if (!outKeyInstance) + { + return NTE_NO_MEMORY; + } + *key = (NCRYPT_KEY_HANDLE)outKeyInstance; + + return providerInstance->functions.OpenKey(providerInstance->kspHandle, &outKeyInstance->kspHandle, name, keyspec, flags); }
SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *provider, const WCHAR *name, DWORD flags)
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 24 ++++++++++++++++++++++++ dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 1 + 3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 23cf6896405..bb6f90e6cf9 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -607,6 +607,30 @@ SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *prop } }
+SECURITY_STATUS WINAPI NCryptSignHash(NCRYPT_KEY_HANDLE key, void *paddingInfo, PBYTE hashValue, DWORD hashSize, + PBYTE signature, DWORD signatureSize, DWORD *result, DWORD flags) +{ + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance * providerInstance; + + TRACE("(0x%lx, %p, %p, 0x%08x, %p, 0x%08x, %p, 0x%08x)\n", key, paddingInfo, hashValue, hashSize, + signature, signatureSize, result, flags); + + if (!key) + { + return NTE_INVALID_HANDLE; + } + keyInstance = handle2key(key); + + if (!keyInstance->provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(keyInstance->provider); + + return providerInstance->functions.SignHash(keyInstance->kspHandle, paddingInfo, hashValue, hashSize, signature, signatureSize, result, flags); +} + static SECURITY_STATUS open_provider(NCRYPT_PROV_HANDLE *providerInstance, const WCHAR *name, const WCHAR *dllName, DWORD flags) { unsigned int size; diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec index cc566313cd1..9c09b061ff7 100644 --- a/dlls/ncrypt/ncrypt.spec +++ b/dlls/ncrypt/ncrypt.spec @@ -91,7 +91,7 @@ @ stub NCryptSecretAgreement @ stub NCryptSetAuditingInterface @ stdcall NCryptSetProperty(ptr wstr ptr long long) -@ stub NCryptSignHash +@ stdcall NCryptSignHash(long ptr ptr long ptr long ptr long) @ stub NCryptStreamClose @ stub NCryptStreamOpenToProtect @ stub NCryptStreamOpenToUnprotect diff --git a/include/ncrypt.h b/include/ncrypt.h index ce82603b673..2a58067b54d 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -92,6 +92,7 @@ BOOL WINAPI NCryptIsKeyHandle(NCRYPT_HANDLE); 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 *, PBYTE, DWORD, DWORD); +SECURITY_STATUS WINAPI NCryptSignHash(NCRYPT_KEY_HANDLE, void *, PBYTE, DWORD, PBYTE, DWORD, DWORD *, DWORD);
#ifdef __cplusplus }
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 24 ++++++++++++++++++++++++ dlls/ncrypt/ncrypt.spec | 2 +- include/ncrypt.h | 1 + 3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index bb6f90e6cf9..3eca9018bec 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -631,6 +631,30 @@ SECURITY_STATUS WINAPI NCryptSignHash(NCRYPT_KEY_HANDLE key, void *paddingInfo, return providerInstance->functions.SignHash(keyInstance->kspHandle, paddingInfo, hashValue, hashSize, signature, signatureSize, result, flags); }
+SECURITY_STATUS WINAPI NCryptVerifySignature(NCRYPT_KEY_HANDLE key, void *paddingInfo, PBYTE hashValue, + DWORD hashSize, PBYTE signature, DWORD signatureSize, DWORD flags) +{ + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance * providerInstance; + + TRACE("(0x%lx, %p, %p, 0x%08x, %p, 0x%08x, 0x%08x)\n", key, paddingInfo, hashValue, hashSize, + signature, signatureSize, flags); + + if (!key) + { + return NTE_INVALID_HANDLE; + } + keyInstance = handle2key(key); + + if (!keyInstance->provider) + { + return NTE_INVALID_HANDLE; + } + providerInstance = handle2provider(keyInstance->provider); + + return providerInstance->functions.VerifySignature(keyInstance->kspHandle, paddingInfo, hashValue, hashSize, signature, signatureSize, flags); +} + static SECURITY_STATUS open_provider(NCRYPT_PROV_HANDLE *providerInstance, const WCHAR *name, const WCHAR *dllName, DWORD flags) { unsigned int size; diff --git a/dlls/ncrypt/ncrypt.spec b/dlls/ncrypt/ncrypt.spec index 9c09b061ff7..77283351660 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(long ptr ptr long ptr long long) @ stub SslChangeNotify @ stub SslComputeClientAuthHash @ stub SslComputeEapKeyBlock diff --git a/include/ncrypt.h b/include/ncrypt.h index 2a58067b54d..6a002d148ab 100644 --- a/include/ncrypt.h +++ b/include/ncrypt.h @@ -93,6 +93,7 @@ SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE, NCRYPT_KEY_HANDLE *, co SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *, const WCHAR *, DWORD); SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE, const WCHAR *, PBYTE, DWORD, DWORD); SECURITY_STATUS WINAPI NCryptSignHash(NCRYPT_KEY_HANDLE, void *, PBYTE, DWORD, PBYTE, DWORD, DWORD *, DWORD); +SECURITY_STATUS WINAPI NCryptVerifySignature(NCRYPT_KEY_HANDLE, void *, PBYTE, DWORD, PBYTE, DWORD, DWORD);
#ifdef __cplusplus }
From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 147 +++++++++++++++++++++++++++++++--- dlls/ncrypt/ncrypt_internal.h | 11 +++ 2 files changed, 145 insertions(+), 13 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index 3eca9018bec..1ea31d42e9a 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -31,6 +31,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
+static struct list bufferList = LIST_INIT(bufferList); + BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) { TRACE("(%p, %u, %p)\n", instance, reason, reserved); @@ -154,6 +156,7 @@ SECURITY_STATUS WINAPI NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE provider, DWORD a DWORD flags) { struct ncrypt_provider_instance *providerInstance; + SECURITY_STATUS ret;
TRACE("(0x%lx, 0x%08x, %p, %p, 0x%08x)\n", provider, alg_ops, alg_count, alg_list, flags);
@@ -162,7 +165,13 @@ SECURITY_STATUS WINAPI NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE provider, DWORD a return NTE_INVALID_HANDLE; } providerInstance = handle2provider(provider); - return providerInstance->functions.EnumAlgorithms(providerInstance->kspHandle, alg_ops, alg_count, alg_list, flags); + ret = providerInstance->functions.EnumAlgorithms(providerInstance->kspHandle, alg_ops, alg_count, alg_list, flags); + if (ret == ERROR_SUCCESS) + { + register_buffer(provider, *alg_list); + } + + return ret; }
SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR *scope, @@ -186,16 +195,60 @@ SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR *
if (firstRound && *enum_state) { - /* FIXME: enum_state must be freed with NCryptFreeBuffer, which as it seems should in turn - call the FreeBuffer function that is in the KSP DLL, so provider should live until after that happens */ - providerInstance->refCount++; + ret = register_buffer(provider, *enum_state); + if (ret == NTE_NO_MEMORY) + { + ret = providerInstance->functions.FreeBuffer(*enum_state); + if (ret != ERROR_SUCCESS) + { + ERR("Provider failed to free enum_state\n"); + } + *enum_state = NULL; + + if (*key_name) + { + ret = providerInstance->functions.FreeBuffer(*key_name); + if (ret != ERROR_SUCCESS) + { + ERR("Provider failed to free key_name\n"); + } + } + *key_name = NULL; + return NTE_NO_MEMORY; + } + else if (ret != ERROR_SUCCESS) + { + FIXME("Unknown error while registering buffer: 0x%08x", ret); + } }
if (ret == ERROR_SUCCESS && *key_name) { - /* FIXME: key_name must be freed with NCryptFreeBuffer, which as it seems should in turn - call the FreeBuffer function that is in the KSP DLL, so provider should live until after that happens */ - providerInstance->refCount++; + ret = register_buffer(provider, *key_name); + if (ret == NTE_NO_MEMORY) + { + ret = providerInstance->functions.FreeBuffer(*key_name); + if (ret != ERROR_SUCCESS) + { + ERR("Provider failed to free key_name\n"); + } + *key_name = NULL; + + if (*enum_state) + { + ret = NCryptFreeBuffer(*enum_state); + if (ret != ERROR_SUCCESS) + { + ERR("Provider failed to unregister enum_state\n"); + } + } + *enum_state = NULL; + return NTE_NO_MEMORY; + } + else if (ret != ERROR_SUCCESS) + { + FIXME("Unknown error while registering buffer: 0x%08x", ret); + } } return ret; } @@ -311,6 +364,7 @@ cleanup: { *providerCount = outCount; *providerList = outList; + register_buffer(0, outList); }
RegCloseKey(hKey); @@ -368,11 +422,47 @@ SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags)
SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf) { - /* FIXME: How do we tell which provider should be called? - How do we update refCounts of referenced objects? */ - FIXME("(%p): semi-stub\n", buf); + struct ncrypt_buffer *cursor, *safetyCursor; + struct ncrypt_provider_instance *providerInstance; + SECURITY_STATUS ret; + BOOL found; + + TRACE("(%p)\n", buf); + + found = FALSE; + + LIST_FOR_EACH_ENTRY_SAFE(cursor, safetyCursor, &bufferList, struct ncrypt_buffer, entry) + { + if (cursor->buffer == buf) + { + found = TRUE; + list_remove(&cursor->entry);
- heap_free(buf); + if (!cursor->owner) + { + heap_free(buf); + heap_free(cursor); + break; + } + + providerInstance = handle2provider(cursor->owner); + ret = providerInstance->functions.FreeBuffer(buf); + if (ret != ERROR_SUCCESS) + { + ERR("Provider failed to free buffer: %p\n", buf); + return ret; + } + unref_provider(cursor->owner); + heap_free(cursor); + break; + } + } + + if (!found) + { + WARN("Couldn't find buffer in list of registered buffers\n"); + return NTE_INVALID_PARAMETER; + } return ERROR_SUCCESS; }
@@ -759,16 +849,47 @@ static struct ncrypt_key_instance* create_key(NCRYPT_PROV_HANDLE provider, const return ret; }
+static SECURITY_STATUS register_buffer(NCRYPT_PROV_HANDLE provider, const void *buffer) +{ + struct ncrypt_buffer *bufferEntry; + + bufferEntry = heap_alloc(sizeof(struct ncrypt_buffer)); + if (!bufferEntry) + { + return NTE_NO_MEMORY; + } + + bufferEntry->buffer = buffer; + bufferEntry->owner = ref_provider(provider); + + list_add_head(&bufferList, &bufferEntry->entry); + return ERROR_SUCCESS; +} + static NCRYPT_PROV_HANDLE ref_provider(NCRYPT_PROV_HANDLE provider) { struct ncrypt_provider_instance *providerInstance;
- providerInstance = handle2provider(provider); - providerInstance->refCount++; + if (provider) + { + providerInstance = handle2provider(provider); + providerInstance->refCount++; + }
return provider; }
+static void unref_provider(NCRYPT_PROV_HANDLE provider) +{ + struct ncrypt_provider_instance *providerInstance; + + if (provider) + { + providerInstance = handle2provider(provider); + providerInstance->refCount--; + } +} + static SECURITY_STATUS free_provider(NCRYPT_HANDLE provider) { struct ncrypt_provider_instance *providerInstance; diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h index 3a87727cb1e..8a6e2b3c3a5 100644 --- a/dlls/ncrypt/ncrypt_internal.h +++ b/dlls/ncrypt/ncrypt_internal.h @@ -22,6 +22,7 @@ #define __NCRYPT_INTERNAL__
#include "bcrypt.h" +#include "wine/list.h"
typedef struct _NCRYPT_KEY_STORAGE_FUNCTION_TABLE { @@ -96,11 +97,21 @@ struct ncrypt_key_instance #define handle2provider(x) ((struct ncrypt_provider_instance*)(x)) #define provider2handle(x) ((NCRYPT_PROV_HANDLE)(x))
+/* A buffer should be passed to the provider that allocated it, + so we need to keep track of it */ +struct ncrypt_buffer +{ + struct list entry; + NCRYPT_PROV_HANDLE owner; + const void *buffer; +};
static SECURITY_STATUS open_provider(NCRYPT_PROV_HANDLE *providerInstance ,const WCHAR *name, const WCHAR *dllName, DWORD flags); static struct ncrypt_key_instance* create_key(NCRYPT_PROV_HANDLE provider, const WCHAR *name); +static SECURITY_STATUS register_buffer(NCRYPT_PROV_HANDLE provider, const void *buffer); static NCRYPT_PROV_HANDLE ref_provider(NCRYPT_PROV_HANDLE provider); +static void unref_provider(NCRYPT_PROV_HANDLE provider); static SECURITY_STATUS free_provider(NCRYPT_HANDLE provider); static SECURITY_STATUS free_key(NCRYPT_HANDLE key);
Hi Ariel,
Thanks for your contribution.
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index c0cc05c43ca..86bc9190717 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -23,7 +23,9 @@ #include "windef.h" #include "winbase.h" #include "ncrypt.h" +#include "winreg.h" #include "wine/debug.h" +#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
@@ -89,6 +91,123 @@ SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR * return NTE_NOT_SUPPORTED; }
+SECURITY_STATUS WINAPI NCryptEnumStorageProviders(DWORD *providerCount, NCryptProviderName **providerList, DWORD flags) +{
- HKEY hKey;
- HKEY hSubKey;
- SECURITY_STATUS ret;
- LSTATUS status;
- DWORD maxKeyLen;
- DWORD i;
- WCHAR providerName[MAX_PATH];
- WCHAR providerKSReg[MAX_PATH];
- DWORD providerNameLength;
- NCryptProviderName *outList;
- DWORD outCount;
- DWORD numKeys;
- void *allocBuffer;
- void *reAllocBuffer;
- DWORD allocSize;
- DWORD totalNamesSize;
We try to avoid Hungarian notation. Please use names like out_count, num_keys, etc.
- TRACE("(%p, %p, 0x%08x)\n", providerCount, providerList, flags);
- if (flags)
- {
FIXME("Ignoring flags: 0x%08x - Not implemented\n", flags);
- }
- ret = ERROR_SUCCESS;
- outList = NULL;
- outCount = 0;
- allocSize = 0;
- status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\CurrentControlSet\Control\Cryptography\Providers", 0, KEY_READ, &hKey);
- if (status != ERROR_SUCCESS)
- {
ERR("Failed to open 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Cryptography\\Providers' error code: 0x%08x\n", status);
This should be a WARN or TRACE at most.
return NTE_NOT_SUPPORTED; /* FIXME: what should be returned here? */
- }
- status = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numKeys, &maxKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
- if (status != ERROR_SUCCESS)
- {
ERR("Failed to query info on 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Cryptography\\Providers' error code: 0x%08x\n", status);
ret = NTE_NOT_SUPPORTED; /* FIXME: what should be returned here? */
goto cleanup;
- }
- for (i = 0; i < numKeys; ++i)
- {
providerNameLength = MAX_PATH;
status = RegEnumKeyExW(hKey, i, providerName, &providerNameLength, NULL, NULL, NULL, NULL);
if (status != ERROR_SUCCESS)
{
ERR("Failed to enumerate sub keys of 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Cryptography\\Providers' error code: 0x%08x\n", status);
ret = NTE_NOT_SUPPORTED; /* FIXME: what should be returned here? */
goto cleanup;
}
/* This registry key should exist if the provider supports key storage */
swprintf(providerKSReg, MAX_PATH - 1, L"%s\\UM\\00010001", providerName);
status = RegOpenKeyExW(hKey, providerKSReg, 0, KEY_READ, &hSubKey);
if (status != ERROR_SUCCESS)
{
/* Provider doesn't support key storage, skip it */
continue;
}
RegCloseKey(hSubKey);
allocSize += sizeof(NCryptProviderName) + (providerNameLength + 1) * sizeof(WCHAR);
if (!outCount++)
{
allocBuffer = heap_alloc(allocSize);
if (!allocBuffer)
{
ERR("Out of memory!\n");
I don't think this is worth an error message.
ret = NTE_NO_MEMORY;
goto cleanup;
}
totalNamesSize = 0;
}
else
{
reAllocBuffer = heap_realloc(allocBuffer, allocSize);
if (!reAllocBuffer)
{
ERR("Out of memory during realloc!\n");
heap_free(allocBuffer);
ret = NTE_NO_MEMORY;
goto cleanup;
}
/* Shift the wstrings that contain the names over by the size of one struct */
memmove((BYTE*)allocBuffer + outCount * sizeof(NCryptProviderName), (BYTE*)allocBuffer + (outCount - 1) * sizeof(NCryptProviderName), totalNamesSize);
}
The reallocated buffer may have moved. You don't need these casts if you make allocBuffer a BYTE *.
outList = allocBuffer;
outList[outCount - 1].pszName = (WCHAR*)((BYTE*)allocBuffer + outCount * sizeof(NCryptProviderName) + totalNamesSize);
outList[outCount - 1].pszComment = NULL;
wcscpy(outList[outCount - 1].pszName, providerName);
totalNamesSize += (providerNameLength + 1) * sizeof(WCHAR);
- }
+cleanup:
- if (ret == ERROR_SUCCESS)
- {
*providerCount = outCount;
*providerList = outList;
- }
- RegCloseKey(hKey);
- return ret;
+}
SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags) { FIXME("(0x%lx, 0x%08x): stub\n", key, flags); @@ -97,8 +216,12 @@ SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE key, DWORD flags)
SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf) {
- FIXME("(%p): stub\n", buf);
- return NTE_NOT_SUPPORTED;
- /* FIXME: How do we tell which provider should be called?
How do we update refCounts of referenced objects? */
- FIXME("(%p): semi-stub\n", buf);
- heap_free(buf);
- return ERROR_SUCCESS;
}
SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object)
Some tests would be nice.