summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2021-10-18 14:34:42 +0000
committerJulian Andres Klode <jak@debian.org>2021-10-18 14:34:42 +0000
commit9d8cad64f03b47576ea0fd22f7d963c031faec3b (patch)
treeea9ffa6160ee3d4c13c8727d56735684387c83c4
parentad7bae309a827592aa228af9470c1aa7abdd189e (diff)
parentdcbae505308758df2870c0424e3f5a1dfebcb5ec (diff)
Merge branch 'pu/signed-by-embedded-key' into 'main'
Add support for embedding PGP keys into Signed-By in deb822 sources See merge request apt-team/apt!176
-rw-r--r--apt-pkg/acquire-item.cc4
-rw-r--r--apt-pkg/deb/debmetaindex.cc23
-rw-r--r--doc/sources.list.5.xml17
-rw-r--r--methods/gpgv.cc34
-rwxr-xr-xtest/integration/test-signed-by-option35
5 files changed, 104 insertions, 9 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index eb8053feb..a4a6bc4a3 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -1912,7 +1912,7 @@ string pkgAcqMetaClearSig::Custom600Headers() const
Header += "\nFail-Ignore: true";
std::string const key = TransactionManager->MetaIndexParser->GetSignedBy();
if (key.empty() == false)
- Header += "\nSigned-By: " + key;
+ Header += "\nSigned-By: " + QuoteString(key, "");
return Header;
}
@@ -2168,7 +2168,7 @@ std::string pkgAcqMetaSig::Custom600Headers() const
std::string Header = pkgAcqTransactionItem::Custom600Headers();
std::string const key = TransactionManager->MetaIndexParser->GetSignedBy();
if (key.empty() == false)
- Header += "\nSigned-By: " + key;
+ Header += "\nSigned-By: " + QuoteString(key, "");
return Header;
}
/*}}}*/
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index d78cea758..88a55a477 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -54,8 +54,27 @@ static std::string transformFingergrpintsWithFilenames(std::string const &finger
return transformFingergrpints(finger);
}
/*}}}*/
-static std::string NormalizeSignedBy(std::string SignedBy, bool const SupportFilenames) /*{{{*/
+// Introducer is set if additional keys may be introduced, for example /*{{{*/
+// by setting it to a filename or a complete key
+static std::string NormalizeSignedBy(std::string SignedBy, bool const Introducer)
{
+ // This is an embedded public pgp key, normalize spaces inside it and empty "." lines
+ if (Introducer && SignedBy.find("-----BEGIN PGP PUBLIC KEY BLOCK-----") != std::string::npos) {
+ std::istringstream is(SignedBy);
+ std::ostringstream os;
+ std::string line;
+
+ while (std::getline(is, line)) {
+ line = APT::String::Strip(line);
+ // The special encoding for empty lines in deb822
+ if (line == ".")
+ line="";
+ os << line << std::endl;
+ }
+ std::clog << "OUTPUT " << os.str() << std::endl;
+ return os.str();
+ }
+
// we could go all fancy and allow short/long/string matches as gpgv/apt-key does,
// but fingerprints are harder to fake than the others and this option is set once,
// not interactively all the time so easy to type is not really a concern.
@@ -67,7 +86,7 @@ static std::string NormalizeSignedBy(std::string SignedBy, bool const SupportFil
fingers.erase(std::remove_if(fingers.begin(), fingers.end(), isAnEmptyString), fingers.end());
if (unlikely(fingers.empty()))
return "";
- if (SupportFilenames)
+ if (Introducer)
std::transform(fingers.begin(), fingers.end(), fingers.begin(), transformFingergrpintsWithFilenames);
else
std::transform(fingers.begin(), fingers.end(), fingers.begin(), transformFingergrpints);
diff --git a/doc/sources.list.5.xml b/doc/sources.list.5.xml
index 6929201a0..ed99f08f8 100644
--- a/doc/sources.list.5.xml
+++ b/doc/sources.list.5.xml
@@ -312,6 +312,23 @@ deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [.
of this repository (only fingerprints can be specified there through).
Otherwise all keys in the trusted keyrings are considered valid
signers for this repository.
+
+ The option may also be set directly to an embedded GPG public key block. Special
+ care is needed to encode the empty line with leading spaces and ".":
+ <literallayout>Types: deb
+URIs: https://deb.debian.org
+Suites: stable
+Components: main contrib non-free
+Signed-By:
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
+ .
+ mDMEYCQjIxYJKwYBBAHaRw8BAQdAD/P5Nvvnvk66SxBBHDbhRml9ORg1WV5CvzKY
+ CuMfoIS0BmFiY2RlZoiQBBMWCgA4FiEErCIG1VhKWMWo2yfAREZd5NfO31cFAmAk
+ IyMCGyMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQREZd5NfO31fbOwD6ArzS
+ dM0Dkd5h2Ujy1b6KcAaVW9FOa5UNfJ9FFBtjLQEBAJ7UyWD3dZzhvlaAwunsk7DG
+ 3bHcln8DMpIJVXht78sL
+ =IE0r
+ -----END PGP PUBLIC KEY BLOCK-----</literallayout>
</para></listitem>
<listitem><para><option>Check-Valid-Until</option> (<option>check-valid-until</option>)
diff --git a/methods/gpgv.cc b/methods/gpgv.cc
index a9da456ec..594e8781a 100644
--- a/methods/gpgv.cc
+++ b/methods/gpgv.cc
@@ -416,6 +416,14 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile,
return _("Unknown error executing apt-key");
}
+static std::string GenerateKeyFile(std::string const key)
+{
+ FileFd fd;
+ GetTempFile("apt-key.XXXXXX.asc", false, &fd);
+ fd.Write(key.data(), key.size());
+ return fd.Name();
+}
+
bool GPGVMethod::URIAcquire(std::string const &Message, FetchItem *Itm)
{
URI const Get(Itm->Uri);
@@ -423,11 +431,27 @@ bool GPGVMethod::URIAcquire(std::string const &Message, FetchItem *Itm)
SignersStorage Signers;
std::vector<std::string> keyFpts, keyFiles;
- for (auto &&key : VectorizeString(LookupTag(Message, "Signed-By"), ','))
- if (key.empty() == false && key[0] == '/')
- keyFiles.emplace_back(std::move(key));
- else
- keyFpts.emplace_back(std::move(key));
+ struct TemporaryFile
+ {
+ std::string name = "";
+ ~TemporaryFile() { if (0) RemoveFile("~TemporaryFile", name); }
+ } tmpKey;
+
+ std::string SignedBy = DeQuoteString(LookupTag(Message, "Signed-By"));
+
+ if (SignedBy.find("-----BEGIN PGP PUBLIC KEY BLOCK-----") != std::string::npos)
+ {
+ tmpKey.name = GenerateKeyFile(SignedBy);
+ keyFiles.emplace_back(tmpKey.name);
+ }
+ else
+ {
+ for (auto &&key : VectorizeString(SignedBy, ','))
+ if (key.empty() == false && key[0] == '/')
+ keyFiles.emplace_back(std::move(key));
+ else
+ keyFpts.emplace_back(std::move(key));
+ }
// Run apt-key on file, extract contents and get the key ID of the signer
string const msg = VerifyGetSigners(Path.c_str(), Itm->DestFile.c_str(), keyFpts, keyFiles, Signers);
diff --git a/test/integration/test-signed-by-option b/test/integration/test-signed-by-option
index faa7dec44..986088bce 100755
--- a/test/integration/test-signed-by-option
+++ b/test/integration/test-signed-by-option
@@ -31,3 +31,38 @@ Signed-By: CDE5618B8805FD6E202CE9C2D73C39E56580B386! AAAAAAAAAAAAAAAAAAAAA
, , BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
EOF
testsuccess --nomsg aptcache policy
+
+buildsimplenativepackage "coolstuff" "all" "1.0" "stable"
+setupaptarchive --no-update
+rm -f rootdir/etc/apt/sources.list.d/* rootdir/etc/apt/sources.list
+rm -f rootdir/etc/apt/trusted.gpg.d/* rootdir/etc/apt/trusted.gpg
+
+cat > rootdir/etc/apt/sources.list.d/deb822.sources << EOF
+Types: deb
+URIs: file://$PWD/aptarchive
+Suites: stable
+Components: main
+xSigned-By:
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
+ .
+ mQENBExsGNYBCADNVx+TQ6h1tEyUP11f7ihfta3ZePkW1rIdkdHgA3Fw/TeLnTEq
+ mWuhMw2pL4zy1vQhU8efNrRaNUrUS7kV3LIdSjd5K4Aizqtsdy/gLKFoTcO8LFIm
+ KAXPg5hZBZ1B1HWvw7Npe4nkIj0Ar+bUyMfyCBUeqoaNeIy31a4IiNo8LdD73DOh
+ 4APKcp+pXh2s2DOmWOnTI8Z+WZ9W2ZurtdZl8g04hszGatwVKrNc6p5wK0wAvJ+X
+ M0HaIVt/+90GVLCMb/Gjf66At73BS19BdRDPi54PPK5N+Q9HZAYq0zPPNySB3l4A
+ vGjZtCqljkSqiaL1C0ZKf8c5ey/FoAviyS7TABEBAAG0M0pvZSBTaXhwYWNrIChB
+ UFQgVGVzdGNhc2VzIER1bW15KSA8am9lQGV4YW1wbGUub3JnPokBNwQTAQoAIQIb
+ AwIeAQIXgAUCV7L5PQULCQgHAwUVCgkICwUWAgMBAAAKCRBakNFB26yNri5RB/sF
+ xRzAFAwwp6TQNeZk3L2zsHD2ZPKaoWzi1l+nD4grfP1enuAnwcLR3HG4zouN3nCg
+ M0PgZEUo2yOAnKK4D5XWkcZjhcoCj133bTW807e+aM6d08ns+piIGJ8VdUVYlNZ2
+ Tnr8eunkUQVkWQGjtHicIJFtjbokIKXzlJtVSklF/kDQ+v93kyj1SNM7Tm57Q01i
+ ZtB2jCXNYvqdlHaZw1oXdVd1R6u0+SSb4wtjHuTeYG76JaCnWKBnvexWhIEN1MxK
+ xNHhRHzEPTYZ4PCCyaRX4YRAwsEMFsscsghpQgqRDhGSWq+jUVI+Aay7FTnd+1UA
+ 1snsGpB0o9qxx8JpGMXI
+ =c/k4
+ -----END PGP PUBLIC KEY BLOCK-----
+EOF
+testfailure apt update -o Debug::Acquire::gpgv=1
+testsuccess grep "NO_PUBKEY 5A90D141DBAC8DAE" rootdir/tmp/testfailure.output
+sed -i s/^xSigned-By/Signed-By/ rootdir/etc/apt/sources.list.d/deb822.sources
+testsuccess apt update -o Debug::Acquire::gpgv=1