Based on the answer given here, I wrote an allocator to securely zero memory.
#include <string>
#include <windows.h>
namespace secure
{
template <class T> class allocator : public std::allocator<T>
{
public:
template<class U> struct rebind { typedef allocator<U> other; };
allocator() throw() {}
allocator(const allocator &) throw() {}
template <class U> allocator(const allocator<U>&) throw() {}
void deallocate(pointer p, size_type num)
{
SecureZeroMemory((void *)p, num);
std::allocator<T>::deallocate(p, num);
}
};
typedef std::basic_string<char, std::char_traits<char>, allocator<char> > string;
}
int main()
{
{
secure::string bar("bar");
secure::string longbar("baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar");
}
}
However, it turns out, depending on how std::string
is implemented, it is possible that the allocator isn't even invoked for small values. In my code, for example, the deallocate
doesn't even get called for the string bar
(on Visual Studio).
The answer, then, is that we cannot use std::string to store sensitive data. Of course, we have the option to write a new class that handles the use case, but I was specifically interested in using std::string
as defined.
Thanks everyone for your help!
char *buf, size_t len
:) – Ordwayclass SecureString
. It's a good idea to copy the interface ofstd::string
so it's a drop-in replacement. – Chrysolite