Expand description
Device keys, to-device, cross-signing, and backup decisions. Signature checks that the protocol requires stay here. Transport does not.
Structs§
- Backup
Version Create Request - Backup
Version Update Request - Delete
Devices Request - Device
List Delta - The
device_listsobject of a sync window: mxids, sorted and de-duplicated. - Device
Signing Upload Request - Keys
Changes Query - Keys
Claim Request - Keys
Query Request - What
keys_upload’s blocking half hands back: the caller’s one-time-key counts, and the peers to wake when its device keys changed. - Keys
Upload Outcome - Keys
Upload Request - PutDevice
Request - Send
ToDevice Request - Version
Query
Enums§
Constants§
- BACKUP_
ALGORITHM - The one key-backup algorithm this server accepts (plan P9 brief, MSC3270
naming) —
m.megolm_backup.v1.curve25519-aes-sha2(the PkEncryption backup) is refused outright, never even reaching storage. - SEND_
TO_ DEVICE_ MAX_ CONTENT_ BYTES - Per-target content-size cap (plan P9 brief: “≤ 64 KiB per content”).
- SEND_
TO_ DEVICE_ MAX_ TARGETS - Per-request cap on
PUT /sendToDevice’s flattened target-device count (plan P9 brief: “≤ 1 000 target devices”).
Functions§
- apply_
device_ signing_ upload - DB-only core for
POST /keys/device_signing/upload(plan P9 brief): validates each provided key object’s shape/ownership, verifies self_signing/user_signing against the master key (freshly uploaded in this SAME call, or the caller’s existing one), and stores whatever was provided. No UIA (single factor, matches every other route in this tree). Replacing an existing master key is allowed (user reset). Returns whether anything was actually written — the caller only wakes peers when it did. - apply_
keys_ upload - DB-only core for
POST /keys/upload: ownership check ondevice_keys, then insert / no-op / authenticated identity reset (seedecide_device_keys_upload), OTK-id validation, and storage. OnDeviceKeysUploadAction::Resetold one-time and fallback keys for this device are wiped before the new identity is stored. Returns whetherdevice_keysactually changed (the caller wakes peers when it did). - apply_
send_ to_ device - DB-only core for
PUT /sendToDevice/{eventType}/{txnId}: txn-deduped per(sender_user_id, sender_device_id, txn_id)— a repeat is a no-op — thenexpand_send_to_device_targetsand one atomic dedup-checked enqueue (crate::keys::enqueue_to_device_deduped). - apply_
signatures_ upload - DB-only core for
POST /keys/signatures/upload: per submitted(target_user, target_key_id)pair, checkssignature_target_is_authorizedand stores the whole submitted value opaquely on success (crate::keys::add_signatures), or files a per-entryM_INVALID_PARAMfailure. Returns thefailuresmap (empty on full success). - backup_
sessions_ to_ response - Shape a batch of stored
crate::keys::KeyBackupSessionrows into the GET response’s three tiers. - backup_
version_ to_ response - build_
keys_ changes_ response - DB-only core for
GET /keys/changes(plan §3.7 / P9 brief): the samedevice_listsdelta/syncreports for(from, to](device_list_delta) — device-list changes and newly shared encrypted rooms among users the caller can see (changed), and users who no longer share any room with the caller (left). - build_
keys_ claim_ response - DB-only core for
POST /keys/claim(plan P9 brief): per requested(mxid, device, algorithm), claims one OTK (or a reusable fallback) — restricted to the SAME share-a-room set as/keys/query— silently omitting any device that yields nothing (no such device, no keys left) or any user this caller may not see. - build_
keys_ claim_ visible build_keys_claim_responsewith an explicit visible-user set (federation).- build_
keys_ query_ response - DB-only core for
POST /keys/query(plan P9 brief): batchdevice_keysfor every requested user this caller may see (self, or a shared-room peer —peers_sharing_a_room_with), plusmaster_keys/self_signing_keysfor the same allowed set, anduser_signing_keysONLY for the caller (spec: a user-signing key is never shared with anyone else). A requested user this caller may NOT see, or an mxid naming no known account, gets an emptydevice_keysentry ({}) rather than being omitted — the caller learns nothing about whether the account even exists. - build_
keys_ query_ visible build_keys_query_responsewith an explicit visible-user set;callerisNonefor a federation request (no user-signing key is returned).- canonical_
json_ without_ signatures - Matrix canonical JSON (RFC 8259 subset: sorted keys, no insignificant
whitespace) of
valuewithsignatures/unsignedstripped — the exact bytes a client signs when producing a cross-signing signature.serde_json::Value::Objectis backed by aBTreeMapeverywhere in this workspace (nopreserve_orderfeature enabled anywhere in the dependency graph —Cargo.toml), so keys are already sorted at every nesting level, and its compactto_stringemits no insignificant whitespace and leaves non-ASCII UTF-8 unescaped — together already exactly canonical JSON’s shape, with no extra re-serialization step needed beyond stripping the two keys. - check_
device_ keys_ ownership device_keys.user_id/device_idmust name the authenticated caller (plan §2 manager decision 5 / P9 brief) — elseM_INVALID_PARAM.- count_
claim_ targets - Total number of
(mxid, device)pairs a/keys/claimrequest asks for — the cost charged against [crate::typing::ClaimRateLimiter] (plan P9 brief: “≤ 100 device claims / minute per caller”). - decide_
device_ keys_ upload - Decide what a
device_keysupload does for an already-authenticated device bearer. Compares only thekeysobject (curve25519/ed25519 identity), notalgorithms/signatures. - device_
list_ delta - The
device_listsdelta of(from_exclusive, to_inclusive]as seen bycaller_user_id— seeDeviceListDelta./sync(incremental) andGET /keys/changesboth build their answer from this one function so the two can never disagree. - device_
to_ json - expand_
send_ to_ device_ targets - Resolve
messagesinto a flat per-device list, expanding"*"to every current device of that recipient (an explicit device entry for the same recipient always overrides the wildcard’s content for that one device, never both delivered) and dropping — silently, per this module’s own documented policy (“no enumeration via to-device”) — any recipient who does not share a joined room with the sender and is not the sender themself. Enforces the per-content-size cap up front; the per-request device-count cap is enforced once, after expansion (a caller mistake, refused outright — unlike the stranger case, a cap violation is unambiguous and refusing it leaks nothing a working client didn’t already know about its own request). - master_
key_ names_ local_ id - Whether
user_id’s master cross-signing key nameslocal_idas one of its owned25519:<local_id>entries — the user-signing case’s authorization check (plan P9 brief: “target must be … another user’s master key”). - master_
verifying_ key - Extract the single
ed25519:<key_id>entry from a cross-signing key object’skeysmap (Matrix’s cross-signing keys always carry exactly one) —(key_id, decoded 32-byte verifying key). - normalize_
put_ backup_ body - Normalize the three
PUT room_keys/keys[...]body shapes into a flat(room_id, session_id, session_data_json)list —session_data_jsonis the WHOLE submittedKeyBackupDataobject (opaque to this server, seecrate::keys::key_backup_sessions.session_data’s own doc), not just its innersession_datafield. - parse_
required_ version - peers_
sharing_ a_ room_ with - Every user id the caller may see key material for through this module’s
share-a-room gate:
user_iditself, plus every user who is JOINED or INVITED in a room the caller is JOINED to (plan P9 brief:/keys/query//keys/claim/PUT /sendToDevice“restrict to users who share a room with the caller, or the caller”; the invited half is P16 S-e — see this module’s own doc). The caller must be joined: a room where the caller is only invited, has left, or is banned contributes nothing. A target outside this set is dropped/emptied by the caller, never distinguished from “no such account”. - require_
current_ backup_ version ?version=must name the caller’s CURRENT (non-deleted) backup version — plan P9 brief: “wrong/stale version → 403 M_WRONG_ROOM_KEYS_VERSION with current_version”. Applies uniformly to GET/PUT/DELETEroom_keys/keys[...].- shared_
room_ transitions - Users who entered (
entered) or stopped sharing (departed, before the still-shares-another-room exclusion the caller applies) an ENCRYPTED room withcaller_user_idin(from_exclusive, to_inclusive]. Encrypted rooms only: the client tracks device lists for those alone, and a public unencrypted channel would otherwise list every one of its members whenever the caller joins it. - signature_
target_ is_ authorized - Whether
caller_mxidmay file a signature against(target_user_id, target_key_id)(plan P9 brief: “the signer must be the caller; target must be the caller’s own device/keys or (for user-signing) another user’s master key”). This endpoint never verifies the signature bytes themselves — only this authorization shape — matchingcrate::keys::cross_signing_signatures’s own “opaque, never verified” contract (the one deliberate exception in this module is/keys/device_signing/upload’s master-key check, scoped to that endpoint alone — see this module’s own doc). - sorted_
mxids - The mxids of
user_ids, sorted and de-duplicated (a user with no mxid row cannot be named to a client and is dropped). - split_
algorithm_ key_ id algorithm:key_id— every one-time/fallback key’s own wire id (plan P9 brief: “OTK ids algorithm:key_id format validated”).- validate_
backup_ algorithm - Refuse anything but this server’s one symmetric key-backup algorithm
(plan P9 brief, MSC3270 naming) —
m.megolm_backup.v1.curve25519-aes-sha2(the PkEncryption backup) is refused outright. - validate_
cross_ signing_ key_ object user_id/usageshape validation shared by all three cross-signing key kinds (plan P9 brief).- verify_
signed_ by_ master - Verify that
target_key_object(aself_signing_key/user_signing_keyupload) carries a valid ed25519 signature bymaster_key_object’s own key, filed undersignatures[caller_mxid]["ed25519:<master_key_id>"]— Matrix’s own cross-signing trust chain (plan P9 brief: “verify with ed25519 over canonical JSON”).