Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CryptoCdc inconsistent #7987

Merged
merged 10 commits into from
Dec 2, 2020
8 changes: 3 additions & 5 deletions crypto/armor.go → crypto/keyring/armor.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package crypto
package keyring

import (
"encoding/hex"
Expand All @@ -9,8 +9,6 @@ import (
"github.com/tendermint/tendermint/crypto/armor"
"github.com/tendermint/tendermint/crypto/xsalsa20symmetric"

"github.com/cosmos/cosmos-sdk/codec/legacy"
cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
Expand Down Expand Up @@ -153,7 +151,7 @@ func encryptPrivKey(privKey cryptotypes.PrivKey, passphrase string) (saltBytes [
}

key = crypto.Sha256(key) // get 32 bytes
privKeyBytes := legacy.Cdc.Amino.MustMarshalBinaryBare(privKey)
privKeyBytes := CryptoCdc.MustMarshalBinaryBare(privKey)
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved

return saltBytes, xsalsa20symmetric.EncryptSymmetric(privKeyBytes, key)
}
Expand Down Expand Up @@ -206,5 +204,5 @@ func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privK
return privKey, err
}

return cryptoAmino.PrivKeyFromBytes(privKeyBytes)
return PrivKeyFromBytes(privKeyBytes)
}
43 changes: 21 additions & 22 deletions crypto/armor_test.go → crypto/keyring/armor_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package crypto_test
package keyring_test

import (
"bytes"
Expand All @@ -14,7 +14,6 @@ import (
"github.com/tendermint/tendermint/crypto/xsalsa20symmetric"

"github.com/cosmos/cosmos-sdk/codec/legacy"
"github.com/cosmos/cosmos-sdk/crypto"
cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand All @@ -25,31 +24,31 @@ import (

func TestArmorUnarmorPrivKey(t *testing.T) {
priv := secp256k1.GenPrivKey()
armored := crypto.EncryptArmorPrivKey(priv, "passphrase", "")
_, _, err := crypto.UnarmorDecryptPrivKey(armored, "wrongpassphrase")
armored := keyring.EncryptArmorPrivKey(priv, "passphrase", "")
_, _, err := keyring.UnarmorDecryptPrivKey(armored, "wrongpassphrase")
require.Error(t, err)
decrypted, algo, err := crypto.UnarmorDecryptPrivKey(armored, "passphrase")
decrypted, algo, err := keyring.UnarmorDecryptPrivKey(armored, "passphrase")
require.NoError(t, err)
require.Equal(t, string(hd.Secp256k1Type), algo)
require.True(t, priv.Equals(decrypted))

// empty string
decrypted, algo, err = crypto.UnarmorDecryptPrivKey("", "passphrase")
decrypted, algo, err = keyring.UnarmorDecryptPrivKey("", "passphrase")
require.Error(t, err)
require.True(t, errors.Is(io.EOF, err))
require.Nil(t, decrypted)
require.Empty(t, algo)

// wrong key type
armored = crypto.ArmorPubKeyBytes(priv.PubKey().Bytes(), "")
_, _, err = crypto.UnarmorDecryptPrivKey(armored, "passphrase")
armored = keyring.ArmorPubKeyBytes(priv.PubKey().Bytes(), "")
_, _, err = keyring.UnarmorDecryptPrivKey(armored, "passphrase")
require.Error(t, err)
require.Contains(t, err.Error(), "unrecognized armor type")

// armor key manually
encryptPrivKeyFn := func(privKey cryptotypes.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte) {
saltBytes = tmcrypto.CRandBytes(16)
key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), crypto.BcryptSecurityParameter)
key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), keyring.BcryptSecurityParameter)
require.NoError(t, err)
key = tmcrypto.Sha256(key) // get 32 bytes
privKeyBytes := legacy.Cdc.Amino.MustMarshalBinaryBare(privKey)
Expand All @@ -64,7 +63,7 @@ func TestArmorUnarmorPrivKey(t *testing.T) {
"type": "secp256k",
}
armored = armor.EncodeArmor("TENDERMINT PRIVATE KEY", headerWrongKdf, encBytes)
_, _, err = crypto.UnarmorDecryptPrivKey(armored, "passphrase")
_, _, err = keyring.UnarmorDecryptPrivKey(armored, "passphrase")
require.Error(t, err)
require.Equal(t, "unrecognized KDF type: wrong", err.Error())
}
Expand All @@ -76,16 +75,16 @@ func TestArmorUnarmorPubKey(t *testing.T) {
// Add keys and see they return in alphabetical order
info, _, err := cstore.NewMnemonic("Bob", keyring.English, types.FullFundraiserPath, hd.Secp256k1)
require.NoError(t, err)
armored := crypto.ArmorPubKeyBytes(legacy.Cdc.Amino.MustMarshalBinaryBare(info.GetPubKey()), "")
pubBytes, algo, err := crypto.UnarmorPubKeyBytes(armored)
armored := keyring.ArmorPubKeyBytes(legacy.Cdc.Amino.MustMarshalBinaryBare(info.GetPubKey()), "")
pubBytes, algo, err := keyring.UnarmorPubKeyBytes(armored)
require.NoError(t, err)
pub, err := cryptoAmino.PubKeyFromBytes(pubBytes)
require.NoError(t, err)
require.Equal(t, string(hd.Secp256k1Type), algo)
require.True(t, pub.Equals(info.GetPubKey()))

armored = crypto.ArmorPubKeyBytes(legacy.Cdc.Amino.MustMarshalBinaryBare(info.GetPubKey()), "unknown")
pubBytes, algo, err = crypto.UnarmorPubKeyBytes(armored)
armored = keyring.ArmorPubKeyBytes(legacy.Cdc.Amino.MustMarshalBinaryBare(info.GetPubKey()), "unknown")
pubBytes, algo, err = keyring.UnarmorPubKeyBytes(armored)
require.NoError(t, err)
pub, err = cryptoAmino.PubKeyFromBytes(pubBytes)
require.NoError(t, err)
Expand All @@ -94,7 +93,7 @@ func TestArmorUnarmorPubKey(t *testing.T) {

armored, err = cstore.ExportPrivKeyArmor("Bob", "passphrase")
require.NoError(t, err)
_, _, err = crypto.UnarmorPubKeyBytes(armored)
_, _, err = keyring.UnarmorPubKeyBytes(armored)
require.Error(t, err)
require.Equal(t, `couldn't unarmor bytes: unrecognized armor type "TENDERMINT PRIVATE KEY", expected: "TENDERMINT PUBLIC KEY"`, err.Error())

Expand All @@ -104,7 +103,7 @@ func TestArmorUnarmorPubKey(t *testing.T) {
"type": "unknown",
}
armored = armor.EncodeArmor("TENDERMINT PUBLIC KEY", header, pubBytes)
_, algo, err = crypto.UnarmorPubKeyBytes(armored)
_, algo, err = keyring.UnarmorPubKeyBytes(armored)
require.NoError(t, err)
// return secp256k1 if version is 0.0.0
require.Equal(t, "secp256k1", algo)
Expand All @@ -114,7 +113,7 @@ func TestArmorUnarmorPubKey(t *testing.T) {
"type": "unknown",
}
armored = armor.EncodeArmor("TENDERMINT PUBLIC KEY", header, pubBytes)
bz, algo, err := crypto.UnarmorPubKeyBytes(armored)
bz, algo, err := keyring.UnarmorPubKeyBytes(armored)
require.Nil(t, bz)
require.Empty(t, algo)
require.Error(t, err)
Expand All @@ -126,7 +125,7 @@ func TestArmorUnarmorPubKey(t *testing.T) {
"version": "unknown",
}
armored = armor.EncodeArmor("TENDERMINT PUBLIC KEY", header, pubBytes)
bz, algo, err = crypto.UnarmorPubKeyBytes(armored)
bz, algo, err = keyring.UnarmorPubKeyBytes(armored)
require.Nil(t, bz)
require.Empty(t, algo)
require.Error(t, err)
Expand All @@ -135,14 +134,14 @@ func TestArmorUnarmorPubKey(t *testing.T) {

func TestArmorInfoBytes(t *testing.T) {
bs := []byte("test")
armoredString := crypto.ArmorInfoBytes(bs)
unarmoredBytes, err := crypto.UnarmorInfoBytes(armoredString)
armoredString := keyring.ArmorInfoBytes(bs)
unarmoredBytes, err := keyring.UnarmorInfoBytes(armoredString)
require.NoError(t, err)
require.True(t, bytes.Equal(bs, unarmoredBytes))
}

func TestUnarmorInfoBytesErrors(t *testing.T) {
unarmoredBytes, err := crypto.UnarmorInfoBytes("")
unarmoredBytes, err := keyring.UnarmorInfoBytes("")
require.Error(t, err)
require.True(t, errors.Is(io.EOF, err))
require.Nil(t, unarmoredBytes)
Expand All @@ -151,7 +150,7 @@ func TestUnarmorInfoBytesErrors(t *testing.T) {
"type": "Info",
"version": "0.0.1",
}
unarmoredBytes, err = crypto.UnarmorInfoBytes(armor.EncodeArmor(
unarmoredBytes, err = keyring.UnarmorInfoBytes(armor.EncodeArmor(
"TENDERMINT KEY INFO", header, []byte("plain-text")))
require.Error(t, err)
require.Equal(t, "unrecognized version: 0.0.1", err.Error())
Expand Down
13 changes: 13 additions & 0 deletions crypto/keyring/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/hd"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)

// CryptoCdc defines the codec required for keys and info
Expand All @@ -25,3 +26,15 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(offlineInfo{}, "crypto/keys/offlineInfo", nil)
cdc.RegisterConcrete(multiInfo{}, "crypto/keys/multiInfo", nil)
}

// PrivKeyFromBytes unmarshals private key bytes and returns a PrivKey
func PrivKeyFromBytes(privKeyBytes []byte) (privKey cryptotypes.PrivKey, err error) {
err = CryptoCdc.UnmarshalBinaryBare(privKeyBytes, &privKey)
return
}

// PubKeyFromBytes unmarshals public key bytes and returns a PubKey
func PubKeyFromBytes(pubKeyBytes []byte) (pubKey cryptotypes.PubKey, err error) {
err = CryptoCdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
return
}
16 changes: 7 additions & 9 deletions crypto/keyring/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import (
tmcrypto "github.com/tendermint/tendermint/crypto"

"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto"
cryptoamino "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/ledger"
"github.com/cosmos/cosmos-sdk/crypto/types"
Expand Down Expand Up @@ -198,7 +196,7 @@ func (ks keystore) ExportPubKeyArmor(uid string) (string, error) {
return "", fmt.Errorf("no key to export with name: %s", uid)
}

return crypto.ArmorPubKeyBytes(CryptoCdc.MustMarshalBinaryBare(bz.GetPubKey()), string(bz.GetAlgo())), nil
return ArmorPubKeyBytes(CryptoCdc.MustMarshalBinaryBare(bz.GetPubKey()), string(bz.GetAlgo())), nil
}

func (ks keystore) ExportPubKeyArmorByAddress(address sdk.Address) (string, error) {
Expand All @@ -221,7 +219,7 @@ func (ks keystore) ExportPrivKeyArmor(uid, encryptPassphrase string) (armor stri
return "", err
}

return crypto.EncryptArmorPrivKey(priv, encryptPassphrase, string(info.GetAlgo())), nil
return EncryptArmorPrivKey(priv, encryptPassphrase, string(info.GetAlgo())), nil
}

// ExportPrivateKeyObject exports an armored private key object.
Expand All @@ -240,7 +238,7 @@ func (ks keystore) ExportPrivateKeyObject(uid string) (types.PrivKey, error) {
return nil, err
}

priv, err = cryptoamino.PrivKeyFromBytes([]byte(linfo.PrivKeyArmor))
priv, err = PrivKeyFromBytes([]byte(linfo.PrivKeyArmor))
if err != nil {
return nil, err
}
Expand All @@ -266,7 +264,7 @@ func (ks keystore) ImportPrivKey(uid, armor, passphrase string) error {
return fmt.Errorf("cannot overwrite key: %s", uid)
}

privKey, algo, err := crypto.UnarmorDecryptPrivKey(armor, passphrase)
privKey, algo, err := UnarmorDecryptPrivKey(armor, passphrase)
if err != nil {
return errors.Wrap(err, "failed to decrypt private key")
}
Expand All @@ -284,12 +282,12 @@ func (ks keystore) ImportPubKey(uid string, armor string) error {
return fmt.Errorf("cannot overwrite key: %s", uid)
}

pubBytes, algo, err := crypto.UnarmorPubKeyBytes(armor)
pubBytes, algo, err := UnarmorPubKeyBytes(armor)
if err != nil {
return err
}

pubKey, err := cryptoamino.PubKeyFromBytes(pubBytes)
pubKey, err := PubKeyFromBytes(pubBytes)
if err != nil {
return err
}
Expand All @@ -316,7 +314,7 @@ func (ks keystore) Sign(uid string, msg []byte) ([]byte, types.PubKey, error) {
return nil, nil, fmt.Errorf("private key not available")
}

priv, err = cryptoamino.PrivKeyFromBytes([]byte(i.PrivKeyArmor))
priv, err = PrivKeyFromBytes([]byte(i.PrivKeyArmor))
if err != nil {
return nil, nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions crypto/keyring/keyring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
bip39 "github.com/cosmos/go-bip39"
"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/crypto"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
Expand All @@ -25,7 +24,7 @@ const (
)

func init() {
crypto.BcryptSecurityParameter = 1
BcryptSecurityParameter = 1
}

func TestNewKeyring(t *testing.T) {
Expand Down
11 changes: 5 additions & 6 deletions crypto/keyring/legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
tmos "github.com/tendermint/tendermint/libs/os"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/crypto"
"github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -117,7 +116,7 @@ func (kb dbKeybase) ExportPrivateKeyObject(name string, passphrase string) (type
return nil, err
}

priv, _, err = crypto.UnarmorDecryptPrivKey(linfo.PrivKeyArmor, passphrase)
priv, _, err = UnarmorDecryptPrivKey(linfo.PrivKeyArmor, passphrase)
if err != nil {
return nil, err
}
Expand All @@ -139,7 +138,7 @@ func (kb dbKeybase) Export(name string) (armor string, err error) {
return "", fmt.Errorf("no key to export with name %s", name)
}

return crypto.ArmorInfoBytes(bz), nil
return ArmorInfoBytes(bz), nil
}

// ExportPubKey returns public keys in ASCII armored format. It retrieves a Info
Expand All @@ -159,7 +158,7 @@ func (kb dbKeybase) ExportPubKey(name string) (armor string, err error) {
return
}

return crypto.ArmorPubKeyBytes(info.GetPubKey().Bytes(), string(info.GetAlgo())), nil
return ArmorPubKeyBytes(info.GetPubKey().Bytes(), string(info.GetAlgo())), nil
}

// ExportPrivKey returns a private key in ASCII armored format.
Expand All @@ -177,7 +176,7 @@ func (kb dbKeybase) ExportPrivKey(name string, decryptPassphrase string,
return "", err
}

return crypto.EncryptArmorPrivKey(priv, encryptPassphrase, string(info.GetAlgo())), nil
return EncryptArmorPrivKey(priv, encryptPassphrase, string(info.GetAlgo())), nil
}

// Close the underlying storage.
Expand Down Expand Up @@ -215,7 +214,7 @@ func (m keyringMigrator) Import(uid string, armor string) error {
return fmt.Errorf("cannot overwrite key %q", uid)
}

infoBytes, err := crypto.UnarmorInfoBytes(armor)
infoBytes, err := UnarmorInfoBytes(armor)
if err != nil {
return err
}
Expand Down