Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
30
third_party/FreeRDP/winpr/libwinpr/ncrypt/CMakeLists.txt
vendored
Normal file
30
third_party/FreeRDP/winpr/libwinpr/ncrypt/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-ncrypt cmake build script
|
||||
#
|
||||
# Copyright 2021 David Fort <contact@hardening-consulting.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if(WITH_PKCS11)
|
||||
winpr_module_add(ncrypt_pkcs11.c pkcs11-headers/pkcs11.h)
|
||||
endif()
|
||||
|
||||
winpr_module_add(ncrypt.c ncrypt.h)
|
||||
|
||||
if(WIN32)
|
||||
winpr_library_add_public(ncrypt)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING_INTERNAL OR BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
7
third_party/FreeRDP/winpr/libwinpr/ncrypt/ModuleOptions.cmake
vendored
Normal file
7
third_party/FreeRDP/winpr/libwinpr/ncrypt/ModuleOptions.cmake
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
set(MINWIN_LAYER "1")
|
||||
set(MINWIN_GROUP "core")
|
||||
set(MINWIN_MAJOR_VERSION "1")
|
||||
set(MINWIN_MINOR_VERSION "0")
|
||||
set(MINWIN_SHORT_NAME "ncrypt")
|
||||
set(MINWIN_LONG_NAME "NCrypt Functions")
|
||||
set(MODULE_LIBRARY_NAME "ncrypt")
|
||||
363
third_party/FreeRDP/winpr/libwinpr/ncrypt/ncrypt.c
vendored
Normal file
363
third_party/FreeRDP/winpr/libwinpr/ncrypt/ncrypt.c
vendored
Normal file
@@ -0,0 +1,363 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* NCrypt library
|
||||
*
|
||||
* Copyright 2021 David Fort <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/library.h>
|
||||
#include <winpr/ncrypt.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <winpr/print.h>
|
||||
#include "../log.h"
|
||||
|
||||
#include "ncrypt.h"
|
||||
|
||||
#define TAG WINPR_TAG("ncrypt")
|
||||
|
||||
const static char NCRYPT_MAGIC[6] = { 'N', 'C', 'R', 'Y', 'P', 'T' };
|
||||
|
||||
SECURITY_STATUS checkNCryptHandle(NCRYPT_HANDLE handle, NCryptHandleType matchType)
|
||||
{
|
||||
if (!handle)
|
||||
{
|
||||
WLog_VRB(TAG, "invalid handle 'nullptr'");
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
const NCryptBaseHandle* base = (NCryptBaseHandle*)handle;
|
||||
if (memcmp(base->magic, NCRYPT_MAGIC, ARRAYSIZE(NCRYPT_MAGIC)) != 0)
|
||||
{
|
||||
char magic1[ARRAYSIZE(NCRYPT_MAGIC) + 1] = WINPR_C_ARRAY_INIT;
|
||||
char magic2[ARRAYSIZE(NCRYPT_MAGIC) + 1] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
memcpy(magic1, base->magic, ARRAYSIZE(NCRYPT_MAGIC));
|
||||
memcpy(magic2, NCRYPT_MAGIC, ARRAYSIZE(NCRYPT_MAGIC));
|
||||
|
||||
WLog_VRB(TAG, "handle '%p' invalid magic '%s' instead of '%s'",
|
||||
WINPR_CXX_COMPAT_CAST(const void*, base), magic1, magic2);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (base->type)
|
||||
{
|
||||
case WINPR_NCRYPT_PROVIDER:
|
||||
case WINPR_NCRYPT_KEY:
|
||||
break;
|
||||
default:
|
||||
WLog_VRB(TAG, "handle '%p' invalid type %d", WINPR_CXX_COMPAT_CAST(const void*, base),
|
||||
WINPR_CXX_COMPAT_CAST(int32_t, base->type));
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((matchType != WINPR_NCRYPT_INVALID) && (base->type != matchType))
|
||||
{
|
||||
WLog_VRB(TAG, "handle '%p' invalid type %d, expected %d",
|
||||
WINPR_CXX_COMPAT_CAST(const void*, base),
|
||||
WINPR_CXX_COMPAT_CAST(int32_t, base->type),
|
||||
WINPR_CXX_COMPAT_CAST(int32_t, matchType));
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
void* ncrypt_new_handle(NCryptHandleType kind, size_t len, NCryptGetPropertyFn getProp,
|
||||
NCryptReleaseFn dtor)
|
||||
{
|
||||
NCryptBaseHandle* ret = calloc(1, len);
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
|
||||
memcpy(ret->magic, NCRYPT_MAGIC, sizeof(ret->magic));
|
||||
ret->type = kind;
|
||||
ret->getPropertyFn = getProp;
|
||||
ret->releaseFn = dtor;
|
||||
return ret;
|
||||
}
|
||||
|
||||
SECURITY_STATUS winpr_NCryptDefault_dtor(NCRYPT_HANDLE handle)
|
||||
{
|
||||
NCryptBaseHandle* h = (NCryptBaseHandle*)handle;
|
||||
if (h)
|
||||
{
|
||||
memset(h->magic, 0, sizeof(h->magic));
|
||||
h->type = WINPR_NCRYPT_INVALID;
|
||||
h->releaseFn = nullptr;
|
||||
free(h);
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
SECURITY_STATUS NCryptEnumStorageProviders(DWORD* wProviderCount,
|
||||
NCryptProviderName** ppProviderList,
|
||||
WINPR_ATTR_UNUSED DWORD dwFlags)
|
||||
{
|
||||
NCryptProviderName* ret = nullptr;
|
||||
size_t stringAllocSize = 0;
|
||||
#ifdef WITH_PKCS11
|
||||
LPWSTR strPtr = nullptr;
|
||||
static const WCHAR emptyComment[1] = WINPR_C_ARRAY_INIT;
|
||||
size_t copyAmount = 0;
|
||||
#endif
|
||||
|
||||
*wProviderCount = 0;
|
||||
*ppProviderList = nullptr;
|
||||
|
||||
#ifdef WITH_PKCS11
|
||||
*wProviderCount += 1;
|
||||
stringAllocSize += (_wcslen(MS_SCARD_PROV) + 1) * sizeof(WCHAR);
|
||||
stringAllocSize += sizeof(emptyComment);
|
||||
#endif
|
||||
|
||||
if (!*wProviderCount)
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
ret = malloc(*wProviderCount * sizeof(NCryptProviderName) + stringAllocSize);
|
||||
if (!ret)
|
||||
return NTE_NO_MEMORY;
|
||||
|
||||
#ifdef WITH_PKCS11
|
||||
strPtr = (LPWSTR)(ret + *wProviderCount);
|
||||
|
||||
ret->pszName = strPtr;
|
||||
copyAmount = (_wcslen(MS_SCARD_PROV) + 1) * sizeof(WCHAR);
|
||||
memcpy(strPtr, MS_SCARD_PROV, copyAmount);
|
||||
strPtr += copyAmount / 2;
|
||||
|
||||
ret->pszComment = strPtr;
|
||||
copyAmount = sizeof(emptyComment);
|
||||
memcpy(strPtr, emptyComment, copyAmount);
|
||||
|
||||
*ppProviderList = ret;
|
||||
#endif
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
SECURITY_STATUS NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE* phProvider, LPCWSTR pszProviderName,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
return winpr_NCryptOpenStorageProviderEx(phProvider, pszProviderName, dwFlags, nullptr);
|
||||
}
|
||||
|
||||
SECURITY_STATUS winpr_NCryptOpenStorageProviderEx(NCRYPT_PROV_HANDLE* phProvider,
|
||||
LPCWSTR pszProviderName, DWORD dwFlags,
|
||||
LPCSTR* modulePaths)
|
||||
{
|
||||
#if defined(WITH_PKCS11)
|
||||
if (pszProviderName && ((_wcscmp(pszProviderName, MS_SMART_CARD_KEY_STORAGE_PROVIDER) == 0) ||
|
||||
(_wcscmp(pszProviderName, MS_SCARD_PROV) == 0)))
|
||||
return NCryptOpenP11StorageProviderEx(phProvider, pszProviderName, dwFlags, modulePaths);
|
||||
|
||||
char buffer[128] = WINPR_C_ARRAY_INIT;
|
||||
(void)ConvertWCharToUtf8(pszProviderName, buffer, sizeof(buffer));
|
||||
WLog_WARN(TAG, "provider '%s' not supported", buffer);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
#else
|
||||
WLog_WARN(TAG, "rebuild with -DWITH_PKCS11=ON to enable smartcard logon support");
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECURITY_STATUS NCryptEnumKeys(NCRYPT_PROV_HANDLE hProvider, LPCWSTR pszScope,
|
||||
NCryptKeyName** ppKeyName, PVOID* ppEnumState, DWORD dwFlags)
|
||||
{
|
||||
SECURITY_STATUS ret = 0;
|
||||
NCryptBaseProvider* provider = (NCryptBaseProvider*)hProvider;
|
||||
|
||||
ret = checkNCryptHandle((NCRYPT_HANDLE)hProvider, WINPR_NCRYPT_PROVIDER);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
return ret;
|
||||
|
||||
return provider->enumKeysFn(hProvider, pszScope, ppKeyName, ppEnumState, dwFlags);
|
||||
}
|
||||
|
||||
SECURITY_STATUS NCryptOpenKey(NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE* phKey,
|
||||
LPCWSTR pszKeyName, DWORD dwLegacyKeySpec, DWORD dwFlags)
|
||||
{
|
||||
SECURITY_STATUS ret = 0;
|
||||
NCryptBaseProvider* provider = (NCryptBaseProvider*)hProvider;
|
||||
|
||||
ret = checkNCryptHandle((NCRYPT_HANDLE)hProvider, WINPR_NCRYPT_PROVIDER);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
return ret;
|
||||
if (!phKey || !pszKeyName)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return provider->openKeyFn(hProvider, phKey, pszKeyName, dwLegacyKeySpec, dwFlags);
|
||||
}
|
||||
|
||||
static NCryptKeyGetPropertyEnum propertyStringToEnum(LPCWSTR pszProperty)
|
||||
{
|
||||
if (_wcscmp(pszProperty, NCRYPT_CERTIFICATE_PROPERTY) == 0)
|
||||
{
|
||||
return NCRYPT_PROPERTY_CERTIFICATE;
|
||||
}
|
||||
else if (_wcscmp(pszProperty, NCRYPT_READER_PROPERTY) == 0)
|
||||
{
|
||||
return NCRYPT_PROPERTY_READER;
|
||||
}
|
||||
else if (_wcscmp(pszProperty, NCRYPT_WINPR_SLOTID) == 0)
|
||||
{
|
||||
return NCRYPT_PROPERTY_SLOTID;
|
||||
}
|
||||
else if (_wcscmp(pszProperty, NCRYPT_NAME_PROPERTY) == 0)
|
||||
{
|
||||
return NCRYPT_PROPERTY_NAME;
|
||||
}
|
||||
|
||||
return NCRYPT_PROPERTY_UNKNOWN;
|
||||
}
|
||||
|
||||
SECURITY_STATUS NCryptGetProperty(NCRYPT_HANDLE hObject, LPCWSTR pszProperty, PBYTE pbOutput,
|
||||
DWORD cbOutput, DWORD* pcbResult, DWORD dwFlags)
|
||||
{
|
||||
NCryptKeyGetPropertyEnum property = NCRYPT_PROPERTY_UNKNOWN;
|
||||
NCryptBaseHandle* base = nullptr;
|
||||
|
||||
if (!hObject)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
base = (NCryptBaseHandle*)hObject;
|
||||
if (memcmp(base->magic, NCRYPT_MAGIC, 6) != 0)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
property = propertyStringToEnum(pszProperty);
|
||||
if (property == NCRYPT_PROPERTY_UNKNOWN)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
|
||||
return base->getPropertyFn(hObject, property, pbOutput, cbOutput, pcbResult, dwFlags);
|
||||
}
|
||||
|
||||
SECURITY_STATUS NCryptFreeObject(NCRYPT_HANDLE hObject)
|
||||
{
|
||||
NCryptBaseHandle* base = nullptr;
|
||||
SECURITY_STATUS ret = checkNCryptHandle(hObject, WINPR_NCRYPT_INVALID);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
return ret;
|
||||
|
||||
base = (NCryptBaseHandle*)hObject;
|
||||
if (base->releaseFn)
|
||||
ret = base->releaseFn(hObject);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SECURITY_STATUS NCryptFreeBuffer(PVOID pvInput)
|
||||
{
|
||||
if (!pvInput)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
free(pvInput);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
SECURITY_STATUS winpr_NCryptOpenStorageProviderEx(NCRYPT_PROV_HANDLE* phProvider,
|
||||
LPCWSTR pszProviderName, DWORD dwFlags,
|
||||
LPCSTR* modulePaths)
|
||||
{
|
||||
typedef SECURITY_STATUS (*NCryptOpenStorageProviderFn)(NCRYPT_PROV_HANDLE * phProvider,
|
||||
LPCWSTR pszProviderName, DWORD dwFlags);
|
||||
SECURITY_STATUS ret = NTE_PROV_DLL_NOT_FOUND;
|
||||
HANDLE lib = LoadLibraryA("ncrypt.dll");
|
||||
if (!lib)
|
||||
return NTE_PROV_DLL_NOT_FOUND;
|
||||
|
||||
NCryptOpenStorageProviderFn ncryptOpenStorageProviderFn =
|
||||
GetProcAddressAs(lib, "NCryptOpenStorageProvider", NCryptOpenStorageProviderFn);
|
||||
if (!ncryptOpenStorageProviderFn)
|
||||
{
|
||||
ret = NTE_PROV_DLL_NOT_FOUND;
|
||||
goto out_free_lib;
|
||||
}
|
||||
|
||||
ret = ncryptOpenStorageProviderFn(phProvider, pszProviderName, dwFlags);
|
||||
|
||||
out_free_lib:
|
||||
FreeLibrary(lib);
|
||||
return ret;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
const char* winpr_NCryptSecurityStatusError(SECURITY_STATUS status)
|
||||
{
|
||||
#define NTE_CASE(S) \
|
||||
case (SECURITY_STATUS)(S): \
|
||||
return #S
|
||||
|
||||
switch (status)
|
||||
{
|
||||
NTE_CASE(ERROR_SUCCESS);
|
||||
NTE_CASE(ERROR_INVALID_PARAMETER);
|
||||
NTE_CASE(ERROR_INVALID_HANDLE);
|
||||
NTE_CASE(ERROR_NOT_SUPPORTED);
|
||||
|
||||
NTE_CASE(NTE_BAD_UID);
|
||||
NTE_CASE(NTE_BAD_HASH);
|
||||
NTE_CASE(NTE_BAD_KEY);
|
||||
NTE_CASE(NTE_BAD_LEN);
|
||||
NTE_CASE(NTE_BAD_DATA);
|
||||
NTE_CASE(NTE_BAD_SIGNATURE);
|
||||
NTE_CASE(NTE_BAD_VER);
|
||||
NTE_CASE(NTE_BAD_ALGID);
|
||||
NTE_CASE(NTE_BAD_FLAGS);
|
||||
NTE_CASE(NTE_BAD_TYPE);
|
||||
NTE_CASE(NTE_BAD_KEY_STATE);
|
||||
NTE_CASE(NTE_BAD_HASH_STATE);
|
||||
NTE_CASE(NTE_NO_KEY);
|
||||
NTE_CASE(NTE_NO_MEMORY);
|
||||
NTE_CASE(NTE_EXISTS);
|
||||
NTE_CASE(NTE_PERM);
|
||||
NTE_CASE(NTE_NOT_FOUND);
|
||||
NTE_CASE(NTE_DOUBLE_ENCRYPT);
|
||||
NTE_CASE(NTE_BAD_PROVIDER);
|
||||
NTE_CASE(NTE_BAD_PROV_TYPE);
|
||||
NTE_CASE(NTE_BAD_PUBLIC_KEY);
|
||||
NTE_CASE(NTE_BAD_KEYSET);
|
||||
NTE_CASE(NTE_PROV_TYPE_NOT_DEF);
|
||||
NTE_CASE(NTE_PROV_TYPE_ENTRY_BAD);
|
||||
NTE_CASE(NTE_KEYSET_NOT_DEF);
|
||||
NTE_CASE(NTE_KEYSET_ENTRY_BAD);
|
||||
NTE_CASE(NTE_PROV_TYPE_NO_MATCH);
|
||||
NTE_CASE(NTE_SIGNATURE_FILE_BAD);
|
||||
NTE_CASE(NTE_PROVIDER_DLL_FAIL);
|
||||
NTE_CASE(NTE_PROV_DLL_NOT_FOUND);
|
||||
NTE_CASE(NTE_BAD_KEYSET_PARAM);
|
||||
NTE_CASE(NTE_FAIL);
|
||||
NTE_CASE(NTE_SYS_ERR);
|
||||
NTE_CASE(NTE_SILENT_CONTEXT);
|
||||
NTE_CASE(NTE_TOKEN_KEYSET_STORAGE_FULL);
|
||||
NTE_CASE(NTE_TEMPORARY_PROFILE);
|
||||
NTE_CASE(NTE_FIXEDPARAMETER);
|
||||
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
#undef NTE_CASE
|
||||
}
|
||||
|
||||
const char* winpr_NCryptGetModulePath(NCRYPT_PROV_HANDLE phProvider)
|
||||
{
|
||||
#if defined(WITH_PKCS11)
|
||||
return NCryptGetModulePath(phProvider);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
96
third_party/FreeRDP/winpr/libwinpr/ncrypt/ncrypt.h
vendored
Normal file
96
third_party/FreeRDP/winpr/libwinpr/ncrypt/ncrypt.h
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* NCrypt library
|
||||
*
|
||||
* Copyright 2021 David Fort <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_LIBWINPR_NCRYPT_NCRYPT_H_
|
||||
#define WINPR_LIBWINPR_NCRYPT_NCRYPT_H_
|
||||
|
||||
#include <winpr/config.h>
|
||||
|
||||
#include <winpr/bcrypt.h>
|
||||
#include <winpr/crypto.h>
|
||||
#include <winpr/ncrypt.h>
|
||||
#include <winpr/error.h>
|
||||
#include <winpr/string.h>
|
||||
|
||||
/** @brief type of ncrypt object */
|
||||
typedef enum
|
||||
{
|
||||
WINPR_NCRYPT_INVALID,
|
||||
WINPR_NCRYPT_PROVIDER,
|
||||
WINPR_NCRYPT_KEY
|
||||
} NCryptHandleType;
|
||||
|
||||
/** @brief dtor function for ncrypt object */
|
||||
typedef SECURITY_STATUS (*NCryptReleaseFn)(NCRYPT_HANDLE handle);
|
||||
|
||||
/** @brief an enum for the kind of property to retrieve */
|
||||
typedef enum
|
||||
{
|
||||
NCRYPT_PROPERTY_CERTIFICATE,
|
||||
NCRYPT_PROPERTY_READER,
|
||||
NCRYPT_PROPERTY_SLOTID,
|
||||
NCRYPT_PROPERTY_NAME,
|
||||
NCRYPT_PROPERTY_UNKNOWN
|
||||
} NCryptKeyGetPropertyEnum;
|
||||
|
||||
typedef SECURITY_STATUS (*NCryptGetPropertyFn)(NCRYPT_HANDLE hObject,
|
||||
NCryptKeyGetPropertyEnum property, PBYTE pbOutput,
|
||||
DWORD cbOutput, DWORD* pcbResult, DWORD dwFlags);
|
||||
|
||||
/** @brief common ncrypt handle items */
|
||||
typedef struct
|
||||
{
|
||||
char magic[6];
|
||||
NCryptHandleType type;
|
||||
NCryptGetPropertyFn getPropertyFn;
|
||||
NCryptReleaseFn releaseFn;
|
||||
} NCryptBaseHandle;
|
||||
|
||||
typedef SECURITY_STATUS (*NCryptEnumKeysFn)(NCRYPT_PROV_HANDLE hProvider, LPCWSTR pszScope,
|
||||
NCryptKeyName** ppKeyName, PVOID* ppEnumState,
|
||||
DWORD dwFlags);
|
||||
typedef SECURITY_STATUS (*NCryptOpenKeyFn)(NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE* phKey,
|
||||
LPCWSTR pszKeyName, DWORD dwLegacyKeySpec,
|
||||
DWORD dwFlags);
|
||||
|
||||
/** @brief common ncrypt provider items */
|
||||
typedef struct
|
||||
{
|
||||
NCryptBaseHandle baseHandle;
|
||||
|
||||
NCryptEnumKeysFn enumKeysFn;
|
||||
NCryptOpenKeyFn openKeyFn;
|
||||
} NCryptBaseProvider;
|
||||
|
||||
SECURITY_STATUS checkNCryptHandle(NCRYPT_HANDLE handle, NCryptHandleType matchType);
|
||||
|
||||
SECURITY_STATUS winpr_NCryptDefault_dtor(NCRYPT_HANDLE handle);
|
||||
|
||||
void* ncrypt_new_handle(NCryptHandleType kind, size_t len, NCryptGetPropertyFn getProp,
|
||||
NCryptReleaseFn dtor);
|
||||
|
||||
#if defined(WITH_PKCS11)
|
||||
SECURITY_STATUS NCryptOpenP11StorageProviderEx(NCRYPT_PROV_HANDLE* phProvider,
|
||||
LPCWSTR pszProviderName, DWORD dwFlags,
|
||||
LPCSTR* modulePaths);
|
||||
|
||||
const char* NCryptGetModulePath(NCRYPT_PROV_HANDLE phProvider);
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_LIBWINPR_NCRYPT_NCRYPT_H_ */
|
||||
1354
third_party/FreeRDP/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c
vendored
Normal file
1354
third_party/FreeRDP/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
third_party/FreeRDP/winpr/libwinpr/ncrypt/pkcs11-headers/.clang-format
vendored
Normal file
1
third_party/FreeRDP/winpr/libwinpr/ncrypt/pkcs11-headers/.clang-format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
DisableFormat: true
|
||||
2418
third_party/FreeRDP/winpr/libwinpr/ncrypt/pkcs11-headers/pkcs11.h
vendored
Normal file
2418
third_party/FreeRDP/winpr/libwinpr/ncrypt/pkcs11-headers/pkcs11.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
26
third_party/FreeRDP/winpr/libwinpr/ncrypt/test/CMakeLists.txt
vendored
Normal file
26
third_party/FreeRDP/winpr/libwinpr/ncrypt/test/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
set(MODULE_NAME "TestNCrypt")
|
||||
set(MODULE_PREFIX "TEST_NCRYPT")
|
||||
|
||||
disable_warnings_for_directory(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS TestNCryptSmartcard.c TestNCryptProviders.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} ${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(test ${${MODULE_PREFIX}_TESTS})
|
||||
get_filename_component(TestName ${test} NAME_WE)
|
||||
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
|
||||
endforeach()
|
||||
|
||||
target_link_libraries(${MODULE_NAME} winpr ${OPENSSL_LIBRARIES})
|
||||
if(WIN32)
|
||||
target_link_libraries(${MODULE_NAME} ncrypt)
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
|
||||
51
third_party/FreeRDP/winpr/libwinpr/ncrypt/test/TestNCryptProviders.c
vendored
Normal file
51
third_party/FreeRDP/winpr/libwinpr/ncrypt/test/TestNCryptProviders.c
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Test for NCrypt library
|
||||
*
|
||||
* Copyright 2021 David Fort <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <winpr/error.h>
|
||||
#include <winpr/ncrypt.h>
|
||||
#include <winpr/string.h>
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#define TAG "testNCrypt"
|
||||
|
||||
int TestNCryptProviders(int argc, char* argv[])
|
||||
{
|
||||
SECURITY_STATUS status = 0;
|
||||
DWORD nproviders = 0;
|
||||
NCryptProviderName* providers = nullptr;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
status = NCryptEnumStorageProviders(&nproviders, &providers, NCRYPT_SILENT_FLAG);
|
||||
if (status != ERROR_SUCCESS)
|
||||
return -1;
|
||||
|
||||
for (DWORD i = 0; i < nproviders; i++)
|
||||
{
|
||||
const NCryptProviderName* provider = &providers[i];
|
||||
char providerNameStr[256] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
(void)ConvertWCharToUtf8(provider->pszName, providerNameStr, ARRAYSIZE(providerNameStr));
|
||||
printf("%d: %s\n", i, providerNameStr);
|
||||
}
|
||||
|
||||
NCryptFreeBuffer(providers);
|
||||
return 0;
|
||||
}
|
||||
164
third_party/FreeRDP/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c
vendored
Normal file
164
third_party/FreeRDP/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Test for NCrypt library
|
||||
*
|
||||
* Copyright 2021 David Fort <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <winpr/error.h>
|
||||
#include <winpr/ncrypt.h>
|
||||
#include <winpr/string.h>
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#define TAG "testNCrypt"
|
||||
|
||||
static void crypto_print_name(const BYTE* b, DWORD sz)
|
||||
{
|
||||
if (sz > INT32_MAX)
|
||||
return;
|
||||
BIO* bio = BIO_new_mem_buf(b, (int)sz);
|
||||
if (!bio)
|
||||
return;
|
||||
|
||||
X509* x509 = d2i_X509_bio(bio, nullptr);
|
||||
if (!x509)
|
||||
goto bio_release;
|
||||
|
||||
X509_NAME* name = X509_get_subject_name(x509);
|
||||
if (!name)
|
||||
goto x509_release;
|
||||
|
||||
char* ret = calloc(1024, sizeof(char));
|
||||
if (!ret)
|
||||
goto bio_release;
|
||||
|
||||
char* ret2 = X509_NAME_oneline(name, ret, 1024);
|
||||
|
||||
printf("\t%s\n", ret2);
|
||||
free(ret);
|
||||
|
||||
x509_release:
|
||||
X509_free(x509);
|
||||
bio_release:
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
int TestNCryptSmartcard(int argc, char* argv[])
|
||||
{
|
||||
int rc = -1;
|
||||
DWORD providerCount = 0;
|
||||
NCryptProviderName* names = nullptr;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
SECURITY_STATUS status = NCryptEnumStorageProviders(&providerCount, &names, NCRYPT_SILENT_FLAG);
|
||||
if (status != ERROR_SUCCESS)
|
||||
return -1;
|
||||
|
||||
for (size_t j = 0; j < providerCount; j++)
|
||||
{
|
||||
const NCryptProviderName* name = &names[j];
|
||||
NCRYPT_PROV_HANDLE provider = 0;
|
||||
char providerNameStr[256] = WINPR_C_ARRAY_INIT;
|
||||
PVOID enumState = nullptr;
|
||||
size_t i = 0;
|
||||
NCryptKeyName* keyName = nullptr;
|
||||
|
||||
if (ConvertWCharToUtf8(name->pszName, providerNameStr, ARRAYSIZE(providerNameStr)) < 0)
|
||||
continue;
|
||||
printf("provider %" PRIuz ": %s\n", j, providerNameStr);
|
||||
|
||||
status = NCryptOpenStorageProvider(&provider, name->pszName, 0);
|
||||
if (status != ERROR_SUCCESS)
|
||||
continue;
|
||||
|
||||
while ((status = NCryptEnumKeys(provider, nullptr, &keyName, &enumState,
|
||||
NCRYPT_SILENT_FLAG)) == ERROR_SUCCESS)
|
||||
{
|
||||
NCRYPT_KEY_HANDLE phKey = 0;
|
||||
DWORD dwFlags = 0;
|
||||
DWORD cbOutput = 0;
|
||||
char keyNameStr[256] = WINPR_C_ARRAY_INIT;
|
||||
WCHAR reader[1024] = WINPR_C_ARRAY_INIT;
|
||||
PBYTE certBytes = nullptr;
|
||||
|
||||
if (ConvertWCharToUtf8(keyName->pszName, keyNameStr, ARRAYSIZE(keyNameStr)) < 0)
|
||||
continue;
|
||||
|
||||
printf("\tkey %" PRIuz ": %s\n", i, keyNameStr);
|
||||
status = NCryptOpenKey(provider, &phKey, keyName->pszName, keyName->dwLegacyKeySpec,
|
||||
dwFlags);
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to open key %s", keyNameStr);
|
||||
continue;
|
||||
}
|
||||
|
||||
status = NCryptGetProperty(phKey, NCRYPT_READER_PROPERTY, (PBYTE)reader, sizeof(reader),
|
||||
&cbOutput, dwFlags);
|
||||
if (status == ERROR_SUCCESS)
|
||||
{
|
||||
char readerStr[1024] = WINPR_C_ARRAY_INIT;
|
||||
|
||||
(void)ConvertWCharNToUtf8(reader, cbOutput, readerStr, ARRAYSIZE(readerStr));
|
||||
printf("\treader: %s\n", readerStr);
|
||||
}
|
||||
|
||||
cbOutput = 0;
|
||||
status = NCryptGetProperty(phKey, NCRYPT_CERTIFICATE_PROPERTY, nullptr, 0, &cbOutput,
|
||||
dwFlags);
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to retrieve certificate len for key '%s'", keyNameStr);
|
||||
goto endofloop;
|
||||
}
|
||||
|
||||
certBytes = calloc(1, cbOutput);
|
||||
status = NCryptGetProperty(phKey, NCRYPT_CERTIFICATE_PROPERTY, certBytes, cbOutput,
|
||||
&cbOutput, dwFlags);
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to retrieve certificate for key %s", keyNameStr);
|
||||
goto endofloop;
|
||||
}
|
||||
|
||||
crypto_print_name(certBytes, cbOutput);
|
||||
free(certBytes);
|
||||
|
||||
endofloop:
|
||||
NCryptFreeBuffer(keyName);
|
||||
NCryptFreeObject((NCRYPT_HANDLE)phKey);
|
||||
i++;
|
||||
}
|
||||
|
||||
NCryptFreeBuffer(enumState);
|
||||
NCryptFreeObject((NCRYPT_HANDLE)provider);
|
||||
|
||||
if (status != NTE_NO_MORE_ITEMS)
|
||||
{
|
||||
(void)fprintf(stderr, "NCryptEnumKeys returned %s [0x%08" PRIx32 "]\n",
|
||||
Win32ErrorCode2Tag(status), status);
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
NCryptFreeBuffer(names);
|
||||
return rc;
|
||||
}
|
||||
Reference in New Issue
Block a user