From e899668213ee8f7d3566bb5754b488d8633c30c7 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Tue, 10 Sep 2019 20:56:00 +0200 Subject: Add JET support --- plugins/gpgme-vala/src/gpgme_helper.vala | 4 +-- plugins/http-files/src/file_sender.vala | 39 +++++++++++++--------- .../omemo/src/file_transfer/file_decryptor.vala | 24 ++++++------- .../omemo/src/file_transfer/file_encryptor.vala | 28 ++++++++-------- plugins/openpgp/CMakeLists.txt | 2 +- .../openpgp/src/file_transfer/file_decryptor.vala | 8 +++-- .../openpgp/src/file_transfer/file_encryptor.vala | 6 +++- plugins/openpgp/src/plugin.vala | 1 + 8 files changed, 62 insertions(+), 50 deletions(-) (limited to 'plugins') diff --git a/plugins/gpgme-vala/src/gpgme_helper.vala b/plugins/gpgme-vala/src/gpgme_helper.vala index c0121842..4a6d94fa 100644 --- a/plugins/gpgme-vala/src/gpgme_helper.vala +++ b/plugins/gpgme-vala/src/gpgme_helper.vala @@ -163,11 +163,11 @@ private static uint8[] get_uint8_from_data(Data data) { data.seek(0); uint8[] buf = new uint8[256]; ssize_t? len = null; - Array res = new Array(false, true, 0); + ByteArray res = new ByteArray(); do { len = data.read(buf); if (len > 0) { - res.append_vals(buf, (int)len); + res.append(buf[0:len]); } } while (len > 0); return res.data; diff --git a/plugins/http-files/src/file_sender.vala b/plugins/http-files/src/file_sender.vala index 3ab0d736..65b33eb4 100644 --- a/plugins/http-files/src/file_sender.vala +++ b/plugins/http-files/src/file_sender.vala @@ -35,11 +35,11 @@ public class HttpFileSender : FileSender, Object { return send_data; } - public async void send_file(Conversation conversation, FileTransfer file_transfer, FileSendData file_send_data) throws FileSendError { + public async void send_file(Conversation conversation, FileTransfer file_transfer, FileSendData file_send_data, FileMeta file_meta) throws FileSendError { HttpFileSendData? send_data = file_send_data as HttpFileSendData; if (send_data == null) return; - yield upload(file_transfer, send_data); + yield upload(file_transfer, send_data, file_meta); file_transfer.info = send_data.url_down; // store the message content temporarily so the message gets filtered out @@ -62,6 +62,10 @@ public class HttpFileSender : FileSender, Object { return file_transfer.size < max_file_sizes[conversation.account]; } + public bool can_encrypt(Conversation conversation, FileTransfer file_transfer) { + return false; + } + public bool is_upload_available(Conversation conversation) { lock (max_file_sizes) { return max_file_sizes.has_key(conversation.account); @@ -74,24 +78,27 @@ public class HttpFileSender : FileSender, Object { } } - private async void upload(FileTransfer file_transfer, HttpFileSendData file_send_data) throws FileSendError { + private static void transfer_more_bytes(InputStream stream, Soup.MessageBody body) { + uint8[] bytes = new uint8[4096]; + ssize_t read = stream.read(bytes); + if (read == 0) { + body.complete(); + return; + } + bytes.length = (int)read; + body.append_buffer(new Soup.Buffer.take(bytes)); + } + + private async void upload(FileTransfer file_transfer, HttpFileSendData file_send_data, FileMeta file_meta) throws FileSendError { Xmpp.XmppStream? stream = stream_interactor.get_stream(file_transfer.account); if (stream == null) return; - uint8[] buf = new uint8[256]; - Array data = new Array(false, true, 0); - size_t len = -1; - do { - try { - len = file_transfer.input_stream.read(buf); - } catch (IOError e) { - throw new FileSendError.UPLOAD_FAILED("HTTP upload: IOError reading stream: %s".printf(e.message)); - } - data.append_vals(buf, (uint) len); - } while(len > 0); - Soup.Message message = new Soup.Message("PUT", file_send_data.url_up); - message.set_request(file_transfer.mime_type, Soup.MemoryUse.COPY, data.data); + message.request_headers.set_content_type(file_meta.mime_type, null); + message.request_headers.set_content_length(file_meta.size); + message.request_body.set_accumulate(false); + message.wrote_headers.connect(() => transfer_more_bytes(file_transfer.input_stream, message.request_body)); + message.wrote_chunk.connect(() => transfer_more_bytes(file_transfer.input_stream, message.request_body)); Soup.Session session = new Soup.Session(); try { yield session.send_async(message); diff --git a/plugins/omemo/src/file_transfer/file_decryptor.vala b/plugins/omemo/src/file_transfer/file_decryptor.vala index bc6f8592..d60ecdc8 100644 --- a/plugins/omemo/src/file_transfer/file_decryptor.vala +++ b/plugins/omemo/src/file_transfer/file_decryptor.vala @@ -1,5 +1,6 @@ using Dino.Entities; +using Crypto; using Signal; namespace Dino.Plugins.Omemo { @@ -56,20 +57,17 @@ public class OmemoFileDecryptor : FileDecryptor, Object { key = iv_and_key[16:48]; } - // Read data - uint8[] buf = new uint8[256]; - Array data = new Array(false, true, 0); - size_t len = -1; - do { - len = yield encrypted_stream.read_async(buf); - data.append_vals(buf, (uint) len); - } while(len > 0); - - // Decrypt - uint8[] cleartext = Signal.aes_decrypt(Cipher.AES_GCM_NOPADDING, key, iv, data.data); file_transfer.encryption = Encryption.OMEMO; - return new MemoryInputStream.from_data(cleartext); - } catch (Error e) { + debug("Decrypting file %s from %s", file_transfer.file_name, file_transfer.server_file_name); + + SymmetricCipher cipher = new SymmetricCipher("AES-GCM"); + cipher.set_key(key); + cipher.set_iv(iv); + return new ConverterInputStream(encrypted_stream, new SymmetricCipherDecrypter((owned) cipher)); + + } catch (Crypto.Error e) { + throw new FileReceiveError.DECRYPTION_FAILED("OMEMO file decryption error: %s".printf(e.message)); + } catch (GLib.Error e) { throw new FileReceiveError.DECRYPTION_FAILED("OMEMO file decryption error: %s".printf(e.message)); } } diff --git a/plugins/omemo/src/file_transfer/file_encryptor.vala b/plugins/omemo/src/file_transfer/file_encryptor.vala index a5445153..5b4e4d96 100644 --- a/plugins/omemo/src/file_transfer/file_encryptor.vala +++ b/plugins/omemo/src/file_transfer/file_encryptor.vala @@ -1,6 +1,7 @@ using Gee; using Gtk; +using Crypto; using Dino.Entities; using Xmpp; using Signal; @@ -22,30 +23,29 @@ public class OmemoFileEncryptor : Dino.FileEncryptor, Object { var omemo_http_file_meta = new OmemoHttpFileMeta(); try { - uint8[] buf = new uint8[256]; - Array data = new Array(false, true, 0); - size_t len = -1; - do { - len = file_transfer.input_stream.read(buf); - data.append_vals(buf, (uint) len); - } while(len > 0); - //Create a key and use it to encrypt the file uint8[] iv = new uint8[16]; Plugin.get_context().randomize(iv); uint8[] key = new uint8[32]; Plugin.get_context().randomize(key); - uint8[] ciphertext = aes_encrypt(Cipher.AES_GCM_NOPADDING, key, iv, data.data); + + SymmetricCipher cipher = new SymmetricCipher("AES-GCM"); + cipher.set_key(key); + cipher.set_iv(iv); omemo_http_file_meta.iv = iv; omemo_http_file_meta.key = key; - omemo_http_file_meta.size = ciphertext.length; - omemo_http_file_meta.mime_type = "pgp"; - file_transfer.input_stream = new MemoryInputStream.from_data(ciphertext, GLib.free); - } catch (Error error) { - throw new FileSendError.ENCRYPTION_FAILED("HTTP upload: Error encrypting stream: %s".printf(error.message)); + omemo_http_file_meta.size = file_transfer.size; + omemo_http_file_meta.mime_type = "omemo"; + file_transfer.input_stream = new ConverterInputStream(file_transfer.input_stream, new SymmetricCipherEncrypter((owned) cipher)); + } catch (Crypto.Error error) { + throw new FileSendError.ENCRYPTION_FAILED("OMEMO file encryption error: %s".printf(error.message)); + } catch (GLib.Error error) { + throw new FileSendError.ENCRYPTION_FAILED("OMEMO file encryption error: %s".printf(error.message)); } + debug("Encrypting file %s as %s", file_transfer.file_name, file_transfer.server_file_name); + return omemo_http_file_meta; } diff --git a/plugins/openpgp/CMakeLists.txt b/plugins/openpgp/CMakeLists.txt index eb50dc71..3f7c1974 100644 --- a/plugins/openpgp/CMakeLists.txt +++ b/plugins/openpgp/CMakeLists.txt @@ -53,7 +53,7 @@ GRESOURCES ${OPENPGP_GRESOURCES_XML} ) -add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\") +add_definitions(${VALA_CFLAGS} -DG_LOG_DOMAIN="OpenPGP" -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\") add_library(openpgp SHARED ${OPENPGP_VALA_C} ${OPENPGP_GRESOURCES_TARGET}) add_dependencies(openpgp ${GETTEXT_PACKAGE}-translations) target_link_libraries(openpgp libdino gpgme-vala ${OPENPGP_PACKAGES}) diff --git a/plugins/openpgp/src/file_transfer/file_decryptor.vala b/plugins/openpgp/src/file_transfer/file_decryptor.vala index 97eb9f43..455f853d 100644 --- a/plugins/openpgp/src/file_transfer/file_decryptor.vala +++ b/plugins/openpgp/src/file_transfer/file_decryptor.vala @@ -19,18 +19,20 @@ public class PgpFileDecryptor : FileDecryptor, Object { public async InputStream decrypt_file(InputStream encrypted_stream, Conversation conversation, FileTransfer file_transfer, FileReceiveData receive_data) throws FileReceiveError { try { uint8[] buf = new uint8[256]; - Array data = new Array(false, true, 0); + ByteArray data = new ByteArray(); size_t len = -1; do { - len = encrypted_stream.read(buf); - data.append_vals(buf, (uint) len); + len = yield encrypted_stream.read_async(buf); + data.append(buf[0:len]); } while(len > 0); GPGHelper.DecryptedData clear_data = GPGHelper.decrypt_data(data.data); file_transfer.encryption = Encryption.PGP; if (clear_data.filename != null && clear_data.filename != "") { + debug("Decrypting file %s from %s", clear_data.filename, file_transfer.file_name); file_transfer.file_name = clear_data.filename; } else if (file_transfer.file_name.has_suffix(".pgp")) { + debug("Decrypting file %s from %s", file_transfer.file_name.substring(0, file_transfer.file_name.length - 4), file_transfer.file_name); file_transfer.file_name = file_transfer.file_name.substring(0, file_transfer.file_name.length - 4); } return new MemoryInputStream.from_data(clear_data.data, GLib.free); diff --git a/plugins/openpgp/src/file_transfer/file_encryptor.vala b/plugins/openpgp/src/file_transfer/file_encryptor.vala index 7d51be60..66e93bd9 100644 --- a/plugins/openpgp/src/file_transfer/file_encryptor.vala +++ b/plugins/openpgp/src/file_transfer/file_encryptor.vala @@ -15,17 +15,21 @@ public class PgpFileEncryptor : Dino.FileEncryptor, Object { } public FileMeta encrypt_file(Conversation conversation, FileTransfer file_transfer) throws FileSendError { + FileMeta file_meta = new FileMeta(); + try { GPG.Key[] keys = stream_interactor.get_module(Manager.IDENTITY).get_key_fprs(conversation); uint8[] enc_content = GPGHelper.encrypt_file(file_transfer.get_file().get_path(), keys, GPG.EncryptFlags.ALWAYS_TRUST, file_transfer.file_name); file_transfer.input_stream = new MemoryInputStream.from_data(enc_content, GLib.free); file_transfer.encryption = Encryption.PGP; file_transfer.server_file_name = Xmpp.random_uuid() + ".pgp"; + file_meta.size = enc_content.length; } catch (Error e) { throw new FileSendError.ENCRYPTION_FAILED("PGP file encryption error: %s".printf(e.message)); } + debug("Encrypting file %s as %s", file_transfer.file_name, file_transfer.server_file_name); - return new FileMeta(); + return file_meta; } public FileSendData? preprocess_send_file(Conversation conversation, FileTransfer file_transfer, FileSendData file_send_data, FileMeta file_meta) { diff --git a/plugins/openpgp/src/plugin.vala b/plugins/openpgp/src/plugin.vala index b4581f31..324b8652 100644 --- a/plugins/openpgp/src/plugin.vala +++ b/plugins/openpgp/src/plugin.vala @@ -31,6 +31,7 @@ public class Plugin : Plugins.RootInterface, Object { Manager.start(app.stream_interactor, db); app.stream_interactor.get_module(FileManager.IDENTITY).add_file_encryptor(new PgpFileEncryptor(app.stream_interactor)); app.stream_interactor.get_module(FileManager.IDENTITY).add_file_decryptor(new PgpFileDecryptor()); + JingleFileHelperRegistry.instance.add_encryption_helper(Encryption.PGP, new JingleFileEncryptionHelperTransferOnly()); internationalize(GETTEXT_PACKAGE, app.search_path_generator.get_locale_path(GETTEXT_PACKAGE, LOCALE_INSTALL_DIR)); } -- cgit v1.2.3-54-g00ecf