diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index de456752b..e6b68d486 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -126,8 +126,8 @@ NarInfo BinaryCacheStore::readNarInfo(const Path & storePath) stats.narInfoRead++; if (publicKeys) { - if (!narInfo->checkSignature(*publicKeys)) - throw Error(format("invalid signature on NAR info file ‘%1%’") % narInfoFile); + if (!narInfo->checkSignatures(*publicKeys)) + throw Error(format("no good signature on NAR info file ‘%1%’") % narInfoFile); } { diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index e9260a09b..9028370ac 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -66,7 +66,7 @@ NarInfo::NarInfo(const std::string & s, const std::string & whence) else if (name == "System") system = value; else if (name == "Sig") - sig = value; + sigs.insert(value); pos = eol + 1; } @@ -98,7 +98,7 @@ std::string NarInfo::to_string() const if (!system.empty()) res += "System: " + system + "\n"; - if (!sig.empty()) + for (auto sig : sigs) res += "Sig: " + sig + "\n"; return res; @@ -123,12 +123,16 @@ Strings NarInfo::shortRefs() const void NarInfo::sign(const SecretKey & secretKey) { - sig = secretKey.signDetached(fingerprint()); + sigs.insert(secretKey.signDetached(fingerprint())); } -bool NarInfo::checkSignature(const PublicKeys & publicKeys) const +unsigned int NarInfo::checkSignatures(const PublicKeys & publicKeys) const { - return sig != "" && verifyDetached(fingerprint(), sig, publicKeys); + unsigned int good = 0; + for (auto & sig : sigs) + if (verifyDetached(fingerprint(), sig, publicKeys)) + good++; + return good; } } diff --git a/src/libstore/nar-info.hh b/src/libstore/nar-info.hh index 22e27cb42..2d04e4526 100644 --- a/src/libstore/nar-info.hh +++ b/src/libstore/nar-info.hh @@ -13,7 +13,6 @@ struct NarInfo : ValidPathInfo Hash fileHash; uint64_t fileSize = 0; std::string system; - std::string sig; // FIXME: support multiple signatures NarInfo() { } NarInfo(const ValidPathInfo & info) : ValidPathInfo(info) { } @@ -31,9 +30,9 @@ struct NarInfo : ValidPathInfo void sign(const SecretKey & secretKey); - /* Return true iff this .narinfo is signed by one of the specified - keys. */ - bool checkSignature(const PublicKeys & publicKeys) const; + /* Return the number of signatures on this .narinfo that were + produced by one of the specified keys. */ + unsigned int checkSignatures(const PublicKeys & publicKeys) const; private: diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 9a2c9daca..1a7440148 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -98,6 +98,13 @@ struct ValidPathInfo unsigned long long narSize = 0; // 0 = unknown unsigned long long id; // internal use only + /* Whether the path is ultimately trusted, that is, it was built + locally or is content-addressable (e.g. added via addToStore() + or the result of a fixed-output derivation). */ + bool ultimate = false; + + StringSet sigs; // note: not necessarily verified + bool operator == (const ValidPathInfo & i) const { return