keycard-go/io/normal_channel.go

55 lines
1.6 KiB
Go
Raw Normal View History

package io
import (
2021-10-21 12:27:09 +00:00
"github.com/status-im/go-ethereum/log"
2019-03-01 17:44:07 +00:00
"github.com/status-im/keycard-go/apdu"
"github.com/status-im/keycard-go/globalplatform"
2019-03-01 17:44:07 +00:00
"github.com/status-im/keycard-go/hexutils"
)
2021-10-21 12:53:57 +00:00
var logger = log.New("package", "keycard-go/io")
2018-10-05 14:40:32 +00:00
// Transmitter defines an interface with one method to transmit raw commands and receive raw responses.
type Transmitter interface {
Transmit([]byte) ([]byte, error)
}
2018-10-05 14:40:32 +00:00
// NormalChannel implements a normal channel to send apdu commands and receive apdu responses.
type NormalChannel struct {
t Transmitter
}
2018-10-05 14:40:32 +00:00
// NewNormalChannel returns a new NormalChannel that sends commands to Transmitter t.
func NewNormalChannel(t Transmitter) *NormalChannel {
return &NormalChannel{t}
}
2018-10-05 14:40:32 +00:00
// Send sends apdu commands to the current Transmitter.
// Based on the smartcard transport protocol (T=0, T=1), it checks responses and sends a Get Response
// command in case of T=0.
func (c *NormalChannel) Send(cmd *apdu.Command) (*apdu.Response, error) {
rawCmd, err := cmd.Serialize()
if err != nil {
return nil, err
}
2018-10-05 09:35:56 +00:00
logger.Debug("apdu command", "hex", hexutils.BytesToHexWithSpaces(rawCmd))
rawResp, err := c.t.Transmit(rawCmd)
if err != nil {
return nil, err
}
2018-10-05 09:35:56 +00:00
logger.Debug("apdu response", "hex", hexutils.BytesToHexWithSpaces(rawResp))
resp, err := apdu.ParseResponse(rawResp)
if err != nil {
return nil, err
}
if resp.Sw1 == globalplatform.Sw1ResponseDataIncomplete && (cmd.Cla != globalplatform.ClaISO7816 || cmd.Ins != globalplatform.InsGetResponse) {
getResponse := globalplatform.NewCommandGetResponse(resp.Sw2)
return c.Send(getResponse)
}
return apdu.ParseResponse(rawResp)
}