[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:
Anton Nikiforov 2022-09-16 09:48:12 +03:00 committed by fyrchik
parent 3df98ce7ba
commit bb02913c39
6 changed files with 23 additions and 85 deletions

View file

@ -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

View file

@ -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 = ""

View file

@ -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) {

View file

@ -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
}

View file

@ -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) priv, err := keys.NewPrivateKeyFromBytes(data)
if err == nil { if err != nil {
return p, nil w, err := wallet.NewWalletFromFile(keyDesc)
if err == nil {
return FromWallet(w, viper.GetString(commonflags.Account))
}
return nil, fmt.Errorf("%w: %v", ErrInvalidKey, err)
} }
return &priv.PrivateKey, nil
w, err := wallet.NewWalletFromFile(keyDesc)
if err == nil {
return FromWallet(w, viper.GetString(commonflags.Account))
}
if len(keyDesc) == nep2Base58Length {
return FromNEP2(keyDesc)
}
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
}

View file

@ -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")
) )