check if applet is already installed

This commit is contained in:
Andrea Franz 2019-03-06 14:31:40 +01:00
parent de9b00d646
commit 341eec2a18
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
3 changed files with 47 additions and 9 deletions

View File

@ -14,21 +14,21 @@ const (
// ErrBadResponse defines an error conaining the returned Sw code and a description message.
type ErrBadResponse struct {
sw uint16
Sw uint16
message string
}
// NewErrBadResponse returns a ErrBadResponse with the specified sw and message values.
func NewErrBadResponse(sw uint16, message string) *ErrBadResponse {
return &ErrBadResponse{
sw: sw,
Sw: sw,
message: message,
}
}
// Error implements the error interface.
func (e *ErrBadResponse) Error() string {
return fmt.Sprintf("bad response %x: %s", e.sw, e.message)
return fmt.Sprintf("bad response %x: %s", e.Sw, e.message)
}
// Response represents a struct containing the smartcard response fields.

View File

@ -1,15 +1,21 @@
package main
import (
"errors"
"fmt"
"os"
"time"
"github.com/status-im/keycard-go/apdu"
"github.com/status-im/keycard-go/globalplatform"
"github.com/status-im/keycard-go/hexutils"
"github.com/status-im/keycard-go/identifiers"
)
var ndefRecord = hexutils.HexToBytes("0024d40f12616e64726f69642e636f6d3a706b67696d2e7374617475732e657468657265756d")
var (
ErrAppletAlreadyInstalled = errors.New("keycard applet already installed")
ndefRecord = hexutils.HexToBytes("0024d40f12616e64726f69642e636f6d3a706b67696d2e7374617475732e657468657265756d")
)
// Installer defines a struct with methods to install applets in a card.
type Installer struct {
@ -24,18 +30,23 @@ func NewInstaller(t globalplatform.Transmitter) *Installer {
}
// Install installs the applet from the specified capFile.
func (i *Installer) Install(capFile *os.File, overwriteApplet bool) (err error) {
func (i *Installer) Install(capFile *os.File, overwriteApplet bool) error {
logger.Info("installation started")
startTime := time.Now()
cmdSet := globalplatform.NewCommandSet(i.c)
logger.Info("check if keycard is already installed")
if err := i.checkAppletAlreadyInstalled(cmdSet, overwriteApplet); err != nil {
logger.Error("check if keycard is already installed failed", "error", err)
return err
}
logger.Info("select ISD")
err := cmdSet.Select()
if err != nil {
logger.Error("select failed", "error", err)
return err
}
logger.Debug("isd retrieved", "isd", hexutils.BytesToHexWithSpaces(isd))
logger.Info("opening secure channel")
if err = cmdSet.OpenSecureChannel(); err != nil {
@ -74,3 +85,27 @@ func (i *Installer) Install(capFile *os.File, overwriteApplet bool) (err error)
logger.Info(fmt.Sprintf("installation completed in %f seconds", elapsed.Seconds()))
return err
}
func (i *Installer) checkAppletAlreadyInstalled(cmdSet *globalplatform.CommandSet, overwriteApplet bool) error {
keycardInstanceAID, err := identifiers.KeycardInstanceAID(1)
if err != nil {
return err
}
err = cmdSet.SelectAID(keycardInstanceAID)
switch e := err.(type) {
case *apdu.ErrBadResponse:
// keycard applet not found, so not installed yet.
if e.Sw == globalplatform.SwFileNotFound {
return nil
}
return err
case nil: // selected successfully, so it's already installed
if overwriteApplet {
return nil
}
return ErrAppletAlreadyInstalled
default:
return err
}
}

View File

@ -3,7 +3,6 @@ package globalplatform
import (
"crypto/rand"
"errors"
"fmt"
"os"
"github.com/status-im/keycard-go/apdu"
@ -26,12 +25,16 @@ func NewCommandSet(c Channel) *CommandSet {
}
func (cs *CommandSet) Select() error {
return cs.SelectAID(nil)
}
func (cs *CommandSet) SelectAID(aid []byte) error {
cmd := apdu.NewCommand(
0x00,
InsSelect,
uint8(0x04),
uint8(0x00),
nil,
aid,
)
cmd.SetLe(0)
@ -173,7 +176,7 @@ func (cs *CommandSet) checkOK(resp *apdu.Response, err error, allowedResponses .
}
}
return fmt.Errorf("unexpected response: %x", resp.Sw)
return apdu.NewErrBadResponse(resp.Sw, "unexpected response")
}
func generateHostChallenge() ([]byte, error) {