Ox: Add private key import.

code-cleanup
Martin Dosch 2 years ago
parent 73f8ac8fb1
commit 428bb86de2

@ -83,7 +83,7 @@ If no configuration file is present or if the values should be overridden it is
the account details via command line options: the account details via command line options:
```plain ```plain
Usage: go-sendxmpp [-cdilnt] [-f value] [--help] [--http-upload value] [-j value] [-m value] [--muc-password value] [--ox] [--ox-genprivkey] [--ox-passphrase value] [-p value] [--raw] [-r value] [--timeout value] [--tls-version value] [-u value] [--version] [parameters ...] Usage: go-sendxmpp [-cdilnt] [-f value] [--help] [--http-upload value] [-j value] [-m value] [--muc-password value] [--ox] [--ox-genprivkey] [--ox-import-privkey value] [--ox-passphrase value] [-p value] [--raw] [-r value] [--timeout value] [--tls-version value] [-u value] [--version] [parameters ...]
-c, --chatroom Send message to a chatroom. -c, --chatroom Send message to a chatroom.
-d, --debug Show debugging info. -d, --debug Show debugging info.
-f, --file=value Set configuration file. (Default: -f, --file=value Set configuration file. (Default:
@ -105,6 +105,8 @@ Usage: go-sendxmpp [-cdilnt] [-f value] [--help] [--http-upload value] [-j value
--ox-genprivkey --ox-genprivkey
Generate a public OpenPGP key for the given JID and publish Generate a public OpenPGP key for the given JID and publish
the corresponding public key. the corresponding public key.
--ox-import-privkey=value
Import an existing private OpenPGP key.
--ox-passphrase=value --ox-passphrase=value
Passphrase for locking and unlocking the private OpenPGP Passphrase for locking and unlocking the private OpenPGP
key. key.

@ -111,6 +111,8 @@ func main() {
"Generate a public OpenPGP key for the given JID and publish the corresponding public key.") "Generate a public OpenPGP key for the given JID and publish the corresponding public key.")
flagOxPassphrase := getopt.StringLong("ox-passphrase", 0, "", flagOxPassphrase := getopt.StringLong("ox-passphrase", 0, "",
"Passphrase for locking and unlocking the private OpenPGP key.") "Passphrase for locking and unlocking the private OpenPGP key.")
flagOxImportPrivKey := getopt.StringLong("ox-import-privkey", 0, "",
"Import an existing private OpenPGP key.")
// Parse command line flags. // Parse command line flags.
getopt.Parse() getopt.Parse()
@ -145,8 +147,8 @@ func main() {
// For listening or sending raw XML it's not required to specify a recipient except // For listening or sending raw XML it's not required to specify a recipient except
// when sending raw messages to MUCs (go-sendxmpp will join the MUC automatically). // when sending raw messages to MUCs (go-sendxmpp will join the MUC automatically).
recipientsList := getopt.Args() recipientsList := getopt.Args()
if (len(recipientsList) == 0 && !*flagRaw && !*flagListen && !*flagOxGenPrivKey) || if (len(recipientsList) == 0 && !*flagRaw && !*flagListen && !*flagOxGenPrivKey &&
(len(recipientsList) == 0 && *flagChatroom) { *flagOxImportPrivKey == "") || (len(recipientsList) == 0 && *flagChatroom) {
log.Fatal("No recipient specified.") log.Fatal("No recipient specified.")
} }
@ -287,6 +289,19 @@ func main() {
os.Exit(0) os.Exit(0)
} }
if *flagOxImportPrivKey != "" {
validatedOwnJid, err := MarshalJID(user)
if err != nil {
log.Fatal(err)
}
err = oxImportPrivKey(validatedOwnJid, *flagOxImportPrivKey,
client)
if err != nil {
log.Fatal(err)
}
os.Exit(0)
}
if *flagOx { if *flagOx {
validatedOwnJid, err := MarshalJID(user) validatedOwnJid, err := MarshalJID(user)
if err != nil { if err != nil {

@ -38,7 +38,11 @@ You can either pipe a programs output to \fBgo\-sendxmpp\fR, write in your termi
.br .br
There is also no check whether the recipients key is trusted as there is no local keyring used\. Go\-sendxmpp just uses the most recent key that is provided via pubsub and checks that it is not expired\. There is also no check whether the recipients key is trusted as there is no local keyring used\. Go\-sendxmpp just uses the most recent key that is provided via pubsub and checks that it is not expired\.
.P .P
\fB\-\-ox\-genprivkey\fR: Generate a public OpenPGP key for the given JID and publish the corresponding public key\. Go\-sendxmpp will save the key in \fB$XDG_DATA_HOME/go\-sendxmpp/oxprivkeys\fR or \fB$HOME/\.local/share/go\-sendxmpp/oxprivkeys\fR\. To protect the key you might want to set a passphrase using \fB\-\-ox\-passphrase\fR while generating the key\. \fB\-\-ox\-genprivkey\fR: Generate a public OpenPGP key for the given JID and publish the corresponding public key\. Go\-sendxmpp will save the key in \fB$XDG_DATA_HOME/go\-sendxmpp/oxprivkeys\fR or \fB$HOME/\.local/share/go\-sendxmpp/oxprivkeys\fR\. To protect the key a passphrase might be set using \fB\-\-ox\-passphrase\fR while generating the key\.
.br
If there is an existing private key for "OpenPGP for XMPP" created by another client (e\.g\. profanity) it might be imported using \fB\-\-ox\-import\-privkey\fR\.
.P
\fB\-\-ox\-import\-privkey\fR=[\fIvalue\fR]: Import an existing private OpenPGP key\.
.P .P
\fB\-\-ox\-passphrase\fR=[\fIvalue\fR]: Passphrase for locking and unlocking the private OpenPGP key\. \fB\-\-ox\-passphrase\fR=[\fIvalue\fR]: Passphrase for locking and unlocking the private OpenPGP key\.
.P .P

@ -137,8 +137,13 @@ file location is specified with <code>-f</code> or <code>--file</code>.</p>
<p><code>--ox-genprivkey</code>: <p><code>--ox-genprivkey</code>:
Generate a public OpenPGP key for the given JID and publish the corresponding public key. Generate a public OpenPGP key for the given JID and publish the corresponding public key.
Go-sendxmpp will save the key in <code>$XDG_DATA_HOME/go-sendxmpp/oxprivkeys</code> or Go-sendxmpp will save the key in <code>$XDG_DATA_HOME/go-sendxmpp/oxprivkeys</code> or
<code>$HOME/.local/share/go-sendxmpp/oxprivkeys</code>. To protect the key you might want to set a <code>$HOME/.local/share/go-sendxmpp/oxprivkeys</code>. To protect the key a passphrase might be set
passphrase using <code>--ox-passphrase</code> while generating the key.</p> using <code>--ox-passphrase</code> while generating the key. <br>
If there is an existing private key for "OpenPGP for XMPP" created by another client (e.g. profanity)
it might be imported using <code>--ox-import-privkey</code>.</p>
<p><code>--ox-import-privkey</code>=[<var>value</var>]:
Import an existing private OpenPGP key.</p>
<p><code>--ox-passphrase</code>=[<var>value</var>]: <p><code>--ox-passphrase</code>=[<var>value</var>]:
Passphrase for locking and unlocking the private OpenPGP key.</p> Passphrase for locking and unlocking the private OpenPGP key.</p>

@ -62,8 +62,13 @@ file location is specified with `-f` or `--file`.
`--ox-genprivkey`: `--ox-genprivkey`:
Generate a public OpenPGP key for the given JID and publish the corresponding public key. Generate a public OpenPGP key for the given JID and publish the corresponding public key.
Go-sendxmpp will save the key in `$XDG_DATA_HOME/go-sendxmpp/oxprivkeys` or Go-sendxmpp will save the key in `$XDG_DATA_HOME/go-sendxmpp/oxprivkeys` or
`$HOME/.local/share/go-sendxmpp/oxprivkeys`. To protect the key you might want to set a `$HOME/.local/share/go-sendxmpp/oxprivkeys`. To protect the key a passphrase might be set
passphrase using `--ox-passphrase` while generating the key. using `--ox-passphrase` while generating the key.
If there is an existing private key for "OpenPGP for XMPP" created by another client (e.g. profanity)
it might be imported using `--ox-import-privkey`.
`--ox-import-privkey`=[<value>]:
Import an existing private OpenPGP key.
`--ox-passphrase`=[<value>]: `--ox-passphrase`=[<value>]:
Passphrase for locking and unlocking the private OpenPGP key. Passphrase for locking and unlocking the private OpenPGP key.

66
ox.go

@ -19,6 +19,52 @@ import (
"github.com/mattn/go-xmpp" // BSD-3-Clause "github.com/mattn/go-xmpp" // BSD-3-Clause
) )
func oxImportPrivKey(jid string, privKeyLocation string, client *xmpp.Client) error {
xmppUri := "xmpp:" + jid
buffer, err := readFile(privKeyLocation)
if err != nil {
return err
}
key, err := crypto.NewKey(buffer.Bytes())
if err != nil {
key, err = crypto.NewKeyFromArmored(buffer.String())
if err != nil {
return err
}
}
entity := key.GetEntity()
if entity.Identities[xmppUri] == nil {
return errors.New("Key identity is not " + xmppUri)
}
pk, err := key.GetPublicKey()
if err != nil {
return err
}
pubKey, err := crypto.NewKey(pk)
if err != nil {
return err
}
fingerprint := strings.ToUpper(pubKey.GetFingerprint())
_, err = oxRecvPublicKey(client, jid, fingerprint)
if err != nil {
return errors.New("Key not found in pubsub: " + fingerprint)
}
location, err := oxGetPrivKeyLoc(jid)
if err != nil {
return err
}
keySerialized, err := key.Serialize()
if err != nil {
return err
}
err = oxStorePrivKey(location,
base64.StdEncoding.EncodeToString(keySerialized))
if err != nil {
log.Fatal(err)
}
return nil
}
func oxGetPrivKeyLoc(jid string) (string, error) { func oxGetPrivKeyLoc(jid string) (string, error) {
var err error var err error
var homeDir, dataDir string var homeDir, dataDir string
@ -89,19 +135,15 @@ func oxGetPrivKey(jid string, passphrase string) (*crypto.Key, error) {
return key, nil return key, nil
} }
func oxStorePrivKey(jid string, privKey string) error { func oxStorePrivKey(location string, privKey string) error {
dataFile, err := oxGetPrivKeyLoc(jid)
if err != nil {
log.Fatal(err)
}
var file *os.File var file *os.File
if _, err := os.Stat(dataFile); os.IsNotExist(err) { if _, err := os.Stat(location); os.IsNotExist(err) {
file, err = os.Create(dataFile) file, err = os.Create(location)
if err != nil { if err != nil {
return err return err
} }
} else { } else {
file, err = os.OpenFile(dataFile, os.O_RDWR, 0600) file, err = os.OpenFile(location, os.O_RDWR, 0600)
if err != nil { if err != nil {
return err return err
} }
@ -112,7 +154,7 @@ func oxStorePrivKey(jid string, privKey string) error {
} else { } else {
_ = file.Chmod(os.FileMode(0200)) _ = file.Chmod(os.FileMode(0200))
} }
_, err = file.Write([]byte(privKey)) _, err := file.Write([]byte(privKey))
if err != nil { if err != nil {
return err return err
} }
@ -141,7 +183,11 @@ func oxGenPrivKey(jid string, client *xmpp.Client, passphrase string) error {
if err != nil { if err != nil {
return err return err
} }
err = oxStorePrivKey(jid, location, err := oxGetPrivKeyLoc(jid)
if err != nil {
return err
}
err = oxStorePrivKey(location,
base64.StdEncoding.EncodeToString(keySerialized)) base64.StdEncoding.EncodeToString(keySerialized))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

Loading…
Cancel
Save