parse key path status

This commit is contained in:
Andrea Franz 2019-03-15 16:09:38 +01:00
parent 9aed67c579
commit f42cbfe8b5
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
5 changed files with 55 additions and 17 deletions

View File

@ -129,7 +129,7 @@ func (i *Initializer) Status(key []byte, index int) (*types.ApplicationStatus, e
}
logger.Info("get status")
appStatus, err := cmdSet.GetStatus()
appStatus, err := cmdSet.GetStatusApplication()
if err != nil {
logger.Error("get status failed", "error", err)
return nil, err

View File

@ -317,16 +317,24 @@ func (s *Shell) commandKeycardGetStatus(args ...string) error {
return err
}
logger.Info("get status")
appStatus, err := s.kCmdSet.GetStatus()
logger.Info("get status application")
appStatus, err := s.kCmdSet.GetStatusApplication()
if err != nil {
logger.Error("get status failed", "error", err)
logger.Error("get status application failed", "error", err)
return err
}
logger.Info("get status key path")
keyStatus, err := s.kCmdSet.GetStatusKeyPath()
if err != nil {
logger.Error("get status key path failed", "error", err)
return err
}
s.write(fmt.Sprintf("STATUS - PIN RETRY COUNT: %d\n", appStatus.PinRetryCount))
s.write(fmt.Sprintf("STATUS - PUK RETRY COUNT: %d\n", appStatus.PUKRetryCount))
s.write(fmt.Sprintf("STATUS - KEY INITIALIZED: %v\n", appStatus.KeyInitialized))
s.write(fmt.Sprintf("STATUS - KEY PATH: %v\n", keyStatus.Path))
return nil
}

View File

@ -151,8 +151,8 @@ func (cs *CommandSet) OpenSecureChannel() error {
return nil
}
func (cs *CommandSet) GetStatus() (*types.ApplicationStatus, error) {
cmd := NewCommandGetStatusApplication()
func (cs *CommandSet) GetStatus(info uint8) (*types.ApplicationStatus, error) {
cmd := NewCommandGetStatus(info)
resp, err := cs.sc.Send(cmd)
if err = cs.checkOK(resp, err); err != nil {
return nil, err
@ -161,6 +161,14 @@ func (cs *CommandSet) GetStatus() (*types.ApplicationStatus, error) {
return types.ParseApplicationStatus(resp.Data)
}
func (cs *CommandSet) GetStatusApplication() (*types.ApplicationStatus, error) {
return cs.GetStatus(P1GetStatusApplication)
}
func (cs *CommandSet) GetStatusKeyPath() (*types.ApplicationStatus, error) {
return cs.GetStatus(P1GetStatusKeyPath)
}
func (cs *CommandSet) VerifyPIN(pin string) error {
cmd := NewCommandVerifyPIN(pin)
resp, err := cs.sc.Send(cmd)

View File

@ -90,14 +90,6 @@ func NewCommandGetStatus(p1 uint8) *apdu.Command {
)
}
func NewCommandGetStatusApplication() *apdu.Command {
return NewCommandGetStatus(P1GetStatusApplication)
}
func NewCommandGetStatusKeyPath() *apdu.Command {
return NewCommandGetStatus(P1GetStatusKeyPath)
}
func NewCommandGenerateKey() *apdu.Command {
return apdu.NewCommand(
globalplatform.ClaGp,

View File

@ -2,27 +2,33 @@ package types
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"strings"
"github.com/status-im/keycard-go/apdu"
)
const hardenedStart = 0x80000000 // 2^31
var ErrApplicationStatusTemplateNotFound = errors.New("application status template not found")
type ApplicationStatus struct {
PinRetryCount int
PUKRetryCount int
KeyInitialized bool
Path string
}
func ParseApplicationStatus(data []byte) (*ApplicationStatus, error) {
appStatus := &ApplicationStatus{}
tpl, err := apdu.FindTag(data, TagApplicationStatusTemplate)
if err != nil {
return nil, ErrApplicationStatusTemplateNotFound
return parseKeyPathStatus(data)
}
appStatus := &ApplicationStatus{}
if pinRetryCount, err := apdu.FindTag(tpl, uint8(0x02)); err == nil && len(pinRetryCount) == 1 {
appStatus.PinRetryCount = int(pinRetryCount[0])
}
@ -39,3 +45,27 @@ func ParseApplicationStatus(data []byte) (*ApplicationStatus, error) {
return appStatus, nil
}
func parseKeyPathStatus(data []byte) (*ApplicationStatus, error) {
appStatus := &ApplicationStatus{}
buf := bytes.NewBuffer(data)
rawPath := make([]uint32, buf.Len()/4)
err := binary.Read(buf, binary.BigEndian, &rawPath)
if err != nil {
return nil, err
}
segments := []string{"m"}
for _, i := range rawPath {
suffix := ""
if i >= hardenedStart {
i = i - hardenedStart
suffix = "'"
}
segments = append(segments, fmt.Sprintf("%d%s", i, suffix))
}
appStatus.Path = strings.Join(segments, "/")
return appStatus, nil
}