Volker Birk 10 months ago
parent 0dd85d2e0a
commit 6f6bc95706

@ -42,8 +42,8 @@ the deployment key, then encrypted with the provisioning key.
## distribution signature
The distribution signature is the PKCS#7 (CMS) detached signature of the
distribution archive file DIST.A using the deployment key.
The distribution signature is the PKCS v1.5 RSASS<PSS, SHA256> detached
signature of the distribution archive file DIST.A using the deployment key.
## deployment key

@ -1,8 +1,26 @@
#include "unpack.hh"
#include <filesystem>
#include <vector>
#include <algorithm>
#include <system_error>
#include <archive.h>
#include <archive_entry.h>
#include <cryptopp/pssr.h>
#ifdef WIN32
// FIXME: name collision possible
static char *mkdtemp(char *template)
{
if (_mktemp(template) == nullptr)
return nullptr;
if (_mkdir(template))
return nullptr;
return template;
}
#endif
namespace SignedPackage {
static bool path_empty(std::string path)
@ -28,10 +46,18 @@ namespace SignedPackage {
std::filesystem::path path = std::filesystem::temp_directory_path() / "spXXXXXXXXXXXX";
size_t size = ((std::string) path).size();
char* buffer = new char[size + 1];
::memcpy(buffer, ((std::string) path).c_str(), size);
buffer[size] = 0;
::mkdtemp(buffer);
char *p = mkdtemp(buffer);
if (p == nullptr) {
delete[] buffer;
throw std::filesystem::filesystem_error(::strerror(errno),
std::error_code(errno, std::system_category()));
}
path = buffer;
delete[] buffer;
@ -40,35 +66,13 @@ namespace SignedPackage {
void extract_archive(
std::string pkg_path,
std::string target_path
)
{
}
std::filesystem::path extract_deployment_archive(
std::string pkg_path,
CryptoPP::PublicKey& deployment_key
)
{
std::filesystem::path target_path = mktempdir();
extract_archive(pkg_path, target_path);
return target_path;
}
void install_if_location_empty(
CryptoPP::PublicKey& deployment_key,
CryptoPP::PrivateKey& provisioning_key,
std::string pkg_path,
std::string target_path
std::string target_path,
std::vector< std::string > filenames
)
{
std::string cwd = std::filesystem::current_path();
std::string tmp_path = extract_deployment_archive(pkg_path, deployment_key);
ensure_target_path(target_path);
std::filesystem::current_path(target_path);
struct archive *a = ::archive_read_new();
::archive_read_support_filter_all(a);
@ -87,7 +91,8 @@ namespace SignedPackage {
std::string pathname{::archive_entry_pathname(entry)};
int n = 0;
if (pathname == "DIST.A" || pathname == "DIST.KEY" || pathname == "DIST.SIG") {
if (!filenames.size() || std::find(filenames.begin(),
filenames.end(), pathname) != filenames.end()) {
do {
r = archive_read_extract(a, entry,
ARCHIVE_EXTRACT_ACL |
@ -110,7 +115,7 @@ namespace SignedPackage {
}
++n;
}
if (n < 3) {
if (filenames.size() && n != filenames.size()) {
::archive_read_close(a);
::archive_read_free(a);
std::filesystem::current_path(cwd);
@ -123,6 +128,54 @@ namespace SignedPackage {
std::filesystem::current_path(cwd);
}
bool check_signature(
std::filesystem::path file,
std::filesystem::path sig,
CryptoPP::PublicKey& key
)
{
CryptoPP::RSASS<CryptoPP::PSS, CryptoPP::SHA256>::Verifier verifier(key);
CryptoPP::SignatureVerificationFilter verificationFilter(verifier,
nullptr,
CryptoPP::SignatureVerificationFilter::SIGNATURE_AT_BEGIN
| CryptoPP::SignatureVerificationFilter::THROW_EXCEPTION);
CryptoPP::FileSource fileSource(((std::string) file).c_str(), false,
new CryptoPP::Redirector(verificationFilter));
CryptoPP::FileSource signatureSource(((std::string) sig).c_str(), false,
new CryptoPP::Redirector(verificationFilter));
signatureSource.PumpAll();
fileSource.PumpAll();
return false;
}
std::filesystem::path extract_deployment_archive(
CryptoPP::PublicKey& deployment_key,
std::string pkg_path
)
{
std::filesystem::path target_path = mktempdir();
extract_archive(pkg_path, target_path, { "DIST.A", "DIST.KEY", "DIST.SIG" });
check_signature(target_path / "DIST.A", target_path / "DIST.SIG", deployment_key);
return target_path;
}
void install_if_location_empty(
CryptoPP::PublicKey& deployment_key,
CryptoPP::PrivateKey& provisioning_key,
std::string pkg_path,
std::string target_path
)
{
std::string tmp_path = extract_deployment_archive(deployment_key, pkg_path);
ensure_target_path(target_path);
}
void provision_system(
pEp::UpdateClient::product p,
pEp::UpdateClient::PublicKey update_key,

@ -19,18 +19,26 @@ namespace SignedPackage {
void extract_archive(
std::string pkg_path,
std::string target_path
std::string target_path,
std::vector< std::string > filenames = { }
);
bool check_signature(
std::filesystem::path file,
std::filesystem::path sig,
CryptoPP::PublicKey& key
);
std::filesystem::path extract_deployment_archive(
std::string pkg_path,
CryptoPP::PublicKey& deployment_key
CryptoPP::PublicKey& deployment_key,
std::string pkg_path
);
void install_if_location_empty(
CryptoPP::PublicKey& deployment_key,
CryptoPP::PrivateKey& provisioning_key,
std::string pkg_path
std::string pkg_path,
std::string target_path
);
void provision_system(

Loading…
Cancel
Save