1mod pk_signing;
16
17use std::sync::{
18 Arc,
19 atomic::{AtomicBool, Ordering},
20};
21
22pub use pk_signing::{MasterSigning, PickledSignings, SelfSigning, SigningError, UserSigning};
23use ruma::{
24 DeviceKeyAlgorithm, DeviceKeyId, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, UserId,
25 api::client::keys::upload_signatures::v3::{Request as SignatureUploadRequest, SignedKeys},
26 events::secret::request::SecretName,
27};
28use serde::{Deserialize, Serialize};
29use tokio::sync::Mutex;
30use vodozemac::Ed25519Signature;
31
32use super::StaticAccountData;
33#[cfg(feature = "experimental-x509-identity-verification")]
34use crate::x509::X509Signer;
35use crate::{
36 Account, DeviceData, OtherUserIdentityData, OwnUserIdentity, OwnUserIdentityData,
37 error::SignatureError,
38 store::SecretImportError,
39 types::{
40 CrossSigningKey, DeviceKeys, MasterPubkey, SelfSigningPubkey, UserSigningPubkey,
41 requests::UploadSigningKeysRequest,
42 },
43};
44
45#[derive(Clone, Debug)]
55pub struct PrivateCrossSigningIdentity {
56 user_id: OwnedUserId,
57 shared: Arc<AtomicBool>,
58 pub(crate) master_key: Arc<Mutex<Option<MasterSigning>>>,
59 pub(crate) user_signing_key: Arc<Mutex<Option<UserSigning>>>,
60 pub(crate) self_signing_key: Arc<Mutex<Option<SelfSigning>>>,
61}
62
63#[derive(Debug, Clone)]
66pub struct DiffResult {
67 master_differs: bool,
69 self_signing_differs: bool,
71 user_signing_differs: bool,
73}
74
75impl DiffResult {
76 pub fn any_differ(&self) -> bool {
78 self.master_differs || self.self_signing_differs || self.user_signing_differs
79 }
80
81 pub fn none_differ(&self) -> bool {
83 !self.master_differs && !self.self_signing_differs && !self.user_signing_differs
84 }
85}
86
87#[derive(Serialize, Deserialize)]
91#[allow(missing_debug_implementations)]
92pub struct PickledCrossSigningIdentity {
93 pub user_id: OwnedUserId,
95 pub shared: bool,
97 pub keys: PickledSignings,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct CrossSigningStatus {
105 pub has_master: bool,
107 pub has_self_signing: bool,
110 pub has_user_signing: bool,
113}
114
115impl CrossSigningStatus {
116 pub fn is_complete(&self) -> bool {
118 self.has_master && self.has_user_signing && self.has_self_signing
119 }
120}
121
122impl PrivateCrossSigningIdentity {
123 pub fn user_id(&self) -> &UserId {
125 &self.user_id
126 }
127
128 pub async fn is_empty(&self) -> bool {
138 let has_master = self.master_key.lock().await.is_some();
139 let has_user = self.user_signing_key.lock().await.is_some();
140 let has_self = self.self_signing_key.lock().await.is_some();
141
142 !(has_master && has_user && has_self)
143 }
144
145 pub async fn master_key_id(&self) -> Option<OwnedDeviceKeyId> {
147 let master_key = self.master_public_key().await?.get_first_key()?.to_base64();
148 let master_key = OwnedDeviceId::from(master_key);
149
150 Some(DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, &master_key))
151 }
152
153 pub async fn can_sign_devices(&self) -> bool {
155 self.self_signing_key.lock().await.is_some()
156 }
157
158 pub async fn can_sign_users(&self) -> bool {
160 self.user_signing_key.lock().await.is_some()
161 }
162
163 pub async fn has_master_key(&self) -> bool {
165 self.master_key.lock().await.is_some()
166 }
167
168 pub async fn status(&self) -> CrossSigningStatus {
171 CrossSigningStatus {
172 has_master: self.has_master_key().await,
173 has_self_signing: self.can_sign_devices().await,
174 has_user_signing: self.can_sign_users().await,
175 }
176 }
177
178 pub async fn master_public_key(&self) -> Option<MasterPubkey> {
180 self.master_key.lock().await.as_ref().map(|m| m.public_key().to_owned())
181 }
182
183 pub async fn self_signing_public_key(&self) -> Option<SelfSigningPubkey> {
185 self.self_signing_key.lock().await.as_ref().map(|k| k.public_key().to_owned())
186 }
187
188 pub async fn user_signing_public_key(&self) -> Option<UserSigningPubkey> {
190 self.user_signing_key.lock().await.as_ref().map(|k| k.public_key().to_owned())
191 }
192
193 pub async fn export_secret(&self, secret_name: &SecretName) -> Option<String> {
202 match secret_name {
203 SecretName::CrossSigningMasterKey => {
204 self.master_key.lock().await.as_ref().map(|m| m.export_seed())
205 }
206 SecretName::CrossSigningUserSigningKey => {
207 self.user_signing_key.lock().await.as_ref().map(|m| m.export_seed())
208 }
209 SecretName::CrossSigningSelfSigningKey => {
210 self.self_signing_key.lock().await.as_ref().map(|m| m.export_seed())
211 }
212 _ => None,
213 }
214 }
215
216 pub(crate) async fn import_secret(
217 &self,
218 public_identity: OwnUserIdentity,
219 secret_name: &SecretName,
220 seed: &str,
221 ) -> Result<(), SecretImportError> {
222 let (master, self_signing, user_signing) = match secret_name {
223 SecretName::CrossSigningMasterKey => (Some(seed), None, None),
224 SecretName::CrossSigningSelfSigningKey => (None, Some(seed), None),
225 SecretName::CrossSigningUserSigningKey => (None, None, Some(seed)),
226 _ => return Ok(()),
227 };
228
229 self.import_secrets(public_identity, master, self_signing, user_signing).await
230 }
231
232 pub(crate) async fn import_secrets(
233 &self,
234 public_identity: OwnUserIdentity,
235 master_key: Option<&str>,
236 self_signing_key: Option<&str>,
237 user_signing_key: Option<&str>,
238 ) -> Result<(), SecretImportError> {
239 let master = if let Some(master_key) = master_key {
240 let master =
241 MasterSigning::from_base64(self.user_id().to_owned(), master_key).map_err(|e| {
242 SecretImportError::Key { name: SecretName::CrossSigningMasterKey, error: e }
243 })?;
244
245 if public_identity.master_key() == master.public_key() {
246 Some(master)
247 } else {
248 return Err(SecretImportError::MismatchedPublicKeys {
249 name: SecretName::CrossSigningMasterKey,
250 });
251 }
252 } else {
253 None
254 };
255
256 let user_signing = if let Some(user_signing_key) = user_signing_key {
257 let subkey = UserSigning::from_base64(self.user_id().to_owned(), user_signing_key)
258 .map_err(|e| SecretImportError::Key {
259 name: SecretName::CrossSigningUserSigningKey,
260 error: e,
261 })?;
262
263 if public_identity.user_signing_key() == subkey.public_key() {
264 Ok(Some(subkey))
265 } else {
266 Err(SecretImportError::MismatchedPublicKeys {
267 name: SecretName::CrossSigningUserSigningKey,
268 })
269 }
270 } else {
271 Ok(None)
272 }?;
273
274 let self_signing = if let Some(self_signing_key) = self_signing_key {
275 let subkey = SelfSigning::from_base64(self.user_id().to_owned(), self_signing_key)
276 .map_err(|e| SecretImportError::Key {
277 name: SecretName::CrossSigningSelfSigningKey,
278 error: e,
279 })?;
280
281 if public_identity.self_signing_key() == subkey.public_key() {
282 Ok(Some(subkey))
283 } else {
284 Err(SecretImportError::MismatchedPublicKeys {
285 name: SecretName::CrossSigningSelfSigningKey,
286 })
287 }
288 } else {
289 Ok(None)
290 }?;
291
292 if let Some(master) = master {
293 *self.master_key.lock().await = Some(master);
294 }
295
296 if let Some(self_signing) = self_signing {
297 *self.self_signing_key.lock().await = Some(self_signing);
298 }
299
300 if let Some(user_signing) = user_signing {
301 *self.user_signing_key.lock().await = Some(user_signing);
302 }
303
304 Ok(())
305 }
306
307 pub async fn import_secrets_unchecked(
315 &self,
316 master_key: Option<&str>,
317 self_signing_key: Option<&str>,
318 user_signing_key: Option<&str>,
319 ) -> Result<(), SecretImportError> {
320 if let Some(master_key) = master_key {
321 let master =
322 MasterSigning::from_base64(self.user_id().to_owned(), master_key).map_err(|e| {
323 SecretImportError::Key { name: SecretName::CrossSigningMasterKey, error: e }
324 })?;
325 *self.master_key.lock().await = Some(master);
326 }
327
328 if let Some(user_signing_key) = user_signing_key {
329 let subkey = UserSigning::from_base64(self.user_id().to_owned(), user_signing_key)
330 .map_err(|e| SecretImportError::Key {
331 name: SecretName::CrossSigningUserSigningKey,
332 error: e,
333 })?;
334 *self.user_signing_key.lock().await = Some(subkey);
335 }
336
337 if let Some(self_signing_key) = self_signing_key {
338 let subkey = SelfSigning::from_base64(self.user_id().to_owned(), self_signing_key)
339 .map_err(|e| SecretImportError::Key {
340 name: SecretName::CrossSigningSelfSigningKey,
341 error: e,
342 })?;
343 *self.self_signing_key.lock().await = Some(subkey);
344 }
345
346 Ok(())
347 }
348
349 pub(crate) async fn clear_if_differs(
352 &self,
353 public_identity: &OwnUserIdentityData,
354 ) -> DiffResult {
355 let result = self.get_public_identity_diff(public_identity).await;
356
357 if result.master_differs {
358 *self.master_key.lock().await = None;
359 }
360
361 if result.user_signing_differs {
362 *self.user_signing_key.lock().await = None;
363 }
364
365 if result.self_signing_differs {
366 *self.self_signing_key.lock().await = None;
367 }
368
369 result
370 }
371
372 pub(crate) async fn get_public_identity_diff(
373 &self,
374 public_identity: &OwnUserIdentityData,
375 ) -> DiffResult {
376 let master_differs = self
377 .master_public_key()
378 .await
379 .is_some_and(|master| &master != public_identity.master_key());
380
381 let user_signing_differs = self
382 .user_signing_public_key()
383 .await
384 .is_some_and(|subkey| &subkey != public_identity.user_signing_key());
385
386 let self_signing_differs = self
387 .self_signing_public_key()
388 .await
389 .is_some_and(|subkey| &subkey != public_identity.self_signing_key());
390
391 DiffResult { master_differs, user_signing_differs, self_signing_differs }
392 }
393
394 pub(crate) async fn get_missing_secrets(&self) -> Vec<SecretName> {
396 let mut missing = Vec::new();
397
398 if !self.has_master_key().await {
399 missing.push(SecretName::CrossSigningMasterKey);
400 }
401
402 if !self.can_sign_devices().await {
403 missing.push(SecretName::CrossSigningSelfSigningKey);
404 }
405
406 if !self.can_sign_users().await {
407 missing.push(SecretName::CrossSigningUserSigningKey);
408 }
409
410 missing
411 }
412
413 pub fn empty(user_id: &UserId) -> Self {
415 Self {
416 user_id: user_id.into(),
417 shared: Arc::new(AtomicBool::new(false)),
418 master_key: Arc::new(Mutex::new(None)),
419 self_signing_key: Arc::new(Mutex::new(None)),
420 user_signing_key: Arc::new(Mutex::new(None)),
421 }
422 }
423
424 async fn public_keys(
425 &self,
426 ) -> Result<(MasterPubkey, SelfSigningPubkey, UserSigningPubkey), SignatureError> {
427 let master_private_key = self.master_key.lock().await;
428 let master_private_key =
429 master_private_key.as_ref().ok_or(SignatureError::MissingSigningKey)?;
430 let self_signing_private_key = self.self_signing_key.lock().await;
431 let self_signing_private_key =
432 self_signing_private_key.as_ref().ok_or(SignatureError::MissingSigningKey)?;
433 let user_signing_private_key = self.user_signing_key.lock().await;
434 let user_signing_private_key =
435 user_signing_private_key.as_ref().ok_or(SignatureError::MissingSigningKey)?;
436
437 let mut master = master_private_key.public_key().to_owned();
438 let mut self_signing = self_signing_private_key.public_key().to_owned();
439 let mut user_signing = user_signing_private_key.public_key().to_owned();
440
441 master_private_key.sign_subkey(master.as_mut());
442 master_private_key.sign_subkey(self_signing.as_mut());
443 master_private_key.sign_subkey(user_signing.as_mut());
444
445 Ok((master, self_signing, user_signing))
446 }
447
448 pub(crate) async fn to_public_identity(&self) -> Result<OwnUserIdentityData, SignatureError> {
449 let (master, self_signing, user_signing) = self.public_keys().await?;
450
451 let identity = OwnUserIdentityData::new(master, self_signing, user_signing)?;
452 identity.mark_as_verified();
453
454 Ok(identity)
455 }
456
457 pub(crate) async fn sign_user(
459 &self,
460 user_identity: &OtherUserIdentityData,
461 ) -> Result<SignatureUploadRequest, SignatureError> {
462 let master_key = self
463 .user_signing_key
464 .lock()
465 .await
466 .as_ref()
467 .ok_or(SignatureError::MissingSigningKey)?
468 .sign_user(user_identity)?;
469
470 let mut user_signed_keys = SignedKeys::new();
471 user_signed_keys.add_cross_signing_keys(
472 user_identity
473 .master_key()
474 .get_first_key()
475 .ok_or(SignatureError::MissingSigningKey)?
476 .to_base64()
477 .into(),
478 master_key.to_raw(),
479 );
480
481 let signed_keys = [(user_identity.user_id().to_owned(), user_signed_keys)].into();
482 Ok(SignatureUploadRequest::new(signed_keys))
483 }
484
485 pub(crate) async fn sign_device(
487 &self,
488 device: &DeviceData,
489 ) -> Result<SignatureUploadRequest, SignatureError> {
490 let mut device_keys = device.as_device_keys().to_owned();
491 device_keys.signatures.clear();
492 self.sign_device_keys(&mut device_keys).await
493 }
494
495 pub(crate) async fn sign_account(
497 &self,
498 account: &StaticAccountData,
499 ) -> Result<SignatureUploadRequest, SignatureError> {
500 let mut device_keys = account.unsigned_device_keys();
501 self.sign_device_keys(&mut device_keys).await
502 }
503
504 pub(crate) async fn sign_device_keys(
505 &self,
506 device_keys: &mut DeviceKeys,
507 ) -> Result<SignatureUploadRequest, SignatureError> {
508 self.self_signing_key
509 .lock()
510 .await
511 .as_ref()
512 .ok_or(SignatureError::MissingSigningKey)?
513 .sign_device(device_keys)?;
514
515 let mut user_signed_keys = SignedKeys::new();
516 user_signed_keys.add_device_keys(device_keys.device_id.clone(), device_keys.to_raw());
517
518 let signed_keys = [(self.user_id.clone(), user_signed_keys)].into();
519 Ok(SignatureUploadRequest::new(signed_keys))
520 }
521
522 pub(crate) async fn sign(&self, message: &str) -> Result<Ed25519Signature, SignatureError> {
523 Ok(self
524 .master_key
525 .lock()
526 .await
527 .as_ref()
528 .ok_or(SignatureError::MissingSigningKey)?
529 .sign(message))
530 }
531
532 fn new_helper(user_id: &UserId, master: MasterSigning) -> Self {
533 let (user, self_signing) = master.new_subkeys();
534
535 Self {
536 user_id: user_id.into(),
537 shared: Arc::new(AtomicBool::new(false)),
538 master_key: Arc::new(Mutex::new(Some(master))),
539 self_signing_key: Arc::new(Mutex::new(Some(self_signing))),
540 user_signing_key: Arc::new(Mutex::new(Some(user))),
541 }
542 }
543
544 #[cfg(any(test, feature = "testing"))]
547 #[allow(dead_code)]
548 pub fn new(user_id: OwnedUserId) -> Self {
549 let master = MasterSigning::new(user_id.to_owned());
550 Self::new_helper(&user_id, master)
551 }
552
553 #[allow(clippy::unused_async, reason = "async is needed for x509")]
570 pub(crate) async fn for_account(
571 account: &Account,
572 #[cfg(feature = "experimental-x509-identity-verification")] x509_signer: Option<
573 &X509Signer,
574 >,
575 ) -> Result<PrivateCrossSigningIdentity, SignatureError> {
576 let mut master = MasterSigning::new(account.user_id().into());
577
578 let cross_signing_key: &mut CrossSigningKey = &mut *master.public_key_mut().as_mut();
582
583 account.sign_cross_signing_key(cross_signing_key)?;
584
585 #[cfg(feature = "experimental-x509-identity-verification")]
586 if let Some(x509_signer) = x509_signer {
587 x509_signer.sign_cross_signing_key(&account.user_id, cross_signing_key).await?;
588 }
589
590 Ok(Self::new_helper(account.user_id(), master))
591 }
592
593 #[cfg(any(test, feature = "testing"))]
594 #[allow(dead_code)]
595 pub fn reset(&mut self) {
598 let new = Self::new(self.user_id().to_owned());
599 *self = new
600 }
601
602 pub fn mark_as_shared(&self) {
604 self.shared.store(true, Ordering::SeqCst)
605 }
606
607 pub fn shared(&self) -> bool {
612 self.shared.load(Ordering::SeqCst)
613 }
614
615 pub async fn pickle(&self) -> PickledCrossSigningIdentity {
626 let master_key = self.master_key.lock().await.as_ref().map(|m| m.pickle());
627
628 let self_signing_key = self.self_signing_key.lock().await.as_ref().map(|m| m.pickle());
629
630 let user_signing_key = self.user_signing_key.lock().await.as_ref().map(|m| m.pickle());
631
632 let keys = PickledSignings { master_key, user_signing_key, self_signing_key };
633
634 PickledCrossSigningIdentity { user_id: self.user_id.clone(), shared: self.shared(), keys }
635 }
636
637 pub fn from_pickle(pickle: PickledCrossSigningIdentity) -> Result<Self, SigningError> {
643 let keys = pickle.keys;
644
645 let master = keys.master_key.map(MasterSigning::from_pickle).transpose()?;
646 let self_signing = keys.self_signing_key.map(SelfSigning::from_pickle).transpose()?;
647 let user_signing = keys.user_signing_key.map(UserSigning::from_pickle).transpose()?;
648
649 Ok(Self {
650 user_id: pickle.user_id.clone(),
651 shared: Arc::new(AtomicBool::from(pickle.shared)),
652 master_key: Arc::new(Mutex::new(master)),
653 self_signing_key: Arc::new(Mutex::new(self_signing)),
654 user_signing_key: Arc::new(Mutex::new(user_signing)),
655 })
656 }
657
658 pub(crate) async fn as_upload_request(&self) -> UploadSigningKeysRequest {
661 let master_key =
662 self.master_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
663
664 let user_signing_key =
665 self.user_signing_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
666
667 let self_signing_key =
668 self.self_signing_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
669
670 UploadSigningKeysRequest { master_key, self_signing_key, user_signing_key }
671 }
672}
673
674#[cfg(test)]
675mod tests {
676 use std::sync::Arc;
677
678 use matrix_sdk_test::async_test;
679 use ruma::{CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, UserId, device_id, user_id};
680 use serde_json::json;
681
682 use super::{PrivateCrossSigningIdentity, pk_signing::Signing};
683 use crate::{
684 identities::{DeviceData, OtherUserIdentityData},
685 olm::{Account, SignedJsonObject, VerifyJson},
686 types::Signatures,
687 };
688
689 fn user_id() -> &'static UserId {
690 user_id!("@example:localhost")
691 }
692
693 #[test]
694 fn test_signature_verification() {
695 let signing = Signing::new();
696 let user_id = user_id();
697 let key_id = DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, "DEVICEID".into());
698
699 let json = json!({
700 "hello": "world"
701 });
702
703 let canonicalized: CanonicalJsonValue = json.try_into().unwrap();
704 let canonicalized = canonicalized.to_string();
705
706 let signature = signing.sign(&canonicalized);
707 let mut signatures = Signatures::new();
708 signatures.add_signature(user_id.to_owned(), key_id.clone(), signature);
709
710 let public_key = signing.public_key();
711
712 public_key
713 .verify_canonicalized_json(user_id, &key_id, &signatures, &canonicalized)
714 .expect("The signature can be verified");
715 }
716
717 #[test]
718 fn test_pickling_signing() {
719 let signing = Signing::new();
720 let pickled = signing.pickle();
721
722 let unpickled = Signing::from_pickle(pickled).unwrap();
723
724 assert_eq!(signing.public_key(), unpickled.public_key());
725 }
726
727 #[async_test]
728 async fn test_private_identity_creation() {
729 let identity = PrivateCrossSigningIdentity::new(user_id().to_owned());
730
731 let master_key = identity.master_key.lock().await;
732 let master_key = master_key.as_ref().unwrap();
733
734 master_key
735 .public_key()
736 .verify_subkey(identity.self_signing_key.lock().await.as_ref().unwrap().public_key())
737 .unwrap();
738
739 master_key
740 .public_key()
741 .verify_subkey(identity.user_signing_key.lock().await.as_ref().unwrap().public_key())
742 .unwrap();
743 }
744
745 #[async_test]
746 async fn test_identity_pickling() {
747 let identity = PrivateCrossSigningIdentity::new(user_id().to_owned());
748
749 let pickled = identity.pickle().await;
750
751 let unpickled = PrivateCrossSigningIdentity::from_pickle(pickled).unwrap();
752
753 assert_eq!(identity.user_id, unpickled.user_id);
754 assert_eq!(&*identity.master_key.lock().await, &*unpickled.master_key.lock().await);
755 assert_eq!(
756 &*identity.user_signing_key.lock().await,
757 &*unpickled.user_signing_key.lock().await
758 );
759 assert_eq!(
760 &*identity.self_signing_key.lock().await,
761 &*unpickled.self_signing_key.lock().await
762 );
763 }
764
765 #[async_test]
766 async fn test_private_identity_signed_by_account() {
767 let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
768 let identity = PrivateCrossSigningIdentity::for_account(
769 &account,
770 #[cfg(feature = "experimental-x509-identity-verification")]
771 None,
772 )
773 .await
774 .unwrap();
775 let master = identity.master_key.lock().await;
776 let master = master.as_ref().unwrap();
777
778 let public_key = master.public_key().as_ref();
779 let signatures = &public_key.signatures;
780 let canonical_json = public_key.to_canonical_json().unwrap();
781
782 account
783 .has_signed_raw(signatures, &canonical_json)
784 .expect("The account should have signed the master key");
785
786 master
787 .public_key()
788 .has_signed_raw(signatures, &canonical_json)
789 .expect("The master key should have self-signed");
790
791 assert!(!master.public_key().signatures().is_empty());
792 }
793
794 #[cfg(feature = "experimental-x509-identity-verification")]
795 #[async_test]
796 async fn test_private_identity_signed_by_x509() {
797 use crate::x509::tests::create_rust_signer_and_verifier;
798
799 let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
800 let (cert, signing_key) =
801 crate::x509::tests::cert_and_key_with_email_in_subject_distinguished_name(
802 "example@localhost",
803 );
804
805 let (x509_signer, x509_verifier) = create_rust_signer_and_verifier(cert, signing_key);
806
807 let identity =
809 PrivateCrossSigningIdentity::for_account(&account, Some(&x509_signer)).await.unwrap();
810 let master = identity.master_key.lock().await;
811 let master = master.as_ref().unwrap();
812
813 let public_key = master.public_key().as_ref();
814
815 assert!(x509_verifier.verify_signed_object(user_id(), public_key));
817 }
818
819 #[async_test]
820 async fn test_sign_device() {
821 let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
822 let identity = PrivateCrossSigningIdentity::for_account(
823 &account,
824 #[cfg(feature = "experimental-x509-identity-verification")]
825 None,
826 )
827 .await
828 .unwrap();
829
830 let mut device = DeviceData::from_account(&account);
831 let self_signing = identity.self_signing_key.lock().await;
832 let self_signing = self_signing.as_ref().unwrap();
833
834 let mut device_keys = device.as_device_keys().to_owned();
835 self_signing.sign_device(&mut device_keys).unwrap();
836 device.update_device(&device_keys).unwrap();
837
838 let public_key = &self_signing.public_key();
839 public_key.verify_device(&device).unwrap()
840 }
841
842 #[async_test]
843 async fn test_sign_user_identity() {
844 let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
845 let identity = PrivateCrossSigningIdentity::for_account(
846 &account,
847 #[cfg(feature = "experimental-x509-identity-verification")]
848 None,
849 )
850 .await
851 .unwrap();
852
853 let bob_account =
854 Account::with_device_id(user_id!("@bob:localhost"), device_id!("DEVICEID"));
855 let bob_private = PrivateCrossSigningIdentity::for_account(
856 &bob_account,
857 #[cfg(feature = "experimental-x509-identity-verification")]
858 None,
859 )
860 .await
861 .unwrap();
862 let mut bob_public = OtherUserIdentityData::from_private(&bob_private).await;
863
864 let user_signing = identity.user_signing_key.lock().await;
865 let user_signing = user_signing.as_ref().unwrap();
866
867 let master = user_signing.sign_user(&bob_public).unwrap();
868
869 assert_eq!(
870 master.signatures.signature_count(),
871 1,
872 "We're only uploading our own signature"
873 );
874
875 bob_public.master_key = Arc::new(master.try_into().unwrap());
876
877 user_signing.public_key().verify_master_key(bob_public.master_key()).unwrap();
878 }
879}