From 76f58a670dfb560560427e6821744b572bf9cc06 Mon Sep 17 00:00:00 2001 From: Andrea Franz Date: Mon, 11 Mar 2019 12:50:16 +0100 Subject: [PATCH] add Init to CommandSet --- actions.go | 85 -------------------------------------- cmd/keycard/initializer.go | 16 ++++--- command_set.go | 17 ++++++++ 3 files changed, 28 insertions(+), 90 deletions(-) diff --git a/actions.go b/actions.go index b6b805d..dbada6f 100644 --- a/actions.go +++ b/actions.go @@ -9,7 +9,6 @@ import ( "github.com/status-im/keycard-go/apdu" "github.com/status-im/keycard-go/crypto" - "github.com/status-im/keycard-go/globalplatform" "github.com/status-im/keycard-go/types" ) @@ -19,51 +18,6 @@ var ( ErrApplicationStatusTemplateNotFound = errors.New("application status template not found") ) -func Select(c types.Channel, aid []byte) (*types.ApplicationInfo, error) { - sel := globalplatform.NewCommandSelect(aid) - resp, err := c.Send(sel) - if err != nil { - return nil, err - } - - err = checkResponse(resp, globalplatform.SwOK, globalplatform.SwFileNotFound) - if err != nil { - return nil, err - } - - info := &types.ApplicationInfo{} - if resp.Sw == globalplatform.SwFileNotFound { - return info, nil - } - - info.Installed = true - if resp.Data[0] == TagSelectResponsePreInitialized { - info.PublicKey = resp.Data[2:] - return info, nil - } - - info.Initialized = true - - return parseApplicationInfo(resp.Data, info) -} - -func Init(c types.Channel, cardPubKey []byte, secrets *Secrets, aid []byte) error { - secureChannel, err := NewSecureChannel(c, cardPubKey) - if err != nil { - return err - } - - data, err := secureChannel.OneShotEncrypt(secrets) - if err != nil { - return err - } - - init := NewCommandInit(data) - resp, err := c.Send(init) - - return checkOKResponse(err, resp) -} - func Pair(c types.Channel, pairingPass string, pin string) (*types.PairingInfo, error) { challenge := make([]byte, 32) if _, err := rand.Read(challenge); err != nil { @@ -147,45 +101,6 @@ func GetStatusApplication(c types.Channel) (*types.ApplicationStatus, error) { return parseApplicationStatus(resp.Data) } -func parseApplicationInfo(data []byte, info *types.ApplicationInfo) (*types.ApplicationInfo, error) { - if data[0] != TagApplicationInfoTemplate { - return nil, ErrWrongApplicationInfoTemplate - } - - instanceUID, err := apdu.FindTag(data, TagApplicationInfoTemplate, uint8(0x8F)) - if err != nil { - return nil, err - } - - pubKey, err := apdu.FindTag(data, TagApplicationInfoTemplate, uint8(0x80)) - if err != nil { - return nil, err - } - - appVersion, err := apdu.FindTag(data, TagApplicationInfoTemplate, uint8(0x02)) - if err != nil { - return nil, err - } - - availableSlots, err := apdu.FindTagN(data, 1, TagApplicationInfoTemplate, uint8(0x02)) - if err != nil { - return nil, err - } - - keyUID, err := apdu.FindTagN(data, 0, TagApplicationInfoTemplate, uint8(0x8E)) - if err != nil { - return nil, err - } - - info.InstanceUID = instanceUID - info.PublicKey = pubKey - info.Version = appVersion - info.AvailableSlots = availableSlots - info.KeyUID = keyUID - - return info, nil -} - func parseApplicationStatus(data []byte) (*types.ApplicationStatus, error) { appStatus := &types.ApplicationStatus{} diff --git a/cmd/keycard/initializer.go b/cmd/keycard/initializer.go index e2ddc7f..a1cceaf 100644 --- a/cmd/keycard/initializer.go +++ b/cmd/keycard/initializer.go @@ -34,25 +34,32 @@ func NewInitializer(t globalplatform.Transmitter) *Initializer { } func (i *Initializer) Init() (*keycard.Secrets, error) { + logger.Info("initialization started") + cmdSet := keycard.NewCommandSet(i.c) + secrets, err := keycard.NewSecrets() if err != nil { return nil, err } - info, err := keycard.Select(i.c, identifiers.KeycardAID) + logger.Info("select keycard applet") + err = cmdSet.Select() if err != nil { + logger.Error("select failed", "error", err) return nil, err } - if !info.Installed { + if !cmdSet.ApplicationInfo.Installed { + logger.Error("initialization failed", "error", errAppletNotInstalled) return nil, errAppletNotInstalled } - if info.Initialized { + if cmdSet.ApplicationInfo.Initialized { + logger.Error("initialization failed", "error", errCardAlreadyInitialized) return nil, errCardAlreadyInitialized } - err = keycard.Init(i.c, info.PublicKey, secrets, identifiers.KeycardAID) + err = cmdSet.Init(secrets) if err != nil { return nil, err } @@ -64,7 +71,6 @@ func (i *Initializer) Init() (*keycard.Secrets, error) { func (i *Initializer) Info() (types.ApplicationInfo, error) { cmdSet := keycard.NewCommandSet(i.c) err := cmdSet.Select() - return cmdSet.ApplicationInfo, err } diff --git a/command_set.go b/command_set.go index c22be06..fec8523 100644 --- a/command_set.go +++ b/command_set.go @@ -50,6 +50,23 @@ func (cs *CommandSet) Select() error { return err } +func (cs *CommandSet) Init(secrets *Secrets) error { + secureChannel, err := NewSecureChannel(cs.c, cs.ApplicationInfo.PublicKey) + if err != nil { + return err + } + + data, err := secureChannel.OneShotEncrypt(secrets) + if err != nil { + return err + } + + init := NewCommandInit(data) + resp, err := cs.c.Send(init) + + return cs.checkOK(resp, err) +} + func (cs *CommandSet) checkOK(resp *apdu.Response, err error, allowedResponses ...uint16) error { if len(allowedResponses) == 0 { allowedResponses = []uint16{apdu.SwOK}