-
Notifications
You must be signed in to change notification settings - Fork 0
/
check.go
104 lines (69 loc) · 2.23 KB
/
check.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package tapcards
import (
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"log"
"log/slog"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
)
func (satscard *Satscard) checkRequest() ([]byte, error) {
nonce, err := satscard.createNonce()
if err != nil {
return nil, err
}
checkCommand := checkCommand{
command: command{Cmd: "check"},
Nonce: nonce,
}
return apduWrap(checkCommand)
}
func (satscard *Satscard) parseCheckData(checkData checkData) error {
slog.Debug("Parse check")
slog.Debug("CHECK", "AuthSignature", fmt.Sprintf("%x", checkData.AuthSignature[:]))
slog.Debug("CHECK", "CardNonce", fmt.Sprintf("%x", checkData.CardNonce[:]))
message := append([]byte(openDime), satscard.currentCardNonce[:]...)
message = append(message, satscard.appNonce[:]...)
if satscard.activeSlotPublicKey != [33]byte{} {
slog.Debug("Adding current slot public key")
message = append(message, satscard.activeSlotPublicKey[:]...)
}
messageDigest := sha256.Sum256([]byte(message))
r := new(btcec.ModNScalar)
r.SetByteSlice(checkData.AuthSignature[0:32])
s := new(btcec.ModNScalar)
s.SetByteSlice(checkData.AuthSignature[32:64])
signature := ecdsa.NewSignature(r, s)
publicKey, err := btcec.ParsePubKey(satscard.cardPublicKey[:])
if err != nil {
return err
}
verified := signature.Verify(messageDigest[:], publicKey)
if !verified {
return errors.New("invalid signature certs")
}
for i := 0; i < len(satscard.certificateChain); i++ {
publicKey, err = signatureToPublicKey(satscard.certificateChain[i], publicKey)
if err != nil {
return err
}
}
// Convert hex string to bytes
factoryRootPublicKeyBytes, err := hex.DecodeString(factoryRootPublicKeyString)
if err != nil {
log.Fatal(err)
}
factoryRootPublicKey, err := btcec.ParsePubKey(factoryRootPublicKeyBytes)
if err != nil {
return err
}
if !factoryRootPublicKey.IsEqual(publicKey) {
slog.Debug("CHECK", "FactoryRootPublicKey", fmt.Sprintf("%x", factoryRootPublicKey.SerializeCompressed()))
slog.Debug("CHECK", "PublicKey", fmt.Sprintf("%x", publicKey.SerializeCompressed()))
return errors.New("counterfeit card: invalid factory root public key")
}
satscard.currentCardNonce = checkData.CardNonce
return nil
}