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.cc113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/libstore/path-info.cc b/src/libstore/path-info.cc
index cb3077c61..2972c0bbe 100644
--- a/src/libstore/path-info.cc
+++ b/src/libstore/path-info.cc
@@ -3,6 +3,117 @@
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(referencesPossiblyToSelf()));
+}
+
+
+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.self);
+ return TextInfo {
+ th,
+ .references = references.others,
+ };
+ },
+ [&](const FixedOutputHash & foh) -> ContentAddressWithReferences {
+ return FixedOutputInfo {
+ foh,
+ .references = references,
+ };
+ },
+ }, *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 : referencesPossiblyToSelf())
+ 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 = {
+ .others = std::move(ti.references),
+ .self = false,
+ };
+ this->ca = std::move((TextHash &&) ti);
+ },
+ [this](FixedOutputInfo && foi) {
+ this->references = std::move(foi.references);
+ this->ca = std::move((FixedOutputHash &&) foi);
+ },
+ }, std::move(info.info));
+}
+
+
StorePathSet ValidPathInfo::referencesPossiblyToSelf() const
{
return references.possiblyToSelf(path);
@@ -18,6 +129,7 @@ void ValidPathInfo::setReferencesPossiblyToSelf(StorePathSet && refs)
return references.setPossiblyToSelf(path, std::move(refs));
}
+
ValidPathInfo ValidPathInfo::read(Source & source, const Store & store, unsigned int format)
{
return read(source, store, format, store.parseStorePath(readString(source)));
@@ -39,6 +151,7 @@ ValidPathInfo ValidPathInfo::read(Source & source, const Store & store, unsigned
return info;
}
+
void ValidPathInfo::write(
Sink & sink,
const Store & store,