Signed-off-by: Nico Schottelius <nico@nico-notebook.schottelius.org>
This commit is contained in:
Nico Schottelius 2025-01-31 15:25:10 +01:00
commit d42a50b3c6
3 changed files with 71 additions and 0 deletions

View file

@ -63,6 +63,10 @@ class UngleichMatrixClient:
self.access_token = self.login_response.json()['access_token']
def get_room_keys(self):
"""
We assume version == 1 is correct because that's what's seen in reality
In theory we need to query the current version on the server first.
"""
self._ensure_logged_in()
params = {
@ -139,6 +143,8 @@ class UngleichMatrixClient:
# use + b'==') to expand padding https://stackoverflow.com/questions/2941995/python-ignore-incorrect-padding-error-when-base64-decoding
ephemeral_key_bytes = base64.b64decode(ephemeral_key + '==')
ephemeral_public_key = X25519PublicKey.from_public_bytes(ephemeral_key_bytes)
# This is effectively ECDH provided by cryptography library
shared_key = self.security_private_key.exchange(ephemeral_public_key)
# when we have shared secret, use HDKF to get the AES part
@ -152,6 +158,7 @@ class UngleichMatrixClient:
# The first 32 bytes are used as the AES key,
# the next 32 bytes are used as the MAC key,
# and the last 16 bytes are used as the AES initialization vector."
# Using a key derivation function
derived_key = HKDF(
algorithm=hashes.SHA256(),
length=80,
@ -171,6 +178,8 @@ class UngleichMatrixClient:
# Pass an empty string through HMAC-SHA-256 using the MAC key generated above. The first 8 bytes of the resulting MAC are base64-encoded, and become the mac property of the session_data.
# hashed message authentication code = HMAC
# This basically allows us to check if we derived the correct key
mac = HMAC(mac_key, hashes.SHA256())
mac.update(b'')
@ -195,6 +204,7 @@ class UngleichMatrixClient:
session_key_bytes = decryptor.update(encrypted_session_key_bytes) + decryptor.finalize()
# Remove PKCS7 padding - block size 128 was guessed / tested to be correct
# Needs to be verified - it should in theory be 256
unpadder = padding.PKCS7(128).unpadder()
data = unpadder.update(session_key_bytes)
data += unpadder.finalize()