|
|
|
@ -25,6 +25,7 @@ var (
|
|
|
|
|
multipleSpaces = regexp.MustCompile(" [ ]+")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ReadAezeed reads an aezeed from the console or the environment variable.
|
|
|
|
|
func ReadAezeed(params *chaincfg.Params) (*hdkeychain.ExtendedKey, time.Time,
|
|
|
|
|
error) {
|
|
|
|
|
|
|
|
|
@ -67,6 +68,32 @@ func ReadAezeed(params *chaincfg.Params) (*hdkeychain.ExtendedKey, time.Time,
|
|
|
|
|
len(cipherSeedMnemonic), 24)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
passphraseBytes, err := ReadPassphrase("doesn't have")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, time.Unix(0, 0), err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var mnemonic aezeed.Mnemonic
|
|
|
|
|
copy(mnemonic[:], cipherSeedMnemonic)
|
|
|
|
|
|
|
|
|
|
// If we're unable to map it back into the ciphertext, then either the
|
|
|
|
|
// mnemonic is wrong, or the passphrase is wrong.
|
|
|
|
|
cipherSeed, err := mnemonic.ToCipherSeed(passphraseBytes)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, time.Unix(0, 0), fmt.Errorf("failed to decrypt "+
|
|
|
|
|
"seed with passphrase: %w", err)
|
|
|
|
|
}
|
|
|
|
|
rootKey, err := hdkeychain.NewMaster(cipherSeed.Entropy[:], params)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, time.Unix(0, 0), fmt.Errorf("failed to derive " +
|
|
|
|
|
"master extended key")
|
|
|
|
|
}
|
|
|
|
|
return rootKey, cipherSeed.BirthdayTime(), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadPassphrase reads a cipher seed passphrase from the console or the
|
|
|
|
|
// environment variable.
|
|
|
|
|
func ReadPassphrase(verb string) ([]byte, error) {
|
|
|
|
|
// Additionally, the user may have a passphrase, that will also need to
|
|
|
|
|
// be provided so the daemon can properly decipher the cipher seed.
|
|
|
|
|
// Try the environment variable first.
|
|
|
|
@ -85,14 +112,14 @@ func ReadAezeed(params *chaincfg.Params) (*hdkeychain.ExtendedKey, time.Time,
|
|
|
|
|
// The environment variable didn't contain anything, we'll read the
|
|
|
|
|
// passphrase from the terminal.
|
|
|
|
|
case passphrase == "":
|
|
|
|
|
fmt.Printf("Input your cipher seed passphrase (press enter " +
|
|
|
|
|
"if your seed doesn't have a passphrase): ")
|
|
|
|
|
fmt.Printf("Input your cipher seed passphrase (press enter "+
|
|
|
|
|
"if your seed %s a passphrase): ", verb)
|
|
|
|
|
var err error
|
|
|
|
|
passphraseBytes, err = terminal.ReadPassword(
|
|
|
|
|
int(syscall.Stdin), //nolint
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, time.Unix(0, 0), err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
fmt.Println()
|
|
|
|
|
|
|
|
|
@ -101,20 +128,5 @@ func ReadAezeed(params *chaincfg.Params) (*hdkeychain.ExtendedKey, time.Time,
|
|
|
|
|
passphraseBytes = []byte(passphrase)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var mnemonic aezeed.Mnemonic
|
|
|
|
|
copy(mnemonic[:], cipherSeedMnemonic)
|
|
|
|
|
|
|
|
|
|
// If we're unable to map it back into the ciphertext, then either the
|
|
|
|
|
// mnemonic is wrong, or the passphrase is wrong.
|
|
|
|
|
cipherSeed, err := mnemonic.ToCipherSeed(passphraseBytes)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, time.Unix(0, 0), fmt.Errorf("failed to decrypt "+
|
|
|
|
|
"seed with passphrase: %w", err)
|
|
|
|
|
}
|
|
|
|
|
rootKey, err := hdkeychain.NewMaster(cipherSeed.Entropy[:], params)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, time.Unix(0, 0), fmt.Errorf("failed to derive " +
|
|
|
|
|
"master extended key")
|
|
|
|
|
}
|
|
|
|
|
return rootKey, cipherSeed.BirthdayTime(), nil
|
|
|
|
|
return passphraseBytes, nil
|
|
|
|
|
}
|
|
|
|
|