add ParseCommand to apdu pkg

This commit is contained in:
Andrea Franz 2019-04-17 23:56:24 +02:00
parent 744a584d51
commit a41d275957
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
2 changed files with 67 additions and 0 deletions

View File

@ -3,8 +3,12 @@ package apdu
import (
"bytes"
"encoding/binary"
"errors"
)
// ErrBadRawCommand is an error returned by ParseCommand in case the command data is not long enough.
var ErrBadRawCommand = errors.New("command must be at least 4 bytes")
// Command struct represent the data sent as an APDU command with CLA, Ins, P1, P2, Lc, Data, and Le.
type Command struct {
Cla uint8
@ -76,3 +80,52 @@ func (c *Command) Serialize() ([]byte, error) {
return buf.Bytes(), nil
}
func (c *Command) deserialize(data []byte) error {
if len(data) < 4 {
return ErrBadRawCommand
}
buf := bytes.NewReader(data)
if err := binary.Read(buf, binary.BigEndian, &c.Cla); err != nil {
return err
}
if err := binary.Read(buf, binary.BigEndian, &c.Ins); err != nil {
return err
}
if err := binary.Read(buf, binary.BigEndian, &c.P1); err != nil {
return err
}
if err := binary.Read(buf, binary.BigEndian, &c.P2); err != nil {
return err
}
var lc uint8
if err := binary.Read(buf, binary.BigEndian, &lc); err != nil {
return nil
}
cmdData := make([]byte, lc)
if err := binary.Read(buf, binary.BigEndian, &cmdData); err != nil {
return nil
}
c.Data = cmdData
var le uint8
if err := binary.Read(buf, binary.BigEndian, &le); err != nil {
return nil
}
c.SetLe(le)
return nil
}
// ParseCommand parses a raw command and returns a Command
func ParseCommand(raw []byte) (*Command, error) {
cmd := &Command{}
return cmd, cmd.deserialize(raw)
}

View File

@ -5,6 +5,7 @@ import (
"github.com/status-im/keycard-go/hexutils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewCommand(t *testing.T) {
@ -27,3 +28,16 @@ func TestNewCommand(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, expected, hexutils.BytesToHexWithSpaces(result))
}
func TestParseCommand(t *testing.T) {
raw := hexutils.HexToBytes("0102030402050607")
cmd, err := ParseCommand(raw)
require.Nil(t, err)
assert.Equal(t, uint8(0x01), cmd.Cla)
assert.Equal(t, uint8(0x02), cmd.Ins)
assert.Equal(t, uint8(0x03), cmd.P1)
assert.Equal(t, uint8(0x04), cmd.P2)
assert.Equal(t, []byte{0x05, 0x06}, cmd.Data)
assert.True(t, cmd.requiresLe)
assert.Equal(t, uint8(0x07), cmd.le)
}