summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2021-02-08 22:29:28 +0300
committerdefanor <defanor@uberspace.net>2021-02-08 22:29:28 +0300
commitedb0f157d4cd4fd16481bce5013b7663fa219dac (patch)
tree4dfa3e23fd5273887c271db25c9558bc18e4fb57
parentdf73e8fe84d3c2c544d12ffa78b310544bb395bb (diff)
Adjust and document XEP-0373 API
-rw-r--r--README1
-rw-r--r--src/rexmpp_console.c6
-rw-r--r--src/rexmpp_openpgp.c45
-rw-r--r--src/rexmpp_openpgp.h66
4 files changed, 69 insertions, 49 deletions
diff --git a/README b/README
index 5b4d422..a5a149c 100644
--- a/README
+++ b/README
@@ -89,6 +89,7 @@ A rough roadmap:
[+] Display name establishment.
[.] A console module.
+[ ] Pubsub (XEP-0060) utility functions.
- Examples and application:
diff --git a/src/rexmpp_console.c b/src/rexmpp_console.c
index a2f14a8..1211129 100644
--- a/src/rexmpp_console.c
+++ b/src/rexmpp_console.c
@@ -304,11 +304,11 @@ void rexmpp_console_feed (rexmpp_t *s, char *str, ssize_t str_len) {
rcpt[1] = NULL;
char *b64 = NULL;
if (strcmp(word, "signcrypt") == 0) {
- b64 = rexmpp_openpgp_encrypt_sign(s, body, rcpt);
+ b64 = rexmpp_openpgp_payload(s, body, rcpt, REXMPP_OX_SIGNCRYPT);
} else if (strcmp(word, "sign") == 0) {
- b64 = rexmpp_openpgp_sign(s, body, rcpt);
+ b64 = rexmpp_openpgp_payload(s, body, rcpt, REXMPP_OX_SIGN);
} else if (strcmp(word, "crypt") == 0) {
- b64 = rexmpp_openpgp_encrypt(s, body, rcpt);
+ b64 = rexmpp_openpgp_payload(s, body, rcpt, REXMPP_OX_CRYPT);
}
xmlNodePtr openpgp = xmlNewNode(NULL, "openpgp");
openpgp->ns = xmlNewNs(openpgp, "urn:xmpp:openpgp:0", NULL);
diff --git a/src/rexmpp_openpgp.c b/src/rexmpp_openpgp.c
index a8acebb..e046bcd 100644
--- a/src/rexmpp_openpgp.c
+++ b/src/rexmpp_openpgp.c
@@ -701,32 +701,26 @@ void rexmpp_openpgp_set_signers (rexmpp_t *s) {
char *rexmpp_openpgp_payload (rexmpp_t *s,
xmlNodePtr payload,
const char **recipients,
- int sign,
- int crypt)
+ enum rexmpp_ox_mode mode)
{
gpgme_error_t err;
int sasl_err;
int i, nkeys = 0, allocated = 0;
gpgme_key_t *keys = NULL;
- if (! (sign || crypt)) {
- rexmpp_log(s, LOG_ERR, "Attempted to neither sign nor encrypt");
- return NULL;
- }
-
/* Prepare an element. */
char *elem_name = NULL;
- if (sign && crypt) {
+ if (mode == REXMPP_OX_SIGNCRYPT) {
elem_name = "signcrypt";
- } else if (sign) {
+ } else if (mode == REXMPP_OX_SIGN) {
elem_name = "sign";
- } else if (crypt) {
+ } else if (mode == REXMPP_OX_CRYPT) {
elem_name = "crypt";
}
xmlNodePtr elem = xmlNewNode(NULL, elem_name);
xmlNewNs(elem, "urn:xmpp:openpgp:0", NULL);
- if (sign) {
+ if (mode == REXMPP_OX_SIGN || mode == REXMPP_OX_SIGNCRYPT) {
rexmpp_openpgp_set_signers(s);
/* Add all the recipients. */
@@ -755,7 +749,7 @@ char *rexmpp_openpgp_payload (rexmpp_t *s,
xmlAddChild(pl, payload);
xmlAddChild(elem, pl);
- if (crypt) {
+ if (mode == REXMPP_OX_CRYPT || mode == REXMPP_OX_SIGNCRYPT) {
/* Add keys for encryption. */
allocated = 8;
keys = malloc(sizeof(gpgme_key_t *) * allocated);
@@ -797,13 +791,13 @@ char *rexmpp_openpgp_payload (rexmpp_t *s,
gpgme_data_t cipher_dh, plain_dh;
gpgme_data_new(&cipher_dh);
gpgme_data_new_from_mem(&plain_dh, plaintext, strlen(plaintext), 0);
- if (sign && crypt) {
+ if (mode == REXMPP_OX_SIGNCRYPT) {
err = gpgme_op_encrypt_sign(s->pgp_ctx, keys, GPGME_ENCRYPT_NO_ENCRYPT_TO,
plain_dh, cipher_dh);
- } else if (crypt) {
+ } else if (mode == REXMPP_OX_CRYPT) {
err = gpgme_op_encrypt(s->pgp_ctx, keys, GPGME_ENCRYPT_NO_ENCRYPT_TO,
plain_dh, cipher_dh);
- } else if (sign) {
+ } else if (mode == REXMPP_OX_SIGN) {
err = gpgme_op_sign(s->pgp_ctx, plain_dh, cipher_dh, GPGME_SIG_MODE_NORMAL);
}
if (keys != NULL) {
@@ -829,27 +823,6 @@ char *rexmpp_openpgp_payload (rexmpp_t *s,
return cipher_base64;
}
-char *rexmpp_openpgp_encrypt_sign (rexmpp_t *s,
- xmlNodePtr payload,
- const char **recipients)
-{
- return rexmpp_openpgp_payload(s, payload, recipients, 1, 1);
-}
-
-char *rexmpp_openpgp_encrypt (rexmpp_t *s,
- xmlNodePtr payload,
- const char **recipients)
-{
- return rexmpp_openpgp_payload(s, payload, recipients, 0, 1);
-}
-
-char *rexmpp_openpgp_sign (rexmpp_t *s,
- xmlNodePtr payload,
- const char **recipients)
-{
- return rexmpp_openpgp_payload(s, payload, recipients, 1, 0);
-}
-
rexmpp_err_t rexmpp_openpgp_set_home_dir (rexmpp_t *s, const char *home_dir) {
gpgme_engine_info_t engine_info;
gpgme_error_t err;
diff --git a/src/rexmpp_openpgp.h b/src/rexmpp_openpgp.h
index 1db5717..bed46b3 100644
--- a/src/rexmpp_openpgp.h
+++ b/src/rexmpp_openpgp.h
@@ -2,7 +2,7 @@
@file rexmpp_openpgp.h
@brief XEP-0373 routines
@author defanor <defanor@uberspace.net>
- @date 2020
+ @date 2020--2021
@copyright MIT license.
*/
#ifndef REXMPP_OPENPGP_H
@@ -10,34 +10,80 @@
#include "rexmpp.h"
+/**
+ @brief A mode corresponding to XEP-0373's OpenPGP content element.
+ */
+enum rexmpp_ox_mode {
+ REXMPP_OX_SIGN,
+ REXMPP_OX_CRYPT,
+ REXMPP_OX_SIGNCRYPT
+};
+
+/**
+ @brief Checks whether we have all the keys from the list of known
+ keys for a given JID, requests missing ones.
+ @param[in] s ::rexmpp
+ @param[in] jid A JID.
+ @param[in] items An <items> element with <public-keys-list> in it.
+*/
rexmpp_err_t
rexmpp_openpgp_check_keys (rexmpp_t *s,
const char *jid,
xmlNodePtr items);
+/**
+ @brief Publishes a key via PEP/pubsub.
+ @param[in] s ::rexmpp
+ @param[in] fp The fingerprint of a key that should be published.
+ @returns ::REXMPP_SUCCESS or an error code.
+*/
rexmpp_err_t rexmpp_openpgp_publish_key (rexmpp_t *s, const char *fp);
+
+/**
+ @brief Retracts a key from PEP/pubsub.
+ @param[in] s ::rexmpp
+ @param[in] fp The fingerprint of a key that should be deleted.
+*/
void rexmpp_openpgp_retract_key (rexmpp_t *s, const char *fp);
+/**
+ @brief Tries to decrypt and/or verify an OpenPGP message.
+ @param[in] s ::rexmpp
+ @param[in] cipher_base64 An OpenPGP ciphertext.
+ @returns A plaintext message body.
+*/
xmlNodePtr
rexmpp_openpgp_decrypt_verify (rexmpp_t *s,
const char *cipher_base64);
+/**
+ @brief Tries to decrypt and/or verify an OpenPGP message from a
+ <message> element, taking into account its attributes.
+ @param[in] s ::rexmpp
+ @param[in] message A <message> element.
+ @param[out] valid Will be set to 1 if the message appears to be
+ valid.
+ @returns A decrypted message body.
+*/
xmlNodePtr
rexmpp_openpgp_decrypt_verify_message (rexmpp_t *s,
xmlNodePtr message,
int *valid);
-char *rexmpp_openpgp_encrypt_sign (rexmpp_t *s,
- xmlNodePtr payload,
- const char **recipients);
-
-char *rexmpp_openpgp_encrypt (rexmpp_t *s,
+/**
+ @brief Encodes a message, producing a signed and/or encrypted
+ payload.
+ @param[in] s ::rexmpp
+ @param[in] payload XML payload.
+ @param[in] recipients A NULL-terminated list of recipient JIDs.
+ @param[in] mode ::rexmpp_ox_mode
+ @returns An encoded <openpgp> payload.
+*/
+char *rexmpp_openpgp_payload (rexmpp_t *s,
xmlNodePtr payload,
- const char **recipients);
+ const char **recipients,
+ enum rexmpp_ox_mode mode);
-char *rexmpp_openpgp_sign (rexmpp_t *s,
- xmlNodePtr payload,
- const char **recipients);
/**
@brief An utility function for setting GPG home directory. An