* `nix-store --export --sign': sign the Nix archive using the RSA key

in /nix/etc/nix/signing-key.sec
This commit is contained in:
Eelco Dolstra 2007-02-21 14:31:42 +00:00
parent 6c9fdb17fb
commit 46e0919ced
8 changed files with 125 additions and 32 deletions

View file

@ -1,6 +1,6 @@
Generate a private key: Generate a private key:
$ openssl genrsa -out mykey.sec 2048 $ (umask 277 && openssl genrsa -out /nix/etc/nix/signing-key.sec 2048)
The private key should be kept secret (only readable to the Nix daemon The private key should be kept secret (only readable to the Nix daemon
user). user).
@ -8,7 +8,7 @@ user).
Generate the corresponding public key: Generate the corresponding public key:
$ openssl rsa -in mykey.sec -pubout > mykey.pub $ openssl rsa -in /nix/etc/nix/signing-key.sec -pubout > /nix/etc/nix/signing-key.pub
The public key should be copied to all machines to which you want to The public key should be copied to all machines to which you want to
export store paths. export store paths.

View file

@ -477,8 +477,7 @@ static void runSetuidHelper(const string & command,
case 0: /* child */ case 0: /* child */
try { try {
std::vector<const char *> args; /* careful with c_str()! std::vector<const char *> args; /* careful with c_str()! */
*/
args.push_back(program.c_str()); args.push_back(program.c_str());
args.push_back(command.c_str()); args.push_back(command.c_str());
args.push_back(arg.c_str()); args.push_back(arg.c_str());

View file

@ -696,21 +696,75 @@ Path LocalStore::addTextToStore(const string & suffix, const string & s,
} }
struct HashAndWriteSink : Sink
{
Sink & writeSink;
HashSink hashSink;
bool hashing;
HashAndWriteSink(Sink & writeSink) : writeSink(writeSink), hashSink(htSHA256)
{
hashing = true;
}
virtual void operator ()
(const unsigned char * data, unsigned int len)
{
writeSink(data, len);
if (hashing) hashSink(data, len);
}
};
#define EXPORT_MAGIC 0x4558494e
void LocalStore::exportPath(const Path & path, bool sign, void LocalStore::exportPath(const Path & path, bool sign,
Sink & sink) Sink & sink)
{ {
assertStorePath(path); assertStorePath(path);
dumpPath(path, sink); HashAndWriteSink hashAndWriteSink(sink);
writeString(path, sink); dumpPath(path, hashAndWriteSink);
writeInt(EXPORT_MAGIC, hashAndWriteSink);
writeString(path, hashAndWriteSink);
PathSet references; PathSet references;
queryReferences(path, references); queryReferences(path, references);
writeStringSet(references, sink); writeStringSet(references, hashAndWriteSink);
Path deriver = queryDeriver(noTxn, path); Path deriver = queryDeriver(noTxn, path);
writeString(deriver, sink); writeString(deriver, hashAndWriteSink);
if (sign) {
Hash hash = hashAndWriteSink.hashSink.finish();
hashAndWriteSink.hashing = false;
writeInt(1, hashAndWriteSink);
//printMsg(lvlError, format("HASH = %1%") % printHash(hash));
Path tmpDir = createTempDir();
AutoDelete delTmp(tmpDir);
Path hashFile = tmpDir + "/hash";
writeStringToFile(hashFile, printHash(hash));
Strings args;
args.push_back("rsautl");
args.push_back("-sign");
args.push_back("-inkey");
args.push_back(nixConfDir + "/signing-key.sec");
args.push_back("-in");
args.push_back(hashFile);
string signature = runProgram("openssl", true, args);
//printMsg(lvlError, format("SIGNATURE = %1%") % signature);
writeString(signature, hashAndWriteSink);
} else
writeInt(0, hashAndWriteSink);
} }

View file

@ -282,27 +282,36 @@ Hash hashFile(HashType ht, const Path & path)
} }
struct HashSink : Sink HashSink::HashSink(HashType ht) : ht(ht)
{ {
HashType ht; ctx = new Ctx;
Ctx ctx; start(ht, *ctx);
virtual void operator () }
HashSink::~HashSink()
{
delete ctx;
}
void HashSink::operator ()
(const unsigned char * data, unsigned int len) (const unsigned char * data, unsigned int len)
{ {
update(ht, ctx, data, len); update(ht, *ctx, data, len);
} }
};
Hash HashSink::finish()
{
Hash hash(ht);
nix::finish(ht, *ctx, hash.hash);
return hash;
}
Hash hashPath(HashType ht, const Path & path, PathFilter & filter) Hash hashPath(HashType ht, const Path & path, PathFilter & filter)
{ {
HashSink sink; HashSink sink(ht);
sink.ht = ht;
Hash hash(ht);
start(ht, sink.ctx);
dumpPath(path, sink, filter); dumpPath(path, sink, filter);
finish(ht, sink.ctx, hash.hash); return sink.finish();
return hash;
} }

View file

@ -2,6 +2,7 @@
#define __HASH_H #define __HASH_H
#include "types.hh" #include "types.hh"
#include "serialise.hh"
namespace nix { namespace nix {
@ -82,6 +83,22 @@ Hash compressHash(const Hash & hash, unsigned int newSize);
HashType parseHashType(const string & s); HashType parseHashType(const string & s);
typedef union Ctx;
class HashSink : public Sink
{
private:
HashType ht;
Ctx * ctx;
public:
HashSink(HashType ht);
~HashSink();
virtual void operator () (const unsigned char * data, unsigned int len);
Hash finish();
};
} }

View file

@ -761,7 +761,7 @@ void killUser(uid_t uid)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
string runProgram(Path program) string runProgram(Path program, bool searchPath, const Strings & args)
{ {
/* Create a pipe. */ /* Create a pipe. */
Pipe pipe; Pipe pipe;
@ -782,7 +782,16 @@ string runProgram(Path program)
if (dup2(pipe.writeSide, STDOUT_FILENO) == -1) if (dup2(pipe.writeSide, STDOUT_FILENO) == -1)
throw SysError("dupping from-hook write side"); throw SysError("dupping from-hook write side");
execl(program.c_str(), program.c_str(), (char *) 0); std::vector<const char *> cargs; /* careful with c_str()! */
cargs.push_back(program.c_str());
for (Strings::const_iterator i = args.begin(); i != args.end(); ++i)
cargs.push_back(i->c_str());
cargs.push_back(0);
if (searchPath)
execvp(program.c_str(), (char * *) &cargs[0]);
else
execv(program.c_str(), (char * *) &cargs[0]);
throw SysError(format("executing `%1%'") % program); throw SysError(format("executing `%1%'") % program);
} catch (std::exception & e) { } catch (std::exception & e) {

View file

@ -231,7 +231,8 @@ void killUser(uid_t uid);
/* Run a program and return its stdout in a string (i.e., like the /* Run a program and return its stdout in a string (i.e., like the
shell backtick operator). */ shell backtick operator). */
string runProgram(Path program); string runProgram(Path program, bool searchPath = false,
const Strings & args = Strings());
/* Wrapper around _exit() on Unix and ExitProcess() on Windows. (On /* Wrapper around _exit() on Unix and ExitProcess() on Windows. (On
Cygwin, _exit() doesn't seem to do the right thing.) */ Cygwin, _exit() doesn't seem to do the right thing.) */

View file

@ -640,10 +640,14 @@ static void opRestore(Strings opFlags, Strings opArgs)
static void opExport(Strings opFlags, Strings opArgs) static void opExport(Strings opFlags, Strings opArgs)
{ {
if (!opFlags.empty()) throw UsageError("unknown flag"); bool sign = false;
for (Strings::iterator i = opFlags.begin();
i != opFlags.end(); ++i)
if (*i == "--sign") sign = true;
else throw UsageError(format("unknown flag `%1%'") % *i);
FdSink sink(STDOUT_FILENO); FdSink sink(STDOUT_FILENO);
store->exportPath(*opArgs.begin(), false, sink); store->exportPath(*opArgs.begin(), sign, sink);
} }