matrix_sdk_crypto/olm/signing/
mod.rs

1// Copyright 2020 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15mod pk_signing;
16
17use std::sync::{
18    atomic::{AtomicBool, Ordering},
19    Arc,
20};
21
22pub use pk_signing::{MasterSigning, PickledSignings, SelfSigning, SigningError, UserSigning};
23use ruma::{
24    api::client::keys::upload_signatures::v3::{Request as SignatureUploadRequest, SignedKeys},
25    events::secret::request::SecretName,
26    DeviceKeyAlgorithm, DeviceKeyId, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, UserId,
27};
28use serde::{Deserialize, Serialize};
29use tokio::sync::Mutex;
30use vodozemac::Ed25519Signature;
31
32use super::StaticAccountData;
33use crate::{
34    error::SignatureError,
35    store::SecretImportError,
36    types::{
37        requests::UploadSigningKeysRequest, DeviceKeys, MasterPubkey, SelfSigningPubkey,
38        UserSigningPubkey,
39    },
40    Account, DeviceData, OtherUserIdentityData, OwnUserIdentity, OwnUserIdentityData,
41};
42
43/// Private cross signing identity.
44///
45/// This object holds the private and public ed25519 key triplet that is used
46/// for cross signing.
47///
48/// The object might be completely empty or have only some of the key pairs
49/// available.
50///
51/// It can be used to sign devices or other identities.
52#[derive(Clone, Debug)]
53pub struct PrivateCrossSigningIdentity {
54    user_id: OwnedUserId,
55    shared: Arc<AtomicBool>,
56    pub(crate) master_key: Arc<Mutex<Option<MasterSigning>>>,
57    pub(crate) user_signing_key: Arc<Mutex<Option<UserSigning>>>,
58    pub(crate) self_signing_key: Arc<Mutex<Option<SelfSigning>>>,
59}
60
61/// A struct containing information on whether any of our cross-signing keys
62/// differ from the public keys that exist on the server.
63#[derive(Debug, Clone)]
64pub struct DiffResult {
65    /// Does the master key differ?
66    master_differs: bool,
67    /// Does the self-signing key differ?
68    self_signing_differs: bool,
69    /// Does the user-signing key differ?
70    user_signing_differs: bool,
71}
72
73impl DiffResult {
74    /// Do any of the cross-signing keys differ?
75    pub fn any_differ(&self) -> bool {
76        self.master_differs || self.self_signing_differs || self.user_signing_differs
77    }
78
79    /// Do none of the cross-signing keys differ?
80    pub fn none_differ(&self) -> bool {
81        !self.master_differs && !self.self_signing_differs && !self.user_signing_differs
82    }
83}
84
85/// The pickled version of a `PrivateCrossSigningIdentity`.
86///
87/// Can be used to store the identity.
88#[derive(Serialize, Deserialize)]
89#[allow(missing_debug_implementations)]
90pub struct PickledCrossSigningIdentity {
91    /// The user id of the identity owner.
92    pub user_id: OwnedUserId,
93    /// Have the public keys of the identity been shared.
94    pub shared: bool,
95    /// The pickled signing keys
96    pub keys: PickledSignings,
97}
98
99/// Struct representing the state of our private cross signing keys, it shows
100/// which private cross signing keys we have locally stored.
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct CrossSigningStatus {
103    /// Do we have the master key.
104    pub has_master: bool,
105    /// Do we have the self signing key, this one is necessary to sign our own
106    /// devices.
107    pub has_self_signing: bool,
108    /// Do we have the user signing key, this one is necessary to sign other
109    /// users.
110    pub has_user_signing: bool,
111}
112
113impl CrossSigningStatus {
114    /// Do we have all the cross signing keys locally stored.
115    pub fn is_complete(&self) -> bool {
116        self.has_master && self.has_user_signing && self.has_self_signing
117    }
118}
119
120impl PrivateCrossSigningIdentity {
121    /// Get the user id that this identity belongs to.
122    pub fn user_id(&self) -> &UserId {
123        &self.user_id
124    }
125
126    /// Is the identity empty.
127    ///
128    /// An empty identity doesn't contain any private keys.
129    ///
130    /// It is usual for the identity not to contain the master key since the
131    /// master key is only needed to sign the subkeys.
132    ///
133    /// An empty identity indicates that either no identity was created for this
134    /// use or that another device created it and hasn't shared it yet with us.
135    pub async fn is_empty(&self) -> bool {
136        let has_master = self.master_key.lock().await.is_some();
137        let has_user = self.user_signing_key.lock().await.is_some();
138        let has_self = self.self_signing_key.lock().await.is_some();
139
140        !(has_master && has_user && has_self)
141    }
142
143    /// Get the key ID of the master key.
144    pub async fn master_key_id(&self) -> Option<OwnedDeviceKeyId> {
145        let master_key = self.master_public_key().await?.get_first_key()?.to_base64();
146        let master_key = OwnedDeviceId::from(master_key);
147
148        Some(DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, &master_key))
149    }
150
151    /// Can we sign our own devices, i.e. do we have a self signing key.
152    pub async fn can_sign_devices(&self) -> bool {
153        self.self_signing_key.lock().await.is_some()
154    }
155
156    /// Can we sign other users, i.e. do we have a user signing key.
157    pub async fn can_sign_users(&self) -> bool {
158        self.user_signing_key.lock().await.is_some()
159    }
160
161    /// Do we have the master key.
162    pub async fn has_master_key(&self) -> bool {
163        self.master_key.lock().await.is_some()
164    }
165
166    /// Get the status of our private cross signing keys, i.e. if we have the
167    /// master key and the subkeys.
168    pub async fn status(&self) -> CrossSigningStatus {
169        CrossSigningStatus {
170            has_master: self.has_master_key().await,
171            has_self_signing: self.can_sign_devices().await,
172            has_user_signing: self.can_sign_users().await,
173        }
174    }
175
176    /// Get the public part of the master key, if we have one.
177    pub async fn master_public_key(&self) -> Option<MasterPubkey> {
178        self.master_key.lock().await.as_ref().map(|m| m.public_key().to_owned())
179    }
180
181    /// Get the public part of the self-signing key, if we have one.
182    pub async fn self_signing_public_key(&self) -> Option<SelfSigningPubkey> {
183        self.self_signing_key.lock().await.as_ref().map(|k| k.public_key().to_owned())
184    }
185
186    /// Get the public part of the user-signing key, if we have one.
187    pub async fn user_signing_public_key(&self) -> Option<UserSigningPubkey> {
188        self.user_signing_key.lock().await.as_ref().map(|k| k.public_key().to_owned())
189    }
190
191    /// Export the seed of the private cross signing key
192    ///
193    /// The exported seed will be encoded as unpadded base64.
194    ///
195    /// # Arguments
196    ///
197    /// * `secret_name` - The type of the cross signing key that should be
198    ///   exported.
199    pub async fn export_secret(&self, secret_name: &SecretName) -> Option<String> {
200        match secret_name {
201            SecretName::CrossSigningMasterKey => {
202                self.master_key.lock().await.as_ref().map(|m| m.export_seed())
203            }
204            SecretName::CrossSigningUserSigningKey => {
205                self.user_signing_key.lock().await.as_ref().map(|m| m.export_seed())
206            }
207            SecretName::CrossSigningSelfSigningKey => {
208                self.self_signing_key.lock().await.as_ref().map(|m| m.export_seed())
209            }
210            _ => None,
211        }
212    }
213
214    pub(crate) async fn import_secret(
215        &self,
216        public_identity: OwnUserIdentity,
217        secret_name: &SecretName,
218        seed: &str,
219    ) -> Result<(), SecretImportError> {
220        let (master, self_signing, user_signing) = match secret_name {
221            SecretName::CrossSigningMasterKey => (Some(seed), None, None),
222            SecretName::CrossSigningSelfSigningKey => (None, Some(seed), None),
223            SecretName::CrossSigningUserSigningKey => (None, None, Some(seed)),
224            _ => return Ok(()),
225        };
226
227        self.import_secrets(public_identity, master, self_signing, user_signing).await
228    }
229
230    pub(crate) async fn import_secrets(
231        &self,
232        public_identity: OwnUserIdentity,
233        master_key: Option<&str>,
234        self_signing_key: Option<&str>,
235        user_signing_key: Option<&str>,
236    ) -> Result<(), SecretImportError> {
237        let master = if let Some(master_key) = master_key {
238            let master =
239                MasterSigning::from_base64(self.user_id().to_owned(), master_key).map_err(|e| {
240                    SecretImportError::Key { name: SecretName::CrossSigningMasterKey, error: e }
241                })?;
242
243            if public_identity.master_key() == master.public_key() {
244                Some(master)
245            } else {
246                return Err(SecretImportError::MismatchedPublicKeys {
247                    name: SecretName::CrossSigningMasterKey,
248                });
249            }
250        } else {
251            None
252        };
253
254        let user_signing = if let Some(user_signing_key) = user_signing_key {
255            let subkey = UserSigning::from_base64(self.user_id().to_owned(), user_signing_key)
256                .map_err(|e| SecretImportError::Key {
257                    name: SecretName::CrossSigningUserSigningKey,
258                    error: e,
259                })?;
260
261            if public_identity.user_signing_key() == subkey.public_key() {
262                Ok(Some(subkey))
263            } else {
264                Err(SecretImportError::MismatchedPublicKeys {
265                    name: SecretName::CrossSigningUserSigningKey,
266                })
267            }
268        } else {
269            Ok(None)
270        }?;
271
272        let self_signing = if let Some(self_signing_key) = self_signing_key {
273            let subkey = SelfSigning::from_base64(self.user_id().to_owned(), self_signing_key)
274                .map_err(|e| SecretImportError::Key {
275                    name: SecretName::CrossSigningSelfSigningKey,
276                    error: e,
277                })?;
278
279            if public_identity.self_signing_key() == subkey.public_key() {
280                Ok(Some(subkey))
281            } else {
282                Err(SecretImportError::MismatchedPublicKeys {
283                    name: SecretName::CrossSigningSelfSigningKey,
284                })
285            }
286        } else {
287            Ok(None)
288        }?;
289
290        if let Some(master) = master {
291            *self.master_key.lock().await = Some(master);
292        }
293
294        if let Some(self_signing) = self_signing {
295            *self.self_signing_key.lock().await = Some(self_signing);
296        }
297
298        if let Some(user_signing) = user_signing {
299            *self.user_signing_key.lock().await = Some(user_signing);
300        }
301
302        Ok(())
303    }
304
305    /// Import the private parts of the cross signing keys into this identity.
306    ///
307    /// The private parts should be unexpanded Ed25519 keys encoded as a base64
308    /// string.
309    ///
310    /// *Note*: This method won't check if the public keys match the public
311    /// keys present on the server.
312    pub async fn import_secrets_unchecked(
313        &self,
314        master_key: Option<&str>,
315        self_signing_key: Option<&str>,
316        user_signing_key: Option<&str>,
317    ) -> Result<(), SecretImportError> {
318        if let Some(master_key) = master_key {
319            let master =
320                MasterSigning::from_base64(self.user_id().to_owned(), master_key).map_err(|e| {
321                    SecretImportError::Key { name: SecretName::CrossSigningMasterKey, error: e }
322                })?;
323            *self.master_key.lock().await = Some(master);
324        }
325
326        if let Some(user_signing_key) = user_signing_key {
327            let subkey = UserSigning::from_base64(self.user_id().to_owned(), user_signing_key)
328                .map_err(|e| SecretImportError::Key {
329                    name: SecretName::CrossSigningUserSigningKey,
330                    error: e,
331                })?;
332            *self.user_signing_key.lock().await = Some(subkey);
333        }
334
335        if let Some(self_signing_key) = self_signing_key {
336            let subkey = SelfSigning::from_base64(self.user_id().to_owned(), self_signing_key)
337                .map_err(|e| SecretImportError::Key {
338                    name: SecretName::CrossSigningSelfSigningKey,
339                    error: e,
340                })?;
341            *self.self_signing_key.lock().await = Some(subkey);
342        }
343
344        Ok(())
345    }
346
347    /// Remove our private cross signing key if the public keys differ from
348    /// what's found in the [`OwnUserIdentityData`].
349    pub(crate) async fn clear_if_differs(
350        &self,
351        public_identity: &OwnUserIdentityData,
352    ) -> DiffResult {
353        let result = self.get_public_identity_diff(public_identity).await;
354
355        if result.master_differs {
356            *self.master_key.lock().await = None;
357        }
358
359        if result.user_signing_differs {
360            *self.user_signing_key.lock().await = None;
361        }
362
363        if result.self_signing_differs {
364            *self.self_signing_key.lock().await = None;
365        }
366
367        result
368    }
369
370    pub(crate) async fn get_public_identity_diff(
371        &self,
372        public_identity: &OwnUserIdentityData,
373    ) -> DiffResult {
374        let master_differs = self
375            .master_public_key()
376            .await
377            .is_some_and(|master| &master != public_identity.master_key());
378
379        let user_signing_differs = self
380            .user_signing_public_key()
381            .await
382            .is_some_and(|subkey| &subkey != public_identity.user_signing_key());
383
384        let self_signing_differs = self
385            .self_signing_public_key()
386            .await
387            .is_some_and(|subkey| &subkey != public_identity.self_signing_key());
388
389        DiffResult { master_differs, user_signing_differs, self_signing_differs }
390    }
391
392    /// Get the names of the secrets we are missing.
393    pub(crate) async fn get_missing_secrets(&self) -> Vec<SecretName> {
394        let mut missing = Vec::new();
395
396        if !self.has_master_key().await {
397            missing.push(SecretName::CrossSigningMasterKey);
398        }
399
400        if !self.can_sign_devices().await {
401            missing.push(SecretName::CrossSigningSelfSigningKey);
402        }
403
404        if !self.can_sign_users().await {
405            missing.push(SecretName::CrossSigningUserSigningKey);
406        }
407
408        missing
409    }
410
411    /// Create a new empty identity.
412    pub fn empty(user_id: &UserId) -> Self {
413        Self {
414            user_id: user_id.into(),
415            shared: Arc::new(AtomicBool::new(false)),
416            master_key: Arc::new(Mutex::new(None)),
417            self_signing_key: Arc::new(Mutex::new(None)),
418            user_signing_key: Arc::new(Mutex::new(None)),
419        }
420    }
421
422    async fn public_keys(
423        &self,
424    ) -> Result<(MasterPubkey, SelfSigningPubkey, UserSigningPubkey), SignatureError> {
425        let master_private_key = self.master_key.lock().await;
426        let master_private_key =
427            master_private_key.as_ref().ok_or(SignatureError::MissingSigningKey)?;
428        let self_signing_private_key = self.self_signing_key.lock().await;
429        let self_signing_private_key =
430            self_signing_private_key.as_ref().ok_or(SignatureError::MissingSigningKey)?;
431        let user_signing_private_key = self.user_signing_key.lock().await;
432        let user_signing_private_key =
433            user_signing_private_key.as_ref().ok_or(SignatureError::MissingSigningKey)?;
434
435        let mut master = master_private_key.public_key().to_owned();
436        let mut self_signing = self_signing_private_key.public_key().to_owned();
437        let mut user_signing = user_signing_private_key.public_key().to_owned();
438
439        master_private_key.sign_subkey(master.as_mut());
440        master_private_key.sign_subkey(self_signing.as_mut());
441        master_private_key.sign_subkey(user_signing.as_mut());
442
443        Ok((master, self_signing, user_signing))
444    }
445
446    pub(crate) async fn to_public_identity(&self) -> Result<OwnUserIdentityData, SignatureError> {
447        let (master, self_signing, user_signing) = self.public_keys().await?;
448
449        let identity = OwnUserIdentityData::new(master, self_signing, user_signing)?;
450        identity.mark_as_verified();
451
452        Ok(identity)
453    }
454
455    /// Sign the given public user identity with this private identity.
456    pub(crate) async fn sign_user(
457        &self,
458        user_identity: &OtherUserIdentityData,
459    ) -> Result<SignatureUploadRequest, SignatureError> {
460        let master_key = self
461            .user_signing_key
462            .lock()
463            .await
464            .as_ref()
465            .ok_or(SignatureError::MissingSigningKey)?
466            .sign_user(user_identity)?;
467
468        let mut user_signed_keys = SignedKeys::new();
469        user_signed_keys.add_cross_signing_keys(
470            user_identity
471                .master_key()
472                .get_first_key()
473                .ok_or(SignatureError::MissingSigningKey)?
474                .to_base64()
475                .into(),
476            master_key.to_raw(),
477        );
478
479        let signed_keys = [(user_identity.user_id().to_owned(), user_signed_keys)].into();
480        Ok(SignatureUploadRequest::new(signed_keys))
481    }
482
483    /// Sign the given device keys with this identity.
484    pub(crate) async fn sign_device(
485        &self,
486        device: &DeviceData,
487    ) -> Result<SignatureUploadRequest, SignatureError> {
488        let mut device_keys = device.as_device_keys().to_owned();
489        device_keys.signatures.clear();
490        self.sign_device_keys(&mut device_keys).await
491    }
492
493    /// Sign an Olm account with this private identity.
494    pub(crate) async fn sign_account(
495        &self,
496        account: &StaticAccountData,
497    ) -> Result<SignatureUploadRequest, SignatureError> {
498        let mut device_keys = account.unsigned_device_keys();
499        self.sign_device_keys(&mut device_keys).await
500    }
501
502    pub(crate) async fn sign_device_keys(
503        &self,
504        device_keys: &mut DeviceKeys,
505    ) -> Result<SignatureUploadRequest, SignatureError> {
506        self.self_signing_key
507            .lock()
508            .await
509            .as_ref()
510            .ok_or(SignatureError::MissingSigningKey)?
511            .sign_device(device_keys)?;
512
513        let mut user_signed_keys = SignedKeys::new();
514        user_signed_keys.add_device_keys(device_keys.device_id.clone(), device_keys.to_raw());
515
516        let signed_keys = [((*self.user_id).to_owned(), user_signed_keys)].into();
517        Ok(SignatureUploadRequest::new(signed_keys))
518    }
519
520    pub(crate) async fn sign(&self, message: &str) -> Result<Ed25519Signature, SignatureError> {
521        Ok(self
522            .master_key
523            .lock()
524            .await
525            .as_ref()
526            .ok_or(SignatureError::MissingSigningKey)?
527            .sign(message))
528    }
529
530    fn new_helper(user_id: &UserId, master: MasterSigning) -> Self {
531        let (user, self_signing) = master.new_subkeys();
532
533        Self {
534            user_id: user_id.into(),
535            shared: Arc::new(AtomicBool::new(false)),
536            master_key: Arc::new(Mutex::new(Some(master))),
537            self_signing_key: Arc::new(Mutex::new(Some(self_signing))),
538            user_signing_key: Arc::new(Mutex::new(Some(user))),
539        }
540    }
541
542    /// Create a new cross signing identity without signing the device that
543    /// created it.
544    #[cfg(any(test, feature = "testing"))]
545    #[allow(dead_code)]
546    pub fn new(user_id: OwnedUserId) -> Self {
547        let master = MasterSigning::new(user_id.to_owned());
548        Self::new_helper(&user_id, master)
549    }
550
551    /**
552     * Create a new private identity, suitable for the given [`Account`].
553     *
554     * The identity will be created with a fresh set of cross-signing keys.
555     * The master key will be signed by the `OlmAccount` (i.e. the device).
556     * The user-signing and self-signing keys will be signed by the
557     * master key.
558     *
559     * Note that after creating a new identity, the device will need to be
560     * signed by the self-signing key. This can be done via
561     * [`PrivateCrossSigningIdentity::sign_account`].
562     *
563     * # Arguments
564     *
565     * * `account` - The Olm account that is creating the new identity.
566     */
567    pub(crate) fn for_account(account: &Account) -> PrivateCrossSigningIdentity {
568        let mut master = MasterSigning::new(account.user_id().into());
569
570        account
571            .sign_cross_signing_key(master.public_key_mut().as_mut())
572            .expect("Can't sign our freshly created master key with our account");
573
574        Self::new_helper(account.user_id(), master)
575    }
576
577    #[cfg(any(test, feature = "testing"))]
578    #[allow(dead_code)]
579    /// Testing helper to reset this CrossSigning with a fresh one using the
580    /// local identity
581    pub fn reset(&mut self) {
582        let new = Self::new(self.user_id().to_owned());
583        *self = new
584    }
585
586    /// Mark the identity as shared.
587    pub fn mark_as_shared(&self) {
588        self.shared.store(true, Ordering::SeqCst)
589    }
590
591    /// Has the identity been shared.
592    ///
593    /// A shared identity here means that the public keys of the identity have
594    /// been uploaded to the server.
595    pub fn shared(&self) -> bool {
596        self.shared.load(Ordering::SeqCst)
597    }
598
599    /// Store the cross signing identity as a pickle.
600    ///
601    /// # Arguments
602    ///
603    /// * `pickle_key` - The key that should be used to encrypt the signing
604    ///   object, must be 32 bytes long.
605    ///
606    /// # Panics
607    ///
608    /// This will panic if the provided pickle key isn't 32 bytes long.
609    pub async fn pickle(&self) -> PickledCrossSigningIdentity {
610        let master_key = self.master_key.lock().await.as_ref().map(|m| m.pickle());
611
612        let self_signing_key = self.self_signing_key.lock().await.as_ref().map(|m| m.pickle());
613
614        let user_signing_key = self.user_signing_key.lock().await.as_ref().map(|m| m.pickle());
615
616        let keys = PickledSignings { master_key, user_signing_key, self_signing_key };
617
618        PickledCrossSigningIdentity { user_id: self.user_id.clone(), shared: self.shared(), keys }
619    }
620
621    /// Restore the private cross signing identity from a pickle.
622    ///
623    /// # Panic
624    ///
625    /// Panics if the pickle_key isn't 32 bytes long.
626    pub fn from_pickle(pickle: PickledCrossSigningIdentity) -> Result<Self, SigningError> {
627        let keys = pickle.keys;
628
629        let master = keys.master_key.map(MasterSigning::from_pickle).transpose()?;
630        let self_signing = keys.self_signing_key.map(SelfSigning::from_pickle).transpose()?;
631        let user_signing = keys.user_signing_key.map(UserSigning::from_pickle).transpose()?;
632
633        Ok(Self {
634            user_id: (*pickle.user_id).into(),
635            shared: Arc::new(AtomicBool::from(pickle.shared)),
636            master_key: Arc::new(Mutex::new(master)),
637            self_signing_key: Arc::new(Mutex::new(self_signing)),
638            user_signing_key: Arc::new(Mutex::new(user_signing)),
639        })
640    }
641
642    /// Get the upload request that is needed to share the public keys of this
643    /// identity.
644    pub(crate) async fn as_upload_request(&self) -> UploadSigningKeysRequest {
645        let master_key =
646            self.master_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
647
648        let user_signing_key =
649            self.user_signing_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
650
651        let self_signing_key =
652            self.self_signing_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
653
654        UploadSigningKeysRequest { master_key, self_signing_key, user_signing_key }
655    }
656}
657
658#[cfg(test)]
659mod tests {
660    use std::sync::Arc;
661
662    use matrix_sdk_test::async_test;
663    use ruma::{device_id, user_id, CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, UserId};
664    use serde_json::json;
665
666    use super::{pk_signing::Signing, PrivateCrossSigningIdentity};
667    use crate::{
668        identities::{DeviceData, OtherUserIdentityData},
669        olm::{Account, SignedJsonObject, VerifyJson},
670        types::Signatures,
671    };
672
673    fn user_id() -> &'static UserId {
674        user_id!("@example:localhost")
675    }
676
677    #[test]
678    fn test_signature_verification() {
679        let signing = Signing::new();
680        let user_id = user_id();
681        let key_id = DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, "DEVICEID".into());
682
683        let json = json!({
684            "hello": "world"
685        });
686
687        let canonicalized: CanonicalJsonValue = json.try_into().unwrap();
688        let canonicalized = canonicalized.to_string();
689
690        let signature = signing.sign(&canonicalized);
691        let mut signatures = Signatures::new();
692        signatures.add_signature(user_id.to_owned(), key_id.clone(), signature);
693
694        let public_key = signing.public_key();
695
696        public_key
697            .verify_canonicalized_json(user_id, &key_id, &signatures, &canonicalized)
698            .expect("The signature can be verified");
699    }
700
701    #[test]
702    fn test_pickling_signing() {
703        let signing = Signing::new();
704        let pickled = signing.pickle();
705
706        let unpickled = Signing::from_pickle(pickled).unwrap();
707
708        assert_eq!(signing.public_key(), unpickled.public_key());
709    }
710
711    #[async_test]
712    async fn test_private_identity_creation() {
713        let identity = PrivateCrossSigningIdentity::new(user_id().to_owned());
714
715        let master_key = identity.master_key.lock().await;
716        let master_key = master_key.as_ref().unwrap();
717
718        master_key
719            .public_key()
720            .verify_subkey(identity.self_signing_key.lock().await.as_ref().unwrap().public_key())
721            .unwrap();
722
723        master_key
724            .public_key()
725            .verify_subkey(identity.user_signing_key.lock().await.as_ref().unwrap().public_key())
726            .unwrap();
727    }
728
729    #[async_test]
730    async fn test_identity_pickling() {
731        let identity = PrivateCrossSigningIdentity::new(user_id().to_owned());
732
733        let pickled = identity.pickle().await;
734
735        let unpickled = PrivateCrossSigningIdentity::from_pickle(pickled).unwrap();
736
737        assert_eq!(identity.user_id, unpickled.user_id);
738        assert_eq!(&*identity.master_key.lock().await, &*unpickled.master_key.lock().await);
739        assert_eq!(
740            &*identity.user_signing_key.lock().await,
741            &*unpickled.user_signing_key.lock().await
742        );
743        assert_eq!(
744            &*identity.self_signing_key.lock().await,
745            &*unpickled.self_signing_key.lock().await
746        );
747    }
748
749    #[async_test]
750    async fn test_private_identity_signed_by_account() {
751        let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
752        let identity = PrivateCrossSigningIdentity::for_account(&account);
753        let master = identity.master_key.lock().await;
754        let master = master.as_ref().unwrap();
755
756        let public_key = master.public_key().as_ref();
757        let signatures = &public_key.signatures;
758        let canonical_json = public_key.to_canonical_json().unwrap();
759
760        account
761            .has_signed_raw(signatures, &canonical_json)
762            .expect("The account should have signed the master key");
763
764        master
765            .public_key()
766            .has_signed_raw(signatures, &canonical_json)
767            .expect("The master key should have self-signed");
768
769        assert!(!master.public_key().signatures().is_empty());
770    }
771
772    #[async_test]
773    async fn test_sign_device() {
774        let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
775        let identity = PrivateCrossSigningIdentity::for_account(&account);
776
777        let mut device = DeviceData::from_account(&account);
778        let self_signing = identity.self_signing_key.lock().await;
779        let self_signing = self_signing.as_ref().unwrap();
780
781        let mut device_keys = device.as_device_keys().to_owned();
782        self_signing.sign_device(&mut device_keys).unwrap();
783        device.update_device(&device_keys).unwrap();
784
785        let public_key = &self_signing.public_key();
786        public_key.verify_device(&device).unwrap()
787    }
788
789    #[async_test]
790    async fn test_sign_user_identity() {
791        let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
792        let identity = PrivateCrossSigningIdentity::for_account(&account);
793
794        let bob_account =
795            Account::with_device_id(user_id!("@bob:localhost"), device_id!("DEVICEID"));
796        let bob_private = PrivateCrossSigningIdentity::for_account(&bob_account);
797        let mut bob_public = OtherUserIdentityData::from_private(&bob_private).await;
798
799        let user_signing = identity.user_signing_key.lock().await;
800        let user_signing = user_signing.as_ref().unwrap();
801
802        let master = user_signing.sign_user(&bob_public).unwrap();
803
804        assert_eq!(
805            master.signatures.signature_count(),
806            1,
807            "We're only uploading our own signature"
808        );
809
810        bob_public.master_key = Arc::new(master.try_into().unwrap());
811
812        user_signing.public_key().verify_master_key(bob_public.master_key()).unwrap();
813    }
814}