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 pub(crate) fn for_account(
570 account: &Account,
571 #[cfg(feature = "experimental-x509-identity-verification")] x509_signer: Option<
572 &X509Signer,
573 >,
574 ) -> Result<PrivateCrossSigningIdentity, SignatureError> {
575 let mut master = MasterSigning::new(account.user_id().into());
576
577 let cross_signing_key: &mut CrossSigningKey = &mut *master.public_key_mut().as_mut();
581
582 account.sign_cross_signing_key(cross_signing_key)?;
583
584 #[cfg(feature = "experimental-x509-identity-verification")]
585 if let Some(x509_signer) = x509_signer {
586 x509_signer.sign_cross_signing_key(&account.user_id, cross_signing_key)?;
587 }
588
589 Ok(Self::new_helper(account.user_id(), master))
590 }
591
592 #[cfg(any(test, feature = "testing"))]
593 #[allow(dead_code)]
594 pub fn reset(&mut self) {
597 let new = Self::new(self.user_id().to_owned());
598 *self = new
599 }
600
601 pub fn mark_as_shared(&self) {
603 self.shared.store(true, Ordering::SeqCst)
604 }
605
606 pub fn shared(&self) -> bool {
611 self.shared.load(Ordering::SeqCst)
612 }
613
614 pub async fn pickle(&self) -> PickledCrossSigningIdentity {
625 let master_key = self.master_key.lock().await.as_ref().map(|m| m.pickle());
626
627 let self_signing_key = self.self_signing_key.lock().await.as_ref().map(|m| m.pickle());
628
629 let user_signing_key = self.user_signing_key.lock().await.as_ref().map(|m| m.pickle());
630
631 let keys = PickledSignings { master_key, user_signing_key, self_signing_key };
632
633 PickledCrossSigningIdentity { user_id: self.user_id.clone(), shared: self.shared(), keys }
634 }
635
636 pub fn from_pickle(pickle: PickledCrossSigningIdentity) -> Result<Self, SigningError> {
642 let keys = pickle.keys;
643
644 let master = keys.master_key.map(MasterSigning::from_pickle).transpose()?;
645 let self_signing = keys.self_signing_key.map(SelfSigning::from_pickle).transpose()?;
646 let user_signing = keys.user_signing_key.map(UserSigning::from_pickle).transpose()?;
647
648 Ok(Self {
649 user_id: pickle.user_id.clone(),
650 shared: Arc::new(AtomicBool::from(pickle.shared)),
651 master_key: Arc::new(Mutex::new(master)),
652 self_signing_key: Arc::new(Mutex::new(self_signing)),
653 user_signing_key: Arc::new(Mutex::new(user_signing)),
654 })
655 }
656
657 pub(crate) async fn as_upload_request(&self) -> UploadSigningKeysRequest {
660 let master_key =
661 self.master_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
662
663 let user_signing_key =
664 self.user_signing_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
665
666 let self_signing_key =
667 self.self_signing_key.lock().await.as_ref().map(|k| k.public_key().as_ref().clone());
668
669 UploadSigningKeysRequest { master_key, self_signing_key, user_signing_key }
670 }
671}
672
673#[cfg(test)]
674mod tests {
675 use std::sync::Arc;
676
677 use matrix_sdk_test::async_test;
678 use ruma::{CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, UserId, device_id, user_id};
679 use serde_json::json;
680
681 use super::{PrivateCrossSigningIdentity, pk_signing::Signing};
682 use crate::{
683 identities::{DeviceData, OtherUserIdentityData},
684 olm::{Account, SignedJsonObject, VerifyJson},
685 types::Signatures,
686 };
687
688 fn user_id() -> &'static UserId {
689 user_id!("@example:localhost")
690 }
691
692 #[test]
693 fn test_signature_verification() {
694 let signing = Signing::new();
695 let user_id = user_id();
696 let key_id = DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, "DEVICEID".into());
697
698 let json = json!({
699 "hello": "world"
700 });
701
702 let canonicalized: CanonicalJsonValue = json.try_into().unwrap();
703 let canonicalized = canonicalized.to_string();
704
705 let signature = signing.sign(&canonicalized);
706 let mut signatures = Signatures::new();
707 signatures.add_signature(user_id.to_owned(), key_id.clone(), signature);
708
709 let public_key = signing.public_key();
710
711 public_key
712 .verify_canonicalized_json(user_id, &key_id, &signatures, &canonicalized)
713 .expect("The signature can be verified");
714 }
715
716 #[test]
717 fn test_pickling_signing() {
718 let signing = Signing::new();
719 let pickled = signing.pickle();
720
721 let unpickled = Signing::from_pickle(pickled).unwrap();
722
723 assert_eq!(signing.public_key(), unpickled.public_key());
724 }
725
726 #[async_test]
727 async fn test_private_identity_creation() {
728 let identity = PrivateCrossSigningIdentity::new(user_id().to_owned());
729
730 let master_key = identity.master_key.lock().await;
731 let master_key = master_key.as_ref().unwrap();
732
733 master_key
734 .public_key()
735 .verify_subkey(identity.self_signing_key.lock().await.as_ref().unwrap().public_key())
736 .unwrap();
737
738 master_key
739 .public_key()
740 .verify_subkey(identity.user_signing_key.lock().await.as_ref().unwrap().public_key())
741 .unwrap();
742 }
743
744 #[async_test]
745 async fn test_identity_pickling() {
746 let identity = PrivateCrossSigningIdentity::new(user_id().to_owned());
747
748 let pickled = identity.pickle().await;
749
750 let unpickled = PrivateCrossSigningIdentity::from_pickle(pickled).unwrap();
751
752 assert_eq!(identity.user_id, unpickled.user_id);
753 assert_eq!(&*identity.master_key.lock().await, &*unpickled.master_key.lock().await);
754 assert_eq!(
755 &*identity.user_signing_key.lock().await,
756 &*unpickled.user_signing_key.lock().await
757 );
758 assert_eq!(
759 &*identity.self_signing_key.lock().await,
760 &*unpickled.self_signing_key.lock().await
761 );
762 }
763
764 #[async_test]
765 async fn test_private_identity_signed_by_account() {
766 let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
767 let identity = PrivateCrossSigningIdentity::for_account(
768 &account,
769 #[cfg(feature = "experimental-x509-identity-verification")]
770 None,
771 )
772 .unwrap();
773 let master = identity.master_key.lock().await;
774 let master = master.as_ref().unwrap();
775
776 let public_key = master.public_key().as_ref();
777 let signatures = &public_key.signatures;
778 let canonical_json = public_key.to_canonical_json().unwrap();
779
780 account
781 .has_signed_raw(signatures, &canonical_json)
782 .expect("The account should have signed the master key");
783
784 master
785 .public_key()
786 .has_signed_raw(signatures, &canonical_json)
787 .expect("The master key should have self-signed");
788
789 assert!(!master.public_key().signatures().is_empty());
790 }
791
792 #[cfg(feature = "experimental-x509-identity-verification")]
793 #[async_test]
794 async fn test_private_identity_signed_by_x509() {
795 use crate::x509::tests::create_rust_signer_and_verifier;
796
797 let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
798 let (cert, signing_key) =
799 crate::x509::tests::cert_and_key_with_email_in_subject_distinguished_name(
800 "example@localhost",
801 );
802
803 let (x509_signer, x509_verifier) = create_rust_signer_and_verifier(cert, signing_key);
804
805 let identity =
807 PrivateCrossSigningIdentity::for_account(&account, Some(&x509_signer)).unwrap();
808 let master = identity.master_key.lock().await;
809 let master = master.as_ref().unwrap();
810
811 let public_key = master.public_key().as_ref();
812
813 assert!(x509_verifier.verify_signed_object(user_id(), public_key));
815 }
816
817 #[async_test]
818 async fn test_sign_device() {
819 let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
820 let identity = PrivateCrossSigningIdentity::for_account(
821 &account,
822 #[cfg(feature = "experimental-x509-identity-verification")]
823 None,
824 )
825 .unwrap();
826
827 let mut device = DeviceData::from_account(&account);
828 let self_signing = identity.self_signing_key.lock().await;
829 let self_signing = self_signing.as_ref().unwrap();
830
831 let mut device_keys = device.as_device_keys().to_owned();
832 self_signing.sign_device(&mut device_keys).unwrap();
833 device.update_device(&device_keys).unwrap();
834
835 let public_key = &self_signing.public_key();
836 public_key.verify_device(&device).unwrap()
837 }
838
839 #[async_test]
840 async fn test_sign_user_identity() {
841 let account = Account::with_device_id(user_id(), device_id!("DEVICEID"));
842 let identity = PrivateCrossSigningIdentity::for_account(
843 &account,
844 #[cfg(feature = "experimental-x509-identity-verification")]
845 None,
846 )
847 .unwrap();
848
849 let bob_account =
850 Account::with_device_id(user_id!("@bob:localhost"), device_id!("DEVICEID"));
851 let bob_private = PrivateCrossSigningIdentity::for_account(
852 &bob_account,
853 #[cfg(feature = "experimental-x509-identity-verification")]
854 None,
855 )
856 .unwrap();
857 let mut bob_public = OtherUserIdentityData::from_private(&bob_private).await;
858
859 let user_signing = identity.user_signing_key.lock().await;
860 let user_signing = user_signing.as_ref().unwrap();
861
862 let master = user_signing.sign_user(&bob_public).unwrap();
863
864 assert_eq!(
865 master.signatures.signature_count(),
866 1,
867 "We're only uploading our own signature"
868 );
869
870 bob_public.master_key = Arc::new(master.try_into().unwrap());
871
872 user_signing.public_key().verify_master_key(bob_public.master_key()).unwrap();
873 }
874}