diff options
author | Timo Kösters <timo@koesters.xyz> | 2023-07-16 16:50:03 +0200 |
---|---|---|
committer | Timo Kösters <timo@koesters.xyz> | 2023-07-16 16:50:03 +0200 |
commit | a9ba067e7758207d1411b24c537cf755608632e8 (patch) | |
tree | b081352e8f7e1cfad4ef096faf5d622d4a1ac881 /src/database | |
parent | 24402312c58855679ccfe58b0d3d27ae041b4336 (diff) | |
download | conduit-a9ba067e7758207d1411b24c537cf755608632e8.zip |
fix: e2ee over federation
Diffstat (limited to 'src/database')
-rw-r--r-- | src/database/key_value/users.rs | 100 |
1 files changed, 58 insertions, 42 deletions
diff --git a/src/database/key_value/users.rs b/src/database/key_value/users.rs index 359a072..0301cda 100644 --- a/src/database/key_value/users.rs +++ b/src/database/key_value/users.rs @@ -451,31 +451,10 @@ impl service::users::Data for KeyValueDatabase { user_signing_key: &Option<Raw<CrossSigningKey>>, ) -> Result<()> { // TODO: Check signatures - let mut prefix = user_id.as_bytes().to_vec(); prefix.push(0xff); - // Master key - let mut master_key_ids = master_key - .deserialize() - .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid master key"))? - .keys - .into_values(); - - let master_key_id = master_key_ids.next().ok_or(Error::BadRequest( - ErrorKind::InvalidParam, - "Master key contained no key.", - ))?; - - if master_key_ids.next().is_some() { - return Err(Error::BadRequest( - ErrorKind::InvalidParam, - "Master key contained more than one key.", - )); - } - - let mut master_key_key = prefix.clone(); - master_key_key.extend_from_slice(master_key_id.as_bytes()); + let (master_key_key, _) = self.parse_master_key(user_id, master_key)?; self.keyid_key .insert(&master_key_key, master_key.json().get().as_bytes())?; @@ -690,45 +669,80 @@ impl service::users::Data for KeyValueDatabase { }) } + fn parse_master_key( + &self, + user_id: &UserId, + master_key: &Raw<CrossSigningKey>, + ) -> Result<(Vec<u8>, CrossSigningKey)> { + let mut prefix = user_id.as_bytes().to_vec(); + prefix.push(0xff); + + let master_key = master_key + .deserialize() + .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid master key"))?; + 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.", + ))?; + if master_key_ids.next().is_some() { + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Master key contained more than one key.", + )); + } + let mut master_key_key = prefix.clone(); + master_key_key.extend_from_slice(master_key_id.as_bytes()); + Ok((master_key_key, master_key)) + } + + fn get_key( + &self, + key: &[u8], + sender_user: Option<&UserId>, + user_id: &UserId, + allowed_signatures: &dyn Fn(&UserId) -> bool, + ) -> Result<Option<Raw<CrossSigningKey>>> { + 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, + sender_user, + user_id, + allowed_signatures, + )?; + + Ok(Some(Raw::from_json( + serde_json::value::to_raw_value(&cross_signing_key) + .expect("Value to RawValue serialization"), + ))) + }) + } + fn get_master_key( &self, + sender_user: Option<&UserId>, user_id: &UserId, allowed_signatures: &dyn Fn(&UserId) -> bool, ) -> Result<Option<Raw<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"), - ))) - }) + self.get_key(&key, sender_user, user_id, allowed_signatures) }) } fn get_self_signing_key( &self, + sender_user: Option<&UserId>, user_id: &UserId, allowed_signatures: &dyn Fn(&UserId) -> bool, ) -> Result<Option<Raw<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"), - ))) - }) + self.get_key(&key, sender_user, user_id, allowed_signatures) }) } @@ -929,6 +943,8 @@ impl service::users::Data for KeyValueDatabase { } } +impl KeyValueDatabase {} + /// Will only return with Some(username) if the password was not empty and the /// username could be successfully parsed. /// If utils::string_from_bytes(...) returns an error that username will be skipped |