Add a SecureBuffer class
SecureBuffer is like SecureString, but a specialization of
std::vector<uint8_t> that cleans up after itself
Tested: Executed various ipmi commands to see that they still work
Change-Id: Ifd255ef682d6e46d981de6a5a294d12f3666698b
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/include/ipmid/message.hpp b/include/ipmid/message.hpp
index 808d96b..8cb9192 100644
--- a/include/ipmid/message.hpp
+++ b/include/ipmid/message.hpp
@@ -21,6 +21,7 @@
#include <exception>
#include <ipmid/api-types.hpp>
#include <ipmid/message/types.hpp>
+#include <ipmid/types.hpp>
#include <memory>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/asio/connection.hpp>
@@ -115,7 +116,7 @@
Payload(Payload&&) = default;
Payload& operator=(Payload&&) = default;
- explicit Payload(std::vector<uint8_t>&& data) : raw(std::move(data))
+ explicit Payload(SecureBuffer&& data) : raw(std::move(data))
{
}
@@ -480,7 +481,7 @@
// partial bytes in the form of bits
fixed_uint_t<details::bitStreamSize> bitStream;
size_t bitCount = 0;
- std::vector<uint8_t> raw;
+ SecureBuffer raw;
size_t rawIndex = 0;
bool trailingOk = true;
bool unpackCheck = false;
@@ -594,8 +595,8 @@
using ptr = std::shared_ptr<Request>;
- explicit Request(Context::ptr context, std::vector<uint8_t>&& d) :
- payload(std::forward<std::vector<uint8_t>>(d)), ctx(context)
+ explicit Request(Context::ptr context, SecureBuffer&& d) :
+ payload(std::forward<SecureBuffer>(d)), ctx(context)
{
}
diff --git a/include/ipmid/message/pack.hpp b/include/ipmid/message/pack.hpp
index 598e650..efafd3d 100644
--- a/include/ipmid/message/pack.hpp
+++ b/include/ipmid/message/pack.hpp
@@ -250,6 +250,22 @@
}
};
+/** @brief Specialization of PackSingle for SecureBuffer */
+template <>
+struct PackSingle<SecureBuffer>
+{
+ static int op(Payload& p, const SecureBuffer& t)
+ {
+ if (p.bitCount != 0)
+ {
+ return 1;
+ }
+ p.raw.reserve(p.raw.size() + t.size());
+ p.raw.insert(p.raw.end(), t.begin(), t.end());
+ return 0;
+ }
+};
+
/** @brief Specialization of PackSingle for std::string_view */
template <>
struct PackSingle<std::string_view>
diff --git a/include/ipmid/message/unpack.hpp b/include/ipmid/message/unpack.hpp
index d9ccba4..4ac4916 100644
--- a/include/ipmid/message/unpack.hpp
+++ b/include/ipmid/message/unpack.hpp
@@ -324,6 +324,20 @@
}
};
+/** @brief Specialization of UnpackSingle for SecureBuffer */
+template <>
+struct UnpackSingle<SecureBuffer>
+{
+ static int op(Payload& p, SecureBuffer& t)
+ {
+ // copy out the remainder of the message
+ t.reserve(p.raw.size() - p.rawIndex);
+ t.insert(t.begin(), p.raw.begin() + p.rawIndex, p.raw.end());
+ p.rawIndex = p.raw.size();
+ return 0;
+ }
+};
+
/** @brief Specialization of UnpackSingle for Payload */
template <>
struct UnpackSingle<Payload>
diff --git a/include/ipmid/types.hpp b/include/ipmid/types.hpp
index 1705335..9c59ea0 100644
--- a/include/ipmid/types.hpp
+++ b/include/ipmid/types.hpp
@@ -259,13 +259,21 @@
using SecureString =
std::basic_string<char, std::char_traits<char>, SecureAllocator<char>>;
+using SecureBuffer = std::vector<uint8_t, SecureAllocator<uint8_t>>;
+
} // namespace ipmi
+
namespace std
{
-
template <>
inline ipmi::SecureString::~SecureString()
{
OPENSSL_cleanse(&((*this)[0]), this->size());
}
+
+template <>
+inline ipmi::SecureBuffer::~SecureBuffer()
+{
+ OPENSSL_cleanse(&((*this)[0]), this->size());
+}
} // namespace std