1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-07 06:01:48 +02:00

Use libsodium instead of OpenSSL for binary cache signing

Sodium's Ed25519 signatures are much shorter than OpenSSL's RSA
signatures. Public keys are also much shorter, so they're now
specified directly in the nix.conf option ‘binary-cache-public-keys’.

The new command ‘nix-store --generate-binary-cache-key’ generates and
prints a public and secret key.
This commit is contained in:
Eelco Dolstra 2015-02-04 16:43:32 +01:00
parent 0d1dafa0c4
commit e0def5bc4b
15 changed files with 196 additions and 91 deletions

View file

@ -925,18 +925,24 @@ std::vector<const char *> stringsToCharPtrs(const Strings & ss)
}
string runProgram(Path program, bool searchPath, const Strings & args)
string runProgram(Path program, bool searchPath, const Strings & args,
const string & input)
{
checkInterrupt();
/* Create a pipe. */
Pipe pipe;
pipe.create();
Pipe stdout, stdin;
stdout.create();
if (!input.empty()) stdin.create();
/* Fork. */
Pid pid = startProcess([&]() {
if (dup2(pipe.writeSide, STDOUT_FILENO) == -1)
if (dup2(stdout.writeSide, STDOUT_FILENO) == -1)
throw SysError("dupping stdout");
if (!input.empty()) {
if (dup2(stdin.readSide, STDIN_FILENO) == -1)
throw SysError("dupping stdin");
}
Strings args_(args);
args_.push_front(program);
@ -950,9 +956,16 @@ string runProgram(Path program, bool searchPath, const Strings & args)
throw SysError(format("executing %1%") % program);
});
pipe.writeSide.close();
stdout.writeSide.close();
string result = drainFD(pipe.readSide);
/* FIXME: This can deadlock if the input is too long. */
if (!input.empty()) {
stdin.readSide.close();
writeFull(stdin.writeSide, input);
stdin.writeSide.close();
}
string result = drainFD(stdout.readSide);
/* Wait for the child to finish. */
int status = pid.wait(true);

View file

@ -285,7 +285,7 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions & options = P
/* Run a program and return its stdout in a string (i.e., like the
shell backtick operator). */
string runProgram(Path program, bool searchPath = false,
const Strings & args = Strings());
const Strings & args = Strings(), const string & input = "");
MakeError(ExecError, Error)

View file

@ -6,6 +6,6 @@ nix-store_SOURCES := $(wildcard $(d)/*.cc)
nix-store_LIBS = libmain libstore libutil libformat
nix-store_LDFLAGS = -lbz2 -pthread
nix-store_LDFLAGS = -lbz2 -pthread $(SODIUM_LIBS)
nix-store_CXXFLAGS = -DCURL=\"$(curl)\"

View file

@ -20,6 +20,8 @@
#include <bzlib.h>
#include <sodium.h>
using namespace nix;
using std::cin;
@ -1006,6 +1008,32 @@ static void opServe(Strings opFlags, Strings opArgs)
}
static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs)
{
foreach (Strings::iterator, i, opFlags)
throw UsageError(format("unknown flag %1%") % *i);
if (opArgs.size() != 1) throw UsageError("one argument expected");
string keyName = opArgs.front();
sodium_init();
unsigned char pk[crypto_sign_PUBLICKEYBYTES];
unsigned char sk[crypto_sign_SECRETKEYBYTES];
if (crypto_sign_keypair(pk, sk) != 0)
throw Error("key generation failed");
// FIXME: super ugly way to do base64 encoding.
auto args = Strings({"-MMIME::Base64", "-0777", "-ne", "print encode_base64($_, '')"});
string pk64 = runProgram("perl", true, args, string((char *) pk, crypto_sign_PUBLICKEYBYTES));
std::cout << keyName << ":" << pk64 << std::endl;
string sk64 = runProgram("perl", true, args, string((char *) sk, crypto_sign_SECRETKEYBYTES));
std::cout << keyName << ":" << sk64 << std::endl;
}
/* Scan the arguments; find the operation, set global flags, put all
other flags in a list, and put all other arguments in another
list. */
@ -1072,14 +1100,16 @@ int main(int argc, char * * argv)
op = opQueryFailedPaths;
else if (*arg == "--clear-failed-paths")
op = opClearFailedPaths;
else if (*arg == "--serve")
op = opServe;
else if (*arg == "--generate-binary-cache-key")
op = opGenerateBinaryCacheKey;
else if (*arg == "--add-root")
gcRoot = absPath(getArg(*arg, arg, end));
else if (*arg == "--indirect")
indirectRoot = true;
else if (*arg == "--no-output")
noOutput = true;
else if (*arg == "--serve")
op = opServe;
else if (*arg != "" && arg->at(0) == '-') {
opFlags.push_back(*arg);
if (*arg == "--max-freed" || *arg == "--max-links" || *arg == "--max-atime") /* !!! hack */