aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/path-info.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/path-info.cc')
-rw-r--r--src/libstore/path-info.cc124
1 files changed, 122 insertions, 2 deletions
diff --git a/src/libstore/path-info.cc b/src/libstore/path-info.cc
index 003685604..93f91e702 100644
--- a/src/libstore/path-info.cc
+++ b/src/libstore/path-info.cc
@@ -3,6 +3,125 @@
namespace nix {
+std::string ValidPathInfo::fingerprint(const Store & store) const
+{
+ if (narSize == 0)
+ throw Error("cannot calculate fingerprint of path '%s' because its size is not known",
+ store.printStorePath(path));
+ return
+ "1;" + store.printStorePath(path) + ";"
+ + narHash.to_string(Base32, true) + ";"
+ + std::to_string(narSize) + ";"
+ + concatStringsSep(",", store.printStorePathSet(references));
+}
+
+
+void ValidPathInfo::sign(const Store & store, const SecretKey & secretKey)
+{
+ sigs.insert(secretKey.signDetached(fingerprint(store)));
+}
+
+std::optional<StorePathDescriptor> ValidPathInfo::fullStorePathDescriptorOpt() const
+{
+ if (! ca)
+ return std::nullopt;
+
+ return StorePathDescriptor {
+ .name = std::string { path.name() },
+ .info = std::visit(overloaded {
+ [&](const TextHash & th) -> ContentAddressWithReferences {
+ assert(references.count(path) == 0);
+ return TextInfo {
+ th,
+ .references = references,
+ };
+ },
+ [&](const FixedOutputHash & foh) -> ContentAddressWithReferences {
+ auto refs = references;
+ bool hasSelfReference = false;
+ if (refs.count(path)) {
+ hasSelfReference = true;
+ refs.erase(path);
+ }
+ return FixedOutputInfo {
+ foh,
+ .references = {
+ .others = std::move(refs),
+ .self = hasSelfReference,
+ },
+ };
+ },
+ }, *ca),
+ };
+}
+
+bool ValidPathInfo::isContentAddressed(const Store & store) const
+{
+ auto fullCaOpt = fullStorePathDescriptorOpt();
+
+ if (! fullCaOpt)
+ return false;
+
+ auto caPath = store.makeFixedOutputPathFromCA(*fullCaOpt);
+
+ bool res = caPath == path;
+
+ if (!res)
+ printError("warning: path '%s' claims to be content-addressed but isn't", store.printStorePath(path));
+
+ return res;
+}
+
+
+size_t ValidPathInfo::checkSignatures(const Store & store, const PublicKeys & publicKeys) const
+{
+ if (isContentAddressed(store)) return maxSigs;
+
+ size_t good = 0;
+ for (auto & sig : sigs)
+ if (checkSignature(store, publicKeys, sig))
+ good++;
+ return good;
+}
+
+
+bool ValidPathInfo::checkSignature(const Store & store, const PublicKeys & publicKeys, const std::string & sig) const
+{
+ return verifyDetached(fingerprint(store), sig, publicKeys);
+}
+
+
+Strings ValidPathInfo::shortRefs() const
+{
+ Strings refs;
+ for (auto & r : references)
+ refs.push_back(std::string(r.to_string()));
+ return refs;
+}
+
+
+ValidPathInfo::ValidPathInfo(
+ const Store & store,
+ StorePathDescriptor && info,
+ Hash narHash)
+ : path(store.makeFixedOutputPathFromCA(info))
+ , narHash(narHash)
+{
+ std::visit(overloaded {
+ [this](TextInfo && ti) {
+ this->references = std::move(ti.references);
+ this->ca = std::move((TextHash &&) ti);
+ },
+ [this](FixedOutputInfo && foi) {
+ this->references = std::move(foi.references.others);
+ if (foi.references.self)
+ this->references.insert(path);
+ this->ca = std::move((FixedOutputHash &&) foi);
+ },
+ }, std::move(info.info));
+}
+
+
ValidPathInfo ValidPathInfo::read(Source & source, const Store & store, unsigned int format)
{
return read(source, store, format, store.parseStorePath(readString(source)));
@@ -14,7 +133,7 @@ ValidPathInfo ValidPathInfo::read(Source & source, const Store & store, unsigned
auto narHash = Hash::parseAny(readString(source), htSHA256);
ValidPathInfo info(path, narHash);
if (deriver != "") info.deriver = store.parseStorePath(deriver);
- info.setReferencesPossiblyToSelf(worker_proto::read(store, source, Phantom<StorePathSet> {}));
+ info.references = worker_proto::read(store, source, Phantom<StorePathSet> {});
source >> info.registrationTime >> info.narSize;
if (format >= 16) {
source >> info.ultimate;
@@ -24,6 +143,7 @@ ValidPathInfo ValidPathInfo::read(Source & source, const Store & store, unsigned
return info;
}
+
void ValidPathInfo::write(
Sink & sink,
const Store & store,
@@ -34,7 +154,7 @@ void ValidPathInfo::write(
sink << store.printStorePath(path);
sink << (deriver ? store.printStorePath(*deriver) : "")
<< narHash.to_string(Base16, false);
- worker_proto::write(store, sink, referencesPossiblyToSelf());
+ worker_proto::write(store, sink, references);
sink << registrationTime << narSize;
if (format >= 16) {
sink << ultimate