@ -8,12 +8,7 @@ use ruma::{
@@ -8,12 +8,7 @@ use ruma::{
DeviceId , DeviceKeyAlgorithm , DeviceKeyId , MilliSecondsSinceUnixEpoch , RoomAliasId , UInt ,
UserId ,
} ;
use std ::{
collections ::BTreeMap ,
convert ::{ TryFrom , TryInto } ,
mem ,
sync ::Arc ,
} ;
use std ::{ collections ::BTreeMap , convert ::TryInto , mem , sync ::Arc } ;
use tracing ::warn ;
use super ::abstraction ::Tree ;
@ -364,7 +359,7 @@ impl Users {
@@ -364,7 +359,7 @@ impl Users {
user_id : & UserId ,
device_id : & DeviceId ,
one_time_key_key : & DeviceKeyId ,
one_time_key_value : & Raw < OneTimeKey > ,
one_time_key_value : & OneTimeKey ,
globals : & super ::globals ::Globals ,
) -> Result < ( ) > {
let mut key = user_id . as_bytes ( ) . to_vec ( ) ;
@ -414,7 +409,7 @@ impl Users {
@@ -414,7 +409,7 @@ impl Users {
device_id : & DeviceId ,
key_algorithm : & DeviceKeyAlgorithm ,
globals : & super ::globals ::Globals ,
) -> Result < Option < ( Box < DeviceKeyId > , Raw < OneTimeKey > ) > > {
) -> Result < Option < ( Box < DeviceKeyId > , OneTimeKey ) > > {
let mut prefix = user_id . as_bytes ( ) . to_vec ( ) ;
prefix . push ( 0xff ) ;
prefix . extend_from_slice ( device_id . as_bytes ( ) ) ;
@ -485,7 +480,7 @@ impl Users {
@@ -485,7 +480,7 @@ impl Users {
& self ,
user_id : & UserId ,
device_id : & DeviceId ,
device_keys : & Raw < DeviceKeys > ,
device_keys : & DeviceKeys ,
rooms : & super ::rooms ::Rooms ,
globals : & super ::globals ::Globals ,
) -> Result < ( ) > {
@ -514,9 +509,9 @@ impl Users {
@@ -514,9 +509,9 @@ impl Users {
pub fn add_cross_signing_keys (
& self ,
user_id : & UserId ,
master_key : & Raw < CrossSigningKey > ,
self_signing_key : & Option < Raw < CrossSigningKey > > ,
user_signing_key : & Option < Raw < CrossSigningKey > > ,
master_key : & CrossSigningKey ,
self_signing_key : & Option < CrossSigningKey > ,
user_signing_key : & Option < CrossSigningKey > ,
rooms : & super ::rooms ::Rooms ,
globals : & super ::globals ::Globals ,
) -> Result < ( ) > {
@ -526,12 +521,7 @@ impl Users {
@@ -526,12 +521,7 @@ impl Users {
prefix . push ( 0xff ) ;
// Master key
let master_key_map = master_key
. deserialize ( )
. map_err ( | _ | Error ::BadRequest ( ErrorKind ::InvalidParam , "Invalid master key" ) ) ?
. keys ;
let mut master_key_ids = master_key_map . values ( ) ;
let mut master_key_ids = master_key . keys . values ( ) ;
let master_key_id = master_key_ids . next ( ) . ok_or ( Error ::BadRequest (
ErrorKind ::InvalidParam ,
"Master key contained no key." ,
@ -547,21 +537,17 @@ impl Users {
@@ -547,21 +537,17 @@ impl Users {
let mut master_key_key = prefix . clone ( ) ;
master_key_key . extend_from_slice ( master_key_id . as_bytes ( ) ) ;
self . keyid_key
. insert ( & master_key_key , master_key . json ( ) . get ( ) . as_bytes ( ) ) ? ;
self . keyid_key . insert (
& master_key_key ,
& serde_json ::to_vec ( & master_key ) . expect ( "CrossSigningKey::to_vec always works" ) ,
) ? ;
self . userid_masterkeyid
. insert ( user_id . as_bytes ( ) , & master_key_key ) ? ;
// Self-signing key
if let Some ( self_signing_key ) = self_signing_key {
let self_signing_key_map = self_signing_key
. deserialize ( )
. map_err ( | _ | {
Error ::BadRequest ( ErrorKind ::InvalidParam , "Invalid self signing key" )
} ) ?
. keys ;
let mut self_signing_key_ids = self_signing_key_map . values ( ) ;
let mut self_signing_key_ids = self_signing_key . keys . values ( ) ;
let self_signing_key_id = self_signing_key_ids . next ( ) . ok_or ( Error ::BadRequest (
ErrorKind ::InvalidParam ,
"Self signing key contained no key." ,
@ -579,7 +565,8 @@ impl Users {
@@ -579,7 +565,8 @@ impl Users {
self . keyid_key . insert (
& self_signing_key_key ,
self_signing_key . json ( ) . get ( ) . as_bytes ( ) ,
& serde_json ::to_vec ( & self_signing_key )
. expect ( "CrossSigningKey::to_vec always works" ) ,
) ? ;
self . userid_selfsigningkeyid
@ -588,13 +575,7 @@ impl Users {
@@ -588,13 +575,7 @@ impl Users {
// User-signing key
if let Some ( user_signing_key ) = user_signing_key {
let user_signing_key_map = user_signing_key
. deserialize ( )
. map_err ( | _ | {
Error ::BadRequest ( ErrorKind ::InvalidParam , "Invalid user signing key" )
} ) ?
. keys ;
let mut user_signing_key_ids = user_signing_key_map . values ( ) ;
let mut user_signing_key_ids = user_signing_key . keys . values ( ) ;
let user_signing_key_id = user_signing_key_ids . next ( ) . ok_or ( Error ::BadRequest (
ErrorKind ::InvalidParam ,
"User signing key contained no key." ,
@ -612,7 +593,8 @@ impl Users {
@@ -612,7 +593,8 @@ impl Users {
self . keyid_key . insert (
& user_signing_key_key ,
user_signing_key . json ( ) . get ( ) . as_bytes ( ) ,
& serde_json ::to_vec ( & user_signing_key )
. expect ( "CrossSigningKey::to_vec always works" ) ,
) ? ;
self . userid_usersigningkeyid
@ -745,7 +727,7 @@ impl Users {
@@ -745,7 +727,7 @@ impl Users {
& self ,
user_id : & UserId ,
device_id : & DeviceId ,
) -> Result < Option < Raw < DeviceKeys > > > {
) -> Result < Option < DeviceKeys > > {
let mut key = user_id . as_bytes ( ) . to_vec ( ) ;
key . push ( 0xff ) ;
key . extend_from_slice ( device_id . as_bytes ( ) ) ;
@ -762,19 +744,25 @@ impl Users {
@@ -762,19 +744,25 @@ impl Users {
& self ,
user_id : & UserId ,
allowed_signatures : F ,
) -> Result < Option < Raw < CrossSigningKey > > > {
) -> Result < Option < CrossSigningKey > > {
self . userid_masterkeyid
. get ( user_id . as_bytes ( ) ) ?
. map_or ( Ok ( None ) , | key | {
self . keyid_key . get ( & key ) ? . map_or ( Ok ( None ) , | bytes | {
let mut cross_signing_key = serde_json ::from_slice ::< serde_json ::Value > ( & bytes )
. map_err ( | _ | Error ::bad_database ( "CrossSigningKey in db is invalid." ) ) ? ;
clean_signatures ( & mut cross_signing_key , user_id , allowed_signatures ) ? ;
Ok ( Some ( Raw ::from_json (
serde_json ::value ::to_raw_value ( & cross_signing_key )
. expect ( "Value to RawValue serialization" ) ,
) ) )
let mut cross_signing_key = serde_json ::from_slice ::< CrossSigningKey > ( & bytes )
. map_err ( | _ | {
Error ::bad_database ( "CrossSigningKey in db is invalid." )
} ) ? ;
// A user is not allowed to see signatures from users other than himself and
// the target user
cross_signing_key . signatures = cross_signing_key
. signatures
. into_iter ( )
. filter ( | ( user , _ ) | allowed_signatures ( user ) )
. collect ( ) ;
Ok ( Some ( cross_signing_key ) )
} )
} )
}
@ -784,25 +772,31 @@ impl Users {
@@ -784,25 +772,31 @@ impl Users {
& self ,
user_id : & UserId ,
allowed_signatures : F ,
) -> Result < Option < Raw < CrossSigningKey > > > {
) -> Result < Option < CrossSigningKey > > {
self . userid_selfsigningkeyid
. get ( user_id . as_bytes ( ) ) ?
. map_or ( Ok ( None ) , | key | {
self . keyid_key . get ( & key ) ? . map_or ( Ok ( None ) , | bytes | {
let mut cross_signing_key = serde_json ::from_slice ::< serde_json ::Value > ( & bytes )
. map_err ( | _ | Error ::bad_database ( "CrossSigningKey in db is invalid." ) ) ? ;
clean_signatures ( & mut cross_signing_key , user_id , allowed_signatures ) ? ;
Ok ( Some ( Raw ::from_json (
serde_json ::value ::to_raw_value ( & cross_signing_key )
. expect ( "Value to RawValue serialization" ) ,
) ) )
let mut cross_signing_key = serde_json ::from_slice ::< CrossSigningKey > ( & bytes )
. map_err ( | _ | {
Error ::bad_database ( "CrossSigningKey in db is invalid." )
} ) ? ;
// A user is not allowed to see signatures from users other than himself and
// the target user
cross_signing_key . signatures = cross_signing_key
. signatures
. into_iter ( )
. filter ( | ( user , _ ) | user = = user_id | | allowed_signatures ( user ) )
. collect ( ) ;
Ok ( Some ( cross_signing_key ) )
} )
} )
}
#[ tracing::instrument(skip(self, user_id)) ]
pub fn get_user_signing_key ( & self , user_id : & UserId ) -> Result < Option < Raw < CrossSigningKey > > > {
pub fn get_user_signing_key ( & self , user_id : & UserId ) -> Result < Option < CrossSigningKey > > {
self . userid_usersigningkeyid
. get ( user_id . as_bytes ( ) ) ?
. map_or ( Ok ( None ) , | key | {
@ -997,30 +991,3 @@ impl Users {
@@ -997,30 +991,3 @@ impl Users {
Ok ( ( ) )
}
}
/// Ensure that a user only sees signatures from themselves and the target user
fn clean_signatures < F : Fn ( & UserId ) -> bool > (
cross_signing_key : & mut serde_json ::Value ,
user_id : & UserId ,
allowed_signatures : F ,
) -> Result < ( ) , Error > {
if let Some ( signatures ) = cross_signing_key
. get_mut ( "signatures" )
. and_then ( | v | v . as_object_mut ( ) )
{
// Don't allocate for the full size of the current signatures, but require
// at most one resize if nothing is dropped
let new_capacity = signatures . len ( ) / 2 ;
for ( user , signature ) in
mem ::replace ( signatures , serde_json ::Map ::with_capacity ( new_capacity ) )
{
let id = < & UserId > ::try_from ( user . as_str ( ) )
. map_err ( | _ | Error ::bad_database ( "Invalid user ID in database." ) ) ? ;
if id = = user_id | | allowed_signatures ( id ) {
signatures . insert ( user , signature ) ;
}
}
}
Ok ( ( ) )
}