Add Nix shell and local 16KB-aligned Olm build

This commit is contained in:
ltadeu6 2026-05-16 15:59:41 -03:00
parent 9bc3651341
commit 700289fef9
15 changed files with 499 additions and 51 deletions

View file

@ -182,7 +182,7 @@ class CryptoService(
/**
* Handles `m.forwarded_room_key` a key shared by another of our own devices in response
* to an `m.room_key_request`. Uses [OlmInboundGroupSession.importSession] because the
* to an `m.room_key_request`. Uses [OlmInboundGroupSession.importSession] because the
* forwarded key is in exported (message-index-aware) format.
*/
private fun handleForwardedRoomKey(content: JsonObject) {

View file

@ -58,14 +58,10 @@ class VerificationService(private val scope: CoroutineScope) {
private var theirUserId: String? = null
private var theirDeviceId: String? = null
private var ourPublicKey: String? = null
private var pendingTheirMac: JsonObject? = null // mac received before we showed emojis
private var pendingTheirMac: JsonObject? = null
private var selectedMacMethod: String? = null
private var hasConfirmedLocally: Boolean = false
// -------------------------------------------------------------------------
// Incoming event dispatch
// -------------------------------------------------------------------------
fun processToDeviceEvent(event: JsonObject) {
val type = (event["type"] as? JsonPrimitive)?.content ?: return
val content = event["content"]?.jsonObject ?: return
@ -74,18 +70,14 @@ class VerificationService(private val scope: CoroutineScope) {
when (type) {
"m.key.verification.request" -> handleRequest(sender, txnId, content)
"m.key.verification.start" -> handleStart(sender, txnId, content)
"m.key.verification.key" -> handleKey(txnId, content)
"m.key.verification.mac" -> handleMac(txnId, content)
"m.key.verification.done" -> handleDone(txnId)
"m.key.verification.cancel" -> handleCancel(txnId, content)
"m.key.verification.start" -> handleStart(sender, txnId, content)
"m.key.verification.key" -> handleKey(txnId, content)
"m.key.verification.mac" -> handleMac(txnId, content)
"m.key.verification.done" -> handleDone(txnId)
"m.key.verification.cancel" -> handleCancel(txnId, content)
}
}
// -------------------------------------------------------------------------
// Request — show banner
// -------------------------------------------------------------------------
private fun handleRequest(sender: String, txnId: String, content: JsonObject) {
if (_state.value !is VerificationState.Idle) return
val fromDevice = (content["from_device"] as? JsonPrimitive)?.content ?: return
@ -95,10 +87,6 @@ class VerificationService(private val scope: CoroutineScope) {
_state.value = VerificationState.Requested(sender, fromDevice, txnId)
}
// -------------------------------------------------------------------------
// Accept — user tapped "Accept" on the banner
// -------------------------------------------------------------------------
fun accept(txnId: String) {
if ((_state.value as? VerificationState.Requested)?.txnId != txnId) return
val toUser = theirUserId ?: return
@ -111,13 +99,8 @@ class VerificationService(private val scope: CoroutineScope) {
scope.launch {
onSend(toUser, toDevice, "m.key.verification.ready", "${txnId}_ready", content)
}
// Stay in Requested state; wait for m.key.verification.start
}
// -------------------------------------------------------------------------
// Start — create OlmSAS, send accept + key
// -------------------------------------------------------------------------
private fun handleStart(sender: String, txnId: String, content: JsonObject) {
if (txnId != currentTxnId) return
val method = (content["method"] as? JsonPrimitive)?.content
@ -145,7 +128,6 @@ class VerificationService(private val scope: CoroutineScope) {
olmSas = sas
ourPublicKey = sas.publicKey
// commitment = unpadded-base64(SHA-256(our_pubkey_base64 + canonical_json(start_content)))
val sha256 = MessageDigest.getInstance("SHA-256")
val commitInput = (ourPublicKey ?: return) + content.toCanonicalJson()
val commitment = Base64.encodeToString(
@ -177,10 +159,6 @@ class VerificationService(private val scope: CoroutineScope) {
}
}
// -------------------------------------------------------------------------
// Key exchange — compute SAS and show emojis
// -------------------------------------------------------------------------
private fun handleKey(txnId: String, content: JsonObject) {
if (txnId != currentTxnId) return
val sas = olmSas ?: return
@ -188,11 +166,10 @@ class VerificationService(private val scope: CoroutineScope) {
sas.setTheirPublicKey(theirKey)
// Initiator = them (sent the start), Accepting = us
val info = "MATRIX_KEY_VERIFICATION_SAS" +
"|${theirUserId}|${theirDeviceId}|${theirKey}" +
"|${userId}|${deviceId}|${ourPublicKey}" +
"|${txnId}"
"|${theirUserId}|${theirDeviceId}|${theirKey}" +
"|${userId}|${deviceId}|${ourPublicKey}" +
"|${txnId}"
val sasBytes = sas.generateShortCode(info, 6)
val emojis = sasBytes.toSasEmojis()
@ -200,10 +177,6 @@ class VerificationService(private val scope: CoroutineScope) {
_state.value = VerificationState.ShowingEmojis(txnId, emojis)
}
// -------------------------------------------------------------------------
// Confirm — user tapped "Confirm emojis match"
// -------------------------------------------------------------------------
fun confirm() {
val state = _state.value as? VerificationState.ShowingEmojis ?: return
val sas = olmSas ?: return
@ -246,10 +219,6 @@ class VerificationService(private val scope: CoroutineScope) {
}
}
// -------------------------------------------------------------------------
// Their MAC — verify and send done
// -------------------------------------------------------------------------
private fun handleMac(txnId: String, content: JsonObject) {
if (txnId != currentTxnId) return
if (_state.value !is VerificationState.ShowingEmojis || !hasConfirmedLocally) {
@ -309,10 +278,6 @@ class VerificationService(private val scope: CoroutineScope) {
}
}
// -------------------------------------------------------------------------
// Done / Cancel
// -------------------------------------------------------------------------
private fun handleDone(txnId: String) {
if (txnId != currentTxnId) return
cleanup()
@ -378,10 +343,6 @@ private fun OlmSAS.calculateMacByMethod(input: String, info: String, method: Str
}
}.getOrNull()
// ---------------------------------------------------------------------------
// SAS emoji derivation (Matrix spec: 42 bits = 7 × 6-bit indices)
// ---------------------------------------------------------------------------
private fun ByteArray.toSasEmojis(): List<SasEmoji> {
val b = map { it.toInt() and 0xFF }
val indices = listOf(
@ -396,7 +357,6 @@ private fun ByteArray.toSasEmojis(): List<SasEmoji> {
return indices.map { SAS_EMOJIS[it] }
}
// Matrix SAS emoji list (indices 063), from the Matrix spec.
private val SAS_EMOJIS = listOf(
SasEmoji("\uD83D\uDC36", "Dog"),
SasEmoji("\uD83D\uDC31", "Cat"),

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.