Skip to content
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

ElementR: fix emoji verification stalling when both ends hit start at the same time #4004

Merged
merged 20 commits into from
Jan 31, 2024

Conversation

uhoreg
Copy link
Member

@uhoreg uhoreg commented Jan 12, 2024

fixes element-hq/element-web#26723

When both ends hit "start", one of the sides will "win" and the other will "lose". The Rust crypto crate on the losing side replaces the SAS verifier with a new one. The current code does not detect this, and continues trying to use the old one. This PR switches the verifier to the new one when it changes.

Checklist

  • Tests written for new code (and old code if feasible)
  • Linter and other CI checks pass
  • Sign-off given on the changes (see CONTRIBUTING.md)

Here's what your changelog entry will look like:

🐛 Bug Fixes

@uhoreg uhoreg requested a review from a team as a code owner January 12, 2024 01:07
Copy link
Member

@BillCarsonFr BillCarsonFr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few questions

src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
@richvdh richvdh self-requested a review January 23, 2024 10:29
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
src/rust-crypto/verification.ts Outdated Show resolved Hide resolved
Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Co-authored-by: Richard van der Hoff <[email protected]>
@uhoreg
Copy link
Member Author

uhoreg commented Jan 26, 2024

This is ready to merge, but I'm taking this afternoon off, and I don't want to merge this and then run off right away, so I'll merge on Monday

Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't review the tests previously. Nothing important here -- generally they look great. Just a few suggestions for cleanups which you might like if you have the time and inclination.

}
const crossSigningKeys = JSON.parse(uploadSigningKeysRequest.body);
// note: the upload signatures request and upload signing keys requests
// don't need to me marked as sent in the Olm machine
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// don't need to me marked as sent in the Olm machine
// don't need to be marked as sent in the Olm machine

'{"one_time_key_counts":{"signed_curve25519":100}}',
);
const crossSigningSignatures = JSON.parse(uploadSignaturesRequest.body);
if (crossSigningSignatures[userId] && crossSigningSignatures[userId][deviceId]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like this should always be true? I'd be tempted to get rid of this condition.

Alternatively, a ? operator would simplify:

Suggested change
if (crossSigningSignatures[userId] && crossSigningSignatures[userId][deviceId]) {
if (crossSigningSignatures[userId]?.[deviceId]) {

Doesn't matter though.

Comment on lines 465 to 467
customHandler:
| ((request: OutgoingRequest | RustSdkCryptoJs.UploadSigningKeysRequest) => Promise<any>)
| undefined = undefined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider defining something like:

type CustomRequestHandler = ((request: OutgoingRequest | RustSdkCryptoJs.UploadSigningKeysRequest) => Promise<any>);

Also, ? after a param is effectively the same as | undefined, and = undefined is the default.

Suggested change
customHandler:
| ((request: OutgoingRequest | RustSdkCryptoJs.UploadSigningKeysRequest) => Promise<any>)
| undefined = undefined,
customHandler?: CustomRequestHandler,

async function makeOutgoingRequest(
request: OutgoingRequest | RustSdkCryptoJs.UploadSigningKeysRequest,
): Promise<any> {
let resp: any = customHandler && (await customHandler(request));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let resp: any = customHandler && (await customHandler(request));
let resp: any = await customHandler?.(request);

I think?

Comment on lines 536 to 543
const promise = (async () => {
while (!stopRequestLoop) {
const requests = await ourOlmMachine.outgoingRequests();
for (const request of requests) {
await makeOutgoingRequest(request);
}
}
})();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit hard to read.

Suggested change
const promise = (async () => {
while (!stopRequestLoop) {
const requests = await ourOlmMachine.outgoingRequests();
for (const request of requests) {
await makeOutgoingRequest(request);
}
}
})();
async function runLoop() {
while (!stopRequestLoop) {
const requests = await ourOlmMachine.outgoingRequests();
for (const request of requests) {
await makeOutgoingRequest(request);
}
}
}
const loopCompletedPromise = runLoop();

request: OutgoingRequest | RustSdkCryptoJs.UploadSigningKeysRequest,
): Promise<any> {
let resp: any = customHandler && (await customHandler(request));
if (resp == undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (resp == undefined) {
if (resp === undefined) {

Copy link
Member

@richvdh richvdh Jan 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be quite nice to stick the whole body of this if condition into a separate handleRequest(ourOlmMachine, theirOlmMachine) function.

resp = { failures: {} };
}
}
if (!(request instanceof RustSdkCryptoJs.UploadSigningKeysRequest) && request.id) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can spell this more succinctly as

Suggested change
if (!(request instanceof RustSdkCryptoJs.UploadSigningKeysRequest) && request.id) {
if (request.id) {

but maybe that upsets typescript?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, TypeScript gets upset about that

@uhoreg uhoreg added this pull request to the merge queue Jan 29, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 29, 2024
@uhoreg uhoreg added this pull request to the merge queue Jan 30, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 30, 2024
@uhoreg uhoreg added this pull request to the merge queue Jan 31, 2024
Merged via the queue into matrix-org:develop with commit 8007bc5 Jan 31, 2024
20 checks passed
@uhoreg uhoreg deleted the verification_tie_breaking branch January 31, 2024 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Element-R: Verification gets stuck if both users hit "verify by emoji"
3 participants