2
0
mirror of https://github.com/boostorg/uuid.git synced 2026-01-26 07:02:21 +00:00
Files
uuid/test/mock_random.cpp
James E. King III a8a1ec3d82 Changed the default random_generator implementation to use
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
2017-12-18 09:56:02 -05:00

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