diff options
author | Dr. David Alan Gilbert <dave@treblig.org> | 2018-02-23 02:39:06 +0000 |
---|---|---|
committer | Dr. David Alan Gilbert <dave@treblig.org> | 2018-02-25 02:08:49 +0000 |
commit | a99c22099a07320c0557816c72d3fd400288681d (patch) | |
tree | d8c16a8b07fcceafa1b13d127d5a5fd7a90c45ec | |
parent | 6de15eeb813822230141adfb2f9a10469212ebde (diff) | |
download | purple-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.c | 58 | ||||
-rw-r--r-- | matrix-e2e.h | 2 |
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 |