QtPass 2.0.0
Developer documentation
Loading...
Searching...
No Matches
gpgidgeneration.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Anne Jan Brouwer
2// SPDX-License-Identifier: GPL-3.0-or-later
8#ifndef SRC_GPGIDGENERATION_H_
9#define SRC_GPGIDGENERATION_H_
10
11#include <QByteArray>
12#include <QString>
13#include <optional>
14
58public:
61 static const QByteArray kGenerationPrefix;
64 static const QByteArray kFolderPrefix;
68 static const QByteArray kStorePrefix;
71 static const qint64 kMaxGeneration;
72
74 struct Header {
76 qint64 generation = 0;
78 std::optional<QString> folder;
80 std::optional<QString> store;
81 };
82
93 static auto parse(const QByteArray &contents, QString *error = nullptr)
94 -> std::optional<Header>;
95
103 static auto header(qint64 generation, const QString &folder,
104 const QString &store = {}) -> QByteArray;
105
114 static auto withHeader(qint64 generation, const QString &folder,
115 const QByteArray &recipients,
116 const QString &store = {}) -> QByteArray;
117
129 static auto storeIdFor(const QString &storeRoot,
130 const std::optional<QString> &onDisk,
131 QString *error = nullptr) -> std::optional<QString>;
132
143 static auto folderOf(const QString &gpgIdFile, const QString &storeRoot)
144 -> std::optional<QString>;
145
155 static auto remembered(const QString &gpgIdFile, QString *error = nullptr)
156 -> std::optional<qint64>;
157
163 enum class Verdict {
165 Accepted,
170 Rollback,
177 Unbound,
183 Conflict,
185 WrongFolder,
191 WrongStore,
193 Malformed,
195 RecordUnavailable,
196 };
197
212 static auto accept(const QString &gpgIdFile, const QByteArray &contents,
213 const QString &storeRoot, QString *error = nullptr)
214 -> Verdict;
215
237 static auto reserveNext(const QString &gpgIdFile,
238 std::optional<qint64> verifiedOnDisk,
239 QString *error = nullptr) -> std::optional<qint64>;
240
253 static auto recordWritten(const QString &gpgIdFile,
254 const QByteArray &contents,
255 QString *error = nullptr) -> bool;
256
264 static auto digest(const QByteArray &contents) -> QString;
265
273 static auto key(const QString &gpgIdFile) -> QString;
274
281 static auto recordFile() -> QString;
282
289 static auto storeRecordFile() -> QString;
290
291private:
302 static auto boundToItsFolder(const QString &gpgIdFile, const Header &header,
303 const QString &storeRoot, QString *error)
304 -> bool;
305
319 static auto ofThisStore(const QString &gpgIdFile, const Header &header,
320 const QString &pinned, bool alreadyAccepted,
321 const QString &recordPath, QString *error) -> bool;
322
333 static auto wayThrough(qint64 last, const QString &recordPath,
334 const QString &saving) -> QString;
335
347 static auto staleList(const QString &gpgIdFile, const Header &header,
348 qint64 last, const QString &recordPath, QString *error)
349 -> Verdict;
350};
351
352#endif // SRC_GPGIDGENERATION_H_
Rollback detection for signed .gpg-id files.
static auto accept(const QString &gpgIdFile, const QByteArray &contents, const QString &storeRoot, QString *error=nullptr) -> Verdict
Decide about a verified list: its folder against where it sits, its generation against the remembered...
static auto ofThisStore(const QString &gpgIdFile, const Header &header, const QString &pinned, bool alreadyAccepted, const QString &recordPath, QString *error) -> bool
Whether header fits the store this device knows by pinned: its store line names that id,...
static auto digest(const QByteArray &contents) -> QString
The digest of a list as the record keeps it: SHA-256 of the exact bytes, hexadecimal,...
static auto header(qint64 generation, const QString &folder, const QString &store={}) -> QByteArray
The header lines for a list.
static auto storeRecordFile() -> QString
The file the store IDs are kept in, next to recordFile() and under its lock, so a QtPass from before ...
static auto folderOf(const QString &gpgIdFile, const QString &storeRoot) -> std::optional< QString >
The store-relative folder of gpgIdFile, as written in and compared against the folder line: ....
static auto reserveNext(const QString &gpgIdFile, std::optional< qint64 > verifiedOnDisk, QString *error=nullptr) -> std::optional< qint64 >
Reserve the generation to write next for gpgIdFile: one above both what this device remembers and ver...
static auto boundToItsFolder(const QString &gpgIdFile, const Header &header, const QString &storeRoot, QString *error) -> bool
Whether header's folder line, if it has one, names the folder the list sits in: a pair copied elsewhe...
static auto recordWritten(const QString &gpgIdFile, const QByteArray &contents, QString *error=nullptr) -> bool
Record the bytes just written for gpgIdFile, so that this device recognises its own list afterwards a...
static auto key(const QString &gpgIdFile) -> QString
The settings key for a .gpg-id: a hash of its canonical path, so path spelling (case,...
Verdict
The outcome of accept(). Only Accepted means the list may be used; the others say why not,...
static auto remembered(const QString &gpgIdFile, QString *error=nullptr) -> std::optional< qint64 >
The highest generation this device has accepted or written for the .gpg-id at gpgIdFile....
static auto staleList(const QString &gpgIdFile, const Header &header, qint64 last, const QString &recordPath, QString *error) -> Verdict
The refusal for a list older than the one accepted here: a rollback, or an unbound list that could be...
static const QByteArray kStorePrefix
static const QByteArray kFolderPrefix
static const qint64 kMaxGeneration
static auto withHeader(qint64 generation, const QString &folder, const QByteArray &recipients, const QString &store={}) -> QByteArray
A complete list: the header in front of the recipients.
static auto recordFile() -> QString
The file the accepted generations are recorded in, so a refusal can name it: removing it forgets what...
static const QByteArray kGenerationPrefix
static auto parse(const QByteArray &contents, QString *error=nullptr) -> std::optional< Header >
The header a .gpg-id's bytes declare.
static auto storeIdFor(const QString &storeRoot, const std::optional< QString > &onDisk, QString *error=nullptr) -> std::optional< QString >
The store id to write into a list of storeRoot: the one this device knows the store by; else onDisk,...
static auto wayThrough(qint64 last, const QString &recordPath, const QString &saving) -> QString
How a holder of the signing key gets through a refusal, in words: saving the recipients writes the ne...
What a list's header says.
std::optional< QString > folder
Nothing when the list carries no folder line.
qint64 generation
0 when the list carries no generation line.
std::optional< QString > store
Nothing when the list carries no store line.