]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* boost uuid/detail/random_provider_wincrypt implementation |
2 | * | |
3 | * Copyright Jens Maurer 2000 | |
4 | * Copyright 2007 Andy Tompkins. | |
5 | * Copyright Steven Watanabe 2010-2011 | |
6 | * Copyright 2017 James E. King III | |
7 | * | |
8 | * Distributed under the Boost Software License, Version 1.0. (See | |
9 | * accompanying file LICENSE_1_0.txt or copy at | |
92f5a8d4 | 10 | * https://www.boost.org/LICENSE_1_0.txt) |
11fdf7f2 TL |
11 | * |
12 | * $Id$ | |
13 | */ | |
14 | ||
92f5a8d4 TL |
15 | #include <cstddef> |
16 | #include <boost/config.hpp> | |
11fdf7f2 | 17 | #include <boost/core/ignore_unused.hpp> |
92f5a8d4 | 18 | #include <boost/move/core.hpp> |
11fdf7f2 TL |
19 | #include <boost/numeric/conversion/cast.hpp> |
20 | #include <boost/winapi/crypt.hpp> | |
21 | #include <boost/winapi/get_last_error.hpp> | |
22 | #include <boost/throw_exception.hpp> | |
23 | ||
24 | #if defined(BOOST_UUID_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB)) | |
25 | # if defined(_WIN32_WCE) | |
26 | # define BOOST_LIB_NAME "coredll" | |
27 | # else | |
28 | # define BOOST_LIB_NAME "advapi32" | |
29 | # endif | |
92f5a8d4 TL |
30 | # if defined(BOOST_AUTO_LINK_NOMANGLE) |
31 | # include <boost/config/auto_link.hpp> | |
32 | # else | |
33 | # define BOOST_AUTO_LINK_NOMANGLE | |
34 | # include <boost/config/auto_link.hpp> | |
35 | # undef BOOST_AUTO_LINK_NOMANGLE | |
36 | # endif | |
11fdf7f2 TL |
37 | #endif |
38 | ||
39 | namespace boost { | |
40 | namespace uuids { | |
41 | namespace detail { | |
42 | ||
43 | class random_provider_base | |
44 | { | |
92f5a8d4 TL |
45 | BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base) |
46 | ||
47 | public: | |
11fdf7f2 | 48 | random_provider_base() |
92f5a8d4 | 49 | : hProv_(0) |
11fdf7f2 | 50 | { |
92f5a8d4 | 51 | boost::winapi::BOOL_ res = boost::winapi::CryptAcquireContextW( |
11fdf7f2 TL |
52 | &hProv_, |
53 | NULL, | |
54 | NULL, | |
55 | boost::winapi::PROV_RSA_FULL_, | |
92f5a8d4 TL |
56 | boost::winapi::CRYPT_VERIFYCONTEXT_ | boost::winapi::CRYPT_SILENT_); |
57 | if (BOOST_UNLIKELY(!res)) | |
11fdf7f2 TL |
58 | { |
59 | boost::winapi::DWORD_ err = boost::winapi::GetLastError(); | |
60 | BOOST_THROW_EXCEPTION(entropy_error(err, "CryptAcquireContext")); | |
61 | } | |
62 | } | |
63 | ||
92f5a8d4 TL |
64 | random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : hProv_(that.hProv_) |
65 | { | |
66 | that.hProv_ = 0; | |
67 | } | |
68 | ||
69 | random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT | |
70 | { | |
71 | destroy(); | |
72 | hProv_ = that.hProv_; | |
73 | that.hProv_ = 0; | |
74 | return *this; | |
75 | } | |
76 | ||
11fdf7f2 TL |
77 | ~random_provider_base() BOOST_NOEXCEPT |
78 | { | |
92f5a8d4 | 79 | destroy(); |
11fdf7f2 TL |
80 | } |
81 | ||
82 | //! Obtain entropy and place it into a memory location | |
83 | //! \param[in] buf the location to write entropy | |
84 | //! \param[in] siz the number of bytes to acquire | |
92f5a8d4 | 85 | void get_random_bytes(void *buf, std::size_t siz) |
11fdf7f2 | 86 | { |
92f5a8d4 TL |
87 | boost::winapi::BOOL_ res = boost::winapi::CryptGenRandom( |
88 | hProv_, | |
89 | boost::numeric_cast<boost::winapi::DWORD_>(siz), | |
90 | static_cast<boost::winapi::BYTE_ *>(buf)); | |
91 | if (BOOST_UNLIKELY(!res)) | |
11fdf7f2 TL |
92 | { |
93 | boost::winapi::DWORD_ err = boost::winapi::GetLastError(); | |
94 | BOOST_THROW_EXCEPTION(entropy_error(err, "CryptGenRandom")); | |
95 | } | |
96 | } | |
97 | ||
92f5a8d4 TL |
98 | private: |
99 | void destroy() BOOST_NOEXCEPT | |
100 | { | |
101 | if (hProv_) | |
102 | { | |
103 | boost::ignore_unused(boost::winapi::CryptReleaseContext(hProv_, 0)); | |
104 | } | |
105 | } | |
106 | ||
107 | private: | |
11fdf7f2 TL |
108 | boost::winapi::HCRYPTPROV_ hProv_; |
109 | }; | |
110 | ||
111 | } // detail | |
112 | } // uuids | |
113 | } // boost |