libkeepass 0.2.0
KeePass key database importer/exporter library
Loading...
Searching...
No Matches
secure.hh
Go to the documentation of this file.
1/*
2 * libkeepass - KeePass key database importer/exporter
3 * Copyright (C) 2014 Christian Kindahl
4 * Copyright (C) 2024 Dominik Krümpelmann
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
26#pragma once
27#include <array>
28#include <cstddef>
29#include <cstdint>
30#include <cstring>
31#include <iosfwd>
32#include <string>
33#include <vector>
34
35#include "libkeepass/export.hh"
36
37namespace keepass {
38
40
47LIBKEEPASS_API void secure_zero(void* data, std::size_t size) noexcept;
48
50
60LIBKEEPASS_API void* secure_alloc(std::size_t size) noexcept;
61
63
67LIBKEEPASS_API void secure_free(void* data, std::size_t size) noexcept;
68
79template <std::size_t N> class SecureBuffer {
80public:
82 SecureBuffer() = default;
83
85 SecureBuffer(const std::array<uint8_t, N>& other) { std::memcpy(data_.data(), other.data(), N); }
86
88 ~SecureBuffer() { secure_zero(data_.data(), data_.size()); }
89
91 SecureBuffer(const SecureBuffer&) = delete;
92
95
97 SecureBuffer(SecureBuffer&& other) noexcept {
98 std::memcpy(data_.data(), other.data_.data(), N);
99 other.Wipe();
100 }
101
105 if (this != &other) {
106 std::memcpy(data_.data(), other.data_.data(), N);
107 other.Wipe();
108 }
109 return *this;
110 }
111
113 uint8_t* data() noexcept { return data_.data(); }
114
116 const uint8_t* data() const noexcept { return data_.data(); }
117
119 std::size_t size() const noexcept { return N; }
120
122 uint8_t* begin() noexcept { return data_.data(); }
123
125 uint8_t* end() noexcept { return data_.data() + N; }
126
128 const uint8_t* begin() const noexcept { return data_.data(); }
129
131 const uint8_t* end() const noexcept { return data_.data() + N; }
132
134 uint8_t& operator[](std::size_t index) noexcept { return data_[index]; }
135
137 const uint8_t& operator[](std::size_t index) const noexcept { return data_[index]; }
138
140 void fill(uint8_t value) noexcept { data_.fill(value); }
141
144 SecureBuffer copy;
145 std::memcpy(copy.data_.data(), data_.data(), N);
146 return copy;
147 }
148
149private:
150 void Wipe() noexcept { secure_zero(data_.data(), data_.size()); }
151
152 std::array<uint8_t, N> data_ = {{0}};
153};
154
165public:
167 SecureBytes() = default;
168
170
174 SecureBytes(const uint8_t* data, std::size_t size);
175
177 explicit SecureBytes(const std::vector<uint8_t>& data);
178
181
183 SecureBytes(const SecureBytes&) = delete;
184
187
189 SecureBytes(SecureBytes&& other) noexcept;
190
194
196 SecureBytes& operator=(const std::vector<uint8_t>& data);
197
199 uint8_t* data() noexcept { return data_; }
200
202 const uint8_t* data() const noexcept { return data_; }
203
205 std::size_t size() const noexcept { return size_; }
206
208 bool empty() const noexcept { return size_ == 0; }
209
211 uint8_t* begin() noexcept { return data_; }
212
214 uint8_t* end() noexcept { return data_ + size_; }
215
217 const uint8_t* begin() const noexcept { return data_; }
218
220 const uint8_t* end() const noexcept { return data_ + size_; }
221
223 uint8_t& operator[](std::size_t index) noexcept { return data_[index]; }
224
226 const uint8_t& operator[](std::size_t index) const noexcept { return data_[index]; }
227
229 void Assign(const uint8_t* data, std::size_t size);
230
232 void Assign(const std::vector<uint8_t>& data);
233
235 void Clear() noexcept;
236
238 SecureBytes Clone() const;
239
241 bool operator==(const SecureBytes& other) const;
242
244 bool operator!=(const SecureBytes& other) const { return !(*this == other); }
245
246private:
247 uint8_t* data_ = nullptr;
248 std::size_t size_ = 0;
249};
250
263public:
266
268 secure_string(const char* str);
269
271 explicit secure_string(const std::string& str);
272
275
277 secure_string(secure_string&& other) noexcept;
278
281
284
286 secure_string& operator=(const char* str) {
287 assign(str);
288 return *this;
289 }
290
292 secure_string& operator=(const std::string& str) {
293 assign(str);
294 return *this;
295 }
296
299
301 const char* data() const noexcept { return data_; }
302
304 char* data() noexcept { return data_; }
305
307 char* begin() noexcept { return data_; }
308
310 const char* begin() const noexcept { return data_; }
311
313 char* end() noexcept { return data_ + size_; }
314
316 const char* end() const noexcept { return data_ + size_; }
317
319 std::size_t size() const noexcept { return size_; }
320
322 std::size_t length() const noexcept { return size_; }
323
325 bool empty() const noexcept { return size_ == 0; }
326
328 const char* c_str() const noexcept { return data_; }
329
331 std::string str() const;
332
334 void clear();
335
337 void assign(const char* str);
338
340 void assign(const std::string& str);
341
343 void assign(const char* data, std::size_t size);
344
345private:
346 void Allocate(const char* data, std::size_t size);
347 void Release() noexcept;
348
349 char* data_ = nullptr;
350 std::size_t size_ = 0;
351};
352
354LIBKEEPASS_API bool operator==(const secure_string& lhs, const secure_string& rhs);
355
357LIBKEEPASS_API bool operator!=(const secure_string& lhs, const secure_string& rhs);
358
360LIBKEEPASS_API bool operator==(const secure_string& lhs, const std::string& rhs);
361
363LIBKEEPASS_API bool operator==(const std::string& lhs, const secure_string& rhs);
364
366LIBKEEPASS_API bool operator!=(const secure_string& lhs, const std::string& rhs);
367
369LIBKEEPASS_API bool operator!=(const std::string& lhs, const secure_string& rhs);
370
372LIBKEEPASS_API bool operator==(const secure_string& lhs, const char* rhs);
373
375LIBKEEPASS_API bool operator==(const char* lhs, const secure_string& rhs);
376
378LIBKEEPASS_API bool operator!=(const secure_string& lhs, const char* rhs);
379
381LIBKEEPASS_API bool operator!=(const char* lhs, const secure_string& rhs);
382
384LIBKEEPASS_API std::ostream& operator<<(std::ostream& os, const secure_string& str);
385
386} // namespace keepass
Fixed-size byte buffer that is zeroized on destruction.
Definition secure.hh:79
std::size_t size() const noexcept
Returns the size of the buffer in bytes.
Definition secure.hh:119
uint8_t & operator[](std::size_t index) noexcept
Returns the byte at the given index.
Definition secure.hh:134
uint8_t * data() noexcept
Returns a pointer to the raw bytes.
Definition secure.hh:113
SecureBuffer(const std::array< uint8_t, N > &other)
Constructs a buffer by copying the given fixed-size byte array.
Definition secure.hh:85
SecureBuffer(const SecureBuffer &)=delete
No implicit copies of key material.
~SecureBuffer()
Zeroizes the stored bytes.
Definition secure.hh:88
SecureBuffer Clone() const
Returns an explicit deep copy of the buffer.
Definition secure.hh:143
uint8_t * begin() noexcept
Returns an iterator to the first byte.
Definition secure.hh:122
SecureBuffer & operator=(SecureBuffer &&other) noexcept
Definition secure.hh:104
const uint8_t * end() const noexcept
Returns a const iterator past the last byte.
Definition secure.hh:131
const uint8_t * data() const noexcept
Returns a const pointer to the raw bytes.
Definition secure.hh:116
void fill(uint8_t value) noexcept
Fills the buffer with the given byte value.
Definition secure.hh:140
SecureBuffer(SecureBuffer &&other) noexcept
Move-constructs by copying the bytes and wiping the source.
Definition secure.hh:97
uint8_t * end() noexcept
Returns an iterator past the last byte.
Definition secure.hh:125
SecureBuffer()=default
Default-constructs a zero-filled buffer.
SecureBuffer & operator=(const SecureBuffer &)=delete
No implicit copies of key material.
const uint8_t * begin() const noexcept
Returns a const iterator to the first byte.
Definition secure.hh:128
const uint8_t & operator[](std::size_t index) const noexcept
Returns the byte at the given index.
Definition secure.hh:137
Dynamic byte buffer that is zeroized in best-effort locked memory.
Definition secure.hh:164
SecureBytes & operator=(const SecureBytes &)=delete
No implicit copies of key material.
std::size_t size() const noexcept
Returns the size of the buffer in bytes.
Definition secure.hh:205
bool empty() const noexcept
Returns whether the buffer is empty.
Definition secure.hh:208
const uint8_t & operator[](std::size_t index) const noexcept
Returns the byte at the given index.
Definition secure.hh:226
void Clear() noexcept
Erases and releases the stored bytes.
uint8_t * begin() noexcept
Returns an iterator to the first byte.
Definition secure.hh:211
SecureBytes(const std::vector< uint8_t > &data)
Constructs a buffer by copying the given byte vector.
uint8_t & operator[](std::size_t index) noexcept
Returns the byte at the given index.
Definition secure.hh:223
SecureBytes()=default
Default-constructs an empty buffer.
~SecureBytes()
Zeroizes and releases the stored bytes.
void Assign(const std::vector< uint8_t > &data)
Replaces the content with a copy of the given byte vector.
void Assign(const uint8_t *data, std::size_t size)
Replaces the content with a copy of the given bytes.
SecureBytes(const SecureBytes &)=delete
No implicit copies of key material.
SecureBytes & operator=(const std::vector< uint8_t > &data)
Replaces the content with a copy of the given byte vector.
SecureBytes(const uint8_t *data, std::size_t size)
Constructs a buffer by copying the given bytes.
const uint8_t * end() const noexcept
Returns a const iterator past the last byte.
Definition secure.hh:220
uint8_t * data() noexcept
Returns a pointer to the raw bytes.
Definition secure.hh:199
const uint8_t * data() const noexcept
Returns a const pointer to the raw bytes.
Definition secure.hh:202
SecureBytes & operator=(SecureBytes &&other) noexcept
const uint8_t * begin() const noexcept
Returns a const iterator to the first byte.
Definition secure.hh:217
uint8_t * end() noexcept
Returns an iterator past the last byte.
Definition secure.hh:214
SecureBytes(SecureBytes &&other) noexcept
Move-constructs by transferring the bytes and wiping the source.
String that is stored in wiped and best-effort locked memory.
Definition secure.hh:262
char * data() noexcept
Returns a pointer to the character data for in-place modification.
Definition secure.hh:304
secure_string(const char *str)
Constructs a string from a NUL-terminated C string.
std::size_t length() const noexcept
Returns the number of characters.
Definition secure.hh:322
void assign(const char *data, std::size_t size)
Replaces the value with a byte range of explicitly known length.
~secure_string()
Zeroizes and releases the stored memory.
const char * data() const noexcept
Returns a pointer to the (NUL-terminated) character data.
Definition secure.hh:301
secure_string & operator=(secure_string &&other) noexcept
Move-assigns, wiping the previous content and the moved-from string.
const char * begin() const noexcept
Returns an iterator to the first character.
Definition secure.hh:310
void clear()
Erases the content, wiping the memory.
const char * c_str() const noexcept
Returns a NUL-terminated pointer to the character data.
Definition secure.hh:328
std::size_t size() const noexcept
Returns the number of characters (excluding the trailing NUL).
Definition secure.hh:319
std::string str() const
Returns an explicit std::string copy of the value.
secure_string & operator=(const secure_string &other)
Copy-assigns by allocating a fresh wiped buffer.
bool empty() const noexcept
Returns whether the string is empty.
Definition secure.hh:325
secure_string(const std::string &str)
Constructs a string from a std::string.
secure_string(const secure_string &other)
Copy-constructs by allocating a fresh wiped buffer.
secure_string & operator=(const char *str)
Assigns from a NUL-terminated C string.
Definition secure.hh:286
void assign(const char *str)
Replaces the value with a NUL-terminated C string.
char * end() noexcept
Returns an iterator past the last character.
Definition secure.hh:313
secure_string()
Constructs an empty string.
void assign(const std::string &str)
Replaces the value with a std::string.
secure_string(secure_string &&other) noexcept
Move-constructs, wiping the moved-from string.
const char * end() const noexcept
Returns an iterator past the last character.
Definition secure.hh:316
secure_string & operator=(const std::string &str)
Assigns from a std::string.
Definition secure.hh:292
char * begin() noexcept
Returns an iterator to the first character.
Definition secure.hh:307
Visibility/export macro for the shared library.
#define LIBKEEPASS_API
Marks a class, function or variable as part of the public ABI.
Definition export.hh:43
LIBKEEPASS_API void secure_zero(void *data, std::size_t size) noexcept
Securely erases a memory region by overwriting it with zero bytes.
LIBKEEPASS_API void secure_free(void *data, std::size_t size) noexcept
Erases and releases memory obtained from secure_alloc().
LIBKEEPASS_API void * secure_alloc(std::size_t size) noexcept
Allocates a memory region that is best-effort locked in RAM.