aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-10-26 10:21:06 +0100
committerJonathan Roelofs <jonathan@codesourcery.com>2017-12-16 15:40:33 -0700
commit7193b89fe567327bb78f4c61c887b2e2fad2ed51 (patch)
treec3064389fdc8d4a07b78882bc77cf475cb4e8d9d /src/common
parentMerge pull request #2881 (diff)
downloadmonero-7193b89fe567327bb78f4c61c887b2e2fad2ed51.tar.xz
Scrub keys from memory just before scope end.
Partially implements #74. Securely erases keys from memory after they are no longer needed. Might have a performance impact, which I haven't measured (perf measurements aren't generally reliable on laptops). Thanks to @stoffu for the suggestion to specialize the pod_to_hex/hex_to_pod functions. Using overloads + SFINAE instead generalizes it so other types can be marked as scrubbed without adding more boilerplate.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/memwipe.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/common/memwipe.h b/src/common/memwipe.h
index e9a3fba7b..c3b4ce8ab 100644
--- a/src/common/memwipe.h
+++ b/src/common/memwipe.h
@@ -31,6 +31,8 @@
#pragma once
#ifdef __cplusplus
+#include <array>
+
extern "C" {
#endif
@@ -39,3 +41,44 @@ void *memwipe(void *src, size_t n);
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+namespace tools {
+
+ /// Scrubs data in the contained type upon destruction.
+ ///
+ /// Primarily useful for making sure that private keys don't stick around in
+ /// memory after the objects that held them have gone out of scope.
+ template <class T>
+ struct scrubbed : public T {
+ using type = T;
+
+ ~scrubbed() {
+ scrub();
+ }
+
+ /// Destroy the contents of the contained type.
+ void scrub() {
+ static_assert(std::is_pod<T>::value,
+ "T cannot be auto-scrubbed. T must be POD.");
+ static_assert(std::is_trivially_destructible<T>::value,
+ "T cannot be auto-scrubbed. T must be trivially destructable.");
+ memwipe(this, sizeof(T));
+ }
+ };
+
+ template <class T, size_t N>
+ using scrubbed_arr = scrubbed<std::array<T, N>>;
+} // namespace tools
+
+// Partial specialization for std::is_pod<tools::scrubbed<T>> so that it can
+// pretend to be the containted type in those contexts.
+namespace std
+{
+ template<class t_scrubbee>
+ struct is_pod<tools::scrubbed<t_scrubbee>> {
+ static const bool value = is_pod<t_scrubbee>::value;
+ };
+}
+
+#endif // __cplusplus