wallet: remove public passphrase prompt
1. Remove passphrase support for public keys. 2. Rename privPassphrase to passphrase to avoid confusion. Note: There has been a bug in the prompt, which prevents users from specifying a custom public passphrase. So, most wallet databases have been using the default password for the public keys, anyway.
This commit is contained in:
parent
9c20f19d23
commit
17c12a678f
14 changed files with 243 additions and 513 deletions
|
@ -266,11 +266,11 @@ func sweep() error {
|
|||
sourceOutputs[unspentOutput.Address] = append(sourceAddressOutputs, unspentOutput)
|
||||
}
|
||||
|
||||
var privatePassphrase string
|
||||
var passphrase string
|
||||
if len(sourceOutputs) != 0 {
|
||||
privatePassphrase, err = promptSecret("Wallet private passphrase")
|
||||
passphrase, err = promptSecret("Wallet passphrase")
|
||||
if err != nil {
|
||||
return errContext(err, "failed to read private passphrase")
|
||||
return errContext(err, "failed to read passphrase")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ func sweep() error {
|
|||
}
|
||||
|
||||
// Unlock the wallet, sign the transaction, and immediately lock.
|
||||
err = rpcClient.WalletPassphrase(privatePassphrase, 60)
|
||||
err = rpcClient.WalletPassphrase(passphrase, 60)
|
||||
if err != nil {
|
||||
reportError("Failed to unlock wallet: %v", err)
|
||||
continue
|
||||
|
|
|
@ -265,7 +265,6 @@ func loadConfig() (*config, []string, error) {
|
|||
ConfigFile: cfgutil.NewExplicitString(defaultConfigFile),
|
||||
AppDataDir: cfgutil.NewExplicitString(defaultAppDataDir),
|
||||
LogDir: defaultLogDir,
|
||||
WalletPass: wallet.InsecurePubPassphrase,
|
||||
CAFile: cfgutil.NewExplicitString(""),
|
||||
RPCKey: cfgutil.NewExplicitString(defaultRPCKeyFile),
|
||||
RPCCert: cfgutil.NewExplicitString(defaultRPCCertFile),
|
||||
|
|
|
@ -52,10 +52,10 @@ func provideSeed(reader *bufio.Reader) ([]byte, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// ProvidePrivPassphrase is used to prompt for the private passphrase which
|
||||
// maybe required during upgrades.
|
||||
func ProvidePrivPassphrase() ([]byte, error) {
|
||||
prompt := "Enter the private passphrase of your wallet: "
|
||||
// ProvidePassphrase is used to prompt for the passphrase which maybe required
|
||||
// during upgrades.
|
||||
func ProvidePassphrase() ([]byte, error) {
|
||||
prompt := "Enter the passphrase of your wallet: "
|
||||
for {
|
||||
fmt.Print(prompt)
|
||||
pass, err := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||
|
@ -147,10 +147,10 @@ func promptUnixTimestamp(reader *bufio.Reader, prefix string,
|
|||
}
|
||||
}
|
||||
|
||||
// promptPass prompts the user for a passphrase with the given prefix. The
|
||||
// function will ask the user to confirm the passphrase and will repeat the
|
||||
// prompts until they enter a matching response.
|
||||
func promptPass(_ *bufio.Reader, prefix string, confirm bool) ([]byte, error) {
|
||||
// promptPassphrase prompts the user for a passphrase with the given prefix.
|
||||
// The function will ask the user to confirm the passphrase and will repeat
|
||||
// the prompts until they enter a matching response.
|
||||
func promptPassphrase(_ *bufio.Reader, prefix string, confirm bool) ([]byte, error) {
|
||||
// Prompt the user until they enter a passphrase.
|
||||
prompt := fmt.Sprintf("%s: ", prefix)
|
||||
for {
|
||||
|
@ -191,56 +191,11 @@ func birthday(reader *bufio.Reader) (time.Time, error) {
|
|||
return promptUnixTimestamp(reader, prompt, "0")
|
||||
}
|
||||
|
||||
// PrivatePass prompts the user for a private passphrase. The user is prompted
|
||||
// for a new private passphrase. All prompts are repeated until the user
|
||||
// enters a valid response.
|
||||
func PrivatePass(reader *bufio.Reader) ([]byte, error) {
|
||||
return promptPass(reader, "Enter the private "+
|
||||
"passphrase for your new wallet", true)
|
||||
}
|
||||
|
||||
// PublicPass prompts the user whether they want to add an additional layer of
|
||||
// encryption to the wallet. When the user answers yes and there is already a
|
||||
// public passphrase provided via the passed config, it prompts them whether or
|
||||
// not to use that configured passphrase. It will also detect when the same
|
||||
// passphrase is used for the private and public passphrase and prompt the user
|
||||
// if they are sure they want to use the same passphrase for both. Finally, all
|
||||
// prompts are repeated until the user enters a valid response.
|
||||
func PublicPass(reader *bufio.Reader, privPass []byte,
|
||||
defaultPubPassphrase, configPubPassphrase []byte) ([]byte, error) {
|
||||
|
||||
pubPass := defaultPubPassphrase
|
||||
usePubPass, err := promptListBool(reader, "Do you want "+
|
||||
"to add an additional layer of encryption for public "+
|
||||
"data?", "no")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !usePubPass {
|
||||
return pubPass, nil
|
||||
}
|
||||
|
||||
if !bytes.Equal(configPubPassphrase, pubPass) {
|
||||
useExisting, err := promptListBool(reader, "Use the "+
|
||||
"existing configured public passphrase for encryption "+
|
||||
"of public data?", "no")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if useExisting {
|
||||
return configPubPassphrase, nil
|
||||
}
|
||||
}
|
||||
pubPass, err = provideSeed(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("NOTE: Use the --walletpass option to configure your " +
|
||||
"public passphrase.")
|
||||
return pubPass, nil
|
||||
// Passphrase prompts the user for a passphrase.
|
||||
// All prompts are repeated until the user enters a valid response.
|
||||
func Passphrase(reader *bufio.Reader) ([]byte, error) {
|
||||
return promptPassphrase(reader, "Enter the passphrase "+
|
||||
"for your new wallet", true)
|
||||
}
|
||||
|
||||
// Seed prompts the user whether they want to use an existing wallet generation
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) 2015-2021 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func ProvideSeed() ([]byte, error) {
|
||||
return nil, fmt.Errorf("prompt not supported in WebAssembly")
|
||||
}
|
||||
|
||||
func ProvidePrivPassphrase() ([]byte, error) {
|
||||
return nil, fmt.Errorf("prompt not supported in WebAssembly")
|
||||
}
|
||||
|
||||
func PrivatePass(_ *bufio.Reader) ([]byte, error) {
|
||||
return nil, fmt.Errorf("prompt not supported in WebAssembly")
|
||||
}
|
||||
|
||||
func PublicPass(_ *bufio.Reader, _, _, _ []byte) ([]byte, error) {
|
||||
return nil, fmt.Errorf("prompt not supported in WebAssembly")
|
||||
}
|
||||
|
||||
func Seed(_ *bufio.Reader) ([]byte, error) {
|
||||
return nil, fmt.Errorf("prompt not supported in WebAssembly")
|
||||
}
|
|
@ -94,7 +94,7 @@ func walletMain() error {
|
|||
if !cfg.NoInitialLoad {
|
||||
// Load the wallet database. It must have been created already
|
||||
// or this will return an appropriate error.
|
||||
_, err = loader.OpenExistingWallet([]byte(cfg.WalletPass), true)
|
||||
_, err = loader.OpenExistingWallet(true)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
|
|
@ -2154,7 +2154,7 @@ func walletPassphrase(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
func walletPassphraseChange(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
cmd := icmd.(*btcjson.WalletPassphraseChangeCmd)
|
||||
|
||||
err := w.ChangePrivatePassphrase([]byte(cmd.OldPassphrase),
|
||||
err := w.ChangePassphrase([]byte(cmd.OldPassphrase),
|
||||
[]byte(cmd.NewPassphrase))
|
||||
if waddrmgr.IsError(err, waddrmgr.ErrWrongPassphrase) {
|
||||
return nil, &btcjson.RPCError{
|
||||
|
|
|
@ -29,9 +29,7 @@ var (
|
|||
|
||||
rootKey, _ = hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
|
||||
|
||||
pubPassphrase = []byte("_DJr{fL4H0O}*-0\n:V1izc)(6BomK")
|
||||
privPassphrase = []byte("81lUHXnOMZ@?XXd7O9xyDIWIbXX-lj")
|
||||
pubPassphrase2 = []byte("-0NV4P~VSJBWbunw}%<Z]fuGpbN[ZI")
|
||||
passphrase = []byte("81lUHXnOMZ@?XXd7O9xyDIWIbXX-lj")
|
||||
privPassphrase2 = []byte("~{<]08%6!-?2s<$(8$8:f(5[4/!/{Y")
|
||||
|
||||
// fastScrypt are parameters used throughout the tests to speed up the
|
||||
|
@ -287,13 +285,13 @@ func setupManager(t *testing.T) (tearDownFunc func(), db walletdb.DB, mgr *Manag
|
|||
return err
|
||||
}
|
||||
err = Create(
|
||||
ns, rootKey, pubPassphrase, privPassphrase,
|
||||
&chaincfg.MainNetParams, fastScrypt, time.Time{},
|
||||
ns, rootKey, passphrase, &chaincfg.MainNetParams,
|
||||
fastScrypt, time.Time{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mgr, err = Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
mgr, err = Open(ns, &chaincfg.MainNetParams)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -34,7 +34,7 @@ var (
|
|||
|
||||
// ObtainUserInputFunc is a function that reads a user input and returns it as
|
||||
// a byte stream. It is used to accept data required during upgrades, for e.g.
|
||||
// wallet seed and private passphrase.
|
||||
// wallet seed and passphrase.
|
||||
type ObtainUserInputFunc func() ([]byte, error)
|
||||
|
||||
// maybeConvertDbError converts the passed error to a ManagerError with an
|
||||
|
|
|
@ -81,7 +81,7 @@ const (
|
|||
InternalBranch uint32 = 1
|
||||
|
||||
// saltSize is the number of bytes of the salt used when hashing
|
||||
// private passphrases.
|
||||
// passphrases.
|
||||
saltSize = 32
|
||||
)
|
||||
|
||||
|
@ -113,11 +113,11 @@ type OpenCallbacks struct {
|
|||
// from the user (or any other mechanism the caller deems fit).
|
||||
ObtainSeed ObtainUserInputFunc
|
||||
|
||||
// ObtainPrivatePass is a callback function that is potentially invoked
|
||||
// ObtainPassphrase is a callback function that is potentially invoked
|
||||
// during upgrades. It is intended to be used to request the wallet
|
||||
// private passphrase from the user (or any other mechanism the caller
|
||||
// deems fit).
|
||||
ObtainPrivatePass ObtainUserInputFunc
|
||||
// passphrase from the user (or any other mechanism the caller deems
|
||||
// fit).
|
||||
ObtainPassphrase ObtainUserInputFunc
|
||||
}
|
||||
|
||||
// DefaultScryptOptions is the default options used with scrypt.
|
||||
|
@ -373,11 +373,11 @@ type Manager struct {
|
|||
cryptoKeyScriptEncrypted []byte
|
||||
cryptoKeyScript EncryptorDecryptor
|
||||
|
||||
// privPassphraseSalt and hashedPrivPassphrase allow for the secure
|
||||
// detection of a correct passphrase on manager unlock when the
|
||||
// manager is already unlocked. The hash is zeroed each lock.
|
||||
privPassphraseSalt [saltSize]byte
|
||||
hashedPrivPassphrase [sha512.Size]byte
|
||||
// pssphraseSalt and hashedPassphrase allow for the secure detection
|
||||
// of a correct passphrase on manager unlock when the manager is already
|
||||
// unlocked. The hash is zeroed each lock.
|
||||
passphraseSalt [saltSize]byte
|
||||
hashedPassphrase [sha512.Size]byte
|
||||
}
|
||||
|
||||
// lock performs a best try effort to remove and zero all secret keys associated
|
||||
|
@ -413,7 +413,7 @@ func (m *Manager) lock() {
|
|||
m.masterKeyPriv.Zero()
|
||||
|
||||
// Zero the hashed passphrase.
|
||||
zero.Bytea64(&m.hashedPrivPassphrase)
|
||||
zero.Bytea64(&m.hashedPassphrase)
|
||||
|
||||
// NOTE: m.cryptoKeyPub is intentionally not cleared here as the address
|
||||
// manager needs to be able to continue to read and decrypt public data
|
||||
|
@ -825,13 +825,12 @@ func (m *Manager) ChainParams() *chaincfg.Params {
|
|||
return m.chainParams
|
||||
}
|
||||
|
||||
// ChangePassphrase changes either the public or private passphrase to the
|
||||
// provided value depending on the private flag. The new passphrase keys are
|
||||
// derived using the scrypt parameters in the options, so changing the
|
||||
// passphrase may be used to bump the computational difficulty needed to brute
|
||||
// force the passphrase.
|
||||
// ChangePassphrase changes passphrase to the provided value. The new
|
||||
// passphrase keys are derived using the scrypt parameters in the options, so
|
||||
// changing the passphrase may be used to bump the computational difficulty
|
||||
// needed to brute force the passphrase.
|
||||
func (m *Manager) ChangePassphrase(ns walletdb.ReadWriteBucket, oldPassphrase,
|
||||
newPassphrase []byte, private bool, config *ScryptOptions) error {
|
||||
newPassphrase []byte, config *ScryptOptions) error {
|
||||
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
|
@ -842,13 +841,9 @@ func (m *Manager) ChangePassphrase(ns walletdb.ReadWriteBucket, oldPassphrase,
|
|||
// cleared when done to avoid leaving a copy in memory.
|
||||
var keyName string
|
||||
secretKey := snacl.SecretKey{Key: &snacl.CryptoKey{}}
|
||||
if private {
|
||||
keyName = "private"
|
||||
secretKey.Parameters = m.masterKeyPriv.Parameters
|
||||
} else {
|
||||
keyName = "public"
|
||||
secretKey.Parameters = m.masterKeyPub.Parameters
|
||||
}
|
||||
keyName = "private"
|
||||
secretKey.Parameters = m.masterKeyPriv.Parameters
|
||||
|
||||
if err := secretKey.DeriveKey(&oldPassphrase); err != nil {
|
||||
if err == snacl.ErrInvalidPassword {
|
||||
str := fmt.Sprintf("invalid passphrase for %s master "+
|
||||
|
@ -870,112 +865,85 @@ func (m *Manager) ChangePassphrase(ns walletdb.ReadWriteBucket, oldPassphrase,
|
|||
}
|
||||
newKeyParams := newMasterKey.Marshal()
|
||||
|
||||
if private {
|
||||
// Technically, the locked state could be checked here to only
|
||||
// do the decrypts when the address manager is locked as the
|
||||
// clear text keys are already available in memory when it is
|
||||
// unlocked, but this is not a hot path, decryption is quite
|
||||
// fast, and it's less cyclomatic complexity to simply decrypt
|
||||
// in either case.
|
||||
// Technically, the locked state could be checked here to only
|
||||
// do the decrypts when the address manager is locked as the
|
||||
// clear text keys are already available in memory when it is
|
||||
// unlocked, but this is not a hot path, decryption is quite
|
||||
// fast, and it's less cyclomatic complexity to simply decrypt
|
||||
// in either case.
|
||||
|
||||
// Create a new salt that will be used for hashing the new
|
||||
// passphrase each unlock.
|
||||
var passphraseSalt [saltSize]byte
|
||||
_, err := rand.Read(passphraseSalt[:])
|
||||
if err != nil {
|
||||
str := "failed to read random source for passhprase salt"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
|
||||
// Re-encrypt the crypto private key using the new master
|
||||
// private key.
|
||||
decPriv, err := secretKey.Decrypt(m.cryptoKeyPrivEncrypted)
|
||||
if err != nil {
|
||||
str := "failed to decrypt crypto private key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
encPriv, err := newMasterKey.Encrypt(decPriv)
|
||||
zero.Bytes(decPriv)
|
||||
if err != nil {
|
||||
str := "failed to encrypt crypto private key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
|
||||
// Re-encrypt the crypto script key using the new master
|
||||
// private key.
|
||||
decScript, err := secretKey.Decrypt(m.cryptoKeyScriptEncrypted)
|
||||
if err != nil {
|
||||
str := "failed to decrypt crypto script key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
encScript, err := newMasterKey.Encrypt(decScript)
|
||||
zero.Bytes(decScript)
|
||||
if err != nil {
|
||||
str := "failed to encrypt crypto script key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
|
||||
// When the manager is locked, ensure the new clear text master
|
||||
// key is cleared from memory now that it is no longer needed.
|
||||
// If unlocked, create the new passphrase hash with the new
|
||||
// passphrase and salt.
|
||||
var hashedPassphrase [sha512.Size]byte
|
||||
if m.locked {
|
||||
newMasterKey.Zero()
|
||||
} else {
|
||||
saltedPassphrase := append(passphraseSalt[:],
|
||||
newPassphrase...)
|
||||
hashedPassphrase = sha512.Sum512(saltedPassphrase)
|
||||
zero.Bytes(saltedPassphrase)
|
||||
}
|
||||
|
||||
// Save the new keys and params to the db in a single
|
||||
// transaction.
|
||||
err = putCryptoKeys(ns, nil, encPriv, encScript)
|
||||
if err != nil {
|
||||
return maybeConvertDbError(err)
|
||||
}
|
||||
|
||||
err = putMasterKeyParams(ns, nil, newKeyParams)
|
||||
if err != nil {
|
||||
return maybeConvertDbError(err)
|
||||
}
|
||||
|
||||
// Now that the db has been successfully updated, clear the old
|
||||
// key and set the new one.
|
||||
copy(m.cryptoKeyPrivEncrypted, encPriv)
|
||||
copy(m.cryptoKeyScriptEncrypted, encScript)
|
||||
m.masterKeyPriv.Zero() // Clear the old key.
|
||||
m.masterKeyPriv = newMasterKey
|
||||
m.privPassphraseSalt = passphraseSalt
|
||||
m.hashedPrivPassphrase = hashedPassphrase
|
||||
} else {
|
||||
// Re-encrypt the crypto public key using the new master public
|
||||
// key.
|
||||
encryptedPub, err := newMasterKey.Encrypt(m.cryptoKeyPub.Bytes())
|
||||
if err != nil {
|
||||
str := "failed to encrypt crypto public key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
|
||||
// Save the new keys and params to the the db in a single
|
||||
// transaction.
|
||||
err = putCryptoKeys(ns, encryptedPub, nil, nil)
|
||||
if err != nil {
|
||||
return maybeConvertDbError(err)
|
||||
}
|
||||
|
||||
err = putMasterKeyParams(ns, newKeyParams, nil)
|
||||
if err != nil {
|
||||
return maybeConvertDbError(err)
|
||||
}
|
||||
|
||||
// Now that the db has been successfully updated, clear the old
|
||||
// key and set the new one.
|
||||
m.masterKeyPub.Zero()
|
||||
m.masterKeyPub = newMasterKey
|
||||
// Create a new salt that will be used for hashing the new
|
||||
// passphrase each unlock.
|
||||
var passphraseSalt [saltSize]byte
|
||||
_, err = rand.Read(passphraseSalt[:])
|
||||
if err != nil {
|
||||
str := "failed to read random source for passhprase salt"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
|
||||
// Re-encrypt the crypto private key using the new master
|
||||
// private key.
|
||||
decPriv, err := secretKey.Decrypt(m.cryptoKeyPrivEncrypted)
|
||||
if err != nil {
|
||||
str := "failed to decrypt crypto private key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
encPriv, err := newMasterKey.Encrypt(decPriv)
|
||||
zero.Bytes(decPriv)
|
||||
if err != nil {
|
||||
str := "failed to encrypt crypto private key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
|
||||
// Re-encrypt the crypto script key using the new master
|
||||
// private key.
|
||||
decScript, err := secretKey.Decrypt(m.cryptoKeyScriptEncrypted)
|
||||
if err != nil {
|
||||
str := "failed to decrypt crypto script key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
encScript, err := newMasterKey.Encrypt(decScript)
|
||||
zero.Bytes(decScript)
|
||||
if err != nil {
|
||||
str := "failed to encrypt crypto script key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
|
||||
// When the manager is locked, ensure the new clear text master
|
||||
// key is cleared from memory now that it is no longer needed.
|
||||
// If unlocked, create the new passphrase hash with the new
|
||||
// passphrase and salt.
|
||||
var hashedPassphrase [sha512.Size]byte
|
||||
if m.locked {
|
||||
newMasterKey.Zero()
|
||||
} else {
|
||||
saltedPassphrase := append(passphraseSalt[:],
|
||||
newPassphrase...)
|
||||
hashedPassphrase = sha512.Sum512(saltedPassphrase)
|
||||
zero.Bytes(saltedPassphrase)
|
||||
}
|
||||
|
||||
// Save the new keys and params to the db in a single
|
||||
// transaction.
|
||||
err = putCryptoKeys(ns, nil, encPriv, encScript)
|
||||
if err != nil {
|
||||
return maybeConvertDbError(err)
|
||||
}
|
||||
|
||||
err = putMasterKeyParams(ns, nil, newKeyParams)
|
||||
if err != nil {
|
||||
return maybeConvertDbError(err)
|
||||
}
|
||||
|
||||
// Now that the db has been successfully updated, clear the old
|
||||
// key and set the new one.
|
||||
copy(m.cryptoKeyPrivEncrypted, encPriv)
|
||||
copy(m.cryptoKeyScriptEncrypted, encScript)
|
||||
m.masterKeyPriv.Zero() // Clear the old key.
|
||||
m.masterKeyPriv = newMasterKey
|
||||
m.passphraseSalt = passphraseSalt
|
||||
m.hashedPassphrase = hashedPassphrase
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1027,11 +995,10 @@ func (m *Manager) Unlock(ns walletdb.ReadBucket, passphrase []byte) error {
|
|||
// Avoid actually unlocking if the manager is already unlocked
|
||||
// and the passphrases match.
|
||||
if !m.locked {
|
||||
saltedPassphrase := append(m.privPassphraseSalt[:],
|
||||
passphrase...)
|
||||
saltedPassphrase := append(m.passphraseSalt[:], passphrase...)
|
||||
hashedPassphrase := sha512.Sum512(saltedPassphrase)
|
||||
zero.Bytes(saltedPassphrase)
|
||||
if hashedPassphrase != m.hashedPrivPassphrase {
|
||||
if hashedPassphrase != m.hashedPassphrase {
|
||||
m.lock()
|
||||
str := "invalid passphrase for master private key"
|
||||
return managerError(ErrWrongPassphrase, str, nil)
|
||||
|
@ -1126,8 +1093,8 @@ func (m *Manager) Unlock(ns walletdb.ReadBucket, passphrase []byte) error {
|
|||
}
|
||||
|
||||
m.locked = false
|
||||
saltedPassphrase := append(m.privPassphraseSalt[:], passphrase...)
|
||||
m.hashedPrivPassphrase = sha512.Sum512(saltedPassphrase)
|
||||
saltedPassphrase := append(m.passphraseSalt[:], passphrase...)
|
||||
m.hashedPassphrase = sha512.Sum512(saltedPassphrase)
|
||||
zero.Bytes(saltedPassphrase)
|
||||
return nil
|
||||
}
|
||||
|
@ -1235,7 +1202,7 @@ func (m *Manager) Decrypt(keyType CryptoKeyType, in []byte) ([]byte, error) {
|
|||
func newManager(chainParams *chaincfg.Params, masterKeyPub *snacl.SecretKey,
|
||||
masterKeyPriv *snacl.SecretKey, cryptoKeyPub EncryptorDecryptor,
|
||||
cryptoKeyPrivEncrypted, cryptoKeyScriptEncrypted []byte, syncInfo *syncState,
|
||||
birthday time.Time, privPassphraseSalt [saltSize]byte,
|
||||
birthday time.Time, passphraseSalt [saltSize]byte,
|
||||
scopedManagers map[KeyScope]*ScopedKeyManager) *Manager {
|
||||
|
||||
m := &Manager{
|
||||
|
@ -1250,7 +1217,7 @@ func newManager(chainParams *chaincfg.Params, masterKeyPub *snacl.SecretKey,
|
|||
cryptoKeyPriv: &cryptoKey{},
|
||||
cryptoKeyScriptEncrypted: cryptoKeyScriptEncrypted,
|
||||
cryptoKeyScript: &cryptoKey{},
|
||||
privPassphraseSalt: privPassphraseSalt,
|
||||
passphraseSalt: passphraseSalt,
|
||||
scopedManagers: scopedManagers,
|
||||
externalAddrSchemas: make(map[AddressType][]KeyScope),
|
||||
internalAddrSchemas: make(map[AddressType][]KeyScope),
|
||||
|
@ -1361,10 +1328,9 @@ func checkBranchKeys(acctKey *hdkeychain.ExtendedKey) error {
|
|||
}
|
||||
|
||||
// loadManager returns a new address manager that results from loading it from
|
||||
// the passed opened database. The public passphrase is required to decrypt
|
||||
// the public keys.
|
||||
func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte,
|
||||
chainParams *chaincfg.Params) (*Manager, error) {
|
||||
// the passed opened database.
|
||||
func loadManager(ns walletdb.ReadBucket, chainParams *chaincfg.Params) (
|
||||
*Manager, error) {
|
||||
|
||||
// Verify the version is neither too old or too new.
|
||||
version, err := fetchManagerVersion(ns)
|
||||
|
@ -1381,7 +1347,7 @@ func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte,
|
|||
}
|
||||
|
||||
// Load the master key params from the db.
|
||||
masterKeyPubParams, masterKeyPrivParams, err := fetchMasterKeyParams(ns)
|
||||
masterKeyPubParams, masterKeyparams, err := fetchMasterKeyParams(ns)
|
||||
if err != nil {
|
||||
return nil, maybeConvertDbError(err)
|
||||
}
|
||||
|
@ -1410,7 +1376,7 @@ func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte,
|
|||
// Set the master private key params, but don't derive it now since the
|
||||
// manager starts off locked.
|
||||
var masterKeyPriv snacl.SecretKey
|
||||
err = masterKeyPriv.Unmarshal(masterKeyPrivParams)
|
||||
err = masterKeyPriv.Unmarshal(masterKeyparams)
|
||||
if err != nil {
|
||||
str := "failed to unmarshal master private key"
|
||||
return nil, managerError(ErrCrypto, str, err)
|
||||
|
@ -1423,6 +1389,8 @@ func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte,
|
|||
str := "failed to unmarshal master public key"
|
||||
return nil, managerError(ErrCrypto, str, err)
|
||||
}
|
||||
|
||||
pubPassphrase := []byte("public") // Hardcoded salt.
|
||||
if err := masterKeyPub.DeriveKey(&pubPassphrase); err != nil {
|
||||
str := "invalid passphrase for master public key"
|
||||
return nil, managerError(ErrWrongPassphrase, str, nil)
|
||||
|
@ -1441,9 +1409,9 @@ func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte,
|
|||
// Create the sync state struct.
|
||||
syncInfo := newSyncState(startBlock, syncedTo)
|
||||
|
||||
// Generate private passphrase salt.
|
||||
var privPassphraseSalt [saltSize]byte
|
||||
_, err = rand.Read(privPassphraseSalt[:])
|
||||
// Generate passphrase salt.
|
||||
var passphraseSalt [saltSize]byte
|
||||
_, err = rand.Read(passphraseSalt[:])
|
||||
if err != nil {
|
||||
str := "failed to read random source for passphrase salt"
|
||||
return nil, managerError(ErrCrypto, str, err)
|
||||
|
@ -1480,7 +1448,7 @@ func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte,
|
|||
mgr := newManager(
|
||||
chainParams, &masterKeyPub, &masterKeyPriv,
|
||||
cryptoKeyPub, cryptoKeyPrivEnc, cryptoKeyScriptEnc, syncInfo,
|
||||
birthday, privPassphraseSalt, scopedManagers)
|
||||
birthday, passphraseSalt, scopedManagers)
|
||||
|
||||
for _, scopedManager := range scopedManagers {
|
||||
scopedManager.rootManager = mgr
|
||||
|
@ -1489,18 +1457,15 @@ func loadManager(ns walletdb.ReadBucket, pubPassphrase []byte,
|
|||
return mgr, nil
|
||||
}
|
||||
|
||||
// Open loads an existing address manager from the given namespace. The public
|
||||
// passphrase is required to decrypt the public keys used to protect the public
|
||||
// information such as addresses. This is important since access to BIP0032
|
||||
// extended keys means it is possible to generate all future addresses.
|
||||
// Open loads an existing address manager from the given namespace.
|
||||
//
|
||||
// If a config structure is passed to the function, that configuration will
|
||||
// override the defaults.
|
||||
//
|
||||
// A ManagerError with an error code of ErrNoExist will be returned if the
|
||||
// passed manager does not exist in the specified namespace.
|
||||
func Open(ns walletdb.ReadBucket, pubPassphrase []byte,
|
||||
chainParams *chaincfg.Params) (*Manager, error) {
|
||||
func Open(ns walletdb.ReadBucket, chainParams *chaincfg.Params) (
|
||||
*Manager, error) {
|
||||
|
||||
// Return an error if the manager has NOT already been created in the
|
||||
// given database namespace.
|
||||
|
@ -1510,7 +1475,7 @@ func Open(ns walletdb.ReadBucket, pubPassphrase []byte,
|
|||
return nil, managerError(ErrNoExist, str, nil)
|
||||
}
|
||||
|
||||
return loadManager(ns, pubPassphrase, chainParams)
|
||||
return loadManager(ns, chainParams)
|
||||
}
|
||||
|
||||
// createManagerKeyScope creates a new key scoped for a target manager's scope.
|
||||
|
@ -1622,12 +1587,10 @@ func createManagerKeyScope(ns walletdb.ReadWriteBucket,
|
|||
// derived. This allows all chained addresses in the address manager
|
||||
// to be recovered by using the same seed.
|
||||
//
|
||||
// All private and public keys and information are protected by secret
|
||||
// keys derived from the provided private and public passphrases. The
|
||||
// public passphrase is required on subsequent opens of the address
|
||||
// manager, and the private passphrase is required to unlock the
|
||||
// address manager in order to gain access to any private keys and
|
||||
// information.
|
||||
// All private keys and information are protected by secret keys derived
|
||||
// from the provided passphrase.
|
||||
// The passphrase is required to unlock the address manager in order to gain
|
||||
// access to any private keys and information.
|
||||
//
|
||||
// If a config structure is passed to the function, that configuration
|
||||
// will override the defaults.
|
||||
|
@ -1636,9 +1599,8 @@ func createManagerKeyScope(ns walletdb.ReadWriteBucket,
|
|||
// returned the address manager already exists in the specified
|
||||
// namespace.
|
||||
func Create(ns walletdb.ReadWriteBucket, rootKey *hdkeychain.ExtendedKey,
|
||||
pubPassphrase, privPassphrase []byte,
|
||||
chainParams *chaincfg.Params, config *ScryptOptions,
|
||||
birthday time.Time) error {
|
||||
passphrase []byte, chainParams *chaincfg.Params,
|
||||
config *ScryptOptions, birthday time.Time) error {
|
||||
|
||||
// Return an error if the manager has already been created in
|
||||
// the given database namespace.
|
||||
|
@ -1647,9 +1609,9 @@ func Create(ns walletdb.ReadWriteBucket, rootKey *hdkeychain.ExtendedKey,
|
|||
return managerError(ErrAlreadyExists, errAlreadyExists, nil)
|
||||
}
|
||||
|
||||
// Ensure the private passphrase is not empty.
|
||||
if len(privPassphrase) == 0 {
|
||||
str := "private passphrase may not be empty"
|
||||
// Ensure the passphrase is not empty.
|
||||
if len(passphrase) == 0 {
|
||||
str := "passphrase may not be empty"
|
||||
return managerError(ErrEmptyPassphrase, str, nil)
|
||||
}
|
||||
|
||||
|
@ -1664,6 +1626,7 @@ func Create(ns walletdb.ReadWriteBucket, rootKey *hdkeychain.ExtendedKey,
|
|||
|
||||
// Generate new master keys. These master keys are used to protect the
|
||||
// crypto keys that will be generated next.
|
||||
pubPassphrase := []byte("public") // Hardcoded salt.
|
||||
masterKeyPub, err := newSecretKey(&pubPassphrase, config)
|
||||
if err != nil {
|
||||
str := "failed to master public key"
|
||||
|
@ -1699,22 +1662,22 @@ func Create(ns walletdb.ReadWriteBucket, rootKey *hdkeychain.ExtendedKey,
|
|||
|
||||
pubParams := masterKeyPub.Marshal()
|
||||
|
||||
var privParams []byte
|
||||
var params []byte
|
||||
var masterKeyPriv *snacl.SecretKey
|
||||
var cryptoKeyPrivEnc []byte
|
||||
var cryptoKeyScriptEnc []byte
|
||||
masterKeyPriv, err = newSecretKey(&privPassphrase, config)
|
||||
masterKeyPriv, err = newSecretKey(&passphrase, config)
|
||||
if err != nil {
|
||||
str := "failed to master private key"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
}
|
||||
defer masterKeyPriv.Zero()
|
||||
|
||||
// Generate the private passphrase salt. This is used when
|
||||
// hashing passwords to detect whether an unlock can be
|
||||
// avoided when the manager is already unlocked.
|
||||
var privPassphraseSalt [saltSize]byte
|
||||
_, err = rand.Read(privPassphraseSalt[:])
|
||||
// Generate the passphrase salt. This is used when hashing passwords
|
||||
// to detect whether an unlock can be avoided when the manager is
|
||||
// already unlocked.
|
||||
var passphraseSalt [saltSize]byte
|
||||
_, err = rand.Read(passphraseSalt[:])
|
||||
if err != nil {
|
||||
str := "failed to read random source for passphrase salt"
|
||||
return managerError(ErrCrypto, str, err)
|
||||
|
@ -1786,10 +1749,10 @@ func Create(ns walletdb.ReadWriteBucket, rootKey *hdkeychain.ExtendedKey,
|
|||
return maybeConvertDbError(err)
|
||||
}
|
||||
|
||||
privParams = masterKeyPriv.Marshal()
|
||||
params = masterKeyPriv.Marshal()
|
||||
|
||||
// Save the master key params to the database.
|
||||
err = putMasterKeyParams(ns, pubParams, privParams)
|
||||
err = putMasterKeyParams(ns, pubParams, params)
|
||||
if err != nil {
|
||||
return maybeConvertDbError(err)
|
||||
}
|
||||
|
|
|
@ -431,7 +431,7 @@ func testExternalAddresses(tc *testContext) bool {
|
|||
// private information is valid as well.
|
||||
err := walletdb.View(tc.db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.Unlock(ns, privPassphrase)
|
||||
return tc.rootManager.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("Unlock: unexpected error: %v", err)
|
||||
|
@ -463,7 +463,7 @@ func testInternalAddresses(tc *testContext) bool {
|
|||
// private information is valid as well.
|
||||
err := walletdb.View(tc.db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.Unlock(ns, privPassphrase)
|
||||
return tc.rootManager.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("Unlock: unexpected error: %v", err)
|
||||
|
@ -603,7 +603,7 @@ func testLocking(tc *testContext) bool {
|
|||
// unexpected errors and the manager properly reports it is unlocked.
|
||||
err = walletdb.View(tc.db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.Unlock(ns, privPassphrase)
|
||||
return tc.rootManager.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("Unlock: unexpected error: %v", err)
|
||||
|
@ -617,7 +617,7 @@ func testLocking(tc *testContext) bool {
|
|||
// Unlocking the manager again is allowed.
|
||||
err = walletdb.View(tc.db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.Unlock(ns, privPassphrase)
|
||||
return tc.rootManager.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("Unlock: unexpected error: %v", err)
|
||||
|
@ -696,7 +696,7 @@ func testImportPrivateKey(tc *testContext) bool {
|
|||
// The manager must be unlocked to import a private key.
|
||||
err := walletdb.View(tc.db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.Unlock(ns, privPassphrase)
|
||||
return tc.rootManager.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("Unlock: unexpected error: %v", err)
|
||||
|
@ -913,7 +913,7 @@ func testImportScript(tc *testContext) bool {
|
|||
// testing private data.
|
||||
err := walletdb.View(tc.db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.Unlock(ns, privPassphrase)
|
||||
return tc.rootManager.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("Unlock: unexpected error: %v", err)
|
||||
|
@ -1122,74 +1122,11 @@ func testMarkUsed(tc *testContext, doScript bool) bool {
|
|||
func testChangePassphrase(tc *testContext) bool {
|
||||
pfx := fmt.Sprintf("(%s) ", tc.caseName)
|
||||
|
||||
// Force an error when changing the passphrase due to failure to
|
||||
// generate a new secret key by replacing the generation function one
|
||||
// that intentionally errors.
|
||||
testName := pfx + "ChangePassphrase (public) with invalid new secret key"
|
||||
|
||||
oldKeyGen := SetSecretKeyGen(failingSecretKeyGen)
|
||||
testName := pfx + "ChangePassphrase with invalid old passphrase"
|
||||
err := walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.ChangePassphrase(
|
||||
ns, pubPassphrase, pubPassphrase2, false, fastScrypt,
|
||||
)
|
||||
})
|
||||
if !checkManagerError(tc.t, testName, err, ErrCrypto) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Attempt to change public passphrase with invalid old passphrase.
|
||||
testName = pfx + "ChangePassphrase (public) with invalid old passphrase"
|
||||
SetSecretKeyGen(oldKeyGen)
|
||||
err = walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.ChangePassphrase(
|
||||
ns, []byte("bogus"), pubPassphrase2, false, fastScrypt,
|
||||
)
|
||||
})
|
||||
if !checkManagerError(tc.t, testName, err, ErrWrongPassphrase) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Change the public passphrase.
|
||||
testName = pfx + "ChangePassphrase (public)"
|
||||
err = walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.ChangePassphrase(
|
||||
ns, pubPassphrase, pubPassphrase2, false, fastScrypt,
|
||||
)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("%s: unexpected error: %v", testName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
// Ensure the public passphrase was successfully changed. We do this by
|
||||
// being able to re-derive the public key with the new passphrase.
|
||||
secretKey := snacl.SecretKey{Key: &snacl.CryptoKey{}}
|
||||
secretKey.Parameters = tc.rootManager.masterKeyPub.Parameters
|
||||
if err := secretKey.DeriveKey(&pubPassphrase2); err != nil {
|
||||
tc.t.Errorf("%s: passphrase does not match", testName)
|
||||
return false
|
||||
}
|
||||
|
||||
// Change the private passphrase back to what it was.
|
||||
err = walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.ChangePassphrase(
|
||||
ns, pubPassphrase2, pubPassphrase, false, fastScrypt,
|
||||
)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("%s: unexpected error: %v", testName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
testName = pfx + "ChangePassphrase (private) with invalid old passphrase"
|
||||
err = walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.ChangePassphrase(
|
||||
ns, []byte("bogus"), privPassphrase2, true, fastScrypt,
|
||||
ns, []byte("bogus"), privPassphrase2, fastScrypt,
|
||||
)
|
||||
})
|
||||
wantErrCode := ErrWrongPassphrase
|
||||
|
@ -1197,12 +1134,11 @@ func testChangePassphrase(tc *testContext) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Change the private passphrase.
|
||||
testName = pfx + "ChangePassphrase (private)"
|
||||
testName = pfx + "ChangePassphrase"
|
||||
err = walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.ChangePassphrase(
|
||||
ns, privPassphrase, privPassphrase2, true, fastScrypt,
|
||||
ns, passphrase, privPassphrase2, fastScrypt,
|
||||
)
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -1217,8 +1153,8 @@ func testChangePassphrase(tc *testContext) bool {
|
|||
return tc.rootManager.Unlock(ns, privPassphrase2)
|
||||
})
|
||||
if err != nil {
|
||||
tc.t.Errorf("%s: failed to unlock with new private "+
|
||||
"passphrase: %v", testName, err)
|
||||
tc.t.Errorf("%s: failed to unlock with new passphrase: %v",
|
||||
testName, err)
|
||||
return false
|
||||
}
|
||||
tc.unlocked = true
|
||||
|
@ -1228,7 +1164,7 @@ func testChangePassphrase(tc *testContext) bool {
|
|||
err = walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return tc.rootManager.ChangePassphrase(
|
||||
ns, privPassphrase2, privPassphrase, true, fastScrypt,
|
||||
ns, privPassphrase2, passphrase, fastScrypt,
|
||||
)
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -1269,7 +1205,7 @@ func testNewAccount(tc *testContext) bool {
|
|||
// to derive account keys
|
||||
err = walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
err := tc.rootManager.Unlock(ns, privPassphrase)
|
||||
err := tc.rootManager.Unlock(ns, passphrase)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -1668,7 +1604,7 @@ func _TestManager(t *testing.T) {
|
|||
{
|
||||
name: "created with seed",
|
||||
rootKey: rootKey,
|
||||
privPassphrase: privPassphrase,
|
||||
privPassphrase: passphrase,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1688,7 +1624,7 @@ func testManagerCase(t *testing.T, caseName string,
|
|||
// returned.
|
||||
err := walletdb.View(db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
_, err := Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
_, err := Open(ns, &chaincfg.MainNetParams)
|
||||
return err
|
||||
})
|
||||
if !checkManagerError(t, "Open non-existent", err, ErrNoExist) {
|
||||
|
@ -1703,13 +1639,13 @@ func testManagerCase(t *testing.T, caseName string,
|
|||
return err
|
||||
}
|
||||
err = Create(
|
||||
ns, caseKey, pubPassphrase, casePrivPassphrase,
|
||||
ns, caseKey, casePrivPassphrase,
|
||||
&chaincfg.MainNetParams, fastScrypt, time.Time{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mgr, err = Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
mgr, err = Open(ns, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1729,7 +1665,7 @@ func testManagerCase(t *testing.T, caseName string,
|
|||
err = walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return Create(
|
||||
ns, caseKey, pubPassphrase, casePrivPassphrase,
|
||||
ns, caseKey, casePrivPassphrase,
|
||||
&chaincfg.MainNetParams, fastScrypt, time.Time{},
|
||||
)
|
||||
})
|
||||
|
@ -1762,7 +1698,7 @@ func testManagerCase(t *testing.T, caseName string,
|
|||
err = walletdb.View(db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
var err error
|
||||
mgr, err = Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
mgr, err = Open(ns, &chaincfg.MainNetParams)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -1845,7 +1781,7 @@ func TestManagerHigherVersion(t *testing.T) {
|
|||
// should expect to see the error ErrUpgrade.
|
||||
err = walletdb.View(db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
_, err := Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
_, err := Open(ns, &chaincfg.MainNetParams)
|
||||
return err
|
||||
})
|
||||
if !checkManagerError(t, "Upgrade needed", err, ErrUpgrade) {
|
||||
|
@ -1869,7 +1805,7 @@ func TestManagerHigherVersion(t *testing.T) {
|
|||
// ErrUpgrade.
|
||||
err = walletdb.View(db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
_, err := Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
_, err := Open(ns, &chaincfg.MainNetParams)
|
||||
return err
|
||||
})
|
||||
if !checkManagerError(t, "Upgrade needed", err, ErrUpgrade) {
|
||||
|
@ -1913,7 +1849,7 @@ func TestEncryptDecryptErrors(t *testing.T) {
|
|||
// Unlock the manager for these tests
|
||||
err = walletdb.View(db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return mgr.Unlock(ns, privPassphrase)
|
||||
return mgr.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Attempted to unlock the manager, but failed:", err)
|
||||
|
@ -1945,7 +1881,7 @@ func TestEncryptDecrypt(t *testing.T) {
|
|||
// Make sure address manager is unlocked
|
||||
err := walletdb.View(db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return mgr.Unlock(ns, privPassphrase)
|
||||
return mgr.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Attempted to unlock the manager, but failed:", err)
|
||||
|
@ -1993,19 +1929,19 @@ func TestScopedKeyManagerManagement(t *testing.T) {
|
|||
return err
|
||||
}
|
||||
err = Create(
|
||||
ns, rootKey, pubPassphrase, privPassphrase,
|
||||
ns, rootKey, passphrase,
|
||||
&chaincfg.MainNetParams, fastScrypt, time.Time{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mgr, err = Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
mgr, err = Open(ns, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mgr.Unlock(ns, privPassphrase)
|
||||
return mgr.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create/open: unexpected error: %v", err)
|
||||
|
@ -2152,12 +2088,12 @@ func TestScopedKeyManagerManagement(t *testing.T) {
|
|||
err = walletdb.View(db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
var err error
|
||||
mgr, err = Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
mgr, err = Open(ns, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mgr.Unlock(ns, privPassphrase)
|
||||
return mgr.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("open: unexpected error: %v", err)
|
||||
|
@ -2243,19 +2179,19 @@ func TestRootHDKeyNeutering(t *testing.T) {
|
|||
return err
|
||||
}
|
||||
err = Create(
|
||||
ns, rootKey, pubPassphrase, privPassphrase,
|
||||
ns, rootKey, passphrase,
|
||||
&chaincfg.MainNetParams, fastScrypt, time.Time{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mgr, err = Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
mgr, err = Open(ns, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mgr.Unlock(ns, privPassphrase)
|
||||
return mgr.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create/open: unexpected error: %v", err)
|
||||
|
@ -2336,19 +2272,19 @@ func TestNewRawAccount(t *testing.T) {
|
|||
return err
|
||||
}
|
||||
err = Create(
|
||||
ns, rootKey, pubPassphrase, privPassphrase,
|
||||
ns, rootKey, passphrase,
|
||||
&chaincfg.MainNetParams, fastScrypt, time.Time{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mgr, err = Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
mgr, err = Open(ns, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mgr.Unlock(ns, privPassphrase)
|
||||
return mgr.Unlock(ns, passphrase)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create/open: unexpected error: %v", err)
|
||||
|
@ -2449,18 +2385,18 @@ func TestDeriveFromKeyPathCache(t *testing.T) {
|
|||
return err
|
||||
}
|
||||
err = Create(
|
||||
ns, rootKey, pubPassphrase, privPassphrase,
|
||||
ns, rootKey, passphrase,
|
||||
&chaincfg.MainNetParams, fastScrypt, time.Time{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mgr, err = Open(ns, pubPassphrase, &chaincfg.MainNetParams)
|
||||
mgr, err = Open(ns, &chaincfg.MainNetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mgr.Unlock(ns, privPassphrase)
|
||||
return mgr.Unlock(ns, passphrase)
|
||||
})
|
||||
require.NoError(t, err, "create/open: unexpected error: %v", err)
|
||||
|
||||
|
|
|
@ -33,19 +33,18 @@ func testWallet(t *testing.T) (*Wallet, func()) {
|
|||
t.Fatalf("unable to create seed: %v", err)
|
||||
}
|
||||
|
||||
pubPass := []byte("hello")
|
||||
privPass := []byte("world")
|
||||
passphrase := []byte("hello world")
|
||||
|
||||
loader := NewLoader(
|
||||
&chaincfg.TestNet3Params, dir, true, defaultDBTimeout, 250,
|
||||
)
|
||||
w, err := loader.CreateNewWallet(pubPass, privPass, seed, time.Now())
|
||||
w, err := loader.CreateNewWallet(passphrase, seed, time.Now())
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create wallet: %v", err)
|
||||
}
|
||||
chainClient := &mockChainClient{}
|
||||
w.chainClient = chainClient
|
||||
if err := w.Unlock(privPass, time.After(10*time.Minute)); err != nil {
|
||||
if err := w.Unlock(passphrase, time.After(10*time.Minute)); err != nil {
|
||||
t.Fatalf("unable to unlock wallet: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -140,10 +140,10 @@ func (l *Loader) OnWalletCreated(fn func(walletdb.ReadWriteTx) error) {
|
|||
l.walletCreated = fn
|
||||
}
|
||||
|
||||
// CreateNewWallet creates a new wallet using the provided public and private
|
||||
// passphrases. The seed is optional. If non-nil, addresses are derived from
|
||||
// this seed. If nil, a secure random seed is generated.
|
||||
func (l *Loader) CreateNewWallet(pubPassphrase, privPassphrase, seed []byte,
|
||||
// CreateNewWallet creates a new wallet using the provided passphrase.
|
||||
// The seed is optional. If non-nil, addresses are derived from this seed.
|
||||
// If nil, a secure random seed is generated.
|
||||
func (l *Loader) CreateNewWallet(passphrase, seed []byte,
|
||||
bday time.Time) (*Wallet, error) {
|
||||
|
||||
var (
|
||||
|
@ -168,20 +168,20 @@ func (l *Loader) CreateNewWallet(pubPassphrase, privPassphrase, seed []byte,
|
|||
}
|
||||
}
|
||||
|
||||
return l.createNewWallet(pubPassphrase, privPassphrase, rootKey, bday)
|
||||
return l.createNewWallet(passphrase, rootKey, bday)
|
||||
}
|
||||
|
||||
// CreateNewWalletExtendedKey creates a new wallet from an extended master root
|
||||
// key using the provided public and private passphrases. The root key is
|
||||
// optional. If non-nil, addresses are derived from this root key. If nil, a
|
||||
// key using the provided passphrase. The root key is optional.
|
||||
// If non-nil, addresses are derived from this root key. If nil, a
|
||||
// secure random seed is generated and the root key is derived from that.
|
||||
func (l *Loader) CreateNewWalletExtendedKey(pubPassphrase, privPassphrase []byte,
|
||||
func (l *Loader) CreateNewWalletExtendedKey(passphrase []byte,
|
||||
rootKey *hdkeychain.ExtendedKey, bday time.Time) (*Wallet, error) {
|
||||
|
||||
return l.createNewWallet(pubPassphrase, privPassphrase, rootKey, bday)
|
||||
return l.createNewWallet(passphrase, rootKey, bday)
|
||||
}
|
||||
|
||||
func (l *Loader) createNewWallet(pubPassphrase, privPassphrase []byte,
|
||||
func (l *Loader) createNewWallet(passphrase []byte,
|
||||
rootKey *hdkeychain.ExtendedKey, bday time.Time) (*Wallet, error) {
|
||||
|
||||
defer l.mu.Unlock()
|
||||
|
@ -216,16 +216,15 @@ func (l *Loader) createNewWallet(pubPassphrase, privPassphrase []byte,
|
|||
}
|
||||
|
||||
// Initialize the newly created database for the wallet before opening.
|
||||
err = CreateWithCallback(
|
||||
l.db, pubPassphrase, privPassphrase, rootKey,
|
||||
l.chainParams, bday, l.walletCreated,
|
||||
err = CreateWithCallback(l.db, passphrase, rootKey, l.chainParams,
|
||||
bday, l.walletCreated,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Open the newly-created wallet.
|
||||
w, err := Open(l.db, pubPassphrase, nil, l.chainParams, l.recoveryWindow)
|
||||
w, err := Open(l.db, nil, l.chainParams, l.recoveryWindow)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -241,11 +240,10 @@ func noConsole() ([]byte, error) {
|
|||
return nil, errNoConsole
|
||||
}
|
||||
|
||||
// OpenExistingWallet opens the wallet from the loader's wallet database path
|
||||
// and the public passphrase. If the loader is being called by a context where
|
||||
// standard input prompts may be used during wallet upgrades, setting
|
||||
// canConsolePrompt will enables these prompts.
|
||||
func (l *Loader) OpenExistingWallet(pubPassphrase []byte, canConsolePrompt bool) (*Wallet, error) {
|
||||
// OpenExistingWallet opens the wallet from the loader's wallet database path.
|
||||
// If the loader is being called by a context where standard input prompts may
|
||||
// be used during wallet upgrades, setting canConsolePrompt will enables these prompts.
|
||||
func (l *Loader) OpenExistingWallet(canConsolePrompt bool) (*Wallet, error) {
|
||||
defer l.mu.Unlock()
|
||||
l.mu.Lock()
|
||||
|
||||
|
@ -274,16 +272,16 @@ func (l *Loader) OpenExistingWallet(pubPassphrase []byte, canConsolePrompt bool)
|
|||
var cbs *waddrmgr.OpenCallbacks
|
||||
if canConsolePrompt {
|
||||
cbs = &waddrmgr.OpenCallbacks{
|
||||
ObtainSeed: prompt.ProvideSeed(),
|
||||
ObtainPrivatePass: prompt.ProvidePrivPassphrase,
|
||||
ObtainSeed: prompt.ProvideSeed(),
|
||||
ObtainPassphrase: prompt.ProvidePassphrase,
|
||||
}
|
||||
} else {
|
||||
cbs = &waddrmgr.OpenCallbacks{
|
||||
ObtainSeed: noConsole,
|
||||
ObtainPrivatePass: noConsole,
|
||||
ObtainSeed: noConsole,
|
||||
ObtainPassphrase: noConsole,
|
||||
}
|
||||
}
|
||||
w, err := Open(l.db, pubPassphrase, cbs, l.chainParams, l.recoveryWindow)
|
||||
w, err := Open(l.db, cbs, l.chainParams, l.recoveryWindow)
|
||||
if err != nil {
|
||||
// If opening the wallet fails (e.g. because of wrong
|
||||
// passphrase), we must close the backing database to
|
||||
|
|
110
wallet/wallet.go
110
wallet/wallet.go
|
@ -36,16 +36,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// InsecurePubPassphrase is the default outer encryption passphrase used
|
||||
// for public data (everything but private keys). Using a non-default
|
||||
// public passphrase can prevent an attacker without the public
|
||||
// passphrase from discovering all past and future wallet addresses if
|
||||
// they gain access to the wallet database.
|
||||
//
|
||||
// NOTE: at time of writing, public encryption only applies to public
|
||||
// data in the waddrmgr namespace. Transactions are not yet encrypted.
|
||||
InsecurePubPassphrase = "public"
|
||||
|
||||
// recoveryBatchSize is the default number of blocks that will be
|
||||
// scanned successively by the recovery manager, in the event that the
|
||||
// wallet is started in recovery mode.
|
||||
|
@ -99,8 +89,6 @@ const (
|
|||
// complete wallet. It contains the Armory-style key store
|
||||
// addresses and keys),
|
||||
type Wallet struct {
|
||||
publicPassphrase []byte
|
||||
|
||||
// Data stores
|
||||
db walletdb.DB
|
||||
Manager *waddrmgr.Manager
|
||||
|
@ -134,7 +122,6 @@ type Wallet struct {
|
|||
holdUnlockRequests chan chan heldUnlock
|
||||
lockState chan bool
|
||||
changePassphrase chan changePassphraseRequest
|
||||
changePassphrases chan changePassphrasesRequest
|
||||
|
||||
NtfnServer *NotificationServer
|
||||
|
||||
|
@ -703,7 +690,7 @@ func (w *Wallet) recovery(chainClient chain.Interface,
|
|||
// that a wallet rescan will be performed from the wallet's tip, which
|
||||
// will be of bestHeight after completing the recovery process.
|
||||
|
||||
pass, err := prompt.ProvidePrivPassphrase()
|
||||
pass, err := prompt.ProvidePassphrase()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1188,16 +1175,9 @@ type (
|
|||
|
||||
changePassphraseRequest struct {
|
||||
old, new []byte
|
||||
private bool
|
||||
err chan error
|
||||
}
|
||||
|
||||
changePassphrasesRequest struct {
|
||||
publicOld, publicNew []byte
|
||||
privateOld, privateNew []byte
|
||||
err chan error
|
||||
}
|
||||
|
||||
// heldUnlock is a tool to prevent the wallet from automatically
|
||||
// locking after some timeout before an operation which needed
|
||||
// the unlocked wallet has finished. Any acquired heldUnlock
|
||||
|
@ -1236,32 +1216,13 @@ out:
|
|||
err := walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
|
||||
addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
return w.Manager.ChangePassphrase(
|
||||
addrmgrNs, req.old, req.new, req.private,
|
||||
addrmgrNs, req.old, req.new,
|
||||
&waddrmgr.DefaultScryptOptions,
|
||||
)
|
||||
})
|
||||
req.err <- err
|
||||
continue
|
||||
|
||||
case req := <-w.changePassphrases:
|
||||
err := walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
|
||||
addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
err := w.Manager.ChangePassphrase(
|
||||
addrmgrNs, req.publicOld, req.publicNew,
|
||||
false, &waddrmgr.DefaultScryptOptions,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return w.Manager.ChangePassphrase(
|
||||
addrmgrNs, req.privateOld, req.privateNew,
|
||||
true, &waddrmgr.DefaultScryptOptions,
|
||||
)
|
||||
})
|
||||
req.err <- err
|
||||
continue
|
||||
|
||||
case req := <-w.holdUnlockRequests:
|
||||
if w.Manager.IsLocked() {
|
||||
close(req)
|
||||
|
@ -1362,45 +1323,16 @@ func (c heldUnlock) release() {
|
|||
c <- struct{}{}
|
||||
}
|
||||
|
||||
// ChangePrivatePassphrase attempts to change the passphrase for a wallet from
|
||||
// ChangePassphrase attempts to change the passphrase for a wallet from
|
||||
// old to new. Changing the passphrase is synchronized with all other address
|
||||
// manager locking and unlocking. The lock state will be the same as it was
|
||||
// before the password change.
|
||||
func (w *Wallet) ChangePrivatePassphrase(old, new []byte) error {
|
||||
func (w *Wallet) ChangePassphrase(old, new []byte) error {
|
||||
err := make(chan error, 1)
|
||||
w.changePassphrase <- changePassphraseRequest{
|
||||
old: old,
|
||||
new: new,
|
||||
private: true,
|
||||
err: err,
|
||||
}
|
||||
return <-err
|
||||
}
|
||||
|
||||
// ChangePublicPassphrase modifies the public passphrase of the wallet.
|
||||
func (w *Wallet) ChangePublicPassphrase(old, new []byte) error {
|
||||
err := make(chan error, 1)
|
||||
w.changePassphrase <- changePassphraseRequest{
|
||||
old: old,
|
||||
new: new,
|
||||
private: false,
|
||||
err: err,
|
||||
}
|
||||
return <-err
|
||||
}
|
||||
|
||||
// ChangePassphrases modifies the public and private passphrase of the wallet
|
||||
// atomically.
|
||||
func (w *Wallet) ChangePassphrases(publicOld, publicNew, privateOld,
|
||||
privateNew []byte) error {
|
||||
|
||||
err := make(chan error, 1)
|
||||
w.changePassphrases <- changePassphrasesRequest{
|
||||
publicOld: publicOld,
|
||||
publicNew: publicNew,
|
||||
privateOld: privateOld,
|
||||
privateNew: privateNew,
|
||||
err: err,
|
||||
old: old,
|
||||
new: new,
|
||||
err: err,
|
||||
}
|
||||
return <-err
|
||||
}
|
||||
|
@ -3659,29 +3591,23 @@ func (w *Wallet) Database() walletdb.DB {
|
|||
|
||||
// CreateWithCallback is the same as Create with an added callback that will be
|
||||
// called in the same transaction the wallet structure is initialized.
|
||||
func CreateWithCallback(db walletdb.DB, pubPass, privPass []byte,
|
||||
func CreateWithCallback(db walletdb.DB, privPass []byte,
|
||||
rootKey *hdkeychain.ExtendedKey, params *chaincfg.Params,
|
||||
birthday time.Time, cb func(walletdb.ReadWriteTx) error) error {
|
||||
|
||||
return create(
|
||||
db, pubPass, privPass, rootKey, params, birthday, cb,
|
||||
)
|
||||
return create(db, privPass, rootKey, params, birthday, cb)
|
||||
}
|
||||
|
||||
// Create creates an new wallet, writing it to an empty database. If the passed
|
||||
// root key is non-nil, it is used. Otherwise, a secure random seed of the
|
||||
// recommended length is generated.
|
||||
func Create(db walletdb.DB, pubPass, privPass []byte,
|
||||
rootKey *hdkeychain.ExtendedKey, params *chaincfg.Params,
|
||||
birthday time.Time) error {
|
||||
func Create(db walletdb.DB, privPass []byte, rootKey *hdkeychain.ExtendedKey,
|
||||
params *chaincfg.Params, birthday time.Time) error {
|
||||
|
||||
return create(
|
||||
db, pubPass, privPass, rootKey, params, birthday, nil,
|
||||
)
|
||||
return create(db, privPass, rootKey, params, birthday, nil)
|
||||
}
|
||||
func create(db walletdb.DB, pubPass, privPass []byte,
|
||||
rootKey *hdkeychain.ExtendedKey, params *chaincfg.Params,
|
||||
birthday time.Time,
|
||||
func create(db walletdb.DB, privPass []byte, rootKey *hdkeychain.ExtendedKey,
|
||||
params *chaincfg.Params, birthday time.Time,
|
||||
cb func(walletdb.ReadWriteTx) error) error {
|
||||
|
||||
// If no root key was provided, we create one now from a random seed.
|
||||
|
@ -3718,7 +3644,7 @@ func create(db walletdb.DB, pubPass, privPass []byte,
|
|||
}
|
||||
|
||||
err = waddrmgr.Create(
|
||||
addrmgrNs, rootKey, pubPass, privPass, params, nil,
|
||||
addrmgrNs, rootKey, privPass, params, nil,
|
||||
birthday,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -3739,7 +3665,7 @@ func create(db walletdb.DB, pubPass, privPass []byte,
|
|||
}
|
||||
|
||||
// Open loads an already-created wallet from the passed database and namespaces.
|
||||
func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks,
|
||||
func Open(db walletdb.DB, cbs *waddrmgr.OpenCallbacks,
|
||||
params *chaincfg.Params, recoveryWindow uint32) (*Wallet, error) {
|
||||
|
||||
var (
|
||||
|
@ -3768,7 +3694,7 @@ func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks,
|
|||
return err
|
||||
}
|
||||
|
||||
addrMgr, err = waddrmgr.Open(addrMgrBucket, pubPass, params)
|
||||
addrMgr, err = waddrmgr.Open(addrMgrBucket, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -3786,7 +3712,6 @@ func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks,
|
|||
log.Infof("Opened wallet") // TODO: log balance? last sync height?
|
||||
|
||||
w := &Wallet{
|
||||
publicPassphrase: pubPass,
|
||||
db: db,
|
||||
Manager: addrMgr,
|
||||
TxStore: txMgr,
|
||||
|
@ -3803,7 +3728,6 @@ func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks,
|
|||
holdUnlockRequests: make(chan chan heldUnlock),
|
||||
lockState: make(chan bool),
|
||||
changePassphrase: make(chan changePassphraseRequest),
|
||||
changePassphrases: make(chan changePassphrasesRequest),
|
||||
chainParams: params,
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
|
|
|
@ -45,18 +45,9 @@ func createWallet(cfg *config) error {
|
|||
activeNet.Params, dbDir, true, cfg.DBTimeout, 250,
|
||||
)
|
||||
|
||||
// Start by prompting for the private passphrase.
|
||||
// Start by prompting for the passphrase.
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
privPass, err := prompt.PrivatePass(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Ascertain the public passphrase. This will either be a value
|
||||
// specified by the user or the default hard-coded public passphrase if
|
||||
// the user does not want the additional public data encryption.
|
||||
pubPass, err := prompt.PublicPass(reader, privPass,
|
||||
[]byte(wallet.InsecurePubPassphrase), []byte(cfg.WalletPass))
|
||||
privPass, err := prompt.Passphrase(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -70,7 +61,7 @@ func createWallet(cfg *config) error {
|
|||
}
|
||||
|
||||
fmt.Println("Creating the wallet...")
|
||||
w, err := loader.CreateNewWallet(pubPass, privPass, seed, bday)
|
||||
w, err := loader.CreateNewWallet(privPass, seed, bday)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -88,9 +79,6 @@ func createSimulationWallet(cfg *config) error {
|
|||
// Simulation wallet password is 'password'.
|
||||
privPass := []byte("password")
|
||||
|
||||
// Public passphrase is the default.
|
||||
pubPass := []byte(wallet.InsecurePubPassphrase)
|
||||
|
||||
netDir := networkDir(cfg.AppDataDir.Value, activeNet.Params)
|
||||
|
||||
// Create the wallet.
|
||||
|
@ -105,7 +93,7 @@ func createSimulationWallet(cfg *config) error {
|
|||
defer db.Close()
|
||||
|
||||
// Create the wallet.
|
||||
err = wallet.Create(db, pubPass, privPass, nil, activeNet.Params, time.Now())
|
||||
err = wallet.Create(db, privPass, nil, activeNet.Params, time.Now())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue