aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. David Alan Gilbert <dave@treblig.org>2018-02-23 02:39:06 +0000
committerDr. David Alan Gilbert <dave@treblig.org>2018-02-25 02:08:49 +0000
commita99c22099a07320c0557816c72d3fd400288681d (patch)
treed8c16a8b07fcceafa1b13d127d5a5fd7a90c45ec
parent6de15eeb813822230141adfb2f9a10469212ebde (diff)
downloadpurple-matrix-a99c22099a07320c0557816c72d3fd400288681d.tar.gz
e2e: Utility to decrypt media data
Pass the received image data through gcrypt to do the decryption using the previously received keys. Signed-off-by: Dr. David Alan Gilbert <dave@treblig.org>
-rw-r--r--matrix-e2e.c58
-rw-r--r--matrix-e2e.h2
2 files changed, 60 insertions, 0 deletions
diff --git a/matrix-e2e.c b/matrix-e2e.c
index 93cee3c..a358185 100644
--- a/matrix-e2e.c
+++ b/matrix-e2e.c
@@ -33,6 +33,7 @@
#include "connection.h"
#ifndef MATRIX_NO_E2E
#include "olm/olm.h"
+#include <gcrypt.h>
struct _MatrixOlmSession;
@@ -1788,6 +1789,56 @@ gboolean matrix_e2e_parse_media_decrypt_info(MatrixMediaCryptInfo **crypt,
return TRUE;
}
+/* Decrypt media (in or inlen) into a buffer it allocates (*out)
+ * returns NULL or an error string.
+ */
+const char *matrix_e2e_decrypt_media(MatrixMediaCryptInfo *crypt,
+ size_t inlen, const void *in, void **out)
+{
+ char *fail_str = NULL;
+ gcry_error_t gcry_err;
+ gcry_cipher_hd_t cipher_hd;
+ gboolean copen = FALSE;
+
+ *out = NULL;
+ gcry_err = gcry_cipher_open(&cipher_hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, 0);
+ if (gcry_err) {
+ fail_str = "failed to open cipher";
+ goto err;
+ }
+ copen = TRUE;
+ gcry_err = gcry_cipher_setkey(cipher_hd, crypt->aes_k, 32);
+ if (gcry_err) {
+ fail_str = "failed to set key";
+ goto err;
+ }
+ /* Note: this is only working if we use setctr not setiv */
+ gcry_err = gcry_cipher_setctr(cipher_hd, crypt->aes_iv, 16);
+ if (gcry_err) {
+ fail_str = "failed to set iv";
+ goto err;
+ }
+ *out = g_malloc(inlen); /* Do I need to round this to block len? */
+ gcry_cipher_final(cipher_hd);
+ gcry_err = gcry_cipher_decrypt(cipher_hd, *out, inlen, in, inlen);
+ if (gcry_err) {
+ g_free(*out);
+ fail_str = "failed to decrypt";
+ goto err;
+ }
+
+ gcry_cipher_close(cipher_hd);
+
+ return NULL;
+
+err:
+ g_free(*out);
+ *out = NULL;
+ if (copen) gcry_cipher_close(cipher_hd);
+
+ return fail_str;
+}
+
static void action_device_info(PurplePluginAction *action)
{
PurpleConnection *pc = (PurpleConnection *) action->context;
@@ -1857,6 +1908,13 @@ gboolean matrix_e2e_parse_media_decrypt_info(MatrixMediaCryptInfo **crypt,
return TRUE;
}
+const char *matrix_e2e_decrypt_media(MatrixMediaCryptInfo *crypt,
+ size_t inlen, const void *in, void **out)
+{
+ return "Crypto not available";
+}
+
+
GList *matrix_e2e_actions(GList *list)
{
return list;
diff --git a/matrix-e2e.h b/matrix-e2e.h
index def07e5..5ab5ee1 100644
--- a/matrix-e2e.h
+++ b/matrix-e2e.h
@@ -34,6 +34,8 @@ void matrix_e2e_decrypt_d2d(struct _PurpleConnection *pc, struct _JsonObject *ev
JsonParser *matrix_e2e_decrypt_room(struct _PurpleConversation *conv, struct _JsonObject *event);
gboolean matrix_e2e_parse_media_decrypt_info(MatrixMediaCryptInfo **crypt,
JsonObject *file_obj);
+const char *matrix_e2e_decrypt_media(MatrixMediaCryptInfo *crypt,
+ size_t inlen, const void *in, void **out);
void matrix_e2e_handle_sync_key_counts(struct _PurpleConnection *pc, struct _JsonObject *count_object, gboolean force_send);
#endif