@@ -1476,6 +1476,42 @@ async def check_cross_signing_setup(self, user_id: str) -> Tuple[bool, bool]:
14761476 else :
14771477 return exists , self .clock .time_msec () < ts_replacable_without_uia_before
14781478
1479+ async def has_different_keys (self , user_id : str , body : JsonDict ) -> bool :
1480+ """
1481+ Check if a key provided in `body` differs from the same key stored in the DB. Returns
1482+ true on the first difference. If a key exists in `body` but does not exist in the DB,
1483+ returns True. If `body` has no keys, this always returns False.
1484+ Note by 'key' we mean Matrix key rather than JSON key.
1485+
1486+ The purpose of this function is to detect whether or not we need to apply UIA checks.
1487+ We must apply UIA checks if any key in the database is being overwritten. If a key is
1488+ being inserted for the first time, or if the key exactly matches what is in the database,
1489+ then no UIA check needs to be performed.
1490+
1491+ Args:
1492+ user_id: The user who sent the `body`.
1493+ body: The JSON request body from POST /keys/device_signing/upload
1494+ Returns:
1495+ True if any key in `body` has a different value in the database.
1496+ """
1497+ # Ensure that each key provided in the request body exactly matches the one we have stored.
1498+ # The first time we see the DB having a different key to the matching request key, bail.
1499+ # Note: we do not care if the DB has a key which the request does not specify, as we only
1500+ # care about *replacements* or *insertions* (i.e UPSERT)
1501+ req_body_key_to_db_key = {
1502+ "master_key" : "master" ,
1503+ "self_signing_key" : "self_signing" ,
1504+ "user_signing_key" : "user_signing" ,
1505+ }
1506+ for req_body_key , db_key in req_body_key_to_db_key .items ():
1507+ if req_body_key in body :
1508+ existing_key = await self .store .get_e2e_cross_signing_key (
1509+ user_id , db_key
1510+ )
1511+ if existing_key != body [req_body_key ]:
1512+ return True
1513+ return False
1514+
14791515
14801516def _check_cross_signing_key (
14811517 key : JsonDict , user_id : str , key_type : str , signing_key : Optional [VerifyKey ] = None
0 commit comments