diff options
| author | Julian Andres Klode <jak@debian.org> | 2024-11-23 19:41:45 +0100 |
|---|---|---|
| committer | Julian Andres Klode <julian.klode@canonical.com> | 2024-11-28 19:01:36 +0100 |
| commit | 623bc8a69d0e89c0f18305403741af4fda8d87bf (patch) | |
| tree | d9ac11b0640c06ee49d1b6261015d828a261dbe1 /apt-pkg/contrib | |
| parent | 62cc071f88cb33c1f6213c9dbd54a10135c5ad34 (diff) | |
gpgv: Verify keyrings and dearmor outside apt-key
Diffstat (limited to 'apt-pkg/contrib')
| -rw-r--r-- | apt-pkg/contrib/gpgv.cc | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index dd1a279fc..fdc292f4f 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -168,17 +168,66 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, Args.push_back(aptkey); Args.push_back("--quiet"); Args.push_back("--readonly"); + auto dearmorKeyOrCheckFormat = [&](std::string const &k) -> std::string + { + FileFd keyFd(k, FileFd::ReadOnly); + if (not keyFd.IsOpen()) + { + apt_warning(std::cerr, statusfd, fd, "The key(s) in the keyring %s are ignored as the file is not readable by user executing apt-key.\n", k.c_str()); + return ""; + } + if (APT::String::Endswith(k, ".gpg") || APT::String::Endswith(k, ".pub")) + { + unsigned char c; + if (not keyFd.Read(&c, sizeof(c))) + goto err; + // Identify the leading byte of an OpenPGP public key packet + // 0x98 -- old-format OpenPGP public key packet, up to 255 octets + // 0x99 -- old-format OpenPGP public key packet, 256-65535 octets + // 0xc6 -- new-format OpenPGP public key packet, any length + if (c == 0x98 || c == 0x99 || c == 0xc6) + return k; + } + else if (APT::String::Endswith(k, ".asc")) + { + std::string b64msg; + int state = 0; + for (std::string line; keyFd.ReadLine(line);) + { + line = APT::String::Strip(line); + if (APT::String::Startswith(line, "-----BEGIN PGP PUBLIC KEY BLOCK-----")) + state = 1; + else if (state == 1 && line == "") + state = 2; + else if (state == 2 && line != "" && line[0] != '=' && line[0] != '-') + b64msg += line; + else if (APT::String::Startswith(line, "-----END")) + state = 3; + } + if (state != 3) + goto err; + + FileFd dearmoredFd; + if (GetTempFile("apt.XXXXXX.gpg", false, &dearmoredFd) == nullptr) + local_exit(EINTERNAL); + if (auto decoded = Base64Decode(b64msg); not decoded.empty()) + dearmoredFd.Write(decoded.data(), decoded.size()); + local_exit.files.push_back(dearmoredFd.Name()); + return dearmoredFd.Name(); + } + err: + apt_warning(std::cerr, statusfd, fd, "The key(s) in the keyring %s are ignored as the file has an unsupported filetype.", k.c_str()); + return ""; + }; auto maybeAddKeyring = [&](std::string const &k) { if (struct stat st; stat(k.c_str(), &st) != 0 || st.st_size == 0) return; - if (access(k.c_str(), R_OK) != 0) + if (auto cleanKey = dearmorKeyOrCheckFormat(k); not cleanKey.empty()) { - apt_warning(std::cerr, statusfd, fd, "The key(s) in the keyring %s are ignored as the file is not readable by user executing apt-key.\n", k.c_str()); - return; + Args.push_back("--keyring"); + Args.push_back(cleanKey); } - Args.push_back("--keyring"); - Args.push_back(k); return; }; |
