From b654381eb38b98aa92df343e3c4a939c1e584443 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 5 Apr 2016 16:39:29 +0200 Subject: [PATCH] Add "nix sign-paths" command E.g. $ nix sign-paths -k ./secret -r $(type -p geeqie) signs geeqie and all its dependencies using the key in ./secret. --- src/libstore/store-api.cc | 3 +++ src/nix/sigs.cc | 50 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index b47376e55..b9939feda 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -312,6 +312,9 @@ void Store::exportPaths(const Paths & paths, std::string ValidPathInfo::fingerprint() const { + if (narSize == 0 || narHash.type == htUnknown) + throw Error(format("cannot calculate fingerprint of path ‘%s’ because its size/hash is not known") + % path); return "1;" + path + ";" + printHashType(narHash.type) + ":" + printHash32(narHash) + ";" diff --git a/src/nix/sigs.cc b/src/nix/sigs.cc index e3544a1fd..bcc46c3e7 100644 --- a/src/nix/sigs.cc +++ b/src/nix/sigs.cc @@ -34,7 +34,7 @@ struct CmdCopySigs : StorePathsCommand restoreAffinity(); // FIXME if (substituterUris.empty()) - throw UsageError("you must specify at least one subtituter using ‘-s’"); + throw UsageError("you must specify at least one substituter using ‘-s’"); // FIXME: factor out commonality with MixVerify. std::vector> substituters; @@ -131,3 +131,51 @@ struct CmdQueryPathSigs : StorePathsCommand }; static RegisterCommand r2(make_ref()); + +struct CmdSignPaths : StorePathsCommand +{ + Path secretKeyFile; + + CmdSignPaths() + { + mkFlag('k', "key-file", {"file"}, "file containing the secret signing key", &secretKeyFile); + } + + std::string name() override + { + return "sign-paths"; + } + + std::string description() override + { + return "sign the specified paths"; + } + + void run(ref store, Paths storePaths) override + { + if (secretKeyFile.empty()) + throw UsageError("you must specify a secret key file using ‘-k’"); + + SecretKey secretKey(readFile(secretKeyFile)); + + size_t added{0}; + + for (auto & storePath : storePaths) { + auto info = store->queryPathInfo(storePath); + + auto info2(info); + info2.sigs.clear(); + info2.sign(secretKey); + assert(!info2.sigs.empty()); + + if (!info.sigs.count(*info2.sigs.begin())) { + store->addSignatures(storePath, info2.sigs); + added++; + } + } + + printMsg(lvlInfo, format("added %d signatures") % added); + } +}; + +static RegisterCommand r3(make_ref());