aboutsummaryrefslogtreecommitdiff
path: root/gocryptfs-xray/xray_main.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2016-09-25 11:11:20 +0200
committerJakob Unterwurzacher2016-09-25 16:43:17 +0200
commit3a9bd92754e3b6984c97f7012fd5f030d7f8e46c (patch)
treef77c048366fd5f9192d2c74082463e9ff40cfc0c /gocryptfs-xray/xray_main.go
parent6c52c1a6e6176ba7b6922ee27df7ddd09991b57e (diff)
xray: add "gocryptfs-xray", on-disk-format exploration tool
Example output for a file encrypted in reverse mode: Header: Version: 2, Id: 0b7f5e2574e4afa859a9bb156a2e7772 Block 0: IV: 0b7f5e2574e4afa859a9bb156a2e7773, Tag: bf39279ac6b1ccd852567aaf26ee386b, Len: 4128 Block 1: IV: 0b7f5e2574e4afa859a9bb156a2e7774, Tag: a4f0f9cde7f70a752254aa8fe7718699, Len: 4128 Block 2: IV: 0b7f5e2574e4afa859a9bb156a2e7775, Tag: b467b153016fc1d531818b65ab9e24f6, Len: 4128 Block 3: IV: 0b7f5e2574e4afa859a9bb156a2e7776, Tag: 1fcb7ffd8f1816fbe807df8148718a5c, Len: 4128 Block 4: IV: 0b7f5e2574e4afa859a9bb156a2e7777, Tag: a217e7933ef434c9f03ad931bb5fde9b, Len: 4128 Block 5: IV: 0b7f5e2574e4afa859a9bb156a2e7778, Tag: f3e6240d75cd66371a0b301111d6f1fc, Len: 4128 Block 6: IV: 0b7f5e2574e4afa859a9bb156a2e7779, Tag: bc85d322ebc7761ae5ef114ea3903a56, Len: 4128 Block 7: IV: 0b7f5e2574e4afa859a9bb156a2e777a, Tag: efda01c6b794690f939a12d6d49ac3af, Len: 4128 Block 8: IV: 0b7f5e2574e4afa859a9bb156a2e777b, Tag: b198329d489d1392080f710206932ff0, Len: 2907
Diffstat (limited to 'gocryptfs-xray/xray_main.go')
-rw-r--r--gocryptfs-xray/xray_main.go85
1 files changed, 85 insertions, 0 deletions
diff --git a/gocryptfs-xray/xray_main.go b/gocryptfs-xray/xray_main.go
new file mode 100644
index 0000000..81e4c10
--- /dev/null
+++ b/gocryptfs-xray/xray_main.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "encoding/hex"
+ "flag"
+ "fmt"
+ "io"
+ "os"
+
+ "github.com/rfjakob/gocryptfs/internal/contentenc"
+ "github.com/rfjakob/gocryptfs/internal/cryptocore"
+)
+
+const (
+ IVLen = contentenc.IVBitLen / 8
+ blockSize = contentenc.DefaultBS + IVLen + cryptocore.AuthTagLen
+)
+
+func errExit(err error) {
+ fmt.Println(err)
+ os.Exit(1)
+}
+
+func prettyPrintHeader(h *contentenc.FileHeader) {
+ id := hex.EncodeToString(h.Id)
+ fmt.Printf("Header: Version: %d, Id: %s\n", h.Version, id)
+}
+
+func main() {
+ flag.Parse()
+ if flag.NArg() != 1 {
+ fmt.Printf("Usage: xray FILE\n")
+ os.Exit(1)
+ }
+ f := flag.Arg(0)
+ fd, err := os.Open(f)
+ if err != nil {
+ errExit(err)
+ }
+
+ headerBytes := make([]byte, contentenc.HEADER_LEN)
+ n, err := fd.ReadAt(headerBytes, 0)
+ if err == io.EOF && n == 0 {
+ fmt.Println("empty file")
+ os.Exit(0)
+ } else if err == io.EOF {
+ fmt.Printf("incomplete file header: read %d bytes, want %d\n", n, contentenc.HEADER_LEN)
+ os.Exit(1)
+ } else if err != nil {
+ errExit(err)
+ }
+ header, err := contentenc.ParseHeader(headerBytes)
+ if err != nil {
+ errExit(err)
+ }
+ prettyPrintHeader(header)
+ var i int64
+ for i = 0; ; i++ {
+ blockLen := int64(blockSize)
+ off := contentenc.HEADER_LEN + i*blockSize
+ iv := make([]byte, IVLen)
+ _, err := fd.ReadAt(iv, off)
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ errExit(err)
+ }
+ tag := make([]byte, cryptocore.AuthTagLen)
+ _, err = fd.ReadAt(tag, off+blockSize-cryptocore.AuthTagLen)
+ if err == io.EOF {
+ fi, err2 := fd.Stat()
+ if err2 != nil {
+ errExit(err2)
+ }
+ _, err2 = fd.ReadAt(tag, fi.Size()-cryptocore.AuthTagLen)
+ if err2 != nil {
+ errExit(err2)
+ }
+ blockLen = (fi.Size() - contentenc.HEADER_LEN) % blockSize
+ } else if err != nil {
+ errExit(err)
+ }
+ fmt.Printf("Block %2d: IV: %s, Tag: %s, Len: %d\n", i, hex.EncodeToString(iv), hex.EncodeToString(tag), blockLen)
+ }
+}