summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2024-12-07 16:44:18 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2024-12-22 23:51:22 +0100
commitda9a05e0b0b2150dbb67090e8b0c3922e46bd5cf (patch)
treea777d725b72b0e2111b62ebed3412921d4ffe647 /apt-pkg
parentb85dd910dcc68b710e1843e8b67935cc96c2a4c9 (diff)
methods: Add new sqv method
The new sqv method uses sequoia's sqv tool to verify files. The tool's interface is quite simple: It returns 0 on success, and prints one line per good signer with the fingerprint. sqv has a configurable crypto policy. We have defined apt-specific override mechanisms for sequoia's standard policy, allowing both users, distributions, and apt package to provide overrides for Sequoia's default policy in meaningful ways. The sqv method will be built and be the standard method for verifying OpenPGP signatures provided that `sqv` is in the PATH during building. It is not built if there was no sqv at build time, so you need a rebuild to enable sqv later on. On the flip side, the gpgv method is always built, but it does need to be always built: If APT::Key::GPGVCommand is set, we need to fallback to it - this is important to support existing users of that interface such as mmdebstrap. Also we want to fall back to it when /usr/bin/sqv disappears - for example in our CI :D A couple of concessions have been made for test suite purposes: - Failure to split a clearsigned file only shows the summary, as the gpgv method also only showed it, and no details why it failed. - We write "Got GOODSIG <fingerprint>" in debug mode to mimic the gpgv code to keep the test suite happy. - In various places in the test suite we assert minimal output from sqv, but sqv's human output is not intended to be stable. This will incur additional work when it breaks. However we do not _parse_ the output, so actual operation of apt is unaffected. A couple of things are suboptimal here: - We are still doing clearsigned splitting ourselves. sqv only has support for detached signatures right now, whereas sqopv has support for clearsigned files as well (but sqopv does not provide any reasons for why signature verification fails or means to set a policy). - Deprecation of algorithms happens on a timebomb basis in sequoia. We have no means to give users warnings ahead of time if their configuration is outdated. We have implemented various bits that probably should be going away: - Fallback to trusted.gpg This is just annoying... - Support for fingerprints in Signed-By (no subkey matching though) The extra work here is arguably less compared to gpgv. - Check the keyring for correctness. With Signed-By everywhere, we should just error out rather than skip broken keyrings. Moo
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc8
-rw-r--r--apt-pkg/contrib/gpgv.cc20
-rw-r--r--apt-pkg/contrib/gpgv.h9
3 files changed, 33 insertions, 4 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 12524778e..69644883b 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -1423,7 +1423,15 @@ string pkgAcqMetaBase::Custom600Headers() const
void pkgAcqMetaBase::QueueForSignatureVerify(pkgAcqTransactionItem * const I, std::string const &File, std::string const &Signature)
{
AuthPass = true;
+#ifdef SQV_EXECUTABLE
+ if (not _config->Find("APT::Key::GPGVCommand").empty() || not FileExists(SQV_EXECUTABLE))
+ I->Desc.URI = "gpgv:" + pkgAcquire::URIEncode(Signature);
+ else {
+ I->Desc.URI = "sqv:" + pkgAcquire::URIEncode(Signature);
+ }
+#else
I->Desc.URI = "gpgv:" + pkgAcquire::URIEncode(Signature);
+#endif
I->DestFile = File;
QueueURI(I->Desc);
I->SetActiveSubprocess("gpgv");
diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc
index 7b0a0d240..48d31a44c 100644
--- a/apt-pkg/contrib/gpgv.cc
+++ b/apt-pkg/contrib/gpgv.cc
@@ -169,7 +169,7 @@ static bool CheckGPGV(std::unordered_map<std::string, std::forward_list<std::str
/// Verifies a file containing a detached signature has the right format
/// @return 0 if succesful, or an exit code for ExecGPGV otherwise.
-static int VerifyDetachedSignatureFile(std::string FileGPG, int fd[2], int statusfd = -1)
+static int VerifyDetachedSignatureFile(std::string const &FileGPG, int fd[2], int statusfd = -1)
{
auto detached = make_unique_FILE(FileGPG, "r");
if (detached.get() == nullptr)
@@ -211,10 +211,17 @@ static int VerifyDetachedSignatureFile(std::string FileGPG, int fd[2], int statu
}
}
}
- if (found_signatures == 0 && statusfd != -1)
+ if (found_signatures == 0)
{
- auto const errtag = "[GNUPG:] NODATA\n";
- FileFd::Write(fd[1], errtag, strlen(errtag));
+ if (statusfd != -1 && fd)
+ {
+ auto const errtag = "[GNUPG:] NODATA\n";
+ FileFd::Write(fd[1], errtag, strlen(errtag));
+ }
+ else
+ {
+ _error->Error("Signed file isn't valid, got 'NODATA' (does the network require authentication?)");
+ }
// guess if this is a binary signature, we never officially supported them,
// but silently accepted them via passing them unchecked to gpgv
if (found_badcontent)
@@ -247,6 +254,11 @@ static int VerifyDetachedSignatureFile(std::string FileGPG, int fd[2], int statu
return 0;
}
+bool VerifyDetachedSignatureFile(std::string const &DetachedSignatureFileName)
+{
+ return VerifyDetachedSignatureFile(DetachedSignatureFileName, nullptr, -1) == 0;
+}
+
std::pair<std::string, std::forward_list<std::string>> APT::Internal::FindGPGV(bool Debug)
{
static thread_local std::unordered_map<std::string, std::forward_list<std::string>> checkedCommands;
diff --git a/apt-pkg/contrib/gpgv.h b/apt-pkg/contrib/gpgv.h
index d4520f3a2..0b84f6bb7 100644
--- a/apt-pkg/contrib/gpgv.h
+++ b/apt-pkg/contrib/gpgv.h
@@ -96,5 +96,14 @@ APT_PUBLIC bool SplitClearSignedFile(std::string const &InFile, FileFd * const C
*/
APT_PUBLIC bool OpenMaybeClearSignedFile(std::string const &ClearSignedFileName, FileFd &MessageFile);
+/** \brief verifiy a detached signature file for correctness.
+ *
+ * We want to expect unavoided content. This may set an error when returning false
+ * but it might not necessarily do so (in case of empty signature file).
+ *
+ * @return true if the detached signature files contains ASCII-armored signatures, otherwise false
+ */
+APT_PUBLIC bool VerifyDetachedSignatureFile(std::string const &DetachedSignatureFileName);
+
APT_PUBLIC bool IsAssertedPubKeyAlgo(std::string const &pkstr, std::string const &option);
#endif