From d25294add79f9ef5a14262bf391b9aeb4e673ca5 Mon Sep 17 00:00:00 2001 From: Martin Dosch Date: Mon, 18 Apr 2022 17:14:03 +0200 Subject: [PATCH] Ox: Cache public keys. --- ox.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/ox.go b/ox.go index 10575d4..b576459 100644 --- a/ox.go +++ b/ox.go @@ -57,7 +57,7 @@ func oxImportPrivKey(jid string, privKeyLocation string, client *xmpp.Client) er if err != nil { return err } - err = oxStorePrivKey(location, + err = oxStoreKey(location, base64.StdEncoding.EncodeToString(keySerialized)) if err != nil { log.Fatal(err) @@ -98,6 +98,39 @@ func oxGetPrivKeyLoc(jid string) (string, error) { return dataFile, nil } +func oxGetPubKeyLoc(fingerprint string) (string, error) { + var err error + var homeDir, dataDir string + switch { + case os.Getenv("$XDG_DATA_HOME") != "": + dataDir = os.Getenv("$XDG_DATA_HOME") + case os.Getenv("$XDG_HOME") != "": + homeDir = os.Getenv("$XDG_HOME") + dataDir = homeDir + "/.local/share" + case os.Getenv("$HOME") != "": + homeDir = os.Getenv("$HOME") + dataDir = homeDir + "/.local/share" + default: + homeDir, err = os.UserHomeDir() + if err != nil { + return "error", err + } + if homeDir == "" { + return "error", err + } + dataDir = homeDir + "/.local/share" + } + dataDir = dataDir + "/go-sendxmpp/oxpubkeys/" + if _, err = os.Stat(dataDir); os.IsNotExist(err) { + err = os.MkdirAll(dataDir, 0700) + if err != nil { + return "error", err + } + } + dataFile := dataDir + fingerprint + return dataFile, nil +} + func oxGetPrivKey(jid string, passphrase string) (*crypto.Key, error) { dataFile, err := oxGetPrivKeyLoc(jid) if err != nil { @@ -135,7 +168,7 @@ func oxGetPrivKey(jid string, passphrase string) (*crypto.Key, error) { return key, nil } -func oxStorePrivKey(location string, privKey string) error { +func oxStoreKey(location string, key string) error { var file *os.File if _, err := os.Stat(location); os.IsNotExist(err) { file, err = os.Create(location) @@ -154,7 +187,7 @@ func oxStorePrivKey(location string, privKey string) error { } else { _ = file.Chmod(os.FileMode(0200)) } - _, err := file.Write([]byte(privKey)) + _, err := file.Write([]byte(key)) if err != nil { return err } @@ -187,7 +220,7 @@ func oxGenPrivKey(jid string, client *xmpp.Client, passphrase string) error { if err != nil { return err } - err = oxStorePrivKey(location, + err = oxStoreKey(location, base64.StdEncoding.EncodeToString(keySerialized)) if err != nil { log.Fatal(err) @@ -325,6 +358,7 @@ func oxRecvPublicKey(client *xmpp.Client, recipient string, func oxGetPublicKey(client *xmpp.Client, recipient string) (*crypto.Key, error) { var oxPublicKeyListRequest IQPubsubRequest var oxPublicKeyListXML OxPublicKeysList + oxPublicKeyListRequest.Xmlns = nsPubsub oxPublicKeyListRequest.Items.Node = nsOxPubKeys oxPublicKeyListRequest.Items.MaxItems = "1" @@ -364,11 +398,37 @@ func oxGetPublicKey(client *xmpp.Client, recipient string) (*crypto.Key, error) return nil, errors.New("server didn't provide public key fingerprints for " + recipient) } + pubKeyLocation, err := oxGetPubKeyLoc(fingerprint) + if err != nil { + return nil, err + } + pubKeyFile, err := readFile(pubKeyLocation) + if err == nil { + decodedPubKey, err := base64.StdEncoding.DecodeString(pubKeyFile.String()) + if err != nil { + return nil, err + } + key, err := crypto.NewKey(decodedPubKey) + if err != nil { + return nil, err + } + if !key.IsExpired() { + return key, nil + } + } key, err := oxRecvPublicKey(client, recipient, fingerprint) if err != nil { return nil, errors.New("Couldn't fetch public key.") } - + keySerialized, err := key.Serialize() + if err != nil { + return nil, err + } + err = oxStoreKey(pubKeyLocation, + base64.StdEncoding.EncodeToString(keySerialized)) + if err != nil { + log.Println(err) + } return key, nil }