add status command and action
This commit is contained in:
parent
6e7e217179
commit
a6d70a9e67
|
@ -258,5 +258,15 @@ func commandStatus(i *actionsets.Installer) error {
|
|||
index := askUint8("Pairing index")
|
||||
key := askHex("Pairing key")
|
||||
|
||||
return i.Status(index, key)
|
||||
appStatus, err := i.Status(index, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Pin retry count: %d\n", appStatus.PinRetryCount)
|
||||
fmt.Printf("PUK retry count: %d\n", appStatus.PUKRetryCount)
|
||||
fmt.Printf("Key initialized: %v\n", appStatus.KeyInitialized)
|
||||
fmt.Printf("Public key derivation: %v\n", appStatus.PubKeyDerivation)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package actions
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
|
@ -13,9 +14,10 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrAlreadyInitialized = errors.New("card already initialized")
|
||||
ErrNotInitialized = errors.New("card not initialized")
|
||||
ErrUnknownApplicationInfoTemplate = errors.New("unknown application info template")
|
||||
ErrAlreadyInitialized = errors.New("card already initialized")
|
||||
ErrNotInitialized = errors.New("card not initialized")
|
||||
ErrWrongApplicationInfoTemplate = errors.New("wrong application info template")
|
||||
ErrApplicationStatusTemplateNotFound = errors.New("application status template not found")
|
||||
)
|
||||
|
||||
func Select(c globalplatform.Channel, aid []byte) (*lightwallet.ApplicationInfo, error) {
|
||||
|
@ -164,13 +166,19 @@ func mutualAuthenticate(sc *lightwallet.SecureChannel) error {
|
|||
return checkOKResponse(err, resp)
|
||||
}
|
||||
|
||||
func Status(index uint8, key []byte) error {
|
||||
return nil
|
||||
func GetStatusApplication(c globalplatform.Channel) (*lightwallet.ApplicationStatus, error) {
|
||||
cmd := lightwallet.NewCommandGetStatusApplication()
|
||||
resp, err := c.Send(cmd)
|
||||
if err = checkOKResponse(err, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return parseApplicationStatus(resp.Data)
|
||||
}
|
||||
|
||||
func parseApplicationInfo(data []byte, info *lightwallet.ApplicationInfo) (*lightwallet.ApplicationInfo, error) {
|
||||
if data[0] != lightwallet.TagApplicationInfoTemplate {
|
||||
return nil, ErrUnknownApplicationInfoTemplate
|
||||
return nil, ErrWrongApplicationInfoTemplate
|
||||
}
|
||||
|
||||
instanceUID, err := apdu.FindTag(data, lightwallet.TagApplicationInfoTemplate, uint8(0x8F))
|
||||
|
@ -207,6 +215,37 @@ func parseApplicationInfo(data []byte, info *lightwallet.ApplicationInfo) (*ligh
|
|||
return info, nil
|
||||
}
|
||||
|
||||
func parseApplicationStatus(data []byte) (*lightwallet.ApplicationStatus, error) {
|
||||
appStatus := &lightwallet.ApplicationStatus{}
|
||||
|
||||
tpl, err := apdu.FindTag(data, lightwallet.TagApplicationStatusTemplate)
|
||||
if err != nil {
|
||||
return nil, ErrApplicationStatusTemplateNotFound
|
||||
}
|
||||
|
||||
if pinRetryCount, err := apdu.FindTag(tpl, uint8(0x02)); err == nil && len(pinRetryCount) == 1 {
|
||||
appStatus.PinRetryCount = int(pinRetryCount[0])
|
||||
}
|
||||
|
||||
if pukRetryCount, err := apdu.FindTagN(tpl, 1, uint8(0x02)); err == nil && len(pukRetryCount) == 1 {
|
||||
appStatus.PUKRetryCount = int(pukRetryCount[0])
|
||||
}
|
||||
|
||||
if keyInitialized, err := apdu.FindTag(tpl, uint8(0x01)); err == nil {
|
||||
if bytes.Equal(keyInitialized, []byte{0xFF}) {
|
||||
appStatus.KeyInitialized = true
|
||||
}
|
||||
}
|
||||
|
||||
if keyDerivationSupported, err := apdu.FindTagN(tpl, 1, uint8(0x01)); err == nil {
|
||||
if bytes.Equal(keyDerivationSupported, []byte{0xFF}) {
|
||||
appStatus.PubKeyDerivation = true
|
||||
}
|
||||
}
|
||||
|
||||
return appStatus, nil
|
||||
}
|
||||
|
||||
func checkOKResponse(err error, resp *apdu.Response) error {
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -110,26 +110,26 @@ func (i *Installer) Info() (*lightwallet.ApplicationInfo, error) {
|
|||
}
|
||||
|
||||
// Status returns
|
||||
func (i *Installer) Status(index uint8, key []byte) error {
|
||||
func (i *Installer) Status(index uint8, key []byte) (*lightwallet.ApplicationStatus, error) {
|
||||
info, err := actions.Select(i.c, walletAID)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !info.Installed {
|
||||
return errAppletNotInstalled
|
||||
return nil, errAppletNotInstalled
|
||||
}
|
||||
|
||||
if !info.Initialized {
|
||||
return errCardNotInitialized
|
||||
return nil, errCardNotInitialized
|
||||
}
|
||||
|
||||
sc, err := actions.OpenSecureChannel(i.c, info, index, key)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil
|
||||
return actions.GetStatusApplication(sc)
|
||||
}
|
||||
|
||||
// Delete deletes the applet and related package from the card.
|
||||
|
|
|
@ -10,12 +10,16 @@ const (
|
|||
InsOpenSecureChannel = uint8(0x10)
|
||||
InsMutuallyAuthenticate = uint8(0x11)
|
||||
InsPair = uint8(0x12)
|
||||
InsGetStatus = uint8(0xF2)
|
||||
|
||||
TagSelectResponsePreInitialized = uint8(0x80)
|
||||
TagApplicationStatusTemplate = uint8(0xA3)
|
||||
TagApplicationInfoTemplate = uint8(0xA4)
|
||||
|
||||
P1PairingFirstStep = uint8(0x00)
|
||||
P1PairingFinalStep = uint8(0x01)
|
||||
P1PairingFirstStep = uint8(0x00)
|
||||
P1PairingFinalStep = uint8(0x01)
|
||||
P1GetStatusApplication = uint8(0x00)
|
||||
P1GetStatusKeyPath = uint8(0x01)
|
||||
)
|
||||
|
||||
func NewCommandInit(data []byte) *apdu.Command {
|
||||
|
@ -67,3 +71,21 @@ func NewCommandMutuallyAuthenticate(data []byte) *apdu.Command {
|
|||
data,
|
||||
)
|
||||
}
|
||||
|
||||
func NewCommandGetStatus(p1 uint8) *apdu.Command {
|
||||
return apdu.NewCommand(
|
||||
globalplatform.ClaGp,
|
||||
InsGetStatus,
|
||||
p1,
|
||||
uint8(0x00),
|
||||
[]byte{},
|
||||
)
|
||||
}
|
||||
|
||||
func NewCommandGetStatusApplication() *apdu.Command {
|
||||
return NewCommandGetStatus(P1GetStatusApplication)
|
||||
}
|
||||
|
||||
func NewCommandGetStatusKeyPath() *apdu.Command {
|
||||
return NewCommandGetStatus(P1GetStatusKeyPath)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,13 @@ type ApplicationInfo struct {
|
|||
KeyUID []byte
|
||||
}
|
||||
|
||||
type ApplicationStatus struct {
|
||||
PinRetryCount int
|
||||
PUKRetryCount int
|
||||
KeyInitialized bool
|
||||
PubKeyDerivation bool
|
||||
}
|
||||
|
||||
type PairingInfo struct {
|
||||
Key []byte
|
||||
Index int
|
||||
|
|
Loading…
Reference in New Issue