libkeepass 0.2.0
KeePass key database importer/exporter library
Loading...
Searching...
No Matches
database.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
25#pragma once
26#include <array>
27#include <cstring>
28#include <memory>
29#include <string>
30#include <vector>
31
32#include "group.hh"
33#include "libkeepass/export.hh"
34#include "libkeepass/secure.hh"
35
36namespace keepass {
37
38class Metadata;
39class Visitor;
40
42enum class CsvFormat { kCsv, kCsvWithPasswords, kCsvWithCustomFields, kCsvKeePass2 };
43
46 std::shared_ptr<Entry> entry;
47 std::string group_path;
48};
49
52 std::vector<EntryDelta> added;
53 std::vector<EntryDelta> modified;
55 std::vector<std::array<uint8_t, 16>> deleted;
56 std::vector<std::string> deleted_paths;
57
59 bool empty() const { return added.empty() && modified.empty() && deleted.empty(); }
60
62 std::string ToJson() const;
63};
64
75public:
77 enum class Cipher { kAes, kTwofish, kChaCha20 };
78
80 enum class Kdf { kAes, kArgon2d, kArgon2id };
81
86 static constexpr uint64_t kMaxTransformRounds = 1U << 28;
87
92 static constexpr uint64_t kMaxArgon2MemoryKiB = 1U << 20; // 1 GiB
93 static constexpr uint64_t kMaxArgon2Iterations = 1U << 20;
94
95private:
96 std::shared_ptr<Group> root_;
97 Cipher cipher_ = Cipher::kAes;
98 Kdf kdf_ = Kdf::kAes;
99 SecureBytes master_seed_;
100 std::array<uint8_t, 16> init_vector_ = {{0}};
101 SecureBuffer<32> transform_seed_;
102 SecureBuffer<32> inner_random_stream_key_;
103 uint64_t transform_rounds_ = 8192;
104 uint64_t argon2_memory_ = 0;
105 uint32_t argon2_parallelism_ = 0;
106 uint32_t argon2_version_ = 0;
107 SecureBytes argon2_salt_;
108 uint64_t argon2_iterations_ = 0;
109 bool compress_ = false;
110 std::shared_ptr<Metadata> meta_;
111 SecureBuffer<32> transformed_key_;
112 bool has_transformed_key_ = false;
113
114public:
116 std::shared_ptr<Group> root() const { return root_; }
117
119 void set_root(std::shared_ptr<Group> root) { root_ = std::move(root); }
120
122 Cipher cipher() const { return cipher_; }
123
125 void set_cipher(Cipher cipher) { cipher_ = cipher; }
126
128 Kdf kdf() const { return kdf_; }
129
131 void set_kdf(Kdf kdf) {
132 if (kdf_ != kdf) {
133 kdf_ = kdf;
134 clear_transformed_key();
135 }
136 }
137
139 const SecureBytes& master_seed() const { return master_seed_; }
140
142 void set_master_seed(const std::array<uint8_t, 16>& master_seed) {
143 master_seed_.Assign(master_seed.data(), master_seed.size());
144 }
145
147 void set_master_seed(const std::vector<uint8_t>& master_seed) {
148 master_seed_.Assign(master_seed);
149 }
150
152 void set_master_seed(SecureBytes master_seed) { master_seed_ = std::move(master_seed); }
153
155 const std::array<uint8_t, 16>& init_vector() const { return init_vector_; }
156
158 void set_init_vector(const std::array<uint8_t, 16>& init_vector) { init_vector_ = init_vector; }
159
161 const SecureBuffer<32>& transform_seed() const { return transform_seed_; }
162
164 void set_transform_seed(const std::array<uint8_t, 32>& transform_seed) {
165 std::memcpy(transform_seed_.data(), transform_seed.data(), transform_seed.size());
166 clear_transformed_key();
167 }
168
171 void set_transform_seed(const SecureBuffer<32>& transform_seed) {
172 transform_seed_ = transform_seed.Clone();
173 clear_transformed_key();
174 }
175
177 const SecureBuffer<32>& inner_random_stream_key() const { return inner_random_stream_key_; }
178
180
184 inner_random_stream_key_ = key.Clone();
185 }
186
188
191 void set_inner_random_stream_key(const std::array<uint8_t, 32>& key) {
192 SecureBuffer<32> secure_key;
193 std::memcpy(secure_key.data(), key.data(), key.size());
194 inner_random_stream_key_ = std::move(secure_key);
195 }
196
198 uint64_t transform_rounds() const { return transform_rounds_; }
199
201 void set_transform_rounds(uint64_t transform_rounds) {
202 transform_rounds_ = transform_rounds;
203 clear_transformed_key();
204 }
205
207 uint64_t argon2_memory() const { return argon2_memory_; }
208
210 void set_argon2_memory(uint64_t argon2_memory) {
211 argon2_memory_ = argon2_memory;
212 clear_transformed_key();
213 }
214
216 uint32_t argon2_parallelism() const { return argon2_parallelism_; }
217
219 void set_argon2_parallelism(uint32_t argon2_parallelism) {
220 argon2_parallelism_ = argon2_parallelism;
221 clear_transformed_key();
222 }
223
225 uint32_t argon2_version() const { return argon2_version_; }
226
228 void set_argon2_version(uint32_t argon2_version) {
229 argon2_version_ = argon2_version;
230 clear_transformed_key();
231 }
232
234 const SecureBytes& argon2_salt() const { return argon2_salt_; }
235
237 void set_argon2_salt(const std::vector<uint8_t>& salt) {
238 argon2_salt_.Assign(salt);
239 clear_transformed_key();
240 }
241
245 argon2_salt_ = std::move(salt);
246 clear_transformed_key();
247 }
248
250 uint64_t argon2_iterations() const { return argon2_iterations_; }
251
253 void set_argon2_iterations(uint64_t iterations) {
254 argon2_iterations_ = iterations;
255 clear_transformed_key();
256 }
257
259 bool compress() const { return compress_; }
260
262 void set_compress(bool compress) { compress_ = compress; }
263
265 const SecureBuffer<32>& transformed_key() const { return transformed_key_; }
266
268 bool has_transformed_key() const { return has_transformed_key_; }
269
272 transformed_key_ = std::move(key);
273 has_transformed_key_ = true;
274 }
275
278 has_transformed_key_ = false;
279 SecureBuffer<32> empty;
280 transformed_key_ = std::move(empty);
281 }
282
284 std::shared_ptr<Metadata> meta() const { return meta_; }
285
287 void set_meta(std::shared_ptr<Metadata> meta) { meta_ = std::move(meta); }
288
290
295 std::vector<std::shared_ptr<Entry>> FindEntries(const std::string& query,
296 bool regex = false) const;
297
299
304 std::vector<std::shared_ptr<Group>> FindGroups(const std::string& query,
305 bool regex = false) const;
306
308
312 std::shared_ptr<Entry> FindEntry(const std::string& title) const;
313
315
319 std::shared_ptr<Group> FindGroup(const std::string& name) const;
320
322 static std::shared_ptr<Entry> NewEntry(const std::string& title = "");
323
325 static std::shared_ptr<Group> NewGroup(const std::string& name = "");
326
328 static void AddEntry(const std::shared_ptr<Group>& group, const std::shared_ptr<Entry>& entry);
329
331 static void AddGroup(const std::shared_ptr<Group>& parent, const std::shared_ptr<Group>& group);
332
334 void DeleteEntry(const std::array<uint8_t, 16>& uuid);
335
337 void DeleteGroup(const std::array<uint8_t, 16>& uuid);
338
340 static void MoveEntry(const std::shared_ptr<Entry>& entry,
341 const std::shared_ptr<Group>& new_group);
342
344 static void MoveGroup(const std::shared_ptr<Group>& group,
345 const std::shared_ptr<Group>& new_parent);
346
348
354
356 void delete_old_history() { DeleteOldHistory(); }
357
359 void TrashEntry(const std::shared_ptr<Entry>& entry);
360
362 void TrashGroup(const std::shared_ptr<Group>& group);
363
366
369
371 void EnableRecycleBin(bool enable = true);
372
375 std::string ToJson(bool include_attachments = false) const;
376
378
393 std::string ToCsv(CsvFormat format = CsvFormat::kCsv) const;
394
396
402 DatabaseDelta DeltaSince(const Database& previous) const;
403
405 size_t EntryCount() const;
406
408 size_t GroupCount() const;
409
411 void Visit(Visitor& visitor) const;
412};
413
414} // namespace keepass
Represents a KeePass (KDB/KDBX) database.
Definition database.hh:74
void set_argon2_iterations(uint64_t iterations)
Sets the Argon2 iteration count, invalidating the cached key.
Definition database.hh:253
void TrashGroup(const std::shared_ptr< Group > &group)
Moves a group to the recycle bin.
void set_argon2_memory(uint64_t argon2_memory)
Sets the Argon2 memory cost in KiB, invalidating the cached key.
Definition database.hh:210
uint64_t transform_rounds() const
Returns the number of AES key-transform rounds.
Definition database.hh:198
void set_argon2_salt(const std::vector< uint8_t > &salt)
Sets the Argon2 salt, invalidating the cached key.
Definition database.hh:237
void DeleteOldHistory()
Applies the database history limits to every entry's history.
uint64_t argon2_iterations() const
Returns the Argon2 iteration count.
Definition database.hh:250
void EnableRecycleBin(bool enable=true)
Enables or disables the recycle bin.
void set_master_seed(const std::array< uint8_t, 16 > &master_seed)
Sets the master seed from a fixed 16-byte array.
Definition database.hh:142
size_t GroupCount() const
Returns the total number of groups in the database (including the root).
uint64_t argon2_memory() const
Returns the Argon2 memory cost in KiB.
Definition database.hh:207
std::shared_ptr< Group > root() const
Returns the root group of the database.
Definition database.hh:116
uint32_t argon2_parallelism() const
Returns the Argon2 parallelism (degree of parallelism).
Definition database.hh:216
void TrashEntry(const std::shared_ptr< Entry > &entry)
Moves an entry to the recycle bin.
static void AddEntry(const std::shared_ptr< Group > &group, const std::shared_ptr< Entry > &entry)
Adds an entry to the given group.
const SecureBytes & argon2_salt() const
Returns the Argon2 salt.
Definition database.hh:234
void set_compress(bool compress)
Sets whether the payload is compressed.
Definition database.hh:262
void DeleteGroup(const std::array< uint8_t, 16 > &uuid)
Deletes the group with the given UUID and its subtree from the database.
void set_cipher(Cipher cipher)
Sets the cipher used to encrypt the database payload.
Definition database.hh:125
void set_root(std::shared_ptr< Group > root)
Sets the root group of the database.
Definition database.hh:119
void set_argon2_salt(SecureBytes salt)
Definition database.hh:244
Kdf kdf() const
Returns the key derivation function used to derive the master key.
Definition database.hh:128
uint32_t argon2_version() const
Returns the Argon2 version number.
Definition database.hh:225
void set_argon2_parallelism(uint32_t argon2_parallelism)
Sets the Argon2 parallelism, invalidating the cached key.
Definition database.hh:219
void DeleteEntry(const std::array< uint8_t, 16 > &uuid)
Deletes the entry with the given UUID from the database.
size_t EntryCount() const
Returns the total number of entries in the database.
DatabaseDelta DeltaSince(const Database &previous) const
Computes the entry-level difference to a previous database snapshot.
void delete_old_history()
Alias for DeleteOldHistory using the library's snake_case style.
Definition database.hh:356
std::vector< std::shared_ptr< Group > > FindGroups(const std::string &query, bool regex=false) const
Finds groups matching the given query anywhere in the database.
const SecureBuffer< 32 > & transform_seed() const
Returns the transform seed used for key derivation.
Definition database.hh:161
static void MoveEntry(const std::shared_ptr< Entry > &entry, const std::shared_ptr< Group > &new_group)
Moves an entry to a different group.
void set_init_vector(const std::array< uint8_t, 16 > &init_vector)
Sets the initialization vector.
Definition database.hh:158
void set_inner_random_stream_key(const std::array< uint8_t, 32 > &key)
Sets the inner random stream key from a fixed 32-byte array.
Definition database.hh:191
const std::array< uint8_t, 16 > & init_vector() const
Returns the initialization vector.
Definition database.hh:155
void set_transformed_key(SecureBuffer< 32 > key)
Sets the transformed master key and marks it as present.
Definition database.hh:271
std::shared_ptr< Entry > FindEntry(const std::string &title) const
Finds the first entry with exactly the given title.
void set_transform_seed(const SecureBuffer< 32 > &transform_seed)
Definition database.hh:171
void set_kdf(Kdf kdf)
Sets the key derivation function, invalidating any cached transformed key.
Definition database.hh:131
Cipher cipher() const
Returns the cipher used to encrypt the database payload.
Definition database.hh:122
const SecureBytes & master_seed() const
Returns the master seed.
Definition database.hh:139
bool IsRecycleBinEnabled() const
Returns whether a recycle bin is configured.
void EmptyRecycleBin()
Empties the recycle bin.
void clear_transformed_key()
Clears any cached transformed key.
Definition database.hh:277
void set_meta(std::shared_ptr< Metadata > meta)
Sets the database metadata.
Definition database.hh:287
std::string ToJson(bool include_attachments=false) const
void set_transform_seed(const std::array< uint8_t, 32 > &transform_seed)
Sets the transform seed, invalidating any cached transformed key.
Definition database.hh:164
void set_master_seed(const std::vector< uint8_t > &master_seed)
Sets the master seed from an arbitrary byte vector.
Definition database.hh:147
const SecureBuffer< 32 > & inner_random_stream_key() const
Returns the inner random stream key.
Definition database.hh:177
static std::shared_ptr< Group > NewGroup(const std::string &name="")
Creates a new group with an optional name.
void set_master_seed(SecureBytes master_seed)
Sets the master seed from a secure byte buffer.
Definition database.hh:152
void Visit(Visitor &visitor) const
Applies a visitor to every group and entry in the database.
void set_transform_rounds(uint64_t transform_rounds)
Sets the number of AES key-transform rounds, invalidating the cached key.
Definition database.hh:201
Kdf
Key derivation functions supported by the importer/exporter.
Definition database.hh:80
Cipher
Cipher algorithms supported for encrypting the database payload.
Definition database.hh:77
void set_inner_random_stream_key(const SecureBuffer< 32 > &key)
Sets the inner random stream key from a secure buffer.
Definition database.hh:183
static void MoveGroup(const std::shared_ptr< Group > &group, const std::shared_ptr< Group > &new_parent)
Moves a group to a different parent group.
bool compress() const
Returns whether the payload is compressed.
Definition database.hh:259
const SecureBuffer< 32 > & transformed_key() const
Returns the transformed master key (if present).
Definition database.hh:265
std::string ToCsv(CsvFormat format=CsvFormat::kCsv) const
Serializes the database to CSV, one line per entry.
static void AddGroup(const std::shared_ptr< Group > &parent, const std::shared_ptr< Group > &group)
Adds a group to the given parent group.
std::shared_ptr< Metadata > meta() const
Returns the database metadata.
Definition database.hh:284
void set_argon2_version(uint32_t argon2_version)
Sets the Argon2 version number, invalidating the cached key.
Definition database.hh:228
static std::shared_ptr< Entry > NewEntry(const std::string &title="")
Creates a new entry with an optional title.
bool has_transformed_key() const
Returns whether a transformed key has been computed.
Definition database.hh:268
std::vector< std::shared_ptr< Entry > > FindEntries(const std::string &query, bool regex=false) const
Finds entries matching the given query anywhere in the database.
std::shared_ptr< Group > FindGroup(const std::string &name) const
Finds the first group with exactly the given name.
Fixed-size byte buffer that is zeroized on destruction.
Definition secure.hh:79
uint8_t * data() noexcept
Returns a pointer to the raw bytes.
Definition secure.hh:113
SecureBuffer Clone() const
Returns an explicit deep copy of the buffer.
Definition secure.hh:143
Dynamic byte buffer that is zeroized in best-effort locked memory.
Definition secure.hh:164
void Assign(const uint8_t *data, std::size_t size)
Replaces the content with a copy of the given bytes.
Visitor pattern over a KeePass group/entry tree.
Definition visitor.hh:42
CsvFormat
Formats for Database::ToCsv().
Definition database.hh:42
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
Type representing a KeePass group (a container for entries and subgroups).
Secure memory handling: zeroization, locked allocations and sensitive value containers.
Entry-level difference between two databases, for incremental backups.
Definition database.hh:51
std::string ToJson() const
Serializes the delta to JSON (entry payloads use Entry::ToJson()).
bool empty() const
Returns whether no change was detected.
Definition database.hh:59
std::vector< std::array< uint8_t, 16 > > deleted
UUIDs (and paths) of entries removed since the previous database.
Definition database.hh:55
One changed entry in a DatabaseDelta.
Definition database.hh:45