add Init to CommandSet
This commit is contained in:
parent
ce5141b390
commit
76f58a670d
85
actions.go
85
actions.go
|
@ -9,7 +9,6 @@ import (
|
||||||
|
|
||||||
"github.com/status-im/keycard-go/apdu"
|
"github.com/status-im/keycard-go/apdu"
|
||||||
"github.com/status-im/keycard-go/crypto"
|
"github.com/status-im/keycard-go/crypto"
|
||||||
"github.com/status-im/keycard-go/globalplatform"
|
|
||||||
"github.com/status-im/keycard-go/types"
|
"github.com/status-im/keycard-go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,51 +18,6 @@ var (
|
||||||
ErrApplicationStatusTemplateNotFound = errors.New("application status template not found")
|
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) {
|
func Pair(c types.Channel, pairingPass string, pin string) (*types.PairingInfo, error) {
|
||||||
challenge := make([]byte, 32)
|
challenge := make([]byte, 32)
|
||||||
if _, err := rand.Read(challenge); err != nil {
|
if _, err := rand.Read(challenge); err != nil {
|
||||||
|
@ -147,45 +101,6 @@ func GetStatusApplication(c types.Channel) (*types.ApplicationStatus, error) {
|
||||||
return parseApplicationStatus(resp.Data)
|
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) {
|
func parseApplicationStatus(data []byte) (*types.ApplicationStatus, error) {
|
||||||
appStatus := &types.ApplicationStatus{}
|
appStatus := &types.ApplicationStatus{}
|
||||||
|
|
||||||
|
|
|
@ -34,25 +34,32 @@ func NewInitializer(t globalplatform.Transmitter) *Initializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Initializer) Init() (*keycard.Secrets, error) {
|
func (i *Initializer) Init() (*keycard.Secrets, error) {
|
||||||
|
logger.Info("initialization started")
|
||||||
|
cmdSet := keycard.NewCommandSet(i.c)
|
||||||
|
|
||||||
secrets, err := keycard.NewSecrets()
|
secrets, err := keycard.NewSecrets()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := keycard.Select(i.c, identifiers.KeycardAID)
|
logger.Info("select keycard applet")
|
||||||
|
err = cmdSet.Select()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Error("select failed", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !info.Installed {
|
if !cmdSet.ApplicationInfo.Installed {
|
||||||
|
logger.Error("initialization failed", "error", errAppletNotInstalled)
|
||||||
return nil, errAppletNotInstalled
|
return nil, errAppletNotInstalled
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.Initialized {
|
if cmdSet.ApplicationInfo.Initialized {
|
||||||
|
logger.Error("initialization failed", "error", errCardAlreadyInitialized)
|
||||||
return nil, errCardAlreadyInitialized
|
return nil, errCardAlreadyInitialized
|
||||||
}
|
}
|
||||||
|
|
||||||
err = keycard.Init(i.c, info.PublicKey, secrets, identifiers.KeycardAID)
|
err = cmdSet.Init(secrets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -64,7 +71,6 @@ func (i *Initializer) Init() (*keycard.Secrets, error) {
|
||||||
func (i *Initializer) Info() (types.ApplicationInfo, error) {
|
func (i *Initializer) Info() (types.ApplicationInfo, error) {
|
||||||
cmdSet := keycard.NewCommandSet(i.c)
|
cmdSet := keycard.NewCommandSet(i.c)
|
||||||
err := cmdSet.Select()
|
err := cmdSet.Select()
|
||||||
|
|
||||||
return cmdSet.ApplicationInfo, err
|
return cmdSet.ApplicationInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,23 @@ func (cs *CommandSet) Select() error {
|
||||||
return err
|
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 {
|
func (cs *CommandSet) checkOK(resp *apdu.Response, err error, allowedResponses ...uint16) error {
|
||||||
if len(allowedResponses) == 0 {
|
if len(allowedResponses) == 0 {
|
||||||
allowedResponses = []uint16{apdu.SwOK}
|
allowedResponses = []uint16{apdu.SwOK}
|
||||||
|
|
Loading…
Reference in New Issue