出于 PA:DSS 的目的,我需要确保 boost::asio::const_buffer(例如在 boost::asio::async_write 中)在超出范围时将被清零。
使用 STL 容器,我可以像这样替换分配器/释放器:
void deallocate(volatile pointer p, size_type n) {
std::memset(p, 0, n * sizeof(T));
::operator delete(p);
}
但是我不知道如何用 boost::asio::const_buffer 实现同样的效果,至少不是以一种仍然让 boost::asio::async_write 来使用它的方式。我也不想重新发明轮子(如果有的话)。
最佳答案
简短回答:Asio 缓冲区不拥有它们的内存,因此它们也不应负责处理它。
首先,你不应该使用
std::memset(p, 0, n * sizeof(T));
使用类似 SecureZeroMemory
的函数相反:How-to ensure that compiler optimizations don't introduce a security risk?
我知道你有 volatile
因为这个原因,但它可能并不总是像你期望的那样受到尊重:
Your
secure_memset
function might not be sufficient. According to http://open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf there are optimizing compilers that will only zero the first byte – Daniel Trebbien Nov 9 '12 at 12:50
背景阅读:
- https://cryptocoding.net/index.php/Coding_rules#Clean_memory_of_secret_data
- http://blog.quarkslab.com/a-glance-at-compiler-internals-keep-my-memset.html
关于 ASIO
确保您完全意识到 Boost Asio 缓冲区没有所有权语义。它们只会引用另一个对象拥有的数据。
More importantly than the question posed, you might want to check that you keep around the buffer data long enough. A common pitfall is to pass a local as a buffer:
std::string response = "OK\r\n\r\n"; asio::async_write(sock_, asio::buffer(response), ...); // OOOPS!!!
This leads to Undefined Behaviour immediately.
IOW const_buffer
是一个概念。有无数种方法可以在(您自己的)对象之上构建它:
A buffer object represents a contiguous region of memory as a 2-tuple consisting of a pointer and size in bytes. A tuple of the form
{void*, size_t}
specifies a mutable (modifiable) region of memory. Similarly, a tuple of the form{const void*, size_t}
specifies a const (non-modifiable) region of memory. These two forms correspond to the classesmutable_buffer
andconst_buffer
, respectively
那么,假设您有缓冲区类型
struct SecureBuffer
{
~SecureBuffer() { shred(); }
size_t size() const { return length_; }
char const* data() const { return data_; }
// ...
private:
void shred(); // uses SecureZeroMemory etc.
std::array<char, 1024> data_ = {0};
size_t length_ = 0u;
};
然后你可以简单地将它传递到你想使用它的地方:
SecureBuffer secret; // member variable (lifetime exceeds async operation)
// ... set data
boost::asio::async_write(sock_,
boost::asio::buffer(secret.data(), secret.size()),
/*...*/
);
关于c++ - boost::asio::const_buffer 的安全释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32558253/