2018-10-22 17:33:53 +00:00
|
|
|
package lightwallet
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
|
|
|
|
|
|
|
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
|
|
|
"github.com/status-im/smartcard-go/apdu"
|
|
|
|
"github.com/status-im/smartcard-go/globalplatform"
|
|
|
|
"github.com/status-im/smartcard-go/lightwallet/crypto"
|
|
|
|
)
|
|
|
|
|
|
|
|
type SecureChannel struct {
|
2018-10-24 16:16:14 +00:00
|
|
|
c globalplatform.Channel
|
|
|
|
secret []byte
|
|
|
|
publicKey *ecdsa.PublicKey
|
2018-10-22 17:33:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewSecureChannel(c globalplatform.Channel, cardKeyData []byte) (*SecureChannel, error) {
|
|
|
|
key, err := ethcrypto.GenerateKey()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
cardPubKey, err := ethcrypto.UnmarshalPubkey(cardKeyData)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
secret := crypto.GenerateECDHSharedSecret(key, cardPubKey)
|
|
|
|
|
|
|
|
return &SecureChannel{
|
2018-10-24 16:16:14 +00:00
|
|
|
c: c,
|
|
|
|
secret: secret,
|
|
|
|
publicKey: &key.PublicKey,
|
2018-10-22 17:33:53 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2018-10-24 16:16:14 +00:00
|
|
|
func (sc *SecureChannel) PublicKey() *ecdsa.PublicKey {
|
|
|
|
return sc.publicKey
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sc *SecureChannel) RawPublicKey() []byte {
|
|
|
|
return ethcrypto.FromECDSAPub(sc.publicKey)
|
|
|
|
}
|
|
|
|
|
2018-10-22 17:33:53 +00:00
|
|
|
func (sc *SecureChannel) Send(cmd *apdu.Command) (*apdu.Response, error) {
|
|
|
|
return sc.c.Send(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sc *SecureChannel) OneShotEncrypt(secrets *Secrets) ([]byte, error) {
|
2018-10-24 16:16:14 +00:00
|
|
|
pubKeyData := ethcrypto.FromECDSAPub(sc.publicKey)
|
2018-10-22 17:33:53 +00:00
|
|
|
data := append([]byte(secrets.Pin()), []byte(secrets.Puk())...)
|
|
|
|
data = append(data, secrets.PairingToken()...)
|
|
|
|
|
|
|
|
return crypto.OneShotEncrypt(pubKeyData, sc.secret, data)
|
|
|
|
}
|