diff options
author | hcpp <hcpp@ydb.tech> | 2023-11-08 12:09:41 +0300 |
---|---|---|
committer | hcpp <hcpp@ydb.tech> | 2023-11-08 12:56:14 +0300 |
commit | a361f5b98b98b44ea510d274f6769164640dd5e1 (patch) | |
tree | c47c80962c6e2e7b06798238752fd3da0191a3f6 /library/cpp/string_utils/secret_string | |
parent | 9478806fde1f4d40bd5a45e7cbe77237dab613e9 (diff) | |
download | ydb-a361f5b98b98b44ea510d274f6769164640dd5e1.tar.gz |
metrics have been added
Diffstat (limited to 'library/cpp/string_utils/secret_string')
-rw-r--r-- | library/cpp/string_utils/secret_string/secret_string.cpp | 68 | ||||
-rw-r--r-- | library/cpp/string_utils/secret_string/secret_string.h | 74 | ||||
-rw-r--r-- | library/cpp/string_utils/secret_string/ya.make | 13 |
3 files changed, 155 insertions, 0 deletions
diff --git a/library/cpp/string_utils/secret_string/secret_string.cpp b/library/cpp/string_utils/secret_string/secret_string.cpp new file mode 100644 index 00000000000..3b68d3cd274 --- /dev/null +++ b/library/cpp/string_utils/secret_string/secret_string.cpp @@ -0,0 +1,68 @@ +#include "secret_string.h" + +#include <util/system/madvise.h> + +namespace NSecretString { + TSecretString::TSecretString(TStringBuf value) { + Init(value); + } + + TSecretString::~TSecretString() { + try { + Clear(); + } catch (...) { + } + } + + TSecretString& TSecretString::operator=(const TSecretString& o) { + if (&o == this) { + return *this; + } + + Init(o.Value_); + + return *this; + } + + /** + * It is not honest "move". Actually it is copy-assignment with cleaning of other instance. + * This way allowes to avoid side effects of string optimizations: + * Copy-On-Write or Short-String-Optimization + */ + TSecretString& TSecretString::operator=(TSecretString&& o) { + if (&o == this) { + return *this; + } + + Init(o.Value_); + o.Clear(); + + return *this; + } + + TSecretString& TSecretString::operator=(const TStringBuf o) { + Init(o); + + return *this; + } + + void TSecretString::Init(TStringBuf value) { + Clear(); + if (value.empty()) { + return; + } + + Value_ = value; + MadviseExcludeFromCoreDump(Value_); + } + + void TSecretString::Clear() { + if (Value_.empty()) { + return; + } + + SecureZero((void*)Value_.data(), Value_.size()); + MadviseIncludeIntoCoreDump(Value_); + Value_.clear(); + } +} diff --git a/library/cpp/string_utils/secret_string/secret_string.h b/library/cpp/string_utils/secret_string/secret_string.h new file mode 100644 index 00000000000..fdb9f6a85ce --- /dev/null +++ b/library/cpp/string_utils/secret_string/secret_string.h @@ -0,0 +1,74 @@ +#pragma once + +#include <library/cpp/string_utils/ztstrbuf/ztstrbuf.h> + +#include <util/generic/string.h> + +namespace NSecretString { + /** + * TSecretString allowes to store some long lived secrets in "secure" storage in memory. + * Common usage: + * 1) read secret value from disk/env/etc + * 2) put it into TSecretString + * 3) destory secret copy from 1) + * + * Useful scenerios for TSecretString: + * - in memory only tasks: using key to create crypto signature; + * - rare network cases: db password on connection or OAuth token in background tasks. + * These cases disclosure the secret + * because of sending it over network with some I/O frameworks. + * Usually such frameworks copy input params to provide network protocol: gRPC, for example. + * + * Supported features: + * 1. Exclude secret from core dump. + * madvise(MADV_DONTDUMP) in ctor excludes full memory page from core dump. + * madvise(MADV_DODUMP) in dtor reverts previous action. + * 2. Zero memory before free. + * + * Code dump looks like this: +(gdb) print s +$1 = (const TSecretString &) @0x7fff23c4c560: { + Value_ = {<TStringBase<TBasicString<char, std::__y1::char_traits<char> >, char, std::__y1::char_traits<char> >> = { + static npos = <optimized out>}, Data_ = 0x107c001d8 <error: Cannot access memory at address 0x107c001d8>}} + */ + + class TSecretString { + public: + TSecretString() = default; + TSecretString(TStringBuf value); + ~TSecretString(); + + TSecretString(const TSecretString& o) + : TSecretString(o.Value()) + { + } + + TSecretString(TSecretString&& o) + : TSecretString(o.Value()) + { + o.Clear(); + } + + TSecretString& operator=(const TSecretString& o); + TSecretString& operator=(TSecretString&& o); + + TSecretString& operator=(const TStringBuf o); + + operator TZtStringBuf() const { + return Value(); + } + + // Provides zero terminated string + TZtStringBuf Value() const { + return TZtStringBuf(Value_); + } + + private: + // TStringBuf breaks Copy-On-Write to provide correct copy-ctor and copy-assignment + void Init(TStringBuf value); + void Clear(); + + private: + TString Value_; + }; +} diff --git a/library/cpp/string_utils/secret_string/ya.make b/library/cpp/string_utils/secret_string/ya.make new file mode 100644 index 00000000000..c1d43f7a1d5 --- /dev/null +++ b/library/cpp/string_utils/secret_string/ya.make @@ -0,0 +1,13 @@ +LIBRARY() + +SRCS( + secret_string.cpp +) + +PEERDIR( + library/cpp/string_utils/ztstrbuf +) + +END() + +RECURSE_FOR_TESTS(ut) |