1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 10:41:16 +02:00

Merge pull request #12976 from picnoir/pic/multisign

store URI: introduce multiple signatures support
This commit is contained in:
Jörg Thalheim 2025-04-14 11:20:41 +02:00 committed by GitHub
commit 3f3fd2c94b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 36 additions and 5 deletions

View file

@ -29,8 +29,17 @@ BinaryCacheStore::BinaryCacheStore(const Params & params)
, Store(params) , Store(params)
{ {
if (secretKeyFile != "") if (secretKeyFile != "")
signer = std::make_unique<LocalSigner>( signers.push_back(std::make_unique<LocalSigner>(
SecretKey { readFile(secretKeyFile) }); SecretKey { readFile(secretKeyFile) }));
if (secretKeyFiles != "") {
std::stringstream ss(secretKeyFiles);
Path keyPath;
while (std::getline(ss, keyPath, ',')) {
signers.push_back(std::make_unique<LocalSigner>(
SecretKey { readFile(keyPath) }));
}
}
StringSink sink; StringSink sink;
sink << narVersionMagic1; sink << narVersionMagic1;
@ -270,9 +279,9 @@ ref<const ValidPathInfo> BinaryCacheStore::addToStoreCommon(
stats.narWriteCompressedBytes += fileSize; stats.narWriteCompressedBytes += fileSize;
stats.narWriteCompressionTimeMs += duration; stats.narWriteCompressionTimeMs += duration;
/* Atomically write the NAR info file.*/ narInfo->sign(*this, signers);
if (signer) narInfo->sign(*this, *signer);
/* Atomically write the NAR info file.*/
writeNarInfo(narInfo); writeNarInfo(narInfo);
stats.narInfoWrite++; stats.narInfoWrite++;

View file

@ -32,6 +32,9 @@ struct BinaryCacheStoreConfig : virtual StoreConfig
const Setting<Path> secretKeyFile{this, "", "secret-key", const Setting<Path> secretKeyFile{this, "", "secret-key",
"Path to the secret key used to sign the binary cache."}; "Path to the secret key used to sign the binary cache."};
const Setting<std::string> secretKeyFiles{this, "", "secret-keys",
"List of comma-separated paths to the secret keys used to sign the binary cache."};
const Setting<Path> localNarCache{this, "", "local-nar-cache", const Setting<Path> localNarCache{this, "", "local-nar-cache",
"Path to a local cache of NARs fetched from this binary cache, used by commands such as `nix store cat`."}; "Path to a local cache of NARs fetched from this binary cache, used by commands such as `nix store cat`."};
@ -57,7 +60,7 @@ class BinaryCacheStore : public virtual BinaryCacheStoreConfig,
{ {
private: private:
std::unique_ptr<Signer> signer; std::vector<std::unique_ptr<Signer>> signers;
protected: protected:

View file

@ -144,6 +144,7 @@ struct ValidPathInfo : UnkeyedValidPathInfo {
std::string fingerprint(const Store & store) const; std::string fingerprint(const Store & store) const;
void sign(const Store & store, const Signer & signer); void sign(const Store & store, const Signer & signer);
void sign(const Store & store, const std::vector<std::unique_ptr<Signer>> & signers);
/** /**
* @return The `ContentAddressWithReferences` that determines the * @return The `ContentAddressWithReferences` that determines the

View file

@ -40,6 +40,14 @@ void ValidPathInfo::sign(const Store & store, const Signer & signer)
sigs.insert(signer.signDetached(fingerprint(store))); sigs.insert(signer.signDetached(fingerprint(store)));
} }
void ValidPathInfo::sign(const Store & store, const std::vector<std::unique_ptr<Signer>> & signers)
{
auto fingerprint = this->fingerprint(store);
for (auto & signer: signers) {
sigs.insert(signer->signDetached(fingerprint));
}
}
std::optional<ContentAddressWithReferences> ValidPathInfo::contentAddressWithReferences() const std::optional<ContentAddressWithReferences> ValidPathInfo::contentAddressWithReferences() const
{ {
if (! ca) if (! ca)

View file

@ -110,3 +110,13 @@ nix store verify --store "$TEST_ROOT"/store0 -r "$outPath2" --trusted-public-key
# Content-addressed stuff can be copied without signatures. # Content-addressed stuff can be copied without signatures.
nix copy --to "$TEST_ROOT"/store0 "$outPathCA" nix copy --to "$TEST_ROOT"/store0 "$outPathCA"
# Test multiple signing keys
nix copy --to "file://$TEST_ROOT/storemultisig?secret-keys=$TEST_ROOT/sk1,$TEST_ROOT/sk2" "$outPath"
for file in "$TEST_ROOT/storemultisig/"*.narinfo; do
if [[ "$(grep -cE '^Sig: cache[1,2]\.example.org' "$file")" -ne 2 ]]; then
echo "ERROR: Cannot find cache1.example.org and cache2.example.org signatures in ${file}"
cat "${file}"
exit 1
fi
done