* `nix-store --export --sign': sign the Nix archive using the RSA key
in /nix/etc/nix/signing-key.sec
This commit is contained in:
		
							parent
							
								
									6c9fdb17fb
								
							
						
					
					
						commit
						46e0919ced
					
				
					 8 changed files with 125 additions and 32 deletions
				
			
		|  | @ -1,6 +1,6 @@ | |||
| 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 | ||||
| user). | ||||
|  | @ -8,7 +8,7 @@ user). | |||
| 
 | ||||
| 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 | ||||
| export store paths. | ||||
|  |  | |||
|  | @ -477,8 +477,7 @@ static void runSetuidHelper(const string & command, | |||
| 
 | ||||
|     case 0: /* child */ | ||||
|         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(command.c_str()); | ||||
|             args.push_back(arg.c_str()); | ||||
|  |  | |||
|  | @ -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, | ||||
|     Sink & sink) | ||||
| { | ||||
|     assertStorePath(path); | ||||
| 
 | ||||
|     dumpPath(path, sink); | ||||
|     HashAndWriteSink hashAndWriteSink(sink); | ||||
|      | ||||
|     writeString(path, sink); | ||||
|     dumpPath(path, hashAndWriteSink); | ||||
| 
 | ||||
|     writeInt(EXPORT_MAGIC, hashAndWriteSink); | ||||
| 
 | ||||
|     writeString(path, hashAndWriteSink); | ||||
|      | ||||
|     PathSet references; | ||||
|     queryReferences(path, references); | ||||
|     writeStringSet(references, sink); | ||||
|     writeStringSet(references, hashAndWriteSink); | ||||
| 
 | ||||
|     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); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -282,27 +282,36 @@ Hash hashFile(HashType ht, const Path & path) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| struct HashSink : Sink | ||||
| HashSink::HashSink(HashType ht) : ht(ht) | ||||
| { | ||||
|     HashType ht; | ||||
|     Ctx ctx; | ||||
|     virtual void operator () | ||||
|         (const unsigned char * data, unsigned int len) | ||||
|     { | ||||
|         update(ht, ctx, data, len); | ||||
|     } | ||||
| }; | ||||
|     ctx = new Ctx; | ||||
|     start(ht, *ctx); | ||||
| } | ||||
|      | ||||
| HashSink::~HashSink() | ||||
| { | ||||
|     delete ctx; | ||||
| } | ||||
| 
 | ||||
| void HashSink::operator () | ||||
|     (const unsigned char * data, unsigned int 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) | ||||
| { | ||||
|     HashSink sink; | ||||
|     sink.ht = ht; | ||||
|     Hash hash(ht); | ||||
|     start(ht, sink.ctx); | ||||
|     HashSink sink(ht); | ||||
|     dumpPath(path, sink, filter); | ||||
|     finish(ht, sink.ctx, hash.hash); | ||||
|     return hash; | ||||
|     return sink.finish(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| #define __HASH_H | ||||
| 
 | ||||
| #include "types.hh" | ||||
| #include "serialise.hh" | ||||
| 
 | ||||
| 
 | ||||
| namespace nix { | ||||
|  | @ -82,6 +83,22 @@ Hash compressHash(const Hash & hash, unsigned int newSize); | |||
| 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(); | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|      | ||||
|  |  | |||
|  | @ -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. */ | ||||
|     Pipe pipe; | ||||
|  | @ -782,7 +782,16 @@ string runProgram(Path program) | |||
|             if (dup2(pipe.writeSide, STDOUT_FILENO) == -1) | ||||
|                 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); | ||||
|              | ||||
|         } catch (std::exception & e) { | ||||
|  |  | |||
|  | @ -231,7 +231,8 @@ void killUser(uid_t uid); | |||
| 
 | ||||
| /* Run a program and return its stdout in a string (i.e., like the
 | ||||
|    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
 | ||||
|    Cygwin, _exit() doesn't seem to do the right thing.) */ | ||||
|  |  | |||
|  | @ -640,10 +640,14 @@ static void opRestore(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); | ||||
|     store->exportPath(*opArgs.begin(), false, sink); | ||||
|     store->exportPath(*opArgs.begin(), sign, sink); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue