From d059767e7946545c2ddad56c267e7639c8bf2a5e Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 17:24:36 +0300 Subject: [PATCH 1/3] Add method to load PrivateKey - from hex string - from wif format - from file path --- load.go | 21 +++++++++++++ load_test.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 load.go create mode 100644 load_test.go diff --git a/load.go b/load.go new file mode 100644 index 0000000..601e89e --- /dev/null +++ b/load.go @@ -0,0 +1,21 @@ +package crypto + +import ( + "crypto/ecdsa" + "encoding/hex" + "io/ioutil" + + "github.com/pkg/errors" +) + +func LoadPrivateKey(val string) (*ecdsa.PrivateKey, error) { + if data, err := ioutil.ReadFile(val); err == nil { + return UnmarshalPrivateKey(data) + } else if data, err = hex.DecodeString(val); err == nil { + return UnmarshalPrivateKey(data) + } else if key, err := WIFDecode(val); err == nil { + return key, nil + } + + return nil, errors.Errorf("unknown key format (%q), expect: hex-string, wif or file-path", val) +} diff --git a/load_test.go b/load_test.go new file mode 100644 index 0000000..b7c3fd4 --- /dev/null +++ b/load_test.go @@ -0,0 +1,86 @@ +package crypto + +import ( + "crypto/x509" + "encoding/hex" + "io/ioutil" + "os" + "testing" + + "github.com/nspcc-dev/neofs-crypto/test" + "github.com/stretchr/testify/require" +) + +func Test_LoadPrivateKey_FromWIF(t *testing.T) { + for i := 0; i < 10; i++ { + expected := test.DecodeKey(i) + + wif, err := WIFEncode(expected) + require.NoError(t, err) + + actual, err := LoadPrivateKey(wif) + require.NoError(t, err) + + require.Equal(t, expected, actual) + } +} + +func Test_LoadPrivateKey_FromHexString(t *testing.T) { + for i := 0; i < 10; i++ { + expected := test.DecodeKey(i) + + hs := hex.EncodeToString(expected.D.Bytes()) + + actual, err := LoadPrivateKey(hs) + require.NoError(t, err) + + require.Equal(t, expected, actual) + } +} + +func Test_LoadPrivateKey_FromFile(t *testing.T) { + for i := 0; i < 10; i++ { + expected := test.DecodeKey(i) + + file, err := ioutil.TempFile("", "_marshaled.key") + require.NoError(t, err) + + defer func() { + require.NoError(t, file.Close()) + require.NoError(t, os.Remove(file.Name())) + }() + + data, err := x509.MarshalECPrivateKey(expected) + require.NoError(t, err) + + _, err = file.Write(data) + require.NoError(t, err) + + actual, err := LoadPrivateKey(file.Name()) + require.NoError(t, err) + + require.Equal(t, expected, actual) + } +} + +func Test_LoadPrivateKey_FromCompressedFormatFile(t *testing.T) { + for i := 0; i < 10; i++ { + expected := test.DecodeKey(i) + + file, err := ioutil.TempFile("", "_compressed.key") + require.NoError(t, err) + + defer func() { + require.NoError(t, file.Close()) + require.NoError(t, os.Remove(file.Name())) + }() + + _, err = file.Write(expected.D.Bytes()) + require.NoError(t, err) + + actual, err := LoadPrivateKey(file.Name()) + require.NoError(t, err) + + require.Equal(t, expected, actual) + } +} From f707f6449cc2205903ea02f4c260b0e017b17855 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 17:29:34 +0300 Subject: [PATCH 2/3] docs: describe LoadPrivateKey in readme --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 2fa03b6..de6b3de 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,16 @@ wif, err := crypto.WIFEncode(sk) // if something went wrong, returns error: skFromWIF, err := crypto.WIFDecode(wif) ``` + +### LoadPrivateKey + +``` +// Load private key from wif format +sk, err := crypto.LoadPrivateKey(wif_string) + +// Load private key from hex string +sk, err := crypto.LoadPrivateKey(hex_string) + +// Load private key from file +sk, err := crypto.LoadPrivateKey(file_path) +``` From 9f21fbbfd52c2bd819d737938720976e9f3dc9e0 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 17:32:08 +0300 Subject: [PATCH 3/3] docs: add doc comment for LoadPrivateKey --- load.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/load.go b/load.go index 601e89e..7c61277 100644 --- a/load.go +++ b/load.go @@ -8,6 +8,10 @@ import ( "github.com/pkg/errors" ) +// LoadPrivateKey allows to load private key from various formats: +// - wif string +// - hex string +// - file path (D-bytes or SEC 1 / ASN.1 DER form) func LoadPrivateKey(val string) (*ecdsa.PrivateKey, error) { if data, err := ioutil.ReadFile(val); err == nil { return UnmarshalPrivateKey(data)