about summary refs log tree commit diff stats
path: root/lib/keystore.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/keystore.go')
-rw-r--r--lib/keystore.go81
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/keystore.go b/lib/keystore.go
new file mode 100644
index 0000000..dcdbd74
--- /dev/null
+++ b/lib/keystore.go
@@ -0,0 +1,81 @@
+package lib
+
+import (
+	"io"
+	"os"
+	"path"
+
+	"github.com/kyoh86/xdg"
+	"golang.org/x/crypto/openpgp"
+	"golang.org/x/crypto/openpgp/packet"
+)
+
+var (
+	Keyring openpgp.EntityList
+
+	locked bool
+)
+
+func InitKeyring() {
+	os.MkdirAll(path.Join(xdg.DataHome(), "aerc"), 0700)
+
+	lockpath := path.Join(xdg.DataHome(), "aerc", "keyring.lock")
+	lockfile, err := os.OpenFile(lockpath, os.O_CREATE|os.O_EXCL, 0600)
+	if err != nil {
+		// TODO: Consider connecting to main process over IPC socket
+		locked = false
+	} else {
+		locked = true
+		lockfile.Close()
+	}
+
+	keypath := path.Join(xdg.DataHome(), "aerc", "keyring.asc")
+	keyfile, err := os.Open(keypath)
+	if os.IsNotExist(err) {
+		return
+	} else if err != nil {
+		panic(err)
+	}
+	defer keyfile.Close()
+
+	Keyring, err = openpgp.ReadKeyRing(keyfile)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func UnlockKeyring() {
+	if !locked {
+		return
+	}
+	lockpath := path.Join(xdg.DataHome(), "aerc", "keyring.lock")
+	os.Remove(lockpath)
+}
+
+func ImportKeys(r io.Reader) error {
+	keys, err := openpgp.ReadKeyRing(r)
+	if err != nil {
+		return err
+	}
+	Keyring = append(Keyring, keys...)
+	if locked {
+		keypath := path.Join(xdg.DataHome(), "aerc", "keyring.asc")
+		keyfile, err := os.OpenFile(keypath, os.O_CREATE|os.O_APPEND, 0600)
+		if err != nil {
+			return err
+		}
+		defer keyfile.Close()
+
+		for _, key := range keys {
+			if key.PrivateKey != nil {
+				err = key.SerializePrivate(keyfile, &packet.Config{})
+			} else {
+				err = key.Serialize(keyfile)
+			}
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}