chore(crypto): Refactor the cross-signing key wrappers

Since the master/self-signing/user-signing public key types are used for
public user identities as well as for the private key type we have, and
we'd like to sign the public key types it makes sense that the types
itself aren't using an Arc.

Let's instead put the Arc inside the user identity structs.

This will allow us later on to more easily sign the public key types.
This commit is contained in:
Damir Jelić
2024-05-08 13:58:25 +02:00
parent aeb85ba836
commit 6b1ef484f2
6 changed files with 53 additions and 27 deletions

View File

@@ -148,7 +148,7 @@ impl OwnUserIdentity {
let cache = self.store.cache().await?;
let account = cache.account().await?;
account.sign_master_key(self.master_key.clone())
account.sign_master_key(&self.master_key)
}
/// Send a verification request to our other devices.
@@ -369,8 +369,8 @@ impl ReadOnlyUserIdentities {
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ReadOnlyUserIdentity {
user_id: OwnedUserId,
pub(crate) master_key: MasterPubkey,
self_signing_key: SelfSigningPubkey,
pub(crate) master_key: Arc<MasterPubkey>,
self_signing_key: Arc<SelfSigningPubkey>,
}
impl PartialEq for ReadOnlyUserIdentity {
@@ -411,14 +411,19 @@ impl ReadOnlyUserIdentity {
) -> Result<Self, SignatureError> {
master_key.verify_subkey(&self_signing_key)?;
Ok(Self { user_id: master_key.user_id().into(), master_key, self_signing_key })
Ok(Self {
user_id: master_key.user_id().into(),
master_key: master_key.into(),
self_signing_key: self_signing_key.into(),
})
}
#[cfg(test)]
pub(crate) async fn from_private(identity: &crate::olm::PrivateCrossSigningIdentity) -> Self {
let master_key = identity.master_key.lock().await.as_ref().unwrap().public_key.clone();
let master_key =
identity.master_key.lock().await.as_ref().unwrap().public_key.clone().into();
let self_signing_key =
identity.self_signing_key.lock().await.as_ref().unwrap().public_key.clone();
identity.self_signing_key.lock().await.as_ref().unwrap().public_key.clone().into();
Self { user_id: identity.user_id().into(), master_key, self_signing_key }
}
@@ -494,9 +499,9 @@ impl ReadOnlyUserIdentity {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReadOnlyOwnUserIdentity {
user_id: OwnedUserId,
master_key: MasterPubkey,
self_signing_key: SelfSigningPubkey,
user_signing_key: UserSigningPubkey,
master_key: Arc<MasterPubkey>,
self_signing_key: Arc<SelfSigningPubkey>,
user_signing_key: Arc<UserSigningPubkey>,
#[serde(
serialize_with = "atomic_bool_serializer",
deserialize_with = "atomic_bool_deserializer"
@@ -551,9 +556,9 @@ impl ReadOnlyOwnUserIdentity {
Ok(Self {
user_id: master_key.user_id().into(),
master_key,
self_signing_key,
user_signing_key,
master_key: master_key.into(),
self_signing_key: self_signing_key.into(),
user_signing_key: user_signing_key.into(),
verified: Arc::new(AtomicBool::new(false)),
})
}
@@ -568,9 +573,9 @@ impl ReadOnlyOwnUserIdentity {
Self {
user_id: identity.user_id().into(),
master_key,
self_signing_key,
user_signing_key,
master_key: master_key.into(),
self_signing_key: self_signing_key.into(),
user_signing_key: user_signing_key.into(),
verified: Arc::new(AtomicBool::new(false)),
}
}
@@ -672,14 +677,14 @@ impl ReadOnlyOwnUserIdentity {
let old = self.clone();
self.self_signing_key = self_signing_key;
self.user_signing_key = user_signing_key;
self.self_signing_key = self_signing_key.into();
self.user_signing_key = user_signing_key.into();
if self.master_key != master_key {
if self.master_key.as_ref() != &master_key {
self.verified.store(false, Ordering::SeqCst);
}
self.master_key = master_key;
self.master_key = master_key.into();
Ok(old != *self)
}

View File

@@ -785,7 +785,7 @@ impl Account {
/// Sign the given Master Key
pub fn sign_master_key(
&self,
master_key: MasterPubkey,
master_key: &MasterPubkey,
) -> Result<SignatureUploadRequest, SignatureError> {
let public_key =
master_key.get_first_key().ok_or(SignatureError::MissingSigningKey)?.to_base64().into();

View File

@@ -662,6 +662,8 @@ impl PrivateCrossSigningIdentity {
#[cfg(test)]
mod tests {
use std::sync::Arc;
use matrix_sdk_test::async_test;
use ruma::{device_id, user_id, CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, UserId};
use serde_json::json;
@@ -810,7 +812,7 @@ mod tests {
"We're only uploading our own signature"
);
bob_public.master_key = master.try_into().unwrap();
bob_public.master_key = Arc::new(master.try_into().unwrap());
user_signing.public_key.verify_master_key(bob_public.master_key()).unwrap();
}

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::{collections::btree_map::Iter, sync::Arc};
use std::collections::btree_map::Iter;
use ruma::{encryption::KeyUsage, DeviceKeyId, OwnedDeviceKeyId, UserId};
use serde::{Deserialize, Serialize};
@@ -31,7 +31,7 @@ use crate::{
/// user signing keys of an user will be signed by their master key.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(try_from = "CrossSigningKey")]
pub struct MasterPubkey(pub(super) Arc<CrossSigningKey>);
pub struct MasterPubkey(pub(super) CrossSigningKey);
impl MasterPubkey {
/// Get the user id of the master key's owner.
@@ -133,6 +133,12 @@ impl AsRef<CrossSigningKey> for MasterPubkey {
}
}
impl AsMut<CrossSigningKey> for MasterPubkey {
fn as_mut(&mut self) -> &mut CrossSigningKey {
&mut self.0
}
}
impl TryFrom<CrossSigningKey> for MasterPubkey {
type Error = serde_json::Error;

View File

@@ -1,4 +1,4 @@
use std::{collections::btree_map::Iter, sync::Arc};
use std::collections::btree_map::Iter;
use ruma::{encryption::KeyUsage, OwnedDeviceKeyId, UserId};
use serde::{Deserialize, Serialize};
@@ -15,7 +15,7 @@ use crate::{
/// Self signing keys are used to sign the user's own devices.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(try_from = "CrossSigningKey")]
pub struct SelfSigningPubkey(pub(super) Arc<CrossSigningKey>);
pub struct SelfSigningPubkey(pub(super) CrossSigningKey);
impl SelfSigningPubkey {
/// Get the user id of the self signing key's owner.
@@ -85,3 +85,9 @@ impl AsRef<CrossSigningKey> for SelfSigningPubkey {
&self.0
}
}
impl AsMut<CrossSigningKey> for SelfSigningPubkey {
fn as_mut(&mut self) -> &mut CrossSigningKey {
&mut self.0
}
}

View File

@@ -1,4 +1,4 @@
use std::{collections::btree_map::Iter, sync::Arc};
use std::collections::btree_map::Iter;
use ruma::{encryption::KeyUsage, OwnedDeviceKeyId, UserId};
use serde::{Deserialize, Serialize};
@@ -11,7 +11,7 @@ use crate::{olm::VerifyJson, types::SigningKeys, SignatureError};
/// User signing keys are used to sign the master keys of other users.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(try_from = "CrossSigningKey")]
pub struct UserSigningPubkey(pub(super) Arc<CrossSigningKey>);
pub struct UserSigningPubkey(pub(super) CrossSigningKey);
impl UserSigningPubkey {
/// Get the user id of the user signing key's owner.
@@ -73,8 +73,15 @@ impl TryFrom<CrossSigningKey> for UserSigningPubkey {
}
}
}
impl AsRef<CrossSigningKey> for UserSigningPubkey {
fn as_ref(&self) -> &CrossSigningKey {
&self.0
}
}
impl AsMut<CrossSigningKey> for UserSigningPubkey {
fn as_mut(&mut self) -> &mut CrossSigningKey {
&mut self.0
}
}