mirror of
https://github.com/status-im/keycard-go.git
synced 2025-01-22 01:38:58 +00:00
check if applet is already installed
This commit is contained in:
parent
de9b00d646
commit
341eec2a18
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user