2019-03-29 06:49:00 -07:00
|
|
|
package mintkey_test
|
|
|
|
|
|
|
|
import (
|
2020-03-01 09:16:22 -08:00
|
|
|
"bytes"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2019-03-29 06:49:00 -07:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
2020-03-01 09:16:22 -08:00
|
|
|
"github.com/tendermint/crypto/bcrypt"
|
|
|
|
"github.com/tendermint/tendermint/crypto"
|
|
|
|
"github.com/tendermint/tendermint/crypto/armor"
|
2019-03-29 06:49:00 -07:00
|
|
|
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
|
|
|
"github.com/tendermint/tendermint/crypto/secp256k1"
|
2020-03-01 09:16:22 -08:00
|
|
|
"github.com/tendermint/tendermint/crypto/xsalsa20symmetric"
|
2019-04-04 07:36:39 -07:00
|
|
|
|
|
|
|
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
|
|
|
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
|
2019-03-29 06:49:00 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestArmorUnarmorPrivKey(t *testing.T) {
|
|
|
|
priv := secp256k1.GenPrivKey()
|
2020-03-01 09:16:22 -08:00
|
|
|
armored := mintkey.EncryptArmorPrivKey(priv, "passphrase", "")
|
|
|
|
_, _, err := mintkey.UnarmorDecryptPrivKey(armored, "wrongpassphrase")
|
2019-03-29 06:49:00 -07:00
|
|
|
require.Error(t, err)
|
2020-03-01 09:16:22 -08:00
|
|
|
decrypted, algo, err := mintkey.UnarmorDecryptPrivKey(armored, "passphrase")
|
2019-03-29 06:49:00 -07:00
|
|
|
require.NoError(t, err)
|
2020-01-14 07:40:10 -08:00
|
|
|
require.Equal(t, string(keys.Secp256k1), algo)
|
2019-03-29 06:49:00 -07:00
|
|
|
require.True(t, priv.Equals(decrypted))
|
2020-03-01 09:16:22 -08:00
|
|
|
|
|
|
|
// empty string
|
|
|
|
decrypted, algo, err = mintkey.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 = mintkey.ArmorPubKeyBytes(priv.PubKey().Bytes(), "")
|
|
|
|
decrypted, algo, err = mintkey.UnarmorDecryptPrivKey(armored, "passphrase")
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Contains(t, err.Error(), "unrecognized armor type")
|
|
|
|
|
|
|
|
// armor key manually
|
|
|
|
encryptPrivKeyFn := func(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte) {
|
|
|
|
saltBytes = crypto.CRandBytes(16)
|
|
|
|
key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), mintkey.BcryptSecurityParameter)
|
|
|
|
require.NoError(t, err)
|
|
|
|
key = crypto.Sha256(key) // get 32 bytes
|
|
|
|
privKeyBytes := privKey.Bytes()
|
|
|
|
return saltBytes, xsalsa20symmetric.EncryptSymmetric(privKeyBytes, key)
|
|
|
|
}
|
|
|
|
saltBytes, encBytes := encryptPrivKeyFn(priv, "passphrase")
|
|
|
|
|
|
|
|
// wrong kdf header
|
|
|
|
headerWrongKdf := map[string]string{
|
|
|
|
"kdf": "wrong",
|
|
|
|
"salt": fmt.Sprintf("%X", saltBytes),
|
|
|
|
"type": "secp256k",
|
|
|
|
}
|
|
|
|
armored = armor.EncodeArmor("TENDERMINT PRIVATE KEY", headerWrongKdf, encBytes)
|
|
|
|
_, _, err = mintkey.UnarmorDecryptPrivKey(armored, "passphrase")
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Equal(t, "unrecognized KDF type: wrong", err.Error())
|
2019-03-29 06:49:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestArmorUnarmorPubKey(t *testing.T) {
|
|
|
|
// Select the encryption and storage for your cryptostore
|
|
|
|
cstore := keys.NewInMemory()
|
|
|
|
|
|
|
|
// Add keys and see they return in alphabetical order
|
|
|
|
info, _, err := cstore.CreateMnemonic("Bob", keys.English, "passphrase", keys.Secp256k1)
|
|
|
|
require.NoError(t, err)
|
2020-03-01 09:16:22 -08:00
|
|
|
armored := mintkey.ArmorPubKeyBytes(info.GetPubKey().Bytes(), "")
|
|
|
|
pubBytes, algo, err := mintkey.UnarmorPubKeyBytes(armored)
|
2019-03-29 06:49:00 -07:00
|
|
|
require.NoError(t, err)
|
|
|
|
pub, err := cryptoAmino.PubKeyFromBytes(pubBytes)
|
|
|
|
require.NoError(t, err)
|
2020-01-14 07:40:10 -08:00
|
|
|
require.Equal(t, string(keys.Secp256k1), algo)
|
2019-03-29 06:49:00 -07:00
|
|
|
require.True(t, pub.Equals(info.GetPubKey()))
|
2020-03-01 09:16:22 -08:00
|
|
|
|
|
|
|
armored = mintkey.ArmorPubKeyBytes(info.GetPubKey().Bytes(), "unknown")
|
|
|
|
pubBytes, algo, err = mintkey.UnarmorPubKeyBytes(armored)
|
|
|
|
require.NoError(t, err)
|
|
|
|
pub, err = cryptoAmino.PubKeyFromBytes(pubBytes)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, "unknown", algo)
|
|
|
|
require.True(t, pub.Equals(info.GetPubKey()))
|
|
|
|
|
|
|
|
// armor pubkey manually
|
|
|
|
header := map[string]string{
|
|
|
|
"version": "0.0.0",
|
|
|
|
"type": "unknown",
|
|
|
|
}
|
|
|
|
armored = armor.EncodeArmor("TENDERMINT PUBLIC KEY", header, pubBytes)
|
|
|
|
_, algo, err = mintkey.UnarmorPubKeyBytes(armored)
|
|
|
|
require.NoError(t, err)
|
|
|
|
// return secp256k1 if version is 0.0.0
|
|
|
|
require.Equal(t, "secp256k1", algo)
|
|
|
|
|
|
|
|
// missing version header
|
|
|
|
header = map[string]string{
|
|
|
|
"type": "unknown",
|
|
|
|
}
|
|
|
|
armored = armor.EncodeArmor("TENDERMINT PUBLIC KEY", header, pubBytes)
|
|
|
|
bz, algo, err := mintkey.UnarmorPubKeyBytes(armored)
|
|
|
|
require.Nil(t, bz)
|
|
|
|
require.Empty(t, algo)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Contains(t, err.Error(), "unrecognized version")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestArmorInfoBytes(t *testing.T) {
|
|
|
|
bs := []byte("test")
|
|
|
|
armoredString := mintkey.ArmorInfoBytes(bs)
|
|
|
|
unarmoredBytes, err := mintkey.UnarmorInfoBytes(armoredString)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.True(t, bytes.Equal(bs, unarmoredBytes))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnarmorInfoBytesErrors(t *testing.T) {
|
|
|
|
unarmoredBytes, err := mintkey.UnarmorInfoBytes("")
|
|
|
|
require.Error(t, err)
|
|
|
|
require.True(t, errors.Is(io.EOF, err))
|
|
|
|
require.Nil(t, unarmoredBytes)
|
|
|
|
|
|
|
|
header := map[string]string{
|
|
|
|
"type": "Info",
|
|
|
|
"version": "0.0.1",
|
|
|
|
}
|
|
|
|
unarmoredBytes, err = mintkey.UnarmorInfoBytes(armor.EncodeArmor(
|
|
|
|
"TENDERMINT KEY INFO", header, []byte("plain-text")))
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Equal(t, "unrecognized version: 0.0.1", err.Error())
|
|
|
|
require.Nil(t, unarmoredBytes)
|
2019-03-29 06:49:00 -07:00
|
|
|
}
|