aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/verify.go30
-rw-r--r--core/crypt.go10
-rw-r--r--core/storage.go35
-rw-r--r--fsverify-paper.md9
-rw-r--r--part.fsverifybin33081 -> 32967 bytes
5 files changed, 47 insertions, 37 deletions
diff --git a/cmd/verify.go b/cmd/verify.go
index 9c7947c..dc7a700 100644
--- a/cmd/verify.go
+++ b/cmd/verify.go
@@ -1,9 +1,11 @@
package cmd
import (
+ "bufio"
"fmt"
"github.com/axtloss/fsverify/core"
"github.com/spf13/cobra"
+ "os"
)
func NewVerifyCommand() *cobra.Command {
@@ -19,20 +21,21 @@ func NewVerifyCommand() *cobra.Command {
func ValidateCommand(_ *cobra.Command, args []string) error {
- header, err := core.ReadHeader("./part.fsverify")
- fmt.Println(header.MagicNumber)
- fmt.Println(header.Signature)
- fmt.Println(header.FilesystemSize)
- fmt.Println(header.TableSize)
+ header, err := core.ReadHeader("/dev/sda")
+ fmt.Printf("Magic Number: %d\n", header.MagicNumber)
+ fmt.Printf("Signature: %s\n" + header.Signature)
+ fmt.Printf("FsSize: %d\n", header.FilesystemSize)
+ fmt.Printf("Table Size: %d\n", header.TableSize)
+ fmt.Printf("Table Size Unit: %d\n", header.TableUnit)
if err != nil {
return err
}
- dbfile, err := core.ReadDB("./part.fsverify")
+ dbfile, err := core.ReadDB("/dev/sda")
if err != nil {
return err
}
fmt.Println("DBFILE: ", dbfile)
- db, err := core.OpenDB(dbfile)
+ db, err := core.OpenDB(dbfile, true)
if err != nil {
return err
}
@@ -42,5 +45,16 @@ func ValidateCommand(_ *cobra.Command, args []string) error {
return err
}
fmt.Println(getnode)
- return nil
+
+ fmt.Println("----")
+
+ disk, err := os.Open("./partition.raw")
+ reader := bufio.NewReader(disk)
+ part, err := core.ReadBlock(getnode, reader)
+ if err != nil {
+ return err
+ }
+ hash, err := core.CalculateBlockHash(part)
+ fmt.Println(hash)
+ return err
}
diff --git a/core/crypt.go b/core/crypt.go
index 6de70e6..f741b8e 100644
--- a/core/crypt.go
+++ b/core/crypt.go
@@ -1,25 +1,25 @@
package core
import (
+ "bytes"
"crypto/sha256"
"fmt"
"io"
- "os"
"strings"
)
func calculateStringHash(a string) (string, error) {
hash := sha256.New()
hash.Write([]byte(a))
- hashInBytes := hash.Sum(nil)[:20]
+ hashInBytes := hash.Sum(nil)[:32]
return strings.TrimSpace(fmt.Sprintf("%x", hashInBytes)), nil
}
-func calculateFileHash(file *os.File) (string, error) {
+func CalculateBlockHash(block []byte) (string, error) {
hash := sha256.New()
- if _, err := io.Copy(hash, file); err != nil {
+ if _, err := io.Copy(hash, bytes.NewReader(block)); err != nil {
return "", err
}
- hashInBytes := hash.Sum(nil)[:20]
+ hashInBytes := hash.Sum(nil)[:32]
return strings.TrimSpace(fmt.Sprintf("%x", hashInBytes)), nil
}
diff --git a/core/storage.go b/core/storage.go
index b3e1b53..363db0f 100644
--- a/core/storage.go
+++ b/core/storage.go
@@ -7,7 +7,6 @@ import (
"fmt"
"io"
"os"
- "strings"
bolt "go.etcd.io/bbolt"
)
@@ -41,7 +40,8 @@ func ReadHeader(partition string) (Header, error) {
header := Header{}
reader := bufio.NewReader(part)
MagicNumber := make([]byte, 2)
- Signature := make([]byte, 302)
+ UntrustedHash := make([]byte, 100)
+ TrustedHash := make([]byte, 88)
FileSystemSize := make([]byte, 4)
TableSize := make([]byte, 4)
TableUnit := make([]byte, 1)
@@ -53,7 +53,11 @@ func ReadHeader(partition string) (Header, error) {
}
header.MagicNumber = int(MagicNum)
- _, err = reader.Read(Signature)
+ _, err = reader.Read(UntrustedHash)
+ if err != nil {
+ return Header{}, err
+ }
+ _, err = reader.Read(TrustedHash)
if err != nil {
return Header{}, err
}
@@ -70,7 +74,7 @@ func ReadHeader(partition string) (Header, error) {
return Header{}, err
}
- header.Signature = string(Signature)
+ 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.FilesystemSize = int(binary.BigEndian.Uint16(FileSystemSize))
header.TableSize = int(binary.BigEndian.Uint32(TableSize))
switch TableUnit[0] {
@@ -104,7 +108,7 @@ func ReadDB(partition string) (string, error) {
defer part.Close()
reader := bufio.NewReader(part)
- _, err = reader.Read(make([]byte, 313))
+ _, err = reader.Read(make([]byte, 199))
if err != nil {
fmt.Println(err)
return "", err
@@ -135,12 +139,12 @@ func ReadDB(partition string) (string, error) {
return temp + "/verify.db", nil
}
-func OpenDB(dbpath string) (*bolt.DB, error) {
+func OpenDB(dbpath string, readonly bool) (*bolt.DB, error) {
_, exist := os.Stat(dbpath)
if os.IsNotExist(exist) {
os.Create(dbpath)
}
- db, err := bolt.Open(dbpath, 0777, nil)
+ db, err := bolt.Open(dbpath, 0777, &bolt.Options{ReadOnly: readonly})
if err != nil {
return nil, err
}
@@ -151,11 +155,13 @@ func AddNode(node Node, db *bolt.DB) error {
var err error
var deferDB bool
if db == nil {
- db, err = OpenDB("my.db")
+ db, err = OpenDB("my.db", false)
if err != nil {
return err
}
deferDB = true
+ } else if db.IsReadOnly() {
+ return fmt.Errorf("Error: database is opened read only, unable to add nodes")
}
err = db.Update(func(tx *bolt.Tx) error {
nodes, err := tx.CreateBucketIfNotExists([]byte("Nodes"))
@@ -180,7 +186,7 @@ func GetNode(checksum string, db *bolt.DB) (Node, error) {
var err error
var deferDB bool
if db == nil {
- db, err = OpenDB("my.db")
+ db, err = OpenDB("my.db", true)
if err != nil {
return Node{}, err
}
@@ -198,14 +204,3 @@ func GetNode(checksum string, db *bolt.DB) (Node, error) {
}
return node, err
}
-
-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
-}
diff --git a/fsverify-paper.md b/fsverify-paper.md
index 82b9cf8..819c422 100644
--- a/fsverify-paper.md
+++ b/fsverify-paper.md
@@ -2,19 +2,20 @@
The FsVerify partition contains a header with the necessary metadata for the filesystem verification, and a bbolt database containing all File and Directory nodes to be checked.
## Partition Header
-`<magic number> <signature> <filesystem size> <table size> <table unit>`
+`<magic number> <untrusted signature hash> <trusted signature hash> <filesystem size> <table size> <table unit>`
Field|Size|Purpose|Value
-----|----|-------|-----
magic number|2 bytes|sanity check|0xACAB
-signature|302 bytes|minisign signature|
+untrusted signature hash|100 bytes|untrusted signature from minisign
+trusted signature hash|88 bytes|trusted signature from minisign
filesystem size|4 bytes|size of the original filesystem in gb
-table size|4 bytes| size of the table in \<table unit\>
+table size|4 bytes| size of the table in <table unit\>
table unit|1 byte|unit of the table size|0x0: bytes, 0x1: kilobytes, 0x2: megabytes, 0x3: gigabytes, 0x4: terabytes, 0x5: petabytes
Due to the filesystem and table size field, which can go up to 0xFFFFFFFF (16777215), the maximum supported partition size and table size is 16777215gb (~16pb)
-The entire Head should be a total of 312 bytes long, reaching from 0x0 to 0x138
+The entire Head should be a total of 199 bytes long, reaching from 0x0 to 0xC7
## Partition Contents / Database
The main database containing the checksums is a [bbolt](https://github.com/etcd-io/bbolt) datbase consisting of a single bucket called `Nodes`
diff --git a/part.fsverify b/part.fsverify
index 1890f21..bd59960 100644
--- a/part.fsverify
+++ b/part.fsverify
Binary files differ