summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2024-07-15 18:42:54 +0200
committerJulian Andres Klode <julian.klode@canonical.com>2024-07-15 19:17:20 +0200
commit29dd6c45bc2579d012ac78ba3100a2485c78ff1d (patch)
tree4dbd536e41e9f6ec318f5b02fcc03e5eebe9141b
parent04cb5104a018184fe1fac114cbc212a9395d6845 (diff)
gpgv: Add IsAssertedPubKeyAlgo() function
This checks whether a public key algorithm is asserted.
-rw-r--r--apt-pkg/contrib/gpgv.cc32
-rw-r--r--apt-pkg/contrib/gpgv.h1
-rw-r--r--test/libapt/assert_pubkeyalgo_test.cc56
3 files changed, 89 insertions, 0 deletions
diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc
index 2fa5b0c30..225acae88 100644
--- a/apt-pkg/contrib/gpgv.cc
+++ b/apt-pkg/contrib/gpgv.cc
@@ -566,3 +566,35 @@ bool OpenMaybeClearSignedFile(std::string const &ClearSignedFileName, FileFd &Me
return not MessageFile.Failed();
}
/*}}}*/
+bool IsAssertedPubKeyAlgo(std::string const &pkstr, std::string const &option) /*{{{*/
+{
+ auto fullAss = APT::String::Startswith(option, "APT::Key") ? _config->Find(option) : option;
+ for (auto &ass : VectorizeString(fullAss, ','))
+ {
+ if (ass == pkstr)
+ return true;
+ // We only implement >= for rsa
+ if (APT::String::Startswith(ass, ">=rsa"))
+ {
+ if (not APT::String::Startswith(pkstr, "rsa"))
+ continue;
+ if (not std::all_of(ass.begin() + 5, ass.end(), isdigit))
+ return _error->Error("Unrecognized public key specification '%s' in option %s: expect only digits after >=rsa", ass.c_str(), option.c_str());
+
+ int assBits = std::stoi(ass.substr(5));
+ int pkBits = std::stoi(pkstr.substr(3));
+
+ if (pkBits >= assBits)
+ return true;
+
+ continue;
+ }
+ if (ass.empty())
+ return _error->Error("Empty item in public key assertion string option %s", option.c_str());
+ if (not std::all_of(ass.begin(), ass.end(), [](char c)
+ { return isalpha(c) || isdigit(c); }))
+ return _error->Error("Unrecognized public key specification '%s' in option %s", ass.c_str(), option.c_str());
+ }
+ return false;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/gpgv.h b/apt-pkg/contrib/gpgv.h
index 1cabed4e6..1f3ef26f9 100644
--- a/apt-pkg/contrib/gpgv.h
+++ b/apt-pkg/contrib/gpgv.h
@@ -86,4 +86,5 @@ APT_PUBLIC bool SplitClearSignedFile(std::string const &InFile, FileFd * const C
*/
APT_PUBLIC bool OpenMaybeClearSignedFile(std::string const &ClearSignedFileName, FileFd &MessageFile);
+APT_PUBLIC bool IsAssertedPubKeyAlgo(std::string const &pkstr, std::string const &option);
#endif
diff --git a/test/libapt/assert_pubkeyalgo_test.cc b/test/libapt/assert_pubkeyalgo_test.cc
new file mode 100644
index 000000000..88a070bbe
--- /dev/null
+++ b/test/libapt/assert_pubkeyalgo_test.cc
@@ -0,0 +1,56 @@
+#include <config.h>
+
+#include <apt-pkg/error.h>
+#include <apt-pkg/gpgv.h>
+
+#include "common.h"
+
+TEST(AssertPubKeyAlgo_Test, test)
+{
+ EXPECT_TRUE(IsAssertedPubKeyAlgo("rsa2048", ">=rsa2048"));
+ _error->DumpErrors();
+ EXPECT_TRUE(_error->empty());
+
+ EXPECT_TRUE(IsAssertedPubKeyAlgo("rsa2048", "another,>=rsa2048"));
+ EXPECT_TRUE(_error->empty());
+
+ EXPECT_FALSE(IsAssertedPubKeyAlgo("rsa2048", ">=rsa2049"));
+ EXPECT_TRUE(_error->empty());
+
+ EXPECT_TRUE(IsAssertedPubKeyAlgo("ed25519", ">=rsa2048,ed25519"));
+ EXPECT_TRUE(_error->empty());
+}
+
+TEST(AssertPubKeyAlgo_Test, CanOnlyCompareRSA)
+{
+ std::string msg;
+ EXPECT_FALSE(IsAssertedPubKeyAlgo("ed25519", ">=ed25519"));
+ EXPECT_TRUE(_error->PopMessage(msg));
+ EXPECT_EQ("Unrecognized public key specification '>=ed25519' in option >=ed25519", msg);
+ EXPECT_TRUE(_error->empty());
+}
+
+TEST(AssertPubKeyAlgo_Test, EmptyOption)
+{
+ std::string msg;
+ EXPECT_FALSE(IsAssertedPubKeyAlgo("ed25519", ""));
+ EXPECT_TRUE(_error->empty());
+
+ EXPECT_FALSE(IsAssertedPubKeyAlgo("ed25519", ","));
+ EXPECT_TRUE(_error->PopMessage(msg));
+ EXPECT_EQ("Empty item in public key assertion string option ,", msg);
+ EXPECT_TRUE(_error->empty());
+
+ EXPECT_FALSE(IsAssertedPubKeyAlgo("ed25519", "moo,"));
+ EXPECT_TRUE(_error->empty());
+
+ EXPECT_FALSE(IsAssertedPubKeyAlgo("ed25519", "moo,,"));
+ EXPECT_TRUE(_error->PopMessage(msg));
+ EXPECT_EQ("Empty item in public key assertion string option moo,,", msg);
+ EXPECT_TRUE(_error->empty());
+
+ EXPECT_FALSE(IsAssertedPubKeyAlgo("ed25519", ",moo"));
+ EXPECT_TRUE(_error->PopMessage(msg));
+ EXPECT_EQ("Empty item in public key assertion string option ,moo", msg);
+ EXPECT_TRUE(_error->empty());
+}