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/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{}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue