add gp-get-status command

This commit is contained in:
Andrea Franz 2019-04-18 00:02:57 +02:00
parent 79afe2a3c7
commit a4820de8c7
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
6 changed files with 82 additions and 22 deletions

4
Gopkg.lock generated
View File

@ -42,7 +42,7 @@
[[projects]] [[projects]]
branch = "develop" branch = "develop"
digest = "1:fdad9e6435d380941cc5a8270d3bb5a1d391069f6e0ad828f3b8d105ce51c263" digest = "1:bb595307da0f85c32419658d722f3260dfb3c1256f8ec4707a204f7375b66b13"
name = "github.com/status-im/keycard-go" name = "github.com/status-im/keycard-go"
packages = [ packages = [
".", ".",
@ -57,7 +57,7 @@
"types", "types",
] ]
pruneopts = "NUT" pruneopts = "NUT"
revision = "8adf2b6627095127f26f77af865c056bb510097a" revision = "dbfad2a8b07afcc0ca3b28b41f8d03376669719f"
[[projects]] [[projects]]
branch = "master" branch = "master"

View File

@ -121,6 +121,7 @@ func NewShell(t keycardio.Transmitter) *Shell {
"gp-delete": s.commandGPDelete, "gp-delete": s.commandGPDelete,
"gp-load": s.commandGPLoad, "gp-load": s.commandGPLoad,
"gp-install-for-install": s.commandGPInstallForInstall, "gp-install-for-install": s.commandGPInstallForInstall,
"gp-get-status": s.commandGPGetStatus,
"keycard-init": s.commandKeycardInit, "keycard-init": s.commandKeycardInit,
"keycard-select": s.commandKeycardSelect, "keycard-select": s.commandKeycardSelect,
"keycard-pair": s.commandKeycardPair, "keycard-pair": s.commandKeycardPair,
@ -317,6 +318,16 @@ func (s *Shell) commandGPInstallForInstall(args ...string) error {
return s.gpCmdSet.InstallForInstall(pkgAID, appletAID, instanceAID, params) return s.gpCmdSet.InstallForInstall(pkgAID, appletAID, instanceAID, params)
} }
func (s *Shell) commandGPGetStatus(args ...string) error {
if err := s.requireArgs(args, 0); err != nil {
return err
}
logger.Info("get status")
return s.gpCmdSet.GetStatus()
}
func (s *Shell) commandKeycardInit(args ...string) error { func (s *Shell) commandKeycardInit(args ...string) error {
if err := s.requireArgs(args, 0); err != nil { if err := s.requireArgs(args, 0); err != nil {
return err return err

View File

@ -3,8 +3,12 @@ package apdu
import ( import (
"bytes" "bytes"
"encoding/binary" "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. // Command struct represent the data sent as an APDU command with CLA, Ins, P1, P2, Lc, Data, and Le.
type Command struct { type Command struct {
Cla uint8 Cla uint8
@ -76,3 +80,52 @@ func (c *Command) Serialize() ([]byte, error) {
return buf.Bytes(), nil 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

@ -41,14 +41,7 @@ func (cs *CommandSet) Select() error {
return err return err
} }
cmd := apdu.NewCommand( cmd := globalplatform.NewCommandSelect(instanceAID)
0x00,
globalplatform.InsSelect,
uint8(0x04),
uint8(0x00),
instanceAID,
)
cmd.SetLe(0) cmd.SetLe(0)
resp, err := cs.c.Send(cmd) resp, err := cs.c.Send(cmd)
if err = cs.checkOK(resp, err); err != nil { if err = cs.checkOK(resp, err); err != nil {

View File

@ -31,14 +31,7 @@ func (cs *CommandSet) Select() error {
} }
func (cs *CommandSet) SelectAID(aid []byte) error { func (cs *CommandSet) SelectAID(aid []byte) error {
cmd := apdu.NewCommand( cmd := NewCommandSelect(aid)
0x00,
InsSelect,
uint8(0x04),
uint8(0x00),
aid,
)
cmd.SetLe(0) cmd.SetLe(0)
resp, err := cs.c.Send(cmd) resp, err := cs.c.Send(cmd)
@ -150,6 +143,20 @@ func (cs *CommandSet) InstallForInstall(packageAID, appletAID, instanceAID, para
return cs.checkOK(resp, err) return cs.checkOK(resp, err)
} }
func (cs *CommandSet) GetStatus() error {
cmd := NewCommandGetStatus([]byte{}, P1GetStatusIssuerSecurityDomain)
resp, err := cs.sc.Send(cmd)
return cs.checkOK(resp, err)
}
func (cs *CommandSet) Channel() types.Channel {
return cs.c
}
func (cs *CommandSet) SecureChannel() *SecureChannel {
return cs.sc
}
func (cs *CommandSet) initializeUpdate(hostChallenge []byte) error { func (cs *CommandSet) initializeUpdate(hostChallenge []byte) error {
cmd := NewCommandInitializeUpdate(hostChallenge) cmd := NewCommandInitializeUpdate(hostChallenge)
resp, err := cs.c.Send(cmd) resp, err := cs.c.Send(cmd)

View File

@ -56,10 +56,6 @@ func NewCommandSelect(aid []byte) *apdu.Command {
aid, aid,
) )
// with T=0 we can both set or not the Le value
// with T=1 it works only without Le
// c.SetLe(0x00)
return c return c
} }