Skip to content

Commit

Permalink
allow for no encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
rusq committed Jan 24, 2023
1 parent f1cf03b commit 3ee2ad5
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 28 deletions.
9 changes: 2 additions & 7 deletions cmd/msgtime/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package main
import (
"fmt"
"os"
"strconv"
"time"

"github.com/rusq/osx-callhistory-decryptor/historydecryptor"
Expand All @@ -31,10 +30,6 @@ func main() {
fmt.Printf("%s\n", date)
}

func convert(floatOffset string) (time.Time, error) {
t, err := strconv.ParseFloat(floatOffset, 64)
if err != nil {
return time.Time{}, err
}
return historydecryptor.CalcCallTime(t), nil
func convert(offset string) (time.Time, error) {
return historydecryptor.CalcCallTime(offset), nil
}
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module github.com/rusq/osx-callhistory-decryptor
go 1.13

require (
github.com/keybase/go-keychain v0.0.0-20201121013009-976c83ec27a6
github.com/mattn/go-sqlite3 v1.11.0
github.com/keybase/go-keychain v0.0.0-20221221221913-9be78f6c498b
github.com/keybase/go.dbus v0.0.0-20200324223359-a94be52c0b03 // indirect
github.com/mattn/go-sqlite3 v1.14.16
gopkg.in/yaml.v2 v2.2.2 // indirect
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/keybase/dbus v0.0.0-20220506165403-5aa21ea2c23a/go.mod h1:YPNKjjE7Ubp9dTbnWvsP3HT+hYnY6TfXzubYTBeUxc8=
github.com/keybase/go-keychain v0.0.0-20201121013009-976c83ec27a6 h1:Mj0fhP9dzHKPijsmli/XbXMDKe1/KWy5xKci8e3nmBg=
github.com/keybase/go-keychain v0.0.0-20201121013009-976c83ec27a6/go.mod h1:N83iQ9rnnzi2KZuTu+0xBcD1JNWn1jSN140ggAF7HeE=
github.com/keybase/go-keychain v0.0.0-20221221221913-9be78f6c498b h1:k2ZvAPXrDB1Q7fGRdUane+T08K+UaL96qH47Setr/7k=
github.com/keybase/go-keychain v0.0.0-20221221221913-9be78f6c498b/go.mod h1:TXh6wFVZNh4iuqbymzy4r3obmj8hTPDlLNnoKNIbvJE=
github.com/keybase/go.dbus v0.0.0-20200324223359-a94be52c0b03/go.mod h1:a8clEhrrGV/d76/f9r2I41BwANMihfZYV9C223vaxqE=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
Expand All @@ -16,3 +25,5 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
3 changes: 2 additions & 1 deletion historydecryptor/getkey.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !darwin
// +build !darwin

package historydecryptor
Expand All @@ -8,7 +9,7 @@ import (

func GetByteKey(keyStr string) ([]byte, error) {
if len(keyStr) == 0 {
return nil, fmt.Errorf("Use -k <key> parameter to supply the key.")
return nil, ErrNoKey
}
key, err := DecodeB64Key([]byte(keyStr))
if err != nil {
Expand Down
28 changes: 21 additions & 7 deletions historydecryptor/historydecryptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"crypto/rand"
"database/sql"
"encoding/csv"
"errors"
"io"
"log"
"strconv"
Expand Down Expand Up @@ -99,16 +100,25 @@ func DecipherHistory(database string, key []byte, output io.Writer, opts ...Opti
blob = make([]byte, 255)
)

err = rows.Scan(&unparsedCallOffset, &answered, &originated, &calltype, &country, &blob)
if err != nil {
if err = rows.Scan(&unparsedCallOffset, &answered, &originated, &calltype, &country, &blob); err != nil {
return 0, err
}
callTime := CalcCallTime(unparsedCallOffset)

address, err := Decipher(blob, key)
if err != nil {
return 0, err
var address []byte
if isEncrypted(blob) {
if len(key) == 0 {
return 0, errors.New("your database is encrypted, but you didn't provide a key")
}
address, err = Decipher(blob, key)
if err != nil {
return 0, err
}
} else {
// this indicates that the row might not be encrypted at all.
address = blob
}

csvOut.Write([]string{callTime.Format(s.timeFmt),
answered, originated, calltype, country.String, string(address)})

Expand All @@ -121,7 +131,11 @@ func DecipherHistory(database string, key []byte, output io.Writer, opts ...Opti
return numRecords, nil
}

//Decipher deciphers ZADDRESS from OS X call history.
func isEncrypted(blob []byte) bool {
return len(blob) >= TagSz+NonceSz
}

// Decipher deciphers ZADDRESS from OS X call history.
func Decipher(data, key []byte) ([]byte, error) {
if len(data) == 0 {
return nil, nil
Expand Down Expand Up @@ -152,7 +166,7 @@ func Decipher(data, key []byte) ([]byte, error) {
return pt, nil
}

//Cipher text conforming to ZADDRESS encryption pattern
// Cipher text conforming to ZADDRESS encryption pattern
func Cipher(text, key []byte) ([]byte, error) {
if len(text) == 0 {
return nil, nil
Expand Down
8 changes: 4 additions & 4 deletions historydecryptor/historydecryptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,16 @@ func TestDecipherHistory(t *testing.T) {

func Test_calcCallTime(t *testing.T) {
type args struct {
callOffset float64
callOffset string
}
tests := []struct {
name string
args args
want time.Time
}{
{"zero offset", args{0.0}, time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC)},
{"negative offset", args{-10.0}, time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC)},
{"positive offset", args{1000.0}, time.Date(2001, time.January, 1, 0, 16, 40, 0, time.UTC)},
{"zero offset", args{"0.0"}, time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC)},
{"negative offset", args{"-10.0"}, time.Date(2000, time.December, 31, 23, 59, 50, 0, time.UTC)},
{"positive offset", args{"1000.0"}, time.Date(2001, time.January, 1, 0, 16, 40, 0, time.UTC)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
6 changes: 4 additions & 2 deletions historydecryptor/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package historydecryptor

import (
"encoding/base64"
"fmt"
"errors"
)

var ErrNoKey = errors.New("key is not supplied")

// DecodeB64Key decodes the provided key from base64 encoding
func DecodeB64Key(key []byte) ([]byte, error) {
if len(key) == 0 {
return nil, fmt.Errorf("key is not supplied")
return nil, ErrNoKey
}
ret := make([]byte, base64.StdEncoding.DecodedLen(len(key)))
l, err := base64.StdEncoding.Decode(ret, key)
Expand Down
16 changes: 11 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var defFile = filepath.Join(os.Getenv("HOME"), "Library", "Application Support",

var (
strKey = flag.String("k", os.Getenv("KEY"), "Base64 key value from OS X keychain, on macOS may be omitted.")
omitDecryption = flag.Bool("no-key", false, "omit decryption")
outputFilename = flag.String("o", "", "output csv filename. If not specified, result is output to stdout")
versionOnly = flag.Bool("v", false, "print version and quit")
timeFormat = flag.String("time-format", historydecryptor.DefTimeFmt, "CSV output time `format`")
Expand Down Expand Up @@ -74,12 +75,12 @@ func main() {
src = defFile
}

if err := run(src, *outputFilename, *strKey); err != nil {
if err := run(src, *outputFilename, *strKey, *omitDecryption); err != nil {
log.Fatal(err)
}
}

func run(src, dst string, strKey string) error {
func run(src, dst string, strKey string, omitDecryption bool) error {
log.Printf("*** database filename: %q", src)
dbfile, err := copytemp(src)
if err != nil {
Expand All @@ -88,9 +89,14 @@ func run(src, dst string, strKey string) error {
defer os.Remove(dbfile)
log.Printf("*** temporary file (will be removed): %q", dbfile)

key, err := historydecryptor.GetByteKey(strKey)
if err != nil {
return fmt.Errorf("%w: make sure you have supplied the key via -k or KEY env variable", err)
var key []byte
if omitDecryption {
key = []byte{}
} else {
key, err = historydecryptor.GetByteKey(strKey)
if err != nil {
return fmt.Errorf("%w: make sure you have supplied the key via -k <key> or KEY env variable", err)
}
}

var output = os.Stdout
Expand Down

0 comments on commit 3ee2ad5

Please sign in to comment.