Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

View File

@@ -0,0 +1,22 @@
# WinPR: Windows Portable Runtime
# libwinpr-bcrypt cmake build script
#
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.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.
winpr_module_add(bcrypt.c)
if(BUILD_TESTING_INTERNAL OR BUILD_TESTING)
add_subdirectory(test)
endif()

View File

@@ -0,0 +1,7 @@
set(MINWIN_LAYER "0")
set(MINWIN_GROUP "none")
set(MINWIN_MAJOR_VERSION "0")
set(MINWIN_MINOR_VERSION "0")
set(MINWIN_SHORT_NAME "bcrypt")
set(MINWIN_LONG_NAME "Cryptography API: Next Generation (CNG)")
set(MODULE_LIBRARY_NAME "${MINWIN_SHORT_NAME}")

View File

@@ -0,0 +1,154 @@
/**
* WinPR: Windows Portable Runtime
* Cryptography API: Next Generation
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.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/config.h>
#include <winpr/wlog.h>
#ifndef _WIN32
#include <winpr/bcrypt.h>
/**
* Cryptography API: Next Generation:
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa376210/
*/
NTSTATUS BCryptOpenAlgorithmProvider(WINPR_ATTR_UNUSED BCRYPT_ALG_HANDLE* phAlgorithm,
WINPR_ATTR_UNUSED LPCWSTR pszAlgId,
WINPR_ATTR_UNUSED LPCWSTR pszImplementation,
WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptCloseAlgorithmProvider(WINPR_ATTR_UNUSED BCRYPT_ALG_HANDLE hAlgorithm,
WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptGetProperty(WINPR_ATTR_UNUSED BCRYPT_HANDLE hObject,
WINPR_ATTR_UNUSED LPCWSTR pszProperty, WINPR_ATTR_UNUSED PUCHAR pbOutput,
WINPR_ATTR_UNUSED ULONG cbOutput, WINPR_ATTR_UNUSED ULONG* pcbResult,
WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptCreateHash(WINPR_ATTR_UNUSED BCRYPT_ALG_HANDLE hAlgorithm,
WINPR_ATTR_UNUSED BCRYPT_HASH_HANDLE* phHash,
WINPR_ATTR_UNUSED PUCHAR pbHashObject,
WINPR_ATTR_UNUSED ULONG cbHashObject, WINPR_ATTR_UNUSED PUCHAR pbSecret,
WINPR_ATTR_UNUSED ULONG cbSecret, WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptDestroyHash(WINPR_ATTR_UNUSED BCRYPT_HASH_HANDLE hHash)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptHashData(WINPR_ATTR_UNUSED BCRYPT_HASH_HANDLE hHash,
WINPR_ATTR_UNUSED PUCHAR pbInput, WINPR_ATTR_UNUSED ULONG cbInput,
WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptFinishHash(WINPR_ATTR_UNUSED BCRYPT_HASH_HANDLE hHash,
WINPR_ATTR_UNUSED PUCHAR pbOutput, WINPR_ATTR_UNUSED ULONG cbOutput,
WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptGenRandom(WINPR_ATTR_UNUSED BCRYPT_ALG_HANDLE hAlgorithm,
WINPR_ATTR_UNUSED PUCHAR pbBuffer, WINPR_ATTR_UNUSED ULONG cbBuffer,
WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptGenerateSymmetricKey(WINPR_ATTR_UNUSED BCRYPT_ALG_HANDLE hAlgorithm,
WINPR_ATTR_UNUSED BCRYPT_KEY_HANDLE* phKey,
WINPR_ATTR_UNUSED PUCHAR pbKeyObject,
WINPR_ATTR_UNUSED ULONG cbKeyObject,
WINPR_ATTR_UNUSED PUCHAR pbSecret,
WINPR_ATTR_UNUSED ULONG cbSecret,
WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptGenerateKeyPair(WINPR_ATTR_UNUSED BCRYPT_ALG_HANDLE hAlgorithm,
WINPR_ATTR_UNUSED BCRYPT_KEY_HANDLE* phKey,
WINPR_ATTR_UNUSED ULONG dwLength, WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptImportKey(WINPR_ATTR_UNUSED BCRYPT_ALG_HANDLE hAlgorithm,
WINPR_ATTR_UNUSED BCRYPT_KEY_HANDLE hImportKey,
WINPR_ATTR_UNUSED LPCWSTR pszBlobType,
WINPR_ATTR_UNUSED BCRYPT_KEY_HANDLE* phKey,
WINPR_ATTR_UNUSED PUCHAR pbKeyObject, WINPR_ATTR_UNUSED ULONG cbKeyObject,
WINPR_ATTR_UNUSED PUCHAR pbInput, WINPR_ATTR_UNUSED ULONG cbInput,
WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptDestroyKey(WINPR_ATTR_UNUSED BCRYPT_KEY_HANDLE hKey)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptEncrypt(WINPR_ATTR_UNUSED BCRYPT_KEY_HANDLE hKey, WINPR_ATTR_UNUSED PUCHAR pbInput,
WINPR_ATTR_UNUSED ULONG cbInput, WINPR_ATTR_UNUSED VOID* pPaddingInfo,
WINPR_ATTR_UNUSED PUCHAR pbIV, WINPR_ATTR_UNUSED ULONG cbIV,
WINPR_ATTR_UNUSED PUCHAR pbOutput, WINPR_ATTR_UNUSED ULONG cbOutput,
WINPR_ATTR_UNUSED ULONG* pcbResult, WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
NTSTATUS BCryptDecrypt(WINPR_ATTR_UNUSED BCRYPT_KEY_HANDLE hKey, WINPR_ATTR_UNUSED PUCHAR pbInput,
WINPR_ATTR_UNUSED ULONG cbInput, WINPR_ATTR_UNUSED VOID* pPaddingInfo,
WINPR_ATTR_UNUSED PUCHAR pbIV, WINPR_ATTR_UNUSED ULONG cbIV,
WINPR_ATTR_UNUSED PUCHAR pbOutput, WINPR_ATTR_UNUSED ULONG cbOutput,
WINPR_ATTR_UNUSED ULONG* pcbResult, WINPR_ATTR_UNUSED ULONG dwFlags)
{
WLog_ERR("TODO", "TODO: implement");
return 0;
}
#endif /* _WIN32 */

View File

@@ -0,0 +1,21 @@
set(MODULE_NAME "TestBCrypt")
disable_warnings_for_directory(${CMAKE_CURRENT_BINARY_DIR})
set(DRIVER ${MODULE_NAME}.c)
set(TESTS TestBCryptDefine.c)
create_test_sourcelist(SRCS ${DRIVER} ${TESTS})
add_executable(${MODULE_NAME} ${SRCS})
target_link_libraries(${MODULE_NAME} winpr)
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
foreach(test ${TESTS})
get_filename_component(TestName ${test} NAME_WE)
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")

View File

@@ -0,0 +1,129 @@
#include <stdio.h>
#include <winpr/string.h>
#include <winpr/bcrypt.h>
#define STR(x) #x
static BOOL test_wchar_len(void)
{
struct test_case
{
size_t bytelen;
const char* name;
const WCHAR* value;
};
const struct test_case test_cases[] = {
{ sizeof(BCRYPT_RSA_ALGORITHM), STR(BCRYPT_RSA_ALGORITHM), BCRYPT_RSA_ALGORITHM },
{ sizeof(BCRYPT_RSA_SIGN_ALGORITHM), STR(BCRYPT_RSA_SIGN_ALGORITHM),
BCRYPT_RSA_SIGN_ALGORITHM },
{ sizeof(BCRYPT_DH_ALGORITHM), STR(BCRYPT_DH_ALGORITHM), BCRYPT_DH_ALGORITHM },
{ sizeof(BCRYPT_DSA_ALGORITHM), STR(BCRYPT_DSA_ALGORITHM), BCRYPT_DSA_ALGORITHM },
{ sizeof(BCRYPT_RC2_ALGORITHM), STR(BCRYPT_RC2_ALGORITHM), BCRYPT_RC2_ALGORITHM },
{ sizeof(BCRYPT_RC4_ALGORITHM), STR(BCRYPT_RC4_ALGORITHM), BCRYPT_RC4_ALGORITHM },
{ sizeof(BCRYPT_AES_ALGORITHM), STR(BCRYPT_AES_ALGORITHM), BCRYPT_AES_ALGORITHM },
{ sizeof(BCRYPT_DES_ALGORITHM), STR(BCRYPT_DES_ALGORITHM), BCRYPT_DES_ALGORITHM },
{ sizeof(BCRYPT_DESX_ALGORITHM), STR(BCRYPT_DESX_ALGORITHM), BCRYPT_DESX_ALGORITHM },
{ sizeof(BCRYPT_3DES_ALGORITHM), STR(BCRYPT_3DES_ALGORITHM), BCRYPT_3DES_ALGORITHM },
{ sizeof(BCRYPT_3DES_112_ALGORITHM), STR(BCRYPT_3DES_112_ALGORITHM),
BCRYPT_3DES_112_ALGORITHM },
{ sizeof(BCRYPT_MD2_ALGORITHM), STR(BCRYPT_MD2_ALGORITHM), BCRYPT_MD2_ALGORITHM },
{ sizeof(BCRYPT_MD4_ALGORITHM), STR(BCRYPT_MD4_ALGORITHM), BCRYPT_MD4_ALGORITHM },
{ sizeof(BCRYPT_MD5_ALGORITHM), STR(BCRYPT_MD5_ALGORITHM), BCRYPT_MD5_ALGORITHM },
{ sizeof(BCRYPT_SHA1_ALGORITHM), STR(BCRYPT_SHA1_ALGORITHM), BCRYPT_SHA1_ALGORITHM },
{ sizeof(BCRYPT_SHA256_ALGORITHM), STR(BCRYPT_SHA256_ALGORITHM), BCRYPT_SHA256_ALGORITHM },
{ sizeof(BCRYPT_SHA384_ALGORITHM), STR(BCRYPT_SHA384_ALGORITHM), BCRYPT_SHA384_ALGORITHM },
{ sizeof(BCRYPT_SHA512_ALGORITHM), STR(BCRYPT_SHA512_ALGORITHM), BCRYPT_SHA512_ALGORITHM },
{ sizeof(BCRYPT_AES_GMAC_ALGORITHM), STR(BCRYPT_AES_GMAC_ALGORITHM),
BCRYPT_AES_GMAC_ALGORITHM },
{ sizeof(BCRYPT_AES_CMAC_ALGORITHM), STR(BCRYPT_AES_CMAC_ALGORITHM),
BCRYPT_AES_CMAC_ALGORITHM },
{ sizeof(BCRYPT_ECDSA_P256_ALGORITHM), STR(BCRYPT_ECDSA_P256_ALGORITHM),
BCRYPT_ECDSA_P256_ALGORITHM },
{ sizeof(BCRYPT_ECDSA_P384_ALGORITHM), STR(BCRYPT_ECDSA_P384_ALGORITHM),
BCRYPT_ECDSA_P384_ALGORITHM },
{ sizeof(BCRYPT_ECDSA_P521_ALGORITHM), STR(BCRYPT_ECDSA_P521_ALGORITHM),
BCRYPT_ECDSA_P521_ALGORITHM },
{ sizeof(BCRYPT_ECDH_P256_ALGORITHM), STR(BCRYPT_ECDH_P256_ALGORITHM),
BCRYPT_ECDH_P256_ALGORITHM },
{ sizeof(BCRYPT_ECDH_P384_ALGORITHM), STR(BCRYPT_ECDH_P384_ALGORITHM),
BCRYPT_ECDH_P384_ALGORITHM },
{ sizeof(BCRYPT_ECDH_P521_ALGORITHM), STR(BCRYPT_ECDH_P521_ALGORITHM),
BCRYPT_ECDH_P521_ALGORITHM },
{ sizeof(BCRYPT_RNG_ALGORITHM), STR(BCRYPT_RNG_ALGORITHM), BCRYPT_RNG_ALGORITHM },
{ sizeof(BCRYPT_RNG_FIPS186_DSA_ALGORITHM), STR(BCRYPT_RNG_FIPS186_DSA_ALGORITHM),
BCRYPT_RNG_FIPS186_DSA_ALGORITHM },
{ sizeof(BCRYPT_RNG_DUAL_EC_ALGORITHM), STR(BCRYPT_RNG_DUAL_EC_ALGORITHM),
BCRYPT_RNG_DUAL_EC_ALGORITHM },
// The following algorithms are only supported on windows 10 onward.
#if !defined(_WIN32) || _WIN32_WINNT >= 0x0A00
{ sizeof(BCRYPT_ECDSA_ALGORITHM), STR(BCRYPT_ECDSA_ALGORITHM), BCRYPT_ECDSA_ALGORITHM },
{ sizeof(BCRYPT_ECDH_ALGORITHM), STR(BCRYPT_ECDH_ALGORITHM), BCRYPT_ECDH_ALGORITHM },
{ sizeof(BCRYPT_XTS_AES_ALGORITHM), STR(BCRYPT_XTS_AES_ALGORITHM),
BCRYPT_XTS_AES_ALGORITHM },
#endif
{ sizeof(MS_PRIMITIVE_PROVIDER), STR(MS_PRIMITIVE_PROVIDER), MS_PRIMITIVE_PROVIDER },
{ sizeof(MS_PLATFORM_CRYPTO_PROVIDER), STR(MS_PLATFORM_CRYPTO_PROVIDER),
MS_PLATFORM_CRYPTO_PROVIDER },
{ sizeof(BCRYPT_OBJECT_LENGTH), STR(BCRYPT_OBJECT_LENGTH), BCRYPT_OBJECT_LENGTH },
{ sizeof(BCRYPT_ALGORITHM_NAME), STR(BCRYPT_ALGORITHM_NAME), BCRYPT_ALGORITHM_NAME },
{ sizeof(BCRYPT_PROVIDER_HANDLE), STR(BCRYPT_PROVIDER_HANDLE), BCRYPT_PROVIDER_HANDLE },
{ sizeof(BCRYPT_CHAINING_MODE), STR(BCRYPT_CHAINING_MODE), BCRYPT_CHAINING_MODE },
{ sizeof(BCRYPT_BLOCK_LENGTH), STR(BCRYPT_BLOCK_LENGTH), BCRYPT_BLOCK_LENGTH },
{ sizeof(BCRYPT_KEY_LENGTH), STR(BCRYPT_KEY_LENGTH), BCRYPT_KEY_LENGTH },
{ sizeof(BCRYPT_KEY_OBJECT_LENGTH), STR(BCRYPT_KEY_OBJECT_LENGTH),
BCRYPT_KEY_OBJECT_LENGTH },
{ sizeof(BCRYPT_KEY_STRENGTH), STR(BCRYPT_KEY_STRENGTH), BCRYPT_KEY_STRENGTH },
{ sizeof(BCRYPT_KEY_LENGTHS), STR(BCRYPT_KEY_LENGTHS), BCRYPT_KEY_LENGTHS },
{ sizeof(BCRYPT_BLOCK_SIZE_LIST), STR(BCRYPT_BLOCK_SIZE_LIST), BCRYPT_BLOCK_SIZE_LIST },
{ sizeof(BCRYPT_EFFECTIVE_KEY_LENGTH), STR(BCRYPT_EFFECTIVE_KEY_LENGTH),
BCRYPT_EFFECTIVE_KEY_LENGTH },
{ sizeof(BCRYPT_HASH_LENGTH), STR(BCRYPT_HASH_LENGTH), BCRYPT_HASH_LENGTH },
{ sizeof(BCRYPT_HASH_OID_LIST), STR(BCRYPT_HASH_OID_LIST), BCRYPT_HASH_OID_LIST },
{ sizeof(BCRYPT_PADDING_SCHEMES), STR(BCRYPT_PADDING_SCHEMES), BCRYPT_PADDING_SCHEMES },
{ sizeof(BCRYPT_SIGNATURE_LENGTH), STR(BCRYPT_SIGNATURE_LENGTH), BCRYPT_SIGNATURE_LENGTH },
{ sizeof(BCRYPT_HASH_BLOCK_LENGTH), STR(BCRYPT_HASH_BLOCK_LENGTH),
BCRYPT_HASH_BLOCK_LENGTH },
{ sizeof(BCRYPT_AUTH_TAG_LENGTH), STR(BCRYPT_AUTH_TAG_LENGTH), BCRYPT_AUTH_TAG_LENGTH },
{ sizeof(BCRYPT_PRIMITIVE_TYPE), STR(BCRYPT_PRIMITIVE_TYPE), BCRYPT_PRIMITIVE_TYPE },
{ sizeof(BCRYPT_IS_KEYED_HASH), STR(BCRYPT_IS_KEYED_HASH), BCRYPT_IS_KEYED_HASH },
{ sizeof(BCRYPT_KEY_DATA_BLOB), STR(BCRYPT_KEY_DATA_BLOB), BCRYPT_KEY_DATA_BLOB }
};
BOOL rc = TRUE;
for (size_t x = 0; x < ARRAYSIZE(test_cases); x++)
{
const struct test_case* cur = &test_cases[x];
// sizeof(WCHAR) == 2, so all strings must have even byte length
if (cur->bytelen % 2 != 0)
{
(void)fprintf(stderr, "[%s] invalid bytelength %" PRIuz, cur->name, cur->bytelen);
rc = FALSE;
continue;
}
// each string must be '\0' terminated
const size_t len = _wcsnlen(cur->value, cur->bytelen / sizeof(WCHAR));
if (len == cur->bytelen / sizeof(WCHAR))
{
(void)fprintf(stderr, "[%s] missing '\0' termination", cur->name);
rc = FALSE;
continue;
}
}
return rc;
}
int TestBCryptDefine(int argc, char* argv[])
{
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
if (!test_wchar_len())
return -1;
return 0;
}