forked from TrueCloudLab/frostfs-node
[nspcc-dev#1128] cli: Remove WIF and NEP2 support in --wallet argument
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
This commit is contained in:
parent
3df98ce7ba
commit
bb02913c39
6 changed files with 23 additions and 85 deletions
|
@ -10,7 +10,7 @@ Changelog for NeoFS Node
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
- Remove WIF and NEP2 support in `neofs-cli`'s --wallet flag (#1128)
|
||||||
### Updated
|
### Updated
|
||||||
|
|
||||||
### Updating from v0.32.0
|
### Updating from v0.32.0
|
||||||
|
|
|
@ -16,7 +16,7 @@ const (
|
||||||
WalletPath = "wallet"
|
WalletPath = "wallet"
|
||||||
WalletPathShorthand = "w"
|
WalletPathShorthand = "w"
|
||||||
WalletPathDefault = ""
|
WalletPathDefault = ""
|
||||||
WalletPathUsage = "WIF (NEP-2) string or path to the wallet or binary key"
|
WalletPathUsage = "path to the wallet or binary key"
|
||||||
|
|
||||||
Account = "address"
|
Account = "address"
|
||||||
AccountShorthand = ""
|
AccountShorthand = ""
|
||||||
|
|
|
@ -23,6 +23,9 @@ func Test_getOrGenerate(t *testing.T) {
|
||||||
w, err := wallet.NewWallet(wallPath)
|
w, err := wallet.NewWallet(wallPath)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
badWallPath := filepath.Join(dir, "bad_wallet.json")
|
||||||
|
require.NoError(t, os.WriteFile(badWallPath, []byte("bad content"), os.ModePerm))
|
||||||
|
|
||||||
acc1, err := wallet.NewAccount()
|
acc1, err := wallet.NewAccount()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, acc1.Encrypt("pass", keys.NEP2ScryptParams()))
|
require.NoError(t, acc1.Encrypt("pass", keys.NEP2ScryptParams()))
|
||||||
|
@ -55,7 +58,8 @@ func Test_getOrGenerate(t *testing.T) {
|
||||||
Writer: io.Discard,
|
Writer: io.Discard,
|
||||||
}, "")
|
}, "")
|
||||||
|
|
||||||
checkKeyError(t, filepath.Join(dir, "badfile"), ErrInvalidKey)
|
checkKeyError(t, filepath.Join(dir, "badfile"), ErrFs)
|
||||||
|
checkKeyError(t, badWallPath, ErrInvalidKey)
|
||||||
|
|
||||||
t.Run("wallet", func(t *testing.T) {
|
t.Run("wallet", func(t *testing.T) {
|
||||||
checkKeyError(t, wallPath, ErrInvalidPassword)
|
checkKeyError(t, wallPath, ErrInvalidPassword)
|
||||||
|
@ -80,27 +84,11 @@ func Test_getOrGenerate(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("WIF", func(t *testing.T) {
|
t.Run("WIF", func(t *testing.T) {
|
||||||
checkKey(t, wifKey.WIF(), wifKey)
|
checkKeyError(t, wifKey.WIF(), ErrFs)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("NEP-2", func(t *testing.T) {
|
t.Run("NEP-2", func(t *testing.T) {
|
||||||
checkKeyError(t, nep2, ErrInvalidPassword)
|
checkKeyError(t, nep2, ErrFs)
|
||||||
|
|
||||||
in.WriteString("invalid\r")
|
|
||||||
checkKeyError(t, nep2, ErrInvalidPassword)
|
|
||||||
|
|
||||||
in.WriteString("pass\r")
|
|
||||||
checkKey(t, nep2, nep2Key)
|
|
||||||
|
|
||||||
t.Run("password from config", func(t *testing.T) {
|
|
||||||
viper.Set("password", "invalid")
|
|
||||||
in.WriteString("pass\r")
|
|
||||||
checkKeyError(t, nep2, ErrInvalidPassword)
|
|
||||||
|
|
||||||
viper.Set("password", "pass")
|
|
||||||
in.WriteString("invalid\r")
|
|
||||||
checkKey(t, nep2, nep2Key)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("raw key", func(t *testing.T) {
|
t.Run("raw key", func(t *testing.T) {
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
package key
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
||||||
)
|
|
||||||
|
|
||||||
const nep2Base58Length = 58
|
|
||||||
|
|
||||||
// FromNEP2 extracts private key from NEP2-encrypted string.
|
|
||||||
func FromNEP2(encryptedWif string) (*ecdsa.PrivateKey, error) {
|
|
||||||
pass, err := getPassword()
|
|
||||||
if err != nil {
|
|
||||||
printVerbose("Can't read password: %v", err)
|
|
||||||
return nil, ErrInvalidPassword
|
|
||||||
}
|
|
||||||
|
|
||||||
k, err := keys.NEP2Decrypt(encryptedWif, pass, keys.NEP2ScryptParams())
|
|
||||||
if err != nil {
|
|
||||||
printVerbose("Invalid key or password: %v", err)
|
|
||||||
return nil, ErrInvalidPassword
|
|
||||||
}
|
|
||||||
|
|
||||||
return &k.PrivateKey, nil
|
|
||||||
}
|
|
|
@ -16,13 +16,8 @@ import (
|
||||||
|
|
||||||
var errCantGenerateKey = errors.New("can't generate new private key")
|
var errCantGenerateKey = errors.New("can't generate new private key")
|
||||||
|
|
||||||
// Get returns private key from the following sources:
|
// Get returns private key from wallet or binary file.
|
||||||
// 1. WIF
|
|
||||||
// 2. Raw binary key
|
|
||||||
// 3. Wallet file
|
|
||||||
// 4. NEP-2 encrypted WIF.
|
|
||||||
// Ideally we want to touch file-system on the last step.
|
// Ideally we want to touch file-system on the last step.
|
||||||
// However, asking for NEP-2 password seems to be confusing if we provide a wallet.
|
|
||||||
// This function assumes that all flags were bind to viper in a `PersistentPreRun`.
|
// This function assumes that all flags were bind to viper in a `PersistentPreRun`.
|
||||||
func Get(cmd *cobra.Command) *ecdsa.PrivateKey {
|
func Get(cmd *cobra.Command) *ecdsa.PrivateKey {
|
||||||
pk, err := get()
|
pk, err := get()
|
||||||
|
@ -32,26 +27,20 @@ func Get(cmd *cobra.Command) *ecdsa.PrivateKey {
|
||||||
|
|
||||||
func get() (*ecdsa.PrivateKey, error) {
|
func get() (*ecdsa.PrivateKey, error) {
|
||||||
keyDesc := viper.GetString(commonflags.WalletPath)
|
keyDesc := viper.GetString(commonflags.WalletPath)
|
||||||
priv, err := keys.NewPrivateKeyFromWIF(keyDesc)
|
data, err := os.ReadFile(keyDesc)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
return &priv.PrivateKey, nil
|
return nil, fmt.Errorf("%w: %v", ErrFs, err)
|
||||||
}
|
|
||||||
|
|
||||||
p, err := getKeyFromFile(keyDesc)
|
|
||||||
if err == nil {
|
|
||||||
return p, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv, err := keys.NewPrivateKeyFromBytes(data)
|
||||||
|
if err != nil {
|
||||||
w, err := wallet.NewWalletFromFile(keyDesc)
|
w, err := wallet.NewWalletFromFile(keyDesc)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return FromWallet(w, viper.GetString(commonflags.Account))
|
return FromWallet(w, viper.GetString(commonflags.Account))
|
||||||
}
|
}
|
||||||
|
return nil, fmt.Errorf("%w: %v", ErrInvalidKey, err)
|
||||||
if len(keyDesc) == nep2Base58Length {
|
|
||||||
return FromNEP2(keyDesc)
|
|
||||||
}
|
}
|
||||||
|
return &priv.PrivateKey, nil
|
||||||
return nil, ErrInvalidKey
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrGenerate is similar to get but generates a new key if commonflags.GenerateKey is set.
|
// GetOrGenerate is similar to get but generates a new key if commonflags.GenerateKey is set.
|
||||||
|
@ -71,17 +60,3 @@ func getOrGenerate() (*ecdsa.PrivateKey, error) {
|
||||||
}
|
}
|
||||||
return get()
|
return get()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getKeyFromFile(keyPath string) (*ecdsa.PrivateKey, error) {
|
|
||||||
data, err := os.ReadFile(keyPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%w: %v", ErrInvalidKey, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
priv, err := keys.NewPrivateKeyFromBytes(data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%w: %v", ErrInvalidKey, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &priv.PrivateKey, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ import (
|
||||||
|
|
||||||
// Key-related errors.
|
// Key-related errors.
|
||||||
var (
|
var (
|
||||||
ErrInvalidKey = errors.New("provided key is incorrect")
|
ErrFs = errors.New("unable to read file from given path")
|
||||||
|
ErrInvalidKey = errors.New("provided key is incorrect, only wallet or binary key supported")
|
||||||
ErrInvalidAddress = errors.New("--address option must be specified and valid")
|
ErrInvalidAddress = errors.New("--address option must be specified and valid")
|
||||||
ErrInvalidPassword = errors.New("invalid password for the encrypted key")
|
ErrInvalidPassword = errors.New("invalid password for the encrypted key")
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue