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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
package core
import (
"bufio"
"fmt"
"os"
"strings"
"aead.dev/minisign"
"github.com/axtloss/fsverify/config"
"github.com/tarm/serial"
)
var TotalReadBlocks int = 0
func fileReadKey() (string, error) {
if _, err := os.Stat(config.KeyLocation); os.IsNotExist(err) {
return "", fmt.Errorf("Key location %s does not exist", config.KeyLocation)
}
file, err := os.Open(config.KeyLocation)
if err != nil {
return "", err
}
defer file.Close()
key := make([]byte, 56)
reader := bufio.NewReader(file)
n, err := reader.Read(key)
if n != 56 {
return "", fmt.Errorf("Error: Key does not match expected key size. expected 56, got %d", n)
}
if err != nil {
return "", err
}
return string(key), nil
}
func serialReadKey() (string, error) {
if _, err := os.Stat(config.KeyLocation); !os.IsNotExist(err) {
fmt.Println("Reconnect arduino now")
for true {
if _, err := os.Stat(config.KeyLocation); os.IsNotExist(err) {
break
}
}
} else {
fmt.Println("Connect arduino now")
}
for true {
if _, err := os.Stat(config.KeyLocation); !os.IsNotExist(err) {
break
}
}
fmt.Println("Arduino connected")
c := &serial.Config{Name: config.KeyLocation, Baud: 9600}
s, err := serial.OpenPort(c)
if err != nil {
return "", err
}
key := ""
for true {
buf := make([]byte, 128)
n, err := s.Read(buf)
if err != nil {
return "", err
}
defer s.Close()
key = key + fmt.Sprintf("%q", buf[:n])
if strings.Count(key, "\\t") == 2 {
break
}
}
key = strings.ReplaceAll(key, "\\t", "")
key = strings.ReplaceAll(key, "\"", "")
if len(key) != 56 {
return "", fmt.Errorf("Error: Key does not match expected key size. expected 56, got %d", len(key))
}
return key, nil
}
func ReadKey() (string, error) {
switch config.KeyStore {
case 0:
return fileReadKey()
case 1:
return fileReadKey()
case 2:
return "", nil
case 3:
return serialReadKey()
}
return "", nil
}
func ReadBlock(node Node, part *bufio.Reader) ([]byte, error) {
block := make([]byte, node.BlockEnd-node.BlockStart)
blockSize := node.BlockEnd - node.BlockStart
_, err := part.Discard(node.BlockStart)
if err != nil {
return []byte{}, err
}
block, err = part.Peek(blockSize)
TotalReadBlocks = TotalReadBlocks + blockSize
return block, err
}
func VerifySignature(key string, signature string, database string) (bool, error) {
var pk minisign.PublicKey
if err := pk.UnmarshalText([]byte(key)); err != nil {
return false, err
}
data, err := os.ReadFile(database)
if err != nil {
return false, err
}
return minisign.Verify(pk, data, []byte(signature)), nil
}
func VerifyBlock(block []byte, node Node) error {
calculatedBlockHash, err := CalculateBlockHash(block)
if err != nil {
return err
}
wantedBlockHash := node.BlockSum
if strings.Compare(calculatedBlockHash, strings.TrimSpace(wantedBlockHash)) == 0 {
return nil
}
return fmt.Errorf("Error: Node %s ranging from %d to %d does not match block", node.PrevNodeSum, node.BlockStart, node.BlockEnd)
}
func VerifyNode(node Node, nextNode Node) error {
nodeHash, err := calculateStringHash(fmt.Sprintf("%d%d%s%s", node.BlockStart, node.BlockEnd, node.BlockSum, node.PrevNodeSum))
if err != nil {
return err
}
if strings.Compare(nodeHash, nextNode.PrevNodeSum) != 0 {
return fmt.Errorf("Node %s is not valid!", node.PrevNodeSum)
}
return nil
}
|