aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/verify.go15
-rw-r--r--config/config.go8
-rw-r--r--core/storage.go8
-rw-r--r--core/verification.go108
-rw-r--r--go.mod5
-rw-r--r--go.sum8
-rw-r--r--part.fsverifybin32968 -> 32200 bytes
-rw-r--r--verifysetup/cmd/root.go22
-rw-r--r--verifysetup/cmd/setup.go20
-rw-r--r--verifysetup/go.mod3
10 files changed, 194 insertions, 3 deletions
diff --git a/cmd/verify.go b/cmd/verify.go
index 2f18d34..2afb354 100644
--- a/cmd/verify.go
+++ b/cmd/verify.go
@@ -79,5 +79,20 @@ func ValidateCommand(_ *cobra.Command, args []string) error {
return err
}
fmt.Printf("Block '%s' ranging from %d to %d matches!\n", getnode.PrevNodeSum, getnode.BlockStart, getnode.BlockEnd)
+
+ fmt.Println("----")
+
+ key, err := core.ReadKey()
+ if err != nil {
+ return err
+ }
+ fmt.Println("Key: " + key)
+
+ err = core.VerifySignature(key, header.Signature, dbfile)
+ if err != nil {
+ return err
+ } else {
+ fmt.Println("Signtaure success")
+ }
return nil
}
diff --git a/config/config.go b/config/config.go
new file mode 100644
index 0000000..ac732af
--- /dev/null
+++ b/config/config.go
@@ -0,0 +1,8 @@
+package config
+
+// How the public key is stored
+// 0: external file, 1: external storage device, 2: tpm2, 3: usb serial
+var KeyStore = 0
+
+// Where the public key is stored, only applies for 0, 1 and 3
+var KeyLocation = "./publickey"
diff --git a/core/storage.go b/core/storage.go
index f6f1ffd..8346c12 100644
--- a/core/storage.go
+++ b/core/storage.go
@@ -99,7 +99,7 @@ func ReadHeader(partition string) (Header, error) {
return Header{}, err
}
- header.Signature = fmt.Sprintf("untrusted comment: signature from minisign secret key\r\n%s\r\ntrusted comment: timestamp:0\tfile:fsverify\thashed\r\n%s\r\n", UntrustedHash, TrustedHash)
+ header.Signature = fmt.Sprintf("untrusted comment: fsverify\r\n%s\r\ntrusted comment: fsverify\r\n%s\r\n", UntrustedHash, TrustedHash)
header.FilesystemSize = int(binary.BigEndian.Uint16(FilesystemSize))
header.TableSize = int(binary.BigEndian.Uint32(TableSize))
header.FilesystemUnit = parseUnitSpec(FilesystemUnit)
@@ -135,10 +135,14 @@ func ReadDB(partition string) (string, error) {
}
db := make([]byte, header.TableSize*header.TableUnit)
- _, err = io.ReadFull(reader, db)
+ n, err := io.ReadFull(reader, db)
if err != nil {
return "", err
}
+ if n != header.TableSize*header.TableUnit {
+ return "", fmt.Errorf("Error: Database is not expected size. Got: %d, expected %d", n, header.TableSize*header.TableUnit)
+ }
+ fmt.Printf("db: %d\n", n)
temp, err := os.MkdirTemp("", "*-fsverify")
if err != nil {
diff --git a/core/verification.go b/core/verification.go
index 5023d06..b48c0b7 100644
--- a/core/verification.go
+++ b/core/verification.go
@@ -3,9 +3,93 @@ package core
import (
"bufio"
"fmt"
+ "os"
"strings"
+
+ "github.com/axtloss/fsverify/config"
+ "github.com/jedisct1/go-minisign"
+ "github.com/tarm/serial"
)
+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
@@ -17,6 +101,30 @@ func ReadBlock(node Node, part *bufio.Reader) ([]byte, error) {
return block, err
}
+func VerifySignature(key string, signature string, database string) error {
+ pk, err := minisign.NewPublicKey(key)
+ if err != nil {
+ return err
+ }
+
+ sig, err := minisign.DecodeSignature(signature)
+ if err != nil {
+ return err
+ }
+
+ data, err := os.ReadFile(database)
+ if err != nil {
+ return err
+ }
+
+ verified, err := pk.Verify(data, sig)
+ if err != nil || !verified {
+ return err
+ }
+
+ return nil
+}
+
func VerifyBlock(block []byte, node Node) error {
calculatedBlockHash, err := CalculateBlockHash(block)
if err != nil {
diff --git a/go.mod b/go.mod
index bd0023e..539470b 100644
--- a/go.mod
+++ b/go.mod
@@ -4,8 +4,11 @@ go 1.21.6
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
+ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 // indirect
go.etcd.io/bbolt v1.3.8 // indirect
- golang.org/x/sys v0.4.0 // indirect
+ golang.org/x/crypto v0.12.0 // indirect
+ golang.org/x/sys v0.11.0 // indirect
)
diff --git a/go.sum b/go.sum
index 6ccfb83..f6679e4 100644
--- a/go.sum
+++ b/go.sum
@@ -1,14 +1,22 @@
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY=
+github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU=
+github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
+golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/part.fsverify b/part.fsverify
index cca63e4..202acd1 100644
--- a/part.fsverify
+++ b/part.fsverify
Binary files differ
diff --git a/verifysetup/cmd/root.go b/verifysetup/cmd/root.go
new file mode 100644
index 0000000..edcb250
--- /dev/null
+++ b/verifysetup/cmd/root.go
@@ -0,0 +1,22 @@
+package cmd
+
+import (
+ "github.com/spf13/cobra"
+ "os"
+)
+
+var rootCmd = &cobra.Command{
+ Use: "verifysetup",
+}
+
+func init() {
+ rootCmd.AddCommand(NewSetupCommand())
+}
+
+func Execute() {
+ // cobra does not exit with a non-zero return code when failing
+ // solution from https://github.com/spf13/cobra/issues/221
+ if err := rootCmd.Execute(); err != nil {
+ os.Exit(1)
+ }
+}
diff --git a/verifysetup/cmd/setup.go b/verifysetup/cmd/setup.go
new file mode 100644
index 0000000..3897903
--- /dev/null
+++ b/verifysetup/cmd/setup.go
@@ -0,0 +1,20 @@
+package cmd
+
+import (
+ "github.com/spf13/cobra"
+)
+
+func NewVerifyCommand() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "setup",
+ Short: "Set up fsverify",
+ RunE: SetupCommand,
+ SilenceUsage: true,
+ }
+
+ return cmd
+}
+
+func SetupCommand(_ *cobra.Command, args []string) error {
+ return nil
+}
diff --git a/verifysetup/go.mod b/verifysetup/go.mod
new file mode 100644
index 0000000..25642c6
--- /dev/null
+++ b/verifysetup/go.mod
@@ -0,0 +1,3 @@
+module github.com/axtloss/fsverify/verifysetup
+
+go 1.21.6