diff options
author | Philipp Hörist <forenjunkie@chello.at> | 2017-01-14 04:11:41 +0300 |
---|---|---|
committer | Philipp Hörist <forenjunkie@chello.at> | 2017-01-14 04:11:41 +0300 |
commit | 57bf69380fedba3ece402e73076952b81ae5ed68 (patch) | |
tree | 9f26388326be9bf23ea97a7d8544a391503d8bb4 | |
parent | 1a5b58b78a3304727e27290ca8ea481b00f9066f (diff) | |
parent | e141482c16ff5fa64ef81be7b99a6a1dd69a0c23 (diff) |
Merge branch 'master' into 'master'
1.0.1
Closes #161
See merge request !12
-rw-r--r-- | omemo/CHANGELOG | 4 | ||||
-rw-r--r-- | omemo/manifest.ini | 2 | ||||
-rw-r--r-- | omemo/omemo/aes_gcm_fallback.py | 24 | ||||
-rw-r--r-- | omemo/omemo/aes_gcm_native.py | 20 | ||||
-rw-r--r-- | omemo/omemo/state.py | 33 | ||||
-rw-r--r-- | omemo/ui.py | 2 | ||||
-rw-r--r-- | omemo/xmpp.py | 11 |
7 files changed, 72 insertions, 24 deletions
diff --git a/omemo/CHANGELOG b/omemo/CHANGELOG index d19f492..0fbe8e4 100644 --- a/omemo/CHANGELOG +++ b/omemo/CHANGELOG @@ -1,3 +1,7 @@ +1.0.1 / 2017-01-14 +- Better XEP Compliance +- Bugfixes + 1.0.0 / 2016-12-04 - Bugfixes diff --git a/omemo/manifest.ini b/omemo/manifest.ini index 3a553c3..f04098b 100644 --- a/omemo/manifest.ini +++ b/omemo/manifest.ini @@ -1,7 +1,7 @@ [info] name: OMEMO short_name: omemo -version: 1.0.0 +version: 1.0.1 description: OMEMO is an XMPP Extension Protocol (XEP) for secure multi-client end-to-end encryption based on Axolotl and PEP. You need to install some dependencys, you can find install instructions for your system in the Gitlab Wiki. authors: Bahtiar `kalkin-` Gadimov <bahtiar@gadimov.de> Daniel Gultsch <daniel@gultsch.de> diff --git a/omemo/omemo/aes_gcm_fallback.py b/omemo/omemo/aes_gcm_fallback.py index a34255a..334eab2 100644 --- a/omemo/omemo/aes_gcm_fallback.py +++ b/omemo/omemo/aes_gcm_fallback.py @@ -29,11 +29,14 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import logging from struct import pack, unpack from Crypto.Cipher import AES from Crypto.Util import strxor +log = logging.getLogger('gajim.plugin_system.omemo') + def gcm_rightshift(vec): for x in range(15, 0, -1): @@ -140,13 +143,20 @@ def gcm_encrypt(k, iv, plaintext, auth_data): def aes_encrypt(key, nonce, plaintext): """ Use AES128 GCM with the given key and iv to encrypt the payload. """ - c, t = gcm_encrypt(key, nonce, plaintext, '') - result = c + t - return result - + return gcm_encrypt(key, nonce, plaintext, '') -def aes_decrypt(key, nonce, payload): +def aes_decrypt(_key, nonce, payload): """ Use AES128 GCM with the given key and iv to decrypt the payload. """ - ciphertext = payload[:-16] - mac = payload[-16:] + if len(_key) >= 32: + # XEP-0384 + log.debug('XEP Compliant Key/Tag') + ciphertext = payload + key = _key[:16] + mac = _key[16:] + else: + # Legacy + log.debug('Legacy Key/Tag') + ciphertext = payload[:-16] + key = _key + mac = payload[-16:] return gcm_decrypt(key, nonce, ciphertext, '', mac) diff --git a/omemo/omemo/aes_gcm_native.py b/omemo/omemo/aes_gcm_native.py index 40bf127..28c7c43 100644 --- a/omemo/omemo/aes_gcm_native.py +++ b/omemo/omemo/aes_gcm_native.py @@ -19,6 +19,7 @@ import os +import logging from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.hazmat.primitives.ciphers import algorithms from cryptography.hazmat.primitives.ciphers.modes import GCM @@ -32,11 +33,22 @@ if os.name == 'nt': else: from cryptography.hazmat.backends import default_backend +log = logging.getLogger('gajim.plugin_system.omemo') -def aes_decrypt(key, iv, payload): +def aes_decrypt(_key, iv, payload): """ Use AES128 GCM with the given key and iv to decrypt the payload. """ - data = payload[:-16] - tag = payload[-16:] + if len(_key) >= 32: + # XEP-0384 + log.debug('XEP Compliant Key/Tag') + data = payload + key = _key[:16] + tag = _key[16:] + else: + # Legacy + log.debug('Legacy Key/Tag') + data = payload[:-16] + key = _key + tag = payload[-16:] if os.name == 'nt': _backend = backend else: @@ -58,4 +70,4 @@ def aes_encrypt(key, iv, plaintext): algorithms.AES(key), GCM(iv), backend=_backend).encryptor() - return encryptor.update(plaintext) + encryptor.finalize() + encryptor.tag + return encryptor.update(plaintext) + encryptor.finalize(), encryptor.tag diff --git a/omemo/omemo/state.py b/omemo/omemo/state.py index 6db7f1a..58c40ca 100644 --- a/omemo/omemo/state.py +++ b/omemo/omemo/state.py @@ -226,12 +226,20 @@ class OmemoState: log.error('No known devices') return + payload, tag = encrypt(key, iv, plaintext) + + # for XEP-384 Compliance uncomment + # key += tag + payload += tag + # Encrypt the message key with for each of receivers devices for device in devices_list: try: if self.isTrusted(jid, device) == TRUSTED: cipher = self.get_session_cipher(jid, device) - encrypted_keys[device] = cipher.encrypt(key).serialize() + cipher_key = cipher.encrypt(key) + prekey = isinstance(cipher_key, PreKeyWhisperMessage) + encrypted_keys[device] = (cipher_key.serialize(), prekey) else: log.debug('Skipped Device because Trust is: ' + str(self.isTrusted(jid, device))) @@ -248,15 +256,15 @@ class OmemoState: try: if self.isTrusted(from_jid, device) == TRUSTED: cipher = self.get_session_cipher(from_jid, device) - encrypted_keys[device] = cipher.encrypt(key).serialize() + cipher_key = cipher.encrypt(key) + prekey = isinstance(cipher_key, PreKeyWhisperMessage) + encrypted_keys[device] = (cipher_key.serialize(), prekey) else: log.debug('Skipped own Device because Trust is: ' + str(self.isTrusted(from_jid, device))) except: log.warning('Failed to find key for device ' + str(device)) - payload = encrypt(key, iv, plaintext) - result = {'sid': self.own_device_id, 'keys': encrypted_keys, 'jid': jid, @@ -279,6 +287,12 @@ class OmemoState: log.error('No known devices') return + payload, tag = encrypt(key, iv, plaintext) + + # for XEP-384 Compliance uncomment + # key += tag + payload += tag + for tup in devices_list: self.get_session_cipher(tup[0], tup[1]) @@ -292,8 +306,9 @@ class OmemoState: for rid, cipher in self.session_ciphers[jid_to].items(): try: if self.isTrusted(jid_to, rid) == TRUSTED: - encrypted_keys[rid] = cipher.encrypt(key). \ - serialize() + cipher_key = cipher.encrypt(key) + prekey = isinstance(cipher_key, PreKeyWhisperMessage) + encrypted_keys[rid] = (cipher_key.serialize(), prekey) else: log.debug('Skipped Device because Trust is: ' + str(self.isTrusted(jid_to, rid))) @@ -313,7 +328,9 @@ class OmemoState: try: cipher = self.get_session_cipher(from_jid, dev) if self.isTrusted(from_jid, dev) == TRUSTED: - encrypted_keys[dev] = cipher.encrypt(key).serialize() + cipher_key = cipher.encrypt(key) + prekey = isinstance(cipher_key, PreKeyWhisperMessage) + encrypted_keys[dev] = (cipher_key.serialize(), prekey) else: log.debug('Skipped own Device because Trust is: ' + str(self.isTrusted(from_jid, dev))) @@ -321,8 +338,6 @@ class OmemoState: log.exception('ERROR:') log.warning('Failed to find key for device ' + str(dev)) - payload = encrypt(key, iv, plaintext) - result = {'sid': self.own_device_id, 'keys': encrypted_keys, 'jid': jid, diff --git a/omemo/ui.py b/omemo/ui.py index b0d6869..0469846 100644 --- a/omemo/ui.py +++ b/omemo/ui.py @@ -322,6 +322,8 @@ class Ui(object): def removeUi(self): self.actions_hbox.remove(self.omemobutton) + self.chat_control._show_lock_image(False, 'OMEMO', False, True, + False) self.chat_control.prepare_context_menu = \ self.chat_control.omemo_orig_prepare_context_menu self.chat_control.send_message = self.chat_control.orig_send_message diff --git a/omemo/xmpp.py b/omemo/xmpp.py index bf31c8d..b7a6696 100644 --- a/omemo/xmpp.py +++ b/omemo/xmpp.py @@ -79,9 +79,14 @@ class OmemoMessage(Node): # , contact_jid, key, iv, payload, dev_id, my_dev_id): Node.__init__(self, 'encrypted', attrs={'xmlns': NS_OMEMO}) header = Node('header', attrs={'sid': msg_dict['sid']}) - for rid, key in msg_dict['keys'].items(): - header.addChild('key', attrs={'rid': rid}).addData(b64encode(key)) - + for rid, (key, prekey) in msg_dict['keys'].items(): + if prekey: + child = header.addChild('key', + attrs={'prekey': 'true', 'rid': rid}) + else: + child = header.addChild('key', + attrs={'rid': rid}) + child.addData(b64encode(key)) header.addChild('iv').addData(b64encode(msg_dict['iv'])) self.addChild(node=header) self.addChild('payload').addData(b64encode(msg_dict['payload'])) |