summaryrefslogtreecommitdiff
path: root/slixmpp/plugins/xep_0454/__init__.py
diff options
context:
space:
mode:
authorMaxime “pep” Buquet <pep@bouah.net>2022-03-18 14:27:26 +0100
committerMaxime “pep” Buquet <pep@bouah.net>2022-03-19 10:31:34 +0100
commitb52540e49f4b314640086f8f5845924af68150b2 (patch)
tree8768d87db57db0fe4f28f42467d5ad86dea557c4 /slixmpp/plugins/xep_0454/__init__.py
parentc1aeab328b8c25d67d29ec7587534e7701007858 (diff)
downloadslixmpp-b52540e49f4b314640086f8f5845924af68150b2.tar.gz
slixmpp-b52540e49f4b314640086f8f5845924af68150b2.tar.bz2
slixmpp-b52540e49f4b314640086f8f5845924af68150b2.tar.xz
slixmpp-b52540e49f4b314640086f8f5845924af68150b2.zip
xep_0454: implement decrypt method
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
Diffstat (limited to 'slixmpp/plugins/xep_0454/__init__.py')
-rw-r--r--slixmpp/plugins/xep_0454/__init__.py40
1 files changed, 40 insertions, 0 deletions
diff --git a/slixmpp/plugins/xep_0454/__init__.py b/slixmpp/plugins/xep_0454/__init__.py
index 9e9c3b02..09d41221 100644
--- a/slixmpp/plugins/xep_0454/__init__.py
+++ b/slixmpp/plugins/xep_0454/__init__.py
@@ -73,6 +73,46 @@ class XEP_0454(BasePlugin):
return (payload, fragment)
@classmethod
+ def decrypt(cls, input_file: IO[bytes], fragment: str) -> bytes:
+ """
+ Decrypts file-like.
+
+ :param input_file: Binary file stream on the file, containing the
+ tag (16 bytes) at the end.
+ :param fragment: 88 hex chars string composed of iv (24 chars)
+ + key (64 chars).
+ """
+
+ assert len(fragment) == 88
+ aes_gcm_iv = bytes.fromhex(fragment[:24])
+ aes_gcm_key = bytes.fromhex(fragment[24:])
+
+ # Find 16 bytes tag
+ input_file.seek(-16, SEEK_END)
+ tag = input_file.read()
+
+ aes_gcm = Cipher(
+ algorithms.AES(aes_gcm_key),
+ modes.GCM(aes_gcm_iv, tag),
+ ).decryptor()
+
+ size = input_file.seek(0, SEEK_END)
+ input_file.seek(0)
+
+ count = size - 16
+ plain = b''
+ while count >= 0:
+ buf = input_file.read(4096)
+ count -= len(buf)
+ if count <= 0:
+ buf += input_file.read()
+ buf = buf[:-16]
+ plain += aes_gcm.update(buf)
+ plain += aes_gcm.finalize()
+
+ return plain
+
+ @classmethod
def format_url(cls, url: str, fragment: str) -> str:
"""Helper to format a HTTPS URL to an AESGCM URI"""
if not url.startswith('https://') or url.find('#') != -1: