mirror of
https://github.com/boostorg/uuid.git
synced 2026-01-26 07:02:21 +00:00
operating-system provided entropy as it is more secure and faster for the typical use case of generating one uuid at a time. This is a breaking change for anyone passing a mt19937 into one of the explicit constructors of random_generator, which would be quite rare. Changed the default random provider on Windows to use BCrypt where available, falling back to Wincrypt when necessary or when explicitly requested through a macro. Provide a new random_generator_mt19937 type definition for use cases where a large number of uuids need to be created with high performance. This is equivalent to the previous definition of random_generator. Provide a random generation benchmark test showing the cutoff where the mt19937-based generator will outperform the standard generator based on wall time. Removed template specialization for boost::random::random_device so that any UniformRandomNumberGenerator can be used properly with random_generator. Replaced the seed_rng detail implementation (which had a number of flaws) with a replacement header-only random_provider implementation. Note: entropy generation errors will cause an entropy_error to be thrown from random_generator. The previous implementation ignored errors and silently failed. Added internal support for entropy generation on cloudabi platform leveraging the new random_provider implementation. Added internal support for Universal Windows Platform (UWP) development leveraging the new random_provider implementation. Added internal support for getentropy() on Linux and OpenBSD if certain requirements are met. This fixes #24 This closes #53
116 lines
2.9 KiB
C++
116 lines
2.9 KiB
C++
//
|
|
// Copyright (c) 2017 James E. King III
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENCE_1_0.txt)
|
|
//
|
|
// The contents of this file are compiled into a loadable
|
|
// library that is used for mocking purposes so that the error
|
|
// paths in the random_provider implementations are exercised.
|
|
//
|
|
|
|
#include <boost/config.hpp>
|
|
#include <boost/core/ignore_unused.hpp>
|
|
|
|
#if defined(BOOST_WINDOWS)
|
|
|
|
#include <boost/winapi/basic_types.hpp>
|
|
|
|
// WinAPI is not currently set up well for building mocks, as
|
|
// the definitions of wincrypt APIs all use BOOST_SYMBOL_IMPORT
|
|
// therefore we cannot include it, but we need some of the types
|
|
// so they are defined here...
|
|
namespace boost {
|
|
namespace winapi {
|
|
typedef ULONG_PTR_ HCRYPTPROV_;
|
|
}
|
|
}
|
|
|
|
// wincrypt has to be mocked through a DLL pretending to be
|
|
// the real thing as the official APIs use __declspec(dllimport)
|
|
|
|
#include <deque>
|
|
std::deque<boost::winapi::BOOL_> wincrypt_next_result;
|
|
|
|
BOOST_SYMBOL_EXPORT bool expectations_capable()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
BOOST_SYMBOL_EXPORT bool expectations_met()
|
|
{
|
|
return wincrypt_next_result.empty();
|
|
}
|
|
|
|
BOOST_SYMBOL_EXPORT void expect_next_call_success(bool success)
|
|
{
|
|
wincrypt_next_result.push_back(success ? 1 : 0);
|
|
}
|
|
|
|
BOOST_SYMBOL_EXPORT bool provider_acquires_context()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
BOOST_SYMBOL_EXPORT
|
|
boost::winapi::BOOL_ WINAPI
|
|
CryptAcquireContextW(
|
|
boost::winapi::HCRYPTPROV_ *phProv,
|
|
boost::winapi::LPCWSTR_ szContainer,
|
|
boost::winapi::LPCWSTR_ szProvider,
|
|
boost::winapi::DWORD_ dwProvType,
|
|
boost::winapi::DWORD_ dwFlags)
|
|
{
|
|
boost::ignore_unused(phProv);
|
|
boost::ignore_unused(szContainer);
|
|
boost::ignore_unused(szProvider);
|
|
boost::ignore_unused(dwProvType);
|
|
boost::ignore_unused(dwFlags);
|
|
|
|
boost::winapi::BOOL_ result = wincrypt_next_result.front();
|
|
wincrypt_next_result.pop_front();
|
|
return result;
|
|
}
|
|
|
|
BOOST_SYMBOL_EXPORT
|
|
boost::winapi::BOOL_ WINAPI
|
|
CryptGenRandom(
|
|
boost::winapi::HCRYPTPROV_ hProv,
|
|
boost::winapi::DWORD_ dwLen,
|
|
boost::winapi::BYTE_ *pbBuffer)
|
|
{
|
|
boost::ignore_unused(hProv);
|
|
boost::ignore_unused(dwLen);
|
|
boost::ignore_unused(pbBuffer);
|
|
|
|
boost::winapi::BOOL_ result = wincrypt_next_result.front();
|
|
wincrypt_next_result.pop_front();
|
|
return result;
|
|
}
|
|
|
|
// the implementation ignores the result of close because it
|
|
// happens in a destructor
|
|
BOOST_SYMBOL_EXPORT
|
|
boost::winapi::BOOL_ WINAPI
|
|
CryptReleaseContext(
|
|
boost::winapi::HCRYPTPROV_ hProv,
|
|
#if defined(_MSC_VER) && (_MSC_VER+0) >= 1500 && (_MSC_VER+0) < 1900 && BOOST_USE_NTDDI_VERSION < BOOST_WINAPI_NTDDI_WINXP
|
|
// see winapi crypt.hpp for more details on why these differ...
|
|
boost::winapi::ULONG_PTR_ dwFlags
|
|
#else
|
|
boost::winapi::DWORD_ dwFlags
|
|
#endif
|
|
)
|
|
{
|
|
boost::ignore_unused(hProv);
|
|
boost::ignore_unused(dwFlags);
|
|
return true;
|
|
}
|
|
|
|
} // end extern "C"
|
|
|
|
#endif
|