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

16
matrix/matrix-client.py Executable file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env python3
import sys
import urllib
from mautrix.client import ClientAPI
matrix_server="ungleich.matrix.ungleich.cloud"
matrix_user="@nico:ungleich.ch"
matrix_password=sys.argv[1]
client = ClientAPI(matrixuser,
base_url=f"https://{matrix_server}"
token="syt_123_456")
await print(client.whoami())

45
matrix/matrix-client.sh Executable file
View file

@ -0,0 +1,45 @@
#!/bin/sh
matrix_server=$1; shift
# matrix_user=$1; shift
# matrix_user=$(echo $matrix_user | sed 's/^@/\@/')
# matrix_password=$1; shift
# Login
# http -j -p "HBhb" \
# https://${matrix_server}/_matrix/client/v3/login \
# identifier:="{ \"type\":\"m.id.user\", \"user\":\"$matrix_user\" }" \
# device_id=nicoshell initial_device_display_name="matrixclientsh" \
# type=m.login.password \
# password=$matrix_password
# {
# "access_token": "..",
# "device_id": "nicoshell",
# "home_server": "ungleich.ch",
# "user_id": "@nico:ungleich.ch",
# "well_known": {
# "m.homeserver": {
# "base_url": "https://ungleich.matrix.ungleich.cloud/"
# }
# }
# }
key_url=https://${matrix_server}/_matrix/client/v3/room_keys/keys
token=$1; shift
http -j -p "HBhb" $key_url \
identifier:="{ \"type\":\"m.id.user\", \"user\":\"$matrix_user\" }" \
device_id=nicoshell initial_device_display_name="matrixclientsh" \
type=m.login.password \
password=$matrix_password
# get device keys + master_keys of Nico
http https://ungleich.matrix.ungleich.cloud/_matrix/client/v3/keys/query access_token=="$token" device_keys:='{ "@nico:ungleich.ch": [] }'
# Get messages
room_id="!..:..."
http 'https://ungleich.matrix.ungleich.cloud/_matrix/client/v3/rooms/!pkPjzozYKUNEbcZKKA:unchat.cat/messages' access_token=="$token"
# Get room keys

View file

@ -63,6 +63,10 @@ class UngleichMatrixClient:
self.access_token = self.login_response.json()['access_token'] self.access_token = self.login_response.json()['access_token']
def get_room_keys(self): 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() self._ensure_logged_in()
params = { 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 # 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_key_bytes = base64.b64decode(ephemeral_key + '==')
ephemeral_public_key = X25519PublicKey.from_public_bytes(ephemeral_key_bytes) 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) shared_key = self.security_private_key.exchange(ephemeral_public_key)
# when we have shared secret, use HDKF to get the AES part # 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 first 32 bytes are used as the AES key,
# the next 32 bytes are used as the MAC key, # the next 32 bytes are used as the MAC key,
# and the last 16 bytes are used as the AES initialization vector." # and the last 16 bytes are used as the AES initialization vector."
# Using a key derivation function
derived_key = HKDF( derived_key = HKDF(
algorithm=hashes.SHA256(), algorithm=hashes.SHA256(),
length=80, 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. # 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 = HMAC(mac_key, hashes.SHA256())
mac.update(b'') mac.update(b'')
@ -195,6 +204,7 @@ class UngleichMatrixClient:
session_key_bytes = decryptor.update(encrypted_session_key_bytes) + decryptor.finalize() session_key_bytes = decryptor.update(encrypted_session_key_bytes) + decryptor.finalize()
# Remove PKCS7 padding - block size 128 was guessed / tested to be correct # 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() unpadder = padding.PKCS7(128).unpadder()
data = unpadder.update(session_key_bytes) data = unpadder.update(session_key_bytes)
data += unpadder.finalize() data += unpadder.finalize()