add Delete to Installer
This commit is contained in:
parent
e33b6d138a
commit
077b96f9ee
10
actions.go
10
actions.go
|
@ -19,7 +19,7 @@ var (
|
|||
ErrApplicationStatusTemplateNotFound = errors.New("application status template not found")
|
||||
)
|
||||
|
||||
func Select(c globalplatform.Channel, aid []byte) (*types.ApplicationInfo, error) {
|
||||
func Select(c types.Channel, aid []byte) (*types.ApplicationInfo, error) {
|
||||
sel := globalplatform.NewCommandSelect(aid)
|
||||
resp, err := c.Send(sel)
|
||||
if err != nil {
|
||||
|
@ -47,7 +47,7 @@ func Select(c globalplatform.Channel, aid []byte) (*types.ApplicationInfo, error
|
|||
return parseApplicationInfo(resp.Data, info)
|
||||
}
|
||||
|
||||
func Init(c globalplatform.Channel, cardPubKey []byte, secrets *Secrets, aid []byte) error {
|
||||
func Init(c types.Channel, cardPubKey []byte, secrets *Secrets, aid []byte) error {
|
||||
secureChannel, err := NewSecureChannel(c, cardPubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -64,7 +64,7 @@ func Init(c globalplatform.Channel, cardPubKey []byte, secrets *Secrets, aid []b
|
|||
return checkOKResponse(err, resp)
|
||||
}
|
||||
|
||||
func Pair(c globalplatform.Channel, pairingPass string, pin string) (*types.PairingInfo, error) {
|
||||
func Pair(c types.Channel, pairingPass string, pin string) (*types.PairingInfo, error) {
|
||||
challenge := make([]byte, 32)
|
||||
if _, err := rand.Read(challenge); err != nil {
|
||||
return nil, err
|
||||
|
@ -106,7 +106,7 @@ func Pair(c globalplatform.Channel, pairingPass string, pin string) (*types.Pair
|
|||
}, nil
|
||||
}
|
||||
|
||||
func OpenSecureChannel(c globalplatform.Channel, appInfo *types.ApplicationInfo, pairingIndex uint8, pairingKey []byte) (*SecureChannel, error) {
|
||||
func OpenSecureChannel(c types.Channel, appInfo *types.ApplicationInfo, pairingIndex uint8, pairingKey []byte) (*SecureChannel, error) {
|
||||
sc, err := NewSecureChannel(c, appInfo.PublicKey)
|
||||
cmd := NewCommandOpenSecureChannel(pairingIndex, sc.RawPublicKey())
|
||||
resp, err := c.Send(cmd)
|
||||
|
@ -137,7 +137,7 @@ func mutualAuthenticate(sc *SecureChannel) error {
|
|||
return checkOKResponse(err, resp)
|
||||
}
|
||||
|
||||
func GetStatusApplication(c globalplatform.Channel) (*types.ApplicationStatus, error) {
|
||||
func GetStatusApplication(c types.Channel) (*types.ApplicationStatus, error) {
|
||||
cmd := NewCommandGetStatusApplication()
|
||||
resp, err := c.Send(cmd)
|
||||
if err = checkOKResponse(err, resp); err != nil {
|
||||
|
|
|
@ -23,7 +23,7 @@ var (
|
|||
|
||||
// Initializer defines a struct with methods to install applets and initialize a card.
|
||||
type Initializer struct {
|
||||
c globalplatform.Channel
|
||||
c types.Channel
|
||||
}
|
||||
|
||||
// NewInitializer returns a new Initializer that communicates to Transmitter t.
|
||||
|
@ -33,40 +33,6 @@ func NewInitializer(t globalplatform.Transmitter) *Initializer {
|
|||
}
|
||||
}
|
||||
|
||||
// Install installs the applet from the specified capFile.
|
||||
func (i *Initializer) Install(capFile *os.File, overwriteApplet bool) error {
|
||||
info, err := keycard.Select(i.c, identifiers.KeycardAID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.Installed && !overwriteApplet {
|
||||
return errors.New("applet already installed")
|
||||
}
|
||||
|
||||
err = i.initGPSecureChannel(keycard.CardManagerAID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
instanceAID, err := identifiers.KeycardInstanceAID(1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = i.deleteAID(identifiers.NdefInstanceAID, instanceAID, identifiers.PackageAID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = i.installApplets(capFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *Initializer) Init() (*keycard.Secrets, error) {
|
||||
secrets, err := keycard.NewSecrets()
|
||||
if err != nil {
|
||||
|
@ -94,61 +60,11 @@ func (i *Initializer) Init() (*keycard.Secrets, error) {
|
|||
return secrets, nil
|
||||
}
|
||||
|
||||
func (i *Initializer) Pair(pairingPass, pin string) (*types.PairingInfo, error) {
|
||||
appInfo, err := keycard.Select(i.c, identifiers.KeycardAID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !appInfo.Initialized {
|
||||
return nil, ErrNotInitialized
|
||||
}
|
||||
|
||||
return keycard.Pair(i.c, pairingPass, pin)
|
||||
}
|
||||
|
||||
// Info returns a types.ApplicationInfo struct with info about the card.
|
||||
func (i *Initializer) Info() (*types.ApplicationInfo, error) {
|
||||
return keycard.Select(i.c, identifiers.KeycardAID)
|
||||
}
|
||||
|
||||
// Status returns
|
||||
func (i *Initializer) Status(index uint8, key []byte) (*types.ApplicationStatus, error) {
|
||||
info, err := keycard.Select(i.c, identifiers.KeycardAID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !info.Installed {
|
||||
return nil, errAppletNotInstalled
|
||||
}
|
||||
|
||||
if !info.Initialized {
|
||||
return nil, errCardNotInitialized
|
||||
}
|
||||
|
||||
sc, err := keycard.OpenSecureChannel(i.c, info, index, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return keycard.GetStatusApplication(sc)
|
||||
}
|
||||
|
||||
// Delete deletes the applet and related package from the card.
|
||||
func (i *Initializer) Delete() error {
|
||||
err := i.initGPSecureChannel(keycard.CardManagerAID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
instanceAID, err := identifiers.KeycardInstanceAID(1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return i.deleteAID(identifiers.NdefInstanceAID, instanceAID, identifiers.PackageAID)
|
||||
}
|
||||
|
||||
func (i *Initializer) initGPSecureChannel(sdaid []byte) error {
|
||||
// select card manager
|
||||
err := i.selectAID(sdaid)
|
||||
|
@ -169,7 +85,7 @@ func (i *Initializer) initGPSecureChannel(sdaid []byte) error {
|
|||
}
|
||||
|
||||
func (i *Initializer) selectAID(aid []byte) error {
|
||||
sel := globalplatform.NewCommandSelect(keycard.CardManagerAID)
|
||||
sel := globalplatform.NewCommandSelect(identifiers.CardManagerAID)
|
||||
_, err := i.send("select", sel)
|
||||
|
||||
return err
|
||||
|
@ -220,7 +136,7 @@ func (i *Initializer) deleteAID(aids ...[]byte) error {
|
|||
|
||||
func (i *Initializer) installApplets(capFile *os.File) error {
|
||||
// install for load
|
||||
preLoad := globalplatform.NewCommandInstallForLoad(identifiers.PackageAID, keycard.CardManagerAID)
|
||||
preLoad := globalplatform.NewCommandInstallForLoad(identifiers.PackageAID, identifiers.CardManagerAID)
|
||||
_, err := i.send("install for load", preLoad)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/status-im/keycard-go/globalplatform"
|
||||
"github.com/status-im/keycard-go/hexutils"
|
||||
"github.com/status-im/keycard-go/identifiers"
|
||||
"github.com/status-im/keycard-go/types"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -19,7 +20,7 @@ var (
|
|||
|
||||
// Installer defines a struct with methods to install applets in a card.
|
||||
type Installer struct {
|
||||
c globalplatform.Channel
|
||||
c types.Channel
|
||||
}
|
||||
|
||||
// NewInstaller returns a new Installer that communicates to Transmitter t.
|
||||
|
@ -86,6 +87,32 @@ func (i *Installer) Install(capFile *os.File, overwriteApplet bool) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Delete deletes the applet from the card.
|
||||
func (i *Installer) Delete() error {
|
||||
cmdSet := globalplatform.NewCommandSet(i.c)
|
||||
|
||||
logger.Info("select ISD")
|
||||
err := cmdSet.Select()
|
||||
if err != nil {
|
||||
logger.Error("select failed", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Info("opening secure channel")
|
||||
if err = cmdSet.OpenSecureChannel(); err != nil {
|
||||
logger.Error("open secure channel failed", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Info("delete old version")
|
||||
if err = cmdSet.DeleteKeycardInstancesAndPackage(); err != nil {
|
||||
logger.Error("delete keycard instances and package failed", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Installer) checkAppletAlreadyInstalled(cmdSet *globalplatform.CommandSet, overwriteApplet bool) error {
|
||||
keycardInstanceAID, err := identifiers.KeycardInstanceAID(1)
|
||||
if err != nil {
|
||||
|
|
|
@ -214,7 +214,7 @@ func commandInfo(card *scard.Card) error {
|
|||
}
|
||||
|
||||
func commandDelete(card *scard.Card) error {
|
||||
i := NewInitializer(card)
|
||||
i := NewInstaller(card)
|
||||
err := i.Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package globalplatform
|
||||
|
||||
import "github.com/status-im/keycard-go/apdu"
|
||||
|
||||
// Channel is an interface with a Send method to send apdu commands and receive apdu responses.
|
||||
type Channel interface {
|
||||
Send(*apdu.Command) (*apdu.Response, error)
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/status-im/keycard-go/apdu"
|
||||
"github.com/status-im/keycard-go/identifiers"
|
||||
"github.com/status-im/keycard-go/types"
|
||||
)
|
||||
|
||||
type LoadingCallback = func(loadingBlock, totalBlocks int)
|
||||
|
@ -14,11 +15,11 @@ type LoadingCallback = func(loadingBlock, totalBlocks int)
|
|||
const defaultKeycardInstanceAID = 1
|
||||
|
||||
type CommandSet struct {
|
||||
c Channel
|
||||
c types.Channel
|
||||
session *Session
|
||||
}
|
||||
|
||||
func NewCommandSet(c Channel) *CommandSet {
|
||||
func NewCommandSet(c types.Channel) *CommandSet {
|
||||
return &CommandSet{
|
||||
c: c,
|
||||
}
|
||||
|
|
|
@ -3,17 +3,18 @@ package globalplatform
|
|||
import (
|
||||
"github.com/status-im/keycard-go/apdu"
|
||||
"github.com/status-im/keycard-go/hexutils"
|
||||
"github.com/status-im/keycard-go/types"
|
||||
)
|
||||
|
||||
// SecureChannel wraps another channel and sends wrapped commands using SCP02Wrapper.
|
||||
type SecureChannel struct {
|
||||
session *Session
|
||||
c Channel
|
||||
c types.Channel
|
||||
w *SCP02Wrapper
|
||||
}
|
||||
|
||||
// NewSecureChannel returns a new SecureChannel based on a session and wrapping a Channel c.
|
||||
func NewSecureChannel(session *Session, c Channel) *SecureChannel {
|
||||
func NewSecureChannel(session *Session, c types.Channel) *SecureChannel {
|
||||
return &SecureChannel{
|
||||
session: session,
|
||||
c: c,
|
||||
|
|
|
@ -3,7 +3,8 @@ package identifiers
|
|||
import "errors"
|
||||
|
||||
var (
|
||||
CardTestKey = []byte{0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}
|
||||
CardManagerAID = []byte{0xa0, 0x00, 0x00, 0x01, 0x51, 0x00, 0x00, 0x00}
|
||||
CardTestKey = []byte{0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}
|
||||
|
||||
PackageAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01}
|
||||
KeycardAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x01}
|
||||
|
|
13
keycard.go
13
keycard.go
|
@ -2,17 +2,4 @@ package keycard
|
|||
|
||||
import "github.com/ethereum/go-ethereum/log"
|
||||
|
||||
var (
|
||||
CardManagerAID = []byte{0xa0, 0x00, 0x00, 0x01, 0x51, 0x00, 0x00, 0x00}
|
||||
CardTestKey = []byte{0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}
|
||||
|
||||
AppletPkgAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01}
|
||||
|
||||
WalletAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x01}
|
||||
WalletInstanceAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x01, 0x01}
|
||||
|
||||
NdefAppletAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x02}
|
||||
NdefInstanceAID = []byte{0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01}
|
||||
)
|
||||
|
||||
var logger = log.New("package", "hardware-wallet-go/lightwallet")
|
||||
|
|
|
@ -9,12 +9,13 @@ 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"
|
||||
)
|
||||
|
||||
var ErrInvalidResponseMAC = errors.New("invalid response MAC")
|
||||
|
||||
type SecureChannel struct {
|
||||
c globalplatform.Channel
|
||||
c types.Channel
|
||||
secret []byte
|
||||
publicKey *ecdsa.PublicKey
|
||||
encKey []byte
|
||||
|
@ -22,7 +23,7 @@ type SecureChannel struct {
|
|||
iv []byte
|
||||
}
|
||||
|
||||
func NewSecureChannel(c globalplatform.Channel, cardKeyData []byte) (*SecureChannel, error) {
|
||||
func NewSecureChannel(c types.Channel, cardKeyData []byte) (*SecureChannel, error) {
|
||||
key, err := ethcrypto.GenerateKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
package types
|
||||
|
||||
import "github.com/status-im/keycard-go/apdu"
|
||||
|
||||
// Channel is an interface with a Send method to send apdu commands and receive apdu responses.
|
||||
type Channel interface {
|
||||
Send(*apdu.Command) (*apdu.Response, error)
|
||||
}
|
||||
|
||||
type ApplicationInfo struct {
|
||||
Installed bool
|
||||
Initialized bool
|
||||
|
|
Loading…
Reference in New Issue