141 lines
3.8 KiB
Go
141 lines
3.8 KiB
Go
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"
|
|
path "path/filepath"
|
|
"sort"
|
|
"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{}
|
|
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 {
|
|
outputLine := ""
|
|
if schemeDefined == false {
|
|
for k := range data {
|
|
schema = append(schema, k)
|
|
}
|
|
|
|
sort.Strings(schema)
|
|
|
|
for _, k := range schema {
|
|
str := strings.SplitN(k, "_", 1)
|
|
outputLine += fmt.Sprintf(`"%v",`, strings.ReplaceAll(str[1], "\"", "\\\""))
|
|
}
|
|
|
|
outputfile = append(outputfile, outputLine)
|
|
schemeDefined = true
|
|
}
|
|
outputLine = ""
|
|
for _, k := range schema {
|
|
outputLine += fmt.Sprintf(`"%v",`, strings.ReplaceAll(data[k], "\"", "\\\""))
|
|
}
|
|
outputfile = append(outputfile, outputLine)
|
|
}
|
|
} 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)
|
|
public, private, err := box.GenerateKey(rand.Reader)
|
|
if err == nil {
|
|
publicStr := base64.StdEncoding.EncodeToString(public[:])
|
|
privateStr := base64.StdEncoding.EncodeToString(private[:])
|
|
err = ioutil.WriteFile(cleanPath(path.Join(cleanPath(keyPath), "key.public")), []byte(publicStr), 0644)
|
|
if err == nil {
|
|
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
|
|
}
|
|
} else {
|
|
lapi.Saved(false, err.Error())
|
|
return
|
|
}
|
|
}
|
|
lapi.Saved(false, err.Error())
|
|
}
|
|
|
|
func cleanPath(uncleanPath string) string {
|
|
cleanPath := path.Join(strings.Replace(uncleanPath, "file://", "", 1))
|
|
|
|
if len(cleanPath) > 1 && cleanPath[0] == '\\' {
|
|
return cleanPath[1:]
|
|
}
|
|
return cleanPath
|
|
}
|