From ea37614efe518ff8f363ddf2465301687e04d977 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 7 Jul 2018 00:03:15 +0100 Subject: wallet: wipe seed from memory where appropriate --- contrib/epee/src/hex.cpp | 10 +++- contrib/epee/src/wipeable_string.cpp | 112 ++++++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 5 deletions(-) (limited to 'contrib/epee/src') diff --git a/contrib/epee/src/hex.cpp b/contrib/epee/src/hex.cpp index c143b2dc2..5c8acc8be 100644 --- a/contrib/epee/src/hex.cpp +++ b/contrib/epee/src/hex.cpp @@ -52,17 +52,21 @@ namespace epee } } - std::string to_hex::string(const span src) + template + T to_hex::convert(const span src) { if (std::numeric_limits::max() / 2 < src.size()) throw std::range_error("hex_view::to_string exceeded maximum size"); - std::string out{}; + T out{}; out.resize(src.size() * 2); - buffer_unchecked(std::addressof(out[0]), src); + to_hex::buffer_unchecked((char*)out.data(), src); // can't see the non const version in wipeable_string?? return out; } + std::string to_hex::string(const span src) { return convert(src); } + epee::wipeable_string to_hex::wipeable_string(const span src) { return convert(src); } + void to_hex::buffer(std::ostream& out, const span src) { write_hex(std::ostreambuf_iterator{out}, src); diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp index 6ed4ee8a2..7c9722765 100644 --- a/contrib/epee/src/wipeable_string.cpp +++ b/contrib/epee/src/wipeable_string.cpp @@ -26,11 +26,22 @@ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include #include #include "memwipe.h" #include "misc_log_ex.h" #include "wipeable_string.h" +namespace +{ + int atolower(int c) + { + if (c >= 'A' && c <= 'Z') + c |= 32; + return c; + } +} + namespace epee { @@ -69,6 +80,12 @@ wipeable_string::wipeable_string(const char *s) memcpy(buffer.data(), s, size()); } +wipeable_string::wipeable_string(const char *s, size_t len) +{ + grow(len); + memcpy(buffer.data(), s, len); +} + wipeable_string::~wipeable_string() { wipe(); @@ -109,9 +126,100 @@ void wipeable_string::push_back(char c) buffer.back() = c; } -void wipeable_string::pop_back() +void wipeable_string::operator+=(char c) +{ + push_back(c); +} + +void wipeable_string::append(const char *ptr, size_t len) +{ + const size_t orgsz = size(); + CHECK_AND_ASSERT_THROW_MES(orgsz < std::numeric_limits::max() - len, "Appended data too large"); + grow(orgsz + len); + if (len > 0) + memcpy(data() + orgsz, ptr, len); +} + +void wipeable_string::operator+=(const char *s) +{ + append(s, strlen(s)); +} + +void wipeable_string::operator+=(const epee::wipeable_string &s) +{ + append(s.data(), s.size()); +} + +void wipeable_string::operator+=(const std::string &s) +{ + append(s.c_str(), s.size()); +} + +void wipeable_string::trim() +{ + size_t prefix = 0; + while (prefix < size() && data()[prefix] == ' ') + ++prefix; + if (prefix > 0) + memmove(buffer.data(), buffer.data() + prefix, size() - prefix); + + size_t suffix = 0; + while (suffix < size()-prefix && data()[size() - 1 - prefix - suffix] == ' ') + ++suffix; + + resize(size() - prefix - suffix); +} + +void wipeable_string::split(std::vector &fields) const +{ + fields.clear(); + size_t len = size(); + const char *ptr = data(); + bool space = true; + while (len--) + { + const char c = *ptr++; + if (c != ' ') + { + if (space) + fields.push_back({}); + fields.back().push_back(c); + } + space = c == ' '; + } +} + +boost::optional wipeable_string::parse_hexstr() const +{ + if (size() % 2 != 0) + return boost::none; + boost::optional res = epee::wipeable_string(""); + const size_t len = size(); + const char *d = data(); + res->grow(0, len / 2); + static constexpr const char hex[] = u8"0123456789abcdef"; + for (size_t i = 0; i < len; i += 2) + { + char c = atolower(d[i]); + const char *ptr0 = strchr(hex, c); + if (!ptr0) + return boost::none; + c = atolower(d[i+1]); + const char *ptr1 = strchr(hex, c); + if (!ptr1) + return boost::none; + res->push_back(((ptr0-hex)<<4) | (ptr1-hex)); + } + return res; +} + +char wipeable_string::pop_back() { - resize(size() - 1); + const size_t sz = size(); + CHECK_AND_ASSERT_THROW_MES(sz > 0, "Popping from an empty string"); + const char c = buffer.back(); + resize(sz - 1); + return c; } void wipeable_string::resize(size_t sz) -- cgit v1.2.3