2020-03-20 21:14:00 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"crypto/rand"
|
|
|
|
"encoding/base64"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"git.openprivacy.ca/openprivacy/log"
|
|
|
|
"github.com/therecipe/qt/core"
|
|
|
|
"github.com/therecipe/qt/qml"
|
|
|
|
"golang.org/x/crypto/curve25519"
|
|
|
|
"golang.org/x/crypto/nacl/box"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2020-03-21 00:00:04 +00:00
|
|
|
path "path/filepath"
|
2020-03-21 19:29:18 +00:00
|
|
|
"sort"
|
2020-03-20 21:14:00 +00:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type LockBoxAPI struct {
|
|
|
|
core.QObject
|
|
|
|
|
|
|
|
QMLEngine *qml.QQmlApplicationEngine
|
|
|
|
Translator *core.QTranslator
|
|
|
|
|
|
|
|
_ func(bool, string) `signal:"Decrypted"`
|
|
|
|
_ func(bool, string) `signal:"Saved"`
|
|
|
|
|
|
|
|
_ func(inputFilename string, outputFilename string, keyfile string) `signal:"decryptFile,auto"`
|
|
|
|
_ func(keyFilename string) `signal:"generateKey,auto"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (lapi *LockBoxAPI) decryptFile(inputFilename string, outputFilename string, keyfile string) {
|
|
|
|
log.Infof("Decrypting File...%v to %v", inputFilename, outputFilename)
|
|
|
|
privateKey := [32]byte{}
|
|
|
|
publicKey := [32]byte{}
|
|
|
|
keyencoded, err := ioutil.ReadFile(cleanPath(keyfile))
|
|
|
|
if err == nil {
|
|
|
|
key, err := base64.StdEncoding.DecodeString(string(keyencoded))
|
|
|
|
if err == nil {
|
|
|
|
copy(privateKey[:], key[:])
|
|
|
|
curve25519.ScalarBaseMult(&publicKey, &privateKey)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
file, err := os.Open(cleanPath(inputFilename))
|
|
|
|
outputfile := []string{}
|
2020-03-24 21:10:01 +00:00
|
|
|
count := 1
|
2020-03-20 21:14:00 +00:00
|
|
|
if err == nil {
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
|
|
schemeDefined := false
|
|
|
|
schema := []string{}
|
|
|
|
for scanner.Scan() {
|
|
|
|
line := scanner.Text()
|
|
|
|
lines := strings.Split(line, "|")
|
|
|
|
if len(lines) == 2 {
|
|
|
|
data, err := base64.StdEncoding.DecodeString(lines[1])
|
|
|
|
if err == nil {
|
|
|
|
message, ok := box.OpenAnonymous([]byte{}, data, &publicKey, &privateKey)
|
|
|
|
if ok {
|
|
|
|
log.Infof("Message: %v, %v\n", string(message), ok)
|
|
|
|
data := make(map[string]string)
|
|
|
|
err := json.Unmarshal(message, &data)
|
|
|
|
if err == nil {
|
2020-03-24 21:10:01 +00:00
|
|
|
outputLine := "num,"
|
2020-03-20 21:14:00 +00:00
|
|
|
if schemeDefined == false {
|
|
|
|
for k := range data {
|
|
|
|
schema = append(schema, k)
|
|
|
|
}
|
2020-03-21 19:29:18 +00:00
|
|
|
|
|
|
|
sort.Strings(schema)
|
|
|
|
|
|
|
|
for _, k := range schema {
|
2020-03-21 21:09:09 +00:00
|
|
|
parts := strings.SplitN(k, "_", 2)
|
|
|
|
var str string
|
|
|
|
if len(parts) > 1 {
|
|
|
|
str = parts[1]
|
|
|
|
} else {
|
|
|
|
str = k
|
|
|
|
}
|
|
|
|
outputLine += fmt.Sprintf(`"%v",`, strings.ReplaceAll(str, "\"", "\\\""))
|
2020-03-21 19:29:18 +00:00
|
|
|
}
|
|
|
|
|
2020-03-20 21:14:00 +00:00
|
|
|
outputfile = append(outputfile, outputLine)
|
|
|
|
schemeDefined = true
|
|
|
|
}
|
2020-03-24 21:10:01 +00:00
|
|
|
outputLine = fmt.Sprintf("%d,", count)
|
2020-03-20 21:14:00 +00:00
|
|
|
for _, k := range schema {
|
|
|
|
outputLine += fmt.Sprintf(`"%v",`, strings.ReplaceAll(data[k], "\"", "\\\""))
|
|
|
|
}
|
|
|
|
outputfile = append(outputfile, outputLine)
|
2020-03-24 21:10:01 +00:00
|
|
|
count++
|
2020-03-20 21:14:00 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
lapi.Decrypted(false, "Error Decrypting File: You might be using the wrong decryption key with this file")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
|
|
}
|
|
|
|
err := ioutil.WriteFile(cleanPath(outputFilename), []byte(strings.Join(outputfile, "\n")), 0644)
|
|
|
|
if err == nil {
|
|
|
|
lapi.Decrypted(true, "File Decrypted Successfully!")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lapi.Decrypted(false, err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (lapi *LockBoxAPI) generateKey(keyPath string) {
|
|
|
|
log.Infof("Saving Key to Path to %v", keyPath)
|
2020-03-24 21:10:01 +00:00
|
|
|
|
|
|
|
_,err := os.Stat(cleanPath(path.Join(cleanPath(keyPath), "key.private")))
|
2020-03-20 21:14:00 +00:00
|
|
|
if err == nil {
|
2020-03-24 21:10:01 +00:00
|
|
|
lapi.Saved(false, "Cannot generate keys without deleting keys that already exist. Please choose a different directory or remove the existing keys.")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
public, private, err := box.GenerateKey(rand.Reader)
|
2020-03-20 21:14:00 +00:00
|
|
|
if err == nil {
|
2020-03-24 21:10:01 +00:00
|
|
|
publicStr := base64.StdEncoding.EncodeToString(public[:])
|
|
|
|
privateStr := base64.StdEncoding.EncodeToString(private[:])
|
|
|
|
err = ioutil.WriteFile(cleanPath(path.Join(cleanPath(keyPath), "key.public")), []byte(publicStr), 0644)
|
2020-03-20 21:14:00 +00:00
|
|
|
if err == nil {
|
2020-03-24 21:10:01 +00:00
|
|
|
err = ioutil.WriteFile(cleanPath(path.Join(cleanPath(keyPath), "key.private")), []byte(privateStr), 0644)
|
|
|
|
if err == nil {
|
|
|
|
lapi.Saved(true, "Key File Saved")
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
lapi.Saved(false, err.Error())
|
|
|
|
return
|
|
|
|
}
|
2020-03-20 21:14:00 +00:00
|
|
|
} else {
|
|
|
|
lapi.Saved(false, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lapi.Saved(false, err.Error())
|
|
|
|
}
|
|
|
|
|
2020-03-21 00:00:04 +00:00
|
|
|
func cleanPath(uncleanPath string) string {
|
|
|
|
cleanPath := path.Join(strings.Replace(uncleanPath, "file://", "", 1))
|
|
|
|
|
|
|
|
if len(cleanPath) > 1 && cleanPath[0] == '\\' {
|
|
|
|
return cleanPath[1:]
|
|
|
|
}
|
|
|
|
return cleanPath
|
2020-03-20 21:14:00 +00:00
|
|
|
}
|