Add commands for generating secret/public keys
This commit is contained in:
parent
555152ffe8
commit
9374c2baea
|
@ -132,11 +132,6 @@ struct CmdHash : NixMultiCommand
|
||||||
command->second->prepare();
|
command->second->prepare();
|
||||||
command->second->run();
|
command->second->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void printHelp(const string & programName, std::ostream & out) override
|
|
||||||
{
|
|
||||||
MultiCommand::printHelp(programName, out);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto rCmdHash = registerCommand<CmdHash>("hash");
|
static auto rCmdHash = registerCommand<CmdHash>("hash");
|
||||||
|
|
19
src/nix/key-convert-secret-to-public.md
Normal file
19
src/nix/key-convert-secret-to-public.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
R""(
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
* Convert a secret key to a public key:
|
||||||
|
|
||||||
|
```console
|
||||||
|
# echo cache.example.org-0:E7lAO+MsPwTFfPXsdPtW8GKui/5ho4KQHVcAGnX+Tti1V4dUxoVoqLyWJ4YESuZJwQ67GVIksDt47og+tPVUZw== \
|
||||||
|
| nix key convert-secret-to-public
|
||||||
|
cache.example.org-0:tVeHVMaFaKi8lieGBErmScEOuxlSJLA7eO6IPrT1VGc=
|
||||||
|
```
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
This command reads a Ed25519 secret key from standard input, and
|
||||||
|
writes the corresponding public key to standard output. For more
|
||||||
|
details, see [nix key generate-secret](./nix3-key-generate-secret.md).
|
||||||
|
|
||||||
|
)""
|
48
src/nix/key-generate-secret.md
Normal file
48
src/nix/key-generate-secret.md
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
R""(
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
* Generate a new secret key:
|
||||||
|
|
||||||
|
```console
|
||||||
|
# nix key generate-secret --key-name cache.example.org-1 > ./secret-key
|
||||||
|
```
|
||||||
|
|
||||||
|
We can then use this key to sign the closure of the Hello package:
|
||||||
|
|
||||||
|
```console
|
||||||
|
# nix build nixpkgs#hello
|
||||||
|
# nix store sign-paths --key-file ./secret-key --recursive ./result
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, we can verify the store paths using the corresponding
|
||||||
|
public key:
|
||||||
|
|
||||||
|
```
|
||||||
|
# nix store verify --trusted-public-keys $(nix key convert-secret-to-public < ./secret-key) ./result
|
||||||
|
```
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
This command generates a new Ed25519 secret key for signing store
|
||||||
|
paths and prints it on standard output. Use `nix key
|
||||||
|
convert-secret-to-public` to get the corresponding public key for
|
||||||
|
verifying signed store paths.
|
||||||
|
|
||||||
|
The mandatory argument `--key-name` specifies a key name (such as
|
||||||
|
`cache.example.org-1). It is used to look up keys on the client when
|
||||||
|
it verifies signatures. It can be anything, but it’s suggested to use
|
||||||
|
the host name of your cache (e.g. `cache.example.org`) with a suffix
|
||||||
|
denoting the number of the key (to be incremented every time you need
|
||||||
|
to revoke a key).
|
||||||
|
|
||||||
|
# Format
|
||||||
|
|
||||||
|
Both secret and public keys are represented as the key name followed
|
||||||
|
by a base-64 encoding of the Ed25519 key data, e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
cache.example.org-0:E7lAO+MsPwTFfPXsdPtW8GKui/5ho4KQHVcAGnX+Tti1V4dUxoVoqLyWJ4YESuZJwQ67GVIksDt47og+tPVUZw==
|
||||||
|
```
|
||||||
|
|
||||||
|
)""
|
|
@ -141,3 +141,90 @@ struct CmdSignPaths : StorePathsCommand
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto rCmdSignPaths = registerCommand2<CmdSignPaths>({"store", "sign-paths"});
|
static auto rCmdSignPaths = registerCommand2<CmdSignPaths>({"store", "sign-paths"});
|
||||||
|
|
||||||
|
#if HAVE_SODIUM
|
||||||
|
struct CmdKeyGenerateSecret : Command
|
||||||
|
{
|
||||||
|
std::optional<std::string> keyName;
|
||||||
|
|
||||||
|
CmdKeyGenerateSecret()
|
||||||
|
{
|
||||||
|
addFlag({
|
||||||
|
.longName = "key-name",
|
||||||
|
.description = "identifier of the key (e.g. `cache.example.org-1`)",
|
||||||
|
.labels = {"name"},
|
||||||
|
.handler = {&keyName},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string description() override
|
||||||
|
{
|
||||||
|
return "generate a secret key for signing store paths";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string doc() override
|
||||||
|
{
|
||||||
|
return
|
||||||
|
#include "key-generate-secret.md"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
if (!keyName)
|
||||||
|
throw UsageError("required argument '--key-name' is missing");
|
||||||
|
|
||||||
|
std::cout << SecretKey::generate(*keyName).to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmdKeyConvertSecretToPublic : Command
|
||||||
|
{
|
||||||
|
std::string description() override
|
||||||
|
{
|
||||||
|
return "generate a public key for verifying store paths from a secret key read from standard input";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string doc() override
|
||||||
|
{
|
||||||
|
return
|
||||||
|
#include "key-convert-secret-to-public.md"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
SecretKey secretKey(drainFD(STDIN_FILENO));
|
||||||
|
std::cout << secretKey.toPublicKey().to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmdKey : NixMultiCommand
|
||||||
|
{
|
||||||
|
CmdKey()
|
||||||
|
: MultiCommand({
|
||||||
|
{"generate-secret", []() { return make_ref<CmdKeyGenerateSecret>(); }},
|
||||||
|
{"convert-secret-to-public", []() { return make_ref<CmdKeyConvertSecretToPublic>(); }},
|
||||||
|
})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string description() override
|
||||||
|
{
|
||||||
|
return "generate and convert Nix signing keys";
|
||||||
|
}
|
||||||
|
|
||||||
|
Category category() override { return catUtility; }
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
if (!command)
|
||||||
|
throw UsageError("'nix flake' requires a sub-command.");
|
||||||
|
settings.requireExperimentalFeature("flakes");
|
||||||
|
command->second->prepare();
|
||||||
|
command->second->run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto rCmdKey = registerCommand<CmdKey>("key");
|
||||||
|
#endif
|
||||||
|
|
|
@ -131,14 +131,14 @@ if [ -n "$HAVE_SODIUM" ]; then
|
||||||
clearCache
|
clearCache
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
||||||
declare -a res=($(nix-store --generate-binary-cache-key test.nixos.org-1 $TEST_ROOT/sk1 $TEST_ROOT/pk1 ))
|
nix key generate-secret --key-name test.nixos.org-1 > $TEST_ROOT/sk1
|
||||||
publicKey="$(cat $TEST_ROOT/pk1)"
|
publicKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk1)
|
||||||
|
|
||||||
res=($(nix-store --generate-binary-cache-key test.nixos.org-1 $TEST_ROOT/sk2 $TEST_ROOT/pk2))
|
nix key generate-secret --key-name test.nixos.org-1 > $TEST_ROOT/sk2
|
||||||
badKey="$(cat $TEST_ROOT/pk2)"
|
badKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk2)
|
||||||
|
|
||||||
res=($(nix-store --generate-binary-cache-key foo.nixos.org-1 $TEST_ROOT/sk3 $TEST_ROOT/pk3))
|
nix key generate-secret --key-name foo.nixos.org-1 > $TEST_ROOT/sk3
|
||||||
otherKey="$(cat $TEST_ROOT/pk3)"
|
otherKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk3)
|
||||||
|
|
||||||
_NIX_FORCE_HTTP= nix copy --to file://$cacheDir?secret-key=$TEST_ROOT/sk1 $outPath
|
_NIX_FORCE_HTTP= nix copy --to file://$cacheDir?secret-key=$TEST_ROOT/sk1 $outPath
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue