-
-
Notifications
You must be signed in to change notification settings - Fork 651
Import room key bundles received after invite. #5080
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 4 commits
b098fce
ff046a2
ec73af6
1688268
c6ff37c
62a2af4
fe0baa6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2010,6 +2010,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa | |
| this.on(ClientEvent.Event, (event) => { | ||
| rustCrypto.onLiveEventFromSync(event); | ||
| }); | ||
| this.on(ClientEvent.ReceivedToDeviceMessage, (payload) => rustCrypto.onReceiveToDeviceMessage(payload)); | ||
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // re-emit the events emitted by the crypto impl | ||
| this.reEmitter.reEmit(rustCrypto, [ | ||
|
|
@@ -2408,7 +2409,12 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa | |
|
|
||
| const roomId = res.room_id; | ||
| if (opts.acceptSharedHistory && inviter && this.cryptoBackend) { | ||
| await this.cryptoBackend.maybeAcceptKeyBundle(roomId, inviter); | ||
| // Try to accept the room key bundle specified in a `m.room_key_bundle` to-device message we (might have) already received. | ||
| const bundleDownloaded = await this.cryptoBackend.maybeAcceptKeyBundle(roomId, inviter); | ||
| // If this fails, i.e. we haven't received this message yet, we need to wait until the to-device message arrives. | ||
| if (!bundleDownloaded) { | ||
| this.cryptoBackend.markRoomAsPendingKeyBundle(roomId, inviter); | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would say that we should combine the two methods into one, to save having this logic in MatrixClient, but maybe having them separate will be better once we come to having this work over restarts?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An alternative could be to call
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think we would want to call I think it's fine as-is |
||
| } | ||
|
|
||
| // In case we were originally given an alias, check the room cache again | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -129,6 +129,9 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH | |
| /** mapping of roomId → encryptor class */ | ||
| private roomEncryptors: Record<string, RoomEncryptor> = {}; | ||
|
|
||
| /** mapping of room ID -> inviter ID for rooms pending MSC4268 key bundles */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this comment is now outdated. |
||
| private roomsPendingKeyBundles: Record<string, string> = {}; | ||
|
|
||
| private eventDecryptor: EventDecryptor; | ||
| private keyClaimManager: KeyClaimManager; | ||
| private outgoingRequestProcessor: OutgoingRequestProcessor; | ||
|
|
@@ -329,7 +332,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH | |
| /** | ||
| * Implementation of {@link CryptoBackend.maybeAcceptKeyBundle}. | ||
| */ | ||
| public async maybeAcceptKeyBundle(roomId: string, inviter: string): Promise<void> { | ||
| public async maybeAcceptKeyBundle(roomId: string, inviter: string): Promise<boolean> { | ||
| // TODO: retry this if it gets interrupted or it fails. (https://github.com/matrix-org/matrix-rust-sdk/issues/5112) | ||
| // TODO: do this in the background. | ||
| // TODO: handle the bundle message arriving after the invite (https://github.com/element-hq/element-web/issues/30740) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this TODO line needs an update |
||
|
|
@@ -352,7 +355,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH | |
| ); | ||
| if (!bundleData) { | ||
| logger.info("No key bundle found for user"); | ||
| return; | ||
| return false; | ||
| } | ||
|
|
||
| logger.info(`Fetching key bundle ${bundleData.url}`); | ||
|
|
@@ -391,7 +394,17 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH | |
| logger.warn(`Error receiving encrypted bundle:`, err); | ||
| throw err; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * Implementation of {@link CryptoBackend.markRoomAsPendingKeyBundle}. | ||
| */ | ||
| public markRoomAsPendingKeyBundle(roomId: string, inviterId: string): void { | ||
| this.roomsPendingKeyBundles[roomId] = inviterId; | ||
| } | ||
|
|
||
| /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| // | ||
| // CryptoApi implementation | ||
|
|
@@ -2138,6 +2151,34 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH | |
| public async getOwnIdentity(): Promise<RustSdkCryptoJs.OwnUserIdentity | undefined> { | ||
| return await this.olmMachine.getIdentity(new RustSdkCryptoJs.UserId(this.userId)); | ||
| } | ||
| /** | ||
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * Handles the receipt of a to-device message, specifically for processing | ||
| * "io.element.msc4268.room_key_bundle" message types. | ||
| * | ||
| * @param payload - The received to-device message payload, which includes | ||
| * the message content and optional encryption information. | ||
| */ | ||
| public async onReceiveToDeviceMessage(payload: ReceivedToDeviceMessage): Promise<void> { | ||
| if (payload.message.type != "io.element.msc4268.room_key_bundle") { | ||
| return; | ||
| } | ||
|
|
||
| const { message, encryptionInfo } = payload; | ||
| const claimedSender = encryptionInfo?.sender ?? message.sender; | ||
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // Validate room ID | ||
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const roomId = message.content.room_id; | ||
| if (typeof roomId !== "string") { | ||
| return; | ||
| } | ||
|
|
||
| // Check if the room is in the map of rooms we expect to receive bundles from, otherwise discard. | ||
| if (this.roomsPendingKeyBundles[roomId] !== claimedSender) { | ||
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return; | ||
| } | ||
|
|
||
| await this.maybeAcceptKeyBundle(roomId, claimedSender); | ||
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| class EventDecryptor { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.