Short answer: Asio buffers don't own their memory, so they should not be responsible for disposing of it either.
First off, you should not use
std::memset(p, 0, n * sizeof(T));
Use a function like SecureZeroMemory
instead: How-to ensure that compiler optimizations don't introduce a security risk?
I realize you had volatile
there for this reason, but it might not always be honoured like you expect:
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
Background reading:
On to ASIO
Make sure you fully realize that Boost Asio buffers have no ownership semantics. They only ever reference data owned by another object.
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
is a concept. There are a gazillion ways to construct it on top of (your own) objects:
documentation
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 classes mutable_buffer
and const_buffer
, respectively
So, let's assume you have your buffer type
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;
};
Then you can simply pass it where you want to use it:
SecureBuffer secret; // member variable (lifetime exceeds async operation)
// ... set data
boost::asio::async_write(sock_,
boost::asio::buffer(secret.data(), secret.size()),
/*...*/
);