
We have a few places where we read secrets into memory, and then do some computation on them. In these cases we should always make sure we zero the allocations before they are free'd. The SecureString wrapper provides this abstraction by wrapping a ByteBuffer and calling explicit_bzero on destruction of the object.
38 lines
1 KiB
C++
38 lines
1 KiB
C++
/*
|
|
* Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/ByteBuffer.h>
|
|
#include <AK/Noncopyable.h>
|
|
#include <AK/StringView.h>
|
|
|
|
namespace Core {
|
|
|
|
class SecretString {
|
|
AK_MAKE_NONCOPYABLE(SecretString);
|
|
|
|
public:
|
|
[[nodiscard]] static SecretString take_ownership(char*&, size_t);
|
|
[[nodiscard]] static SecretString take_ownership(ByteBuffer&&);
|
|
|
|
[[nodiscard]] bool is_empty() const { return m_secure_buffer.is_empty(); }
|
|
[[nodiscard]] size_t length() const { return m_secure_buffer.size(); }
|
|
[[nodiscard]] char const* characters() const { return reinterpret_cast<const char*>(m_secure_buffer.data()); }
|
|
[[nodiscard]] StringView view() const { return { characters(), length() }; }
|
|
|
|
SecretString() = default;
|
|
~SecretString();
|
|
SecretString(SecretString&&) = default;
|
|
SecretString& operator=(SecretString&&) = default;
|
|
|
|
private:
|
|
explicit SecretString(ByteBuffer&&);
|
|
|
|
ByteBuffer m_secure_buffer;
|
|
};
|
|
|
|
}
|