|
QtPass 2.0.0
Developer documentation
|
The detached signature on a store's .gpg-id: whether the configured signing key is usable, signing the file, and checking that an existing .gpg-id.sig was made by one of the configured keys. More...
#include <gpgidsigner.h>
Public Types | |
| using | Exec |
| Blocking process runner: Executor::executeBlocking()'s shape. | |
Public Member Functions | |
| GpgIdSigner (QString gpgExecutable, QStringList signingKeys, Exec exec=Exec()) | |
| Create a signer. | |
| auto | enabled () const -> bool |
| Whether any signing key is configured at all. | |
| auto | keys () const -> const QStringList & |
| The keys this signer was given. | |
| auto | haveSecretKey () const -> bool |
| Whether gpg has the secret key that sign() will use, i.e. the first configured key. | |
| auto | sign (const QString &gpgIdFile, const QByteArray &contents, QString *error=nullptr) const -> bool |
Write <file>.sig, a detached signature by the first key over contents, the bytes the caller just wrote as gpgIdFile. | |
| auto | verify (const QByteArray &contents, const QString &signatureFile) const -> bool |
| Check a detached signature against the given bytes: gpg must report a VALIDSIG whose key or primary-key fingerprint is one of the configured keys. | |
| auto | verifyFile (const QString &gpgIdFile, QByteArray *contents) const -> bool |
Read gpgIdFile and verify it against <file>.sig. | |
Static Public Member Functions | |
| static auto | keysFromSetting (const QString &passSigningKey) -> QStringList |
| Split the settings value into keys, upper-cased the way gpg prints fingerprints. | |
| static auto | validSigFingerprints (const QString &statusOutput) -> QStringList |
| Pick the fingerprints out of gpg's --status-fd VALIDSIG line. | |
Static Public Attributes | |
| static constexpr qint64 | kMaxSignatureBytes = 64 * 1024 |
| Most bytes of a .gpg-id.sig verify() hands to gpg. | |
Private Member Functions | |
| auto | run (const QStringList &args, QString *out=nullptr, QString *err=nullptr, const QString &input=QString()) const -> int |
Run gpg with args through m_exec. | |
Private Attributes | |
| QString | m_gpg |
| The gpg executable, as configured. | |
| QStringList | m_keys |
| The configured signing keys. The first one signs; a signature by any of them verifies. | |
| Exec | m_exec |
| How gpg is run; replaced by a fake in the unit tests. | |
The detached signature on a store's .gpg-id: whether the configured signing key is usable, signing the file, and checking that an existing .gpg-id.sig was made by one of the configured keys.
Every gpg run goes through the Exec given at construction, so the re-encryption worker can hand in its cancellable runner and tests a fake. With no signing keys configured signing is off and verification passes: pass itself only checks signatures when PASSWORD_STORE_SIGNING_KEY is set.
Definition at line 28 of file gpgidsigner.h.
| using GpgIdSigner::Exec |
Blocking process runner: Executor::executeBlocking()'s shape.
Definition at line 41 of file gpgidsigner.h.
Create a signer.
| gpgExecutable | The gpg binary; a wsl prefix routes file paths through wslpath. |
| signingKeys | Full fingerprints from the settings (40 hex characters for v4 keys, 64 for v5/v6), as pass's PASSWORD_STORE_SIGNING_KEY requires: gpg reports fingerprints in its KEY_CONSIDERED and VALIDSIG status lines, so a short key ID would never pass haveSecretKey() or verify(). The first one signs, any of them verifies. |
| exec | Process runner; Executor::executeBlocking() when empty. |
Definition at line 19 of file gpgidsigner.cpp.
|
inline |
Whether any signing key is configured at all.
Definition at line 72 of file gpgidsigner.h.
| auto GpgIdSigner::haveSecretKey | ( | ) | const -> bool |
Whether gpg has the secret key that sign() will use, i.e. the first configured key.
Definition at line 47 of file gpgidsigner.cpp.
|
inline |
The keys this signer was given.
Definition at line 78 of file gpgidsigner.h.
|
static |
Split the settings value into keys, upper-cased the way gpg prints fingerprints.
| passSigningKey | The space-separated setting. |
Definition at line 31 of file gpgidsigner.cpp.
|
private |
Run gpg with args through m_exec.
| args | Arguments for gpg. |
| out | If non-null, receives stdout. |
| err | If non-null, receives stderr. |
| input | Data for gpg's stdin; empty for none. |
Definition at line 42 of file gpgidsigner.cpp.
| auto GpgIdSigner::sign | ( | const QString & | gpgIdFile, |
| const QByteArray & | contents, | ||
| QString * | error = nullptr ) const -> bool |
Write <file>.sig, a detached signature by the first key over contents, the bytes the caller just wrote as gpgIdFile.
gpg signs what it is fed on stdin, not what is under the file's name by the time it reads it (a co-writer of the store could have swapped the list between the write and the signing, and the user's key would have vouched for theirs), and writes the signature into a directory of QtPass's own; the signature then goes next to the list through Util::writeFileReplacing(), never by opening the .sig name.
Only the first key signs, as --local-user: gpg then fails when that secret key is missing, where --default-key would quietly sign with another one. The new signature is verified against contents the way verify() does before it is placed; one that is not by a configured key is not written.
| gpgIdFile | The .gpg-id the signature is for; <gpgIdFile>.sig is written. |
| contents | The exact bytes of that file, as written. UTF-8 text, as a recipient list is; anything else is refused, as verify() refuses it. |
| error | Receives gpg's stderr, or the reason, when it fails. |
Definition at line 65 of file gpgidsigner.cpp.
|
static |
Pick the fingerprints out of gpg's --status-fd VALIDSIG line.
| statusOutput | gpg's status output. |
Definition at line 125 of file gpgidsigner.cpp.
| auto GpgIdSigner::verify | ( | const QByteArray & | contents, |
| const QString & | signatureFile ) const -> bool |
Check a detached signature against the given bytes: gpg must report a VALIDSIG whose key or primary-key fingerprint is one of the configured keys.
The data goes to gpg on stdin, so the caller verifies exactly the bytes it is about to use as the recipient list; verifying a path and reading it again afterwards would let anyone who can write to the store swap the file in between (#1842).
| contents | The .gpg-id bytes. |
| signatureFile | The .gpg-id.sig next to it. |
Definition at line 160 of file gpgidsigner.cpp.
| auto GpgIdSigner::verifyFile | ( | const QString & | gpgIdFile, |
| QByteArray * | contents ) const -> bool |
Read gpgIdFile and verify it against <file>.sig.
| gpgIdFile | The .gpg-id. |
| contents | Receives the bytes that were verified, so the caller can parse those and nothing else. |
Definition at line 215 of file gpgidsigner.cpp.
|
staticconstexpr |
Most bytes of a .gpg-id.sig verify() hands to gpg.
A detached signature is well under a KiB; far beyond any real one.
Definition at line 35 of file gpgidsigner.h.
|
private |
How gpg is run; replaced by a fake in the unit tests.
Definition at line 159 of file gpgidsigner.h.
|
private |
The gpg executable, as configured.
Definition at line 152 of file gpgidsigner.h.
|
private |
The configured signing keys. The first one signs; a signature by any of them verifies.
Definition at line 157 of file gpgidsigner.h.