add Init to CommandSet

This commit is contained in:
Andrea Franz 2019-03-11 12:50:16 +01:00
parent ce5141b390
commit 76f58a670d
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
3 changed files with 28 additions and 90 deletions

View File

@ -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{}

View File

@ -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
}

View File

@ -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}