add Secrets struct
This commit is contained in:
parent
ec500a3ab6
commit
9def1c00c3
|
@ -29,30 +29,30 @@ func NewInstaller(t Transmitter) *Installer {
|
|||
}
|
||||
}
|
||||
|
||||
func (i *Installer) Install(capFile *os.File) error {
|
||||
func (i *Installer) Install(capFile *os.File) (*Secrets, error) {
|
||||
sel := globalplatform.NewCommandSelect(sdaid)
|
||||
resp, err := i.send("select", sel)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// initialize update
|
||||
hostChallenge, err := generateHostChallenge()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
init := globalplatform.NewCommandInitializeUpdate(hostChallenge)
|
||||
resp, err = i.send("initialize update", init)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// verify cryptogram and initialize session keys
|
||||
keys := globalplatform.NewKeyProvider(testKey, testKey)
|
||||
session, err := globalplatform.NewSession(keys, resp, hostChallenge)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i.c = NewSecureChannel(session, i.c)
|
||||
|
@ -61,12 +61,12 @@ func (i *Installer) Install(capFile *os.File) error {
|
|||
encKey := session.KeyProvider().Enc()
|
||||
extAuth, err := globalplatform.NewCommandExternalAuthenticate(encKey, session.CardChallenge(), hostChallenge)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err = i.send("external authenticate", extAuth)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// delete current pkg and applet
|
||||
|
@ -79,7 +79,7 @@ func (i *Installer) Install(capFile *os.File) error {
|
|||
del := globalplatform.NewCommandDelete(aid)
|
||||
resp, err = i.send("delete", del, globalplatform.SwOK, globalplatform.SwReferencedDataNotFound)
|
||||
if err != nil {
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,32 +87,39 @@ func (i *Installer) Install(capFile *os.File) error {
|
|||
preLoad := globalplatform.NewCommandInstallForLoad(statusPkgAID, sdaid)
|
||||
resp, err = i.send("install for load", preLoad)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// load
|
||||
load, err := globalplatform.NewLoadCommandStream(capFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for load.Next() {
|
||||
cmd := load.GetCommand()
|
||||
resp, err = i.send(fmt.Sprintf("load %d", load.Index()), cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// install for install
|
||||
params := []byte{0xAA, 0xBB}
|
||||
secrets, err := NewSecrets()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
params := []byte(secrets.Puk())
|
||||
params = append(params, secrets.PairingToken()...)
|
||||
|
||||
install := globalplatform.NewCommandInstallForInstall(statusPkgAID, statusAppletAID, statusAppletAID, params)
|
||||
resp, err = i.send("install for install", install)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil
|
||||
return secrets, nil
|
||||
}
|
||||
|
||||
func (i *Installer) send(description string, cmd *apdu.Command, allowedResponses ...uint16) (*apdu.Response, error) {
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package lightwallet
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
||||
const (
|
||||
pairingTokenSalt = "Status Hardware Wallet Lite"
|
||||
maxPukNumber = int64(999999999999)
|
||||
)
|
||||
|
||||
type Secrets struct {
|
||||
puk string
|
||||
pairingPass string
|
||||
pairingToken []byte
|
||||
}
|
||||
|
||||
func NewSecrets() (*Secrets, error) {
|
||||
pairingPass, err := generatePairingPass()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
puk, err := rand.Int(rand.Reader, big.NewInt(maxPukNumber))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Secrets{
|
||||
puk: fmt.Sprintf("%012d", puk.Int64()),
|
||||
pairingPass: pairingPass,
|
||||
pairingToken: generatePairingToken(pairingPass),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Secrets) Puk() string {
|
||||
return s.puk
|
||||
}
|
||||
|
||||
func (s *Secrets) PairingPass() string {
|
||||
return s.pairingPass
|
||||
}
|
||||
|
||||
func (s *Secrets) PairingToken() []byte {
|
||||
return s.pairingToken
|
||||
}
|
||||
|
||||
func generatePairingPass() (string, error) {
|
||||
r := make([]byte, 12)
|
||||
_, err := rand.Read(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return base64.URLEncoding.EncodeToString(r), nil
|
||||
}
|
||||
|
||||
func generatePairingToken(pass string) []byte {
|
||||
return pbkdf2.Key(norm.NFKD.Bytes([]byte(pass)), norm.NFKD.Bytes([]byte(pairingTokenSalt)), 50000, 32, sha256.New)
|
||||
}
|
Loading…
Reference in New Issue