fix(e2ee): scope public-key cache by mid to prevent cross-contact key mixups - #219
Open
nezumi0627 wants to merge 1 commit into
Open
fix(e2ee): scope public-key cache by mid to prevent cross-contact key mixups#219nezumi0627 wants to merge 1 commit into
nezumi0627 wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The per-user E2EE public key cache was keyed only by
keyId(e2eePublicKeys:${keyId}), not by mid.LINE E2EE key ids are small per-account counters — each account's first registered key typically gets id 1 or 2. With two or more E2EE-capable contacts, the cache slots collide:
negotiateE2EEPublicKeyoverwrote the shared slot, so two contacts with the same keyId continuously evicted each other's keys.This also masked itself on the send side:
encryptE2EEMessagecallsnegotiateE2EEPublicKeydirectly and never touches this cache.Fix
Cache key becomes
e2eePublicKeys:${mid}:${keyId}(read + write). Old keyId-only entries are simply never hit again and get re-negotiated once per contact — no migration needed.Also fixes a latent always-throw path in the same block: when callers omitted
keyId, negotiation succeeded butreceiverKeyId == undefinedwas always false, throwing`E2EE key id undefined not found…`and wasting an RPC. An omittedkeyIdnow means "accept whatever the server negotiated" (cached under its actual id).Testing
New
publickey_cache.test.ts:keyId: previously threwInternalError; now returns the negotiated key.Full suite:
deno test --allow-all— 216 passed, 0 failed.