forked from TrueCloudLab/neoneo-go
keys: check length first, then do things in WIFDecode
Otherwise we can easily panic there on bad input.
This commit is contained in:
parent
3c722a9498
commit
eb67145f81
3 changed files with 53 additions and 23 deletions
|
@ -110,7 +110,9 @@ func NewPrivateKeyFromWIF(wif string) (*PrivateKey, error) {
|
|||
// Good documentation about this process can be found here:
|
||||
// https://en.bitcoin.it/wiki/Wallet_import_format
|
||||
func (p *PrivateKey) WIF() string {
|
||||
w, err := WIFEncode(p.Bytes(), WIFVersion, true)
|
||||
pb := p.Bytes()
|
||||
defer slice.Clean(pb)
|
||||
w, err := WIFEncode(pb, WIFVersion, true)
|
||||
// The only way WIFEncode() can fail is if we're to give it a key of
|
||||
// wrong size, but we have a proper key here, aren't we?
|
||||
if err != nil {
|
||||
|
|
|
@ -59,36 +59,31 @@ func WIFDecode(wif string, version byte) (*WIF, error) {
|
|||
if version == 0x00 {
|
||||
version = WIFVersion
|
||||
}
|
||||
w := &WIF{
|
||||
Version: version,
|
||||
S: wif,
|
||||
}
|
||||
switch len(b) {
|
||||
case 33: // OK, uncompressed public key.
|
||||
case 34: // OK, compressed public key.
|
||||
// Check the compression flag.
|
||||
if b[33] != 0x01 {
|
||||
return nil, fmt.Errorf("invalid compression flag %d expecting %d", b[33], 0x01)
|
||||
}
|
||||
w.Compressed = true
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid WIF length %d, expecting 33 or 34", len(b))
|
||||
}
|
||||
|
||||
if b[0] != version {
|
||||
return nil, fmt.Errorf("invalid WIF version got %d, expected %d", b[0], version)
|
||||
}
|
||||
|
||||
// Derive the PrivateKey.
|
||||
privKey, err := NewPrivateKeyFromBytes(b[1:33])
|
||||
w.PrivateKey, err = NewPrivateKeyFromBytes(b[1:33])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w := &WIF{
|
||||
Version: version,
|
||||
PrivateKey: privKey,
|
||||
S: wif,
|
||||
}
|
||||
|
||||
// This is an uncompressed WIF.
|
||||
if len(b) == 33 {
|
||||
w.Compressed = false
|
||||
return w, nil
|
||||
}
|
||||
|
||||
if len(b) != 34 {
|
||||
return nil, fmt.Errorf("invalid WIF length: %d expecting 34", len(b))
|
||||
}
|
||||
|
||||
// Check the compression flag.
|
||||
if b[33] != 0x01 {
|
||||
return nil, fmt.Errorf("invalid compression flag %d expecting %d", b[34], 0x01)
|
||||
}
|
||||
|
||||
w.Compressed = true
|
||||
return w, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/base58"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -65,3 +66,35 @@ func TestWIFEncodeDecode(t *testing.T) {
|
|||
_, err := WIFEncode(wifInv, 0, true)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestBadWIFDecode(t *testing.T) {
|
||||
_, err := WIFDecode("garbage", 0)
|
||||
require.Error(t, err)
|
||||
|
||||
s := base58.CheckEncode([]byte{})
|
||||
_, err = WIFDecode(s, 0)
|
||||
require.Error(t, err)
|
||||
|
||||
uncompr := make([]byte, 33)
|
||||
compr := make([]byte, 34)
|
||||
|
||||
s = base58.CheckEncode(compr)
|
||||
_, err = WIFDecode(s, 0)
|
||||
require.Error(t, err)
|
||||
|
||||
s = base58.CheckEncode(uncompr)
|
||||
_, err = WIFDecode(s, 0)
|
||||
require.Error(t, err)
|
||||
|
||||
compr[33] = 1
|
||||
compr[0] = WIFVersion
|
||||
uncompr[0] = WIFVersion
|
||||
|
||||
s = base58.CheckEncode(compr)
|
||||
_, err = WIFDecode(s, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
s = base58.CheckEncode(uncompr)
|
||||
_, err = WIFDecode(s, 0)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue