@@ -754,27 +754,73 @@ async def _process_received_pdu(
754
754
# if we don't then we mark the device cache for that user as stale.
755
755
if event .type == EventTypes .Encrypted :
756
756
device_id = event .content .get ("device_id" )
757
+ sender_key = event .content .get ("sender_key" )
758
+
759
+ cached_devices = await self .store .get_cached_devices_for_user (event .sender )
760
+
761
+ resync = False # Whether we should resync device lists.
762
+
763
+ device = None
757
764
if device_id is not None :
758
- cached_devices = await self .store .get_cached_devices_for_user (
759
- event .sender
760
- )
761
- if device_id not in cached_devices :
765
+ device = cached_devices .get (device_id )
766
+ if device is None :
762
767
logger .info (
763
768
"Received event from remote device not in our cache: %s %s" ,
764
769
event .sender ,
765
770
device_id ,
766
771
)
767
- await self .store .mark_remote_user_device_cache_as_stale (
768
- event .sender
772
+ resync = True
773
+
774
+ # We also check if the `sender_key` matches what we expect.
775
+ if sender_key is not None :
776
+ # Figure out what sender key we're expecting. If we know the
777
+ # device and recognize the algorithm then we can work out the
778
+ # exact key to expect. Otherwise check it matches any key we
779
+ # have for that device.
780
+ if device :
781
+ keys = device .get ("keys" , {}).get ("keys" , {})
782
+
783
+ if event .content .get ("algorithm" ) == "m.megolm.v1.aes-sha2" :
784
+ # For this algorithm we expect a curve25519 key.
785
+ key_name = "curve25519:%s" % (device_id ,)
786
+ current_keys = [keys .get (key_name )]
787
+ else :
788
+ # We don't know understand the algorithm, so we just
789
+ # check it matches a key for the device.
790
+ current_keys = keys .values ()
791
+ elif device_id :
792
+ # We don't have any keys for the device ID.
793
+ current_keys = []
794
+ else :
795
+ # The event didn't include a device ID, so we just look for
796
+ # keys across all devices.
797
+ current_keys = (
798
+ key
799
+ for device in cached_devices
800
+ for key in device .get ("keys" , {}).get ("keys" , {}).values ()
769
801
)
770
802
771
- # Immediately attempt a resync in the background
772
- if self .config .worker_app :
773
- return run_in_background (self ._user_device_resync , event .sender )
774
- else :
775
- return run_in_background (
776
- self ._device_list_updater .user_device_resync , event .sender
777
- )
803
+ # We now check that the sender key matches (one of) the expected
804
+ # keys.
805
+ if sender_key not in current_keys :
806
+ logger .info (
807
+ "Received event from remote device with unexpected sender key: %s %s: %s" ,
808
+ event .sender ,
809
+ device_id or "<no device_id>" ,
810
+ sender_key ,
811
+ )
812
+ resync = True
813
+
814
+ if resync :
815
+ await self .store .mark_remote_user_device_cache_as_stale (event .sender )
816
+
817
+ # Immediately attempt a resync in the background
818
+ if self .config .worker_app :
819
+ return run_in_background (self ._user_device_resync , event .sender )
820
+ else :
821
+ return run_in_background (
822
+ self ._device_list_updater .user_device_resync , event .sender
823
+ )
778
824
779
825
@log_function
780
826
async def backfill (self , dest , room_id , limit , extremities ):
0 commit comments