diff --git a/pkg/crypto/keys/publickey.go b/pkg/crypto/keys/publickey.go index c03f6dfa3..9eaf4688a 100644 --- a/pkg/crypto/keys/publickey.go +++ b/pkg/crypto/keys/publickey.go @@ -6,6 +6,7 @@ import ( "crypto/elliptic" "crypto/x509" "encoding/hex" + "encoding/json" "fmt" "math/big" @@ -274,3 +275,28 @@ func (p *PublicKey) String() string { by := hex.EncodeToString(p.Y.Bytes()) return fmt.Sprintf("%s%s", bx, by) } + +// MarshalJSON implements the json.Marshaler interface. +func (p PublicKey) MarshalJSON() ([]byte, error) { + return json.Marshal(hex.EncodeToString(p.Bytes())) +} + +// UnmarshalJSON implements json.Unmarshaler interface. +func (p *PublicKey) UnmarshalJSON(data []byte) error { + l := len(data) + if l < 2 || data[0] != '"' || data[l-1] != '"' { + return errors.New("wrong format") + } + + bytes := make([]byte, l-2) + _, err := hex.Decode(bytes, data[1:l-1]) + if err != nil { + return err + } + err = p.DecodeBytes(bytes) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/crypto/keys/publickey_test.go b/pkg/crypto/keys/publickey_test.go index 813798704..e99f8d347 100644 --- a/pkg/crypto/keys/publickey_test.go +++ b/pkg/crypto/keys/publickey_test.go @@ -2,6 +2,7 @@ package keys import ( "encoding/hex" + "encoding/json" "math/rand" "sort" "testing" @@ -143,3 +144,45 @@ func getPubKey(t *testing.T) *PublicKey { require.NoError(t, err) return pubKey } + +func TestMarshallJSON(t *testing.T) { + str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c" + pubKey, err := NewPublicKeyFromString(str) + require.NoError(t, err) + + bytes, err := json.Marshal(&pubKey) + require.NoError(t, err) + require.Equal(t, []byte(`"`+str+`"`), bytes) +} + +func TestUnmarshallJSON(t *testing.T) { + str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c" + expected, err := NewPublicKeyFromString(str) + require.NoError(t, err) + + actual := &PublicKey{} + err = json.Unmarshal([]byte(`"`+str+`"`), actual) + require.NoError(t, err) + require.Equal(t, expected, actual) +} + +func TestUnmarshallJSONBadCompresed(t *testing.T) { + str := `"02ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"` + actual := &PublicKey{} + err := json.Unmarshal([]byte(str), actual) + require.Error(t, err) +} + +func TestUnmarshallJSONNotAHex(t *testing.T) { + str := `"04Tb17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"` + actual := &PublicKey{} + err := json.Unmarshal([]byte(str), actual) + require.Error(t, err) +} + +func TestUnmarshallJSONBadFormat(t *testing.T) { + str := "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + actual := &PublicKey{} + err := json.Unmarshal([]byte(str), actual) + require.Error(t, err) +}