diff options
author | defanor <defanor@uberspace.net> | 2021-02-08 22:29:28 +0300 |
---|---|---|
committer | defanor <defanor@uberspace.net> | 2021-02-08 22:29:28 +0300 |
commit | edb0f157d4cd4fd16481bce5013b7663fa219dac (patch) | |
tree | 4dfa3e23fd5273887c271db25c9558bc18e4fb57 | |
parent | df73e8fe84d3c2c544d12ffa78b310544bb395bb (diff) |
Adjust and document XEP-0373 API
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | src/rexmpp_console.c | 6 | ||||
-rw-r--r-- | src/rexmpp_openpgp.c | 45 | ||||
-rw-r--r-- | src/rexmpp_openpgp.h | 66 |
4 files changed, 69 insertions, 49 deletions
@@ -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 |