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.
This commit is contained in:
Eelco Dolstra 2016-04-05 16:39:29 +02:00
parent d0f5719c2a
commit b654381eb3
2 changed files with 52 additions and 1 deletions

View file

@ -312,6 +312,9 @@ void Store::exportPaths(const Paths & paths,
std::string ValidPathInfo::fingerprint() const 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 return
"1;" + path + ";" "1;" + path + ";"
+ printHashType(narHash.type) + ":" + printHash32(narHash) + ";" + printHashType(narHash.type) + ":" + printHash32(narHash) + ";"

View file

@ -34,7 +34,7 @@ struct CmdCopySigs : StorePathsCommand
restoreAffinity(); // FIXME restoreAffinity(); // FIXME
if (substituterUris.empty()) 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. // FIXME: factor out commonality with MixVerify.
std::vector<ref<Store>> substituters; std::vector<ref<Store>> substituters;
@ -131,3 +131,51 @@ struct CmdQueryPathSigs : StorePathsCommand
}; };
static RegisterCommand r2(make_ref<CmdQueryPathSigs>()); static RegisterCommand r2(make_ref<CmdQueryPathSigs>());
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> 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<CmdSignPaths>());