Derive from the mnemonic's words joined by single spaces (closes #49)
check / check (push) Successful in 2m40s
check / check (push) Successful in 2m40s
The seed is computed over the mnemonic string itself, and only its ends were trimmed, so the same words one per line, tab-separated or double-spaced passed the checksum but gave different keys. The words are now joined with single spaces before the checksum and the seed. A test shows each of those three spacings gives the README SSH vector, and the README section on giving the mnemonic says so. Model: opus-5-5
This commit is contained in:
@@ -106,9 +106,8 @@ order; the first one found wins:
|
|||||||
|
|
||||||
1. `--mnemonic-command <command>`: a shell command, run with `sh -c`, whose
|
1. `--mnemonic-command <command>`: a shell command, run with `sh -c`, whose
|
||||||
standard output is the mnemonic. Example:
|
standard output is the mnemonic. Example:
|
||||||
`--mnemonic-command 'secret get foo'`. Whitespace around the output is
|
`--mnemonic-command 'secret get foo'`. If the command exits with a non-zero
|
||||||
dropped. If the command exits with a non-zero status, the tool prints its
|
status, the tool prints its standard error and exits with status 1.
|
||||||
standard error and exits with status 1.
|
|
||||||
2. Environment variable `KEYFUNC_MNEMONIC_COMMAND`: the same, as a shell command
|
2. Environment variable `KEYFUNC_MNEMONIC_COMMAND`: the same, as a shell command
|
||||||
held in the environment.
|
held in the environment.
|
||||||
3. Environment variable `KEYFUNC_MNEMONIC`: the mnemonic itself.
|
3. Environment variable `KEYFUNC_MNEMONIC`: the mnemonic itself.
|
||||||
@@ -116,7 +115,9 @@ order; the first one found wins:
|
|||||||
|
|
||||||
If none of these is available and standard input is not a terminal, the tool
|
If none of these is available and standard input is not a terminal, the tool
|
||||||
refuses and exits with status 1. A mnemonic that fails the BIP-39 checksum is
|
refuses and exits with status 1. A mnemonic that fails the BIP-39 checksum is
|
||||||
refused with a message saying so.
|
refused with a message saying so. Keys are derived from the mnemonic's words
|
||||||
|
joined by single spaces, whatever whitespace is around or between them, so one
|
||||||
|
word per line, tabs or extra spaces give the same keys.
|
||||||
|
|
||||||
`KEYFUNC_MNEMONIC` and `KEYFUNC_MNEMONIC_COMMAND` are removed from the
|
`KEYFUNC_MNEMONIC` and `KEYFUNC_MNEMONIC_COMMAND` are removed from the
|
||||||
environment before the system `ssh` (`keyfunc ssh to`) and `sftp`
|
environment before the system `ssh` (`keyfunc ssh to`) and `sftp`
|
||||||
|
|||||||
@@ -47,6 +47,25 @@ func TestTheReadmeTestVectors(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTheSpacingBetweenTheWordsDoesNotChangeTheKeys(t *testing.T) {
|
||||||
|
words := strings.Fields(example())
|
||||||
|
|
||||||
|
for name, spaced := range map[string]string{
|
||||||
|
"one word per line": strings.Join(words, "\n"),
|
||||||
|
"double spaces": strings.Join(words, " "),
|
||||||
|
"tabs": strings.Join(words, "\t"),
|
||||||
|
} {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Setenv(mnemonic.Variable, spaced)
|
||||||
|
|
||||||
|
require.Equal(t,
|
||||||
|
vectorZero+" keyfunc/ssh/0",
|
||||||
|
strings.TrimSpace(run(t, "ssh", "pub", "-n", "0")),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTheCommentCanBeChosen(t *testing.T) {
|
func TestTheCommentCanBeChosen(t *testing.T) {
|
||||||
t.Setenv(mnemonic.Variable, example())
|
t.Setenv(mnemonic.Variable, example())
|
||||||
|
|
||||||
|
|||||||
@@ -104,10 +104,11 @@ func ask() (string, error) {
|
|||||||
return checked(string(typed))
|
return checked(string(typed))
|
||||||
}
|
}
|
||||||
|
|
||||||
// checked drops the surrounding whitespace and refuses a mnemonic that
|
// checked joins the words with single spaces, whatever whitespace
|
||||||
// does not pass the BIP-39 checksum.
|
// separated them, since the seed is computed over the string itself,
|
||||||
|
// and refuses a mnemonic that does not pass the BIP-39 checksum.
|
||||||
func checked(words string) (string, error) {
|
func checked(words string) (string, error) {
|
||||||
words = strings.TrimSpace(words)
|
words = strings.Join(strings.Fields(words), " ")
|
||||||
|
|
||||||
if !bip39.IsMnemonicValid(words) {
|
if !bip39.IsMnemonicValid(words) {
|
||||||
return "", ErrChecksum
|
return "", ErrChecksum
|
||||||
|
|||||||
Reference in New Issue
Block a user