Skip to main content

matrix_sdk_crypto/identities/
user.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
15use std::{
16    collections::HashMap,
17    ops::{Deref, DerefMut},
18    sync::{
19        Arc,
20        atomic::{AtomicBool, Ordering},
21    },
22};
23
24use as_variant::as_variant;
25use matrix_sdk_common::locks::RwLock;
26use ruma::{
27    DeviceId, EventId, OwnedDeviceId, OwnedUserId, RoomId, UserId,
28    api::client::keys::upload_signatures::v3::{Request as SignatureUploadRequest, SignedKeys},
29    events::{key::verification::VerificationMethod, room::message::MessageType},
30};
31use serde::{Deserialize, Deserializer, Serialize};
32use serde_json::Value;
33use tracing::{error, info};
34
35#[cfg(feature = "experimental-x509-identity-verification")]
36use crate::x509::X509Verifier;
37use crate::{
38    CryptoStoreError, DeviceData, VerificationRequest,
39    error::SignatureError,
40    store::{
41        Store,
42        types::{Changes, IdentityChanges},
43    },
44    types::{
45        CrossSigningKey, MasterPubkey, SelfSigningPubkey, UserSigningPubkey,
46        requests::OutgoingVerificationRequest,
47    },
48    verification::VerificationMachine,
49};
50
51/// Enum over the different user identity types we can have.
52#[derive(Debug, Clone)]
53pub enum UserIdentity {
54    /// Our own user identity.
55    Own(OwnUserIdentity),
56    /// An identity belonging to another user.
57    Other(OtherUserIdentity),
58}
59
60impl UserIdentity {
61    /// Destructure the enum into an [`OwnUserIdentity`] if it's of the correct
62    /// type.
63    pub fn own(self) -> Option<OwnUserIdentity> {
64        as_variant!(self, Self::Own)
65    }
66
67    /// Destructure the enum into an [`OtherUserIdentity`] if it's of the
68    /// correct type.
69    pub fn other(self) -> Option<OtherUserIdentity> {
70        as_variant!(self, Self::Other)
71    }
72
73    /// Get the ID of the user this identity belongs to.
74    pub fn user_id(&self) -> &UserId {
75        match self {
76            UserIdentity::Own(u) => u.user_id(),
77            UserIdentity::Other(u) => u.user_id(),
78        }
79    }
80
81    pub(crate) fn new(
82        store: Store,
83        identity: UserIdentityData,
84        verification_machine: VerificationMachine,
85        own_identity: Option<OwnUserIdentityData>,
86    ) -> Self {
87        match identity {
88            UserIdentityData::Own(i) => {
89                Self::Own(OwnUserIdentity { inner: i, verification_machine, store })
90            }
91            UserIdentityData::Other(i) => {
92                // X509Verifier holds an Arc so cloning it gives us a reference to the single
93                // underlying RustRawX509Verifier
94                #[cfg(feature = "experimental-x509-identity-verification")]
95                let x509_verifier = store.x509_verifier().cloned();
96
97                Self::Other(OtherUserIdentity {
98                    inner: i,
99                    own_identity,
100                    #[cfg(feature = "experimental-x509-identity-verification")]
101                    x509_verifier,
102                    verification_machine,
103                })
104            }
105        }
106    }
107
108    /// Check if this user identity is verified.
109    ///
110    /// For our own identity, this means either that we have checked the public
111    /// keys in the identity against the private keys; or that the identity
112    /// has been manually marked as verified via
113    /// [`OwnUserIdentity::verify`].
114    ///
115    /// For another user's identity, it means that we have verified our own
116    /// identity as above, *and* that the other user's identity has been signed
117    /// by our own user-signing key.
118    pub fn is_verified(&self) -> bool {
119        match self {
120            UserIdentity::Own(u) => u.is_verified(),
121            UserIdentity::Other(u) => u.is_verified(),
122        }
123    }
124
125    /// True if we verified this identity at some point in the past.
126    ///
127    /// To reset this latch back to `false`, one must call
128    /// [`UserIdentity::withdraw_verification()`].
129    pub fn was_previously_verified(&self) -> bool {
130        match self {
131            UserIdentity::Own(u) => u.was_previously_verified(),
132            UserIdentity::Other(u) => u.was_previously_verified(),
133        }
134    }
135
136    /// Reset the flag that records that the identity has been verified, thus
137    /// clearing [`UserIdentity::was_previously_verified`] and
138    /// [`UserIdentity::has_verification_violation`].
139    pub async fn withdraw_verification(&self) -> Result<(), CryptoStoreError> {
140        match self {
141            UserIdentity::Own(u) => u.withdraw_verification().await,
142            UserIdentity::Other(u) => u.withdraw_verification().await,
143        }
144    }
145
146    /// Remember this identity, ensuring it does not result in a pin violation.
147    ///
148    /// When we first see a user, we assume their cryptographic identity has not
149    /// been tampered with by the homeserver or another entity with
150    /// man-in-the-middle capabilities. We remember this identity and call this
151    /// action "pinning".
152    ///
153    /// If the identity presented for the user changes later on, the newly
154    /// presented identity is considered to be in "pin violation". This
155    /// method explicitly accepts the new identity, allowing it to replace
156    /// the previously pinned one and bringing it out of pin violation.
157    ///
158    /// UIs should display a warning to the user when encountering an identity
159    /// which is not verified and is in pin violation. See
160    /// [`OtherUserIdentity::identity_needs_user_approval`].
161    pub async fn pin(&self) -> Result<(), CryptoStoreError> {
162        match self {
163            UserIdentity::Own(_) => {
164                // Nothing to be done for our own identity: we already
165                // consider it trusted in this sense.
166                Ok(())
167            }
168            UserIdentity::Other(u) => u.pin_current_master_key().await,
169        }
170    }
171
172    /// Was this identity previously verified, and is no longer?
173    pub fn has_verification_violation(&self) -> bool {
174        match self {
175            UserIdentity::Own(u) => u.has_verification_violation(),
176            UserIdentity::Other(u) => u.has_verification_violation(),
177        }
178    }
179}
180
181impl From<OwnUserIdentity> for UserIdentity {
182    fn from(i: OwnUserIdentity) -> Self {
183        Self::Own(i)
184    }
185}
186
187impl From<OtherUserIdentity> for UserIdentity {
188    fn from(i: OtherUserIdentity) -> Self {
189        Self::Other(i)
190    }
191}
192
193/// Struct representing a cross signing identity of a user.
194///
195/// This is the user identity of a user that is our own. Other users will
196/// only contain a master key and a self signing key, meaning that only device
197/// signatures can be checked with this identity.
198///
199/// This struct wraps the [`OwnUserIdentityData`] type and allows a verification
200/// to be requested to verify our own device with the user identity.
201#[derive(Debug, Clone)]
202pub struct OwnUserIdentity {
203    pub(crate) inner: OwnUserIdentityData,
204    pub(crate) verification_machine: VerificationMachine,
205    store: Store,
206}
207
208impl Deref for OwnUserIdentity {
209    type Target = OwnUserIdentityData;
210
211    fn deref(&self) -> &Self::Target {
212        &self.inner
213    }
214}
215
216impl DerefMut for OwnUserIdentity {
217    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
218        &mut self.inner
219    }
220}
221
222impl OwnUserIdentity {
223    /// Mark our user identity as verified.
224    ///
225    /// This will mark the identity locally as verified and sign it with our own
226    /// device.
227    ///
228    /// Returns a signature upload request that needs to be sent out.
229    pub async fn verify(&self) -> Result<SignatureUploadRequest, SignatureError> {
230        self.mark_as_verified();
231
232        let changes = Changes {
233            identities: IdentityChanges {
234                changed: vec![self.inner.clone().into()],
235                new: vec![],
236                unchanged: vec![],
237            },
238            ..Default::default()
239        };
240
241        if let Err(e) = self.verification_machine.store.save_changes(changes).await {
242            error!(error = ?e, "Couldn't store our own user identity after marking it as verified");
243        }
244
245        let cache = self.store.cache().await?;
246        let account = cache.account().await?;
247        #[cfg(feature = "experimental-x509-identity-verification")]
248        let x509_signer = self.store.x509_signer();
249
250        let public_key = self
251            .master_key
252            .get_first_key()
253            .ok_or(SignatureError::MissingSigningKey)?
254            .to_base64()
255            .into();
256
257        let mut cross_signing_key: CrossSigningKey = (*self.master_key).as_ref().clone();
258        cross_signing_key.signatures.clear();
259        account.sign_cross_signing_key(&mut cross_signing_key)?;
260
261        // N.B. Duplicate of
262        // `matrix_sdk_crypto::olm::signing::PrivateCrossSigningIdentity::for_account`
263
264        #[cfg(feature = "experimental-x509-identity-verification")]
265        if let Some(x509_signer) = x509_signer {
266            x509_signer.sign_cross_signing_key(&self.user_id, &mut cross_signing_key)?;
267        }
268
269        let mut user_signed_keys = SignedKeys::new();
270        user_signed_keys.add_cross_signing_keys(public_key, cross_signing_key.to_raw());
271
272        let signed_keys = [(self.user_id().to_owned(), user_signed_keys)].into();
273        Ok(SignatureUploadRequest::new(signed_keys))
274    }
275
276    /// Send a verification request to our other devices.
277    pub async fn request_verification(
278        &self,
279    ) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> {
280        self.request_verification_helper(None).await
281    }
282
283    /// Send a verification request to our other devices while specifying our
284    /// supported methods.
285    ///
286    /// # Arguments
287    ///
288    /// * `methods` - The verification methods that we're supporting.
289    pub async fn request_verification_with_methods(
290        &self,
291        methods: Vec<VerificationMethod>,
292    ) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> {
293        self.request_verification_helper(Some(methods)).await
294    }
295
296    /// Does our user identity trust our own device, i.e. have we signed our
297    /// own device keys with our self-signing key.
298    pub async fn trusts_our_own_device(&self) -> Result<bool, CryptoStoreError> {
299        Ok(if let Some(signatures) = self.verification_machine.store.device_signatures().await? {
300            let mut device_keys = self.store.cache().await?.account().await?.device_keys();
301            device_keys.signatures = signatures;
302
303            self.inner.self_signing_key().verify_device_keys(&device_keys).is_ok()
304        } else {
305            false
306        })
307    }
308
309    async fn request_verification_helper(
310        &self,
311        methods: Option<Vec<VerificationMethod>>,
312    ) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> {
313        let all_devices = self.verification_machine.store.get_user_devices(self.user_id()).await?;
314        let devices = self
315            .inner
316            .filter_devices_to_request(all_devices, self.verification_machine.own_device_id());
317
318        Ok(self.verification_machine.request_to_device_verification(
319            self.user_id(),
320            devices,
321            methods,
322        ))
323    }
324
325    /// Remove the requirement for this identity to be verified.
326    pub async fn withdraw_verification(&self) -> Result<(), CryptoStoreError> {
327        self.inner.withdraw_verification();
328        let to_save = UserIdentityData::Own(self.inner.clone());
329        let changes = Changes {
330            identities: IdentityChanges { changed: vec![to_save], ..Default::default() },
331            ..Default::default()
332        };
333        self.verification_machine.store.inner().save_changes(changes).await?;
334        Ok(())
335    }
336}
337
338/// Struct representing a cross signing identity of a user.
339///
340/// This is the user identity of a user that isn't our own. Other users will
341/// only contain a master key and a self signing key, meaning that only device
342/// signatures can be checked with this identity.
343///
344/// This struct wraps a read-only version of the struct and allows verifications
345/// to be requested to verify our own device with the user identity.
346#[derive(Debug, Clone)]
347pub struct OtherUserIdentity {
348    pub(crate) inner: OtherUserIdentityData,
349    pub(crate) own_identity: Option<OwnUserIdentityData>,
350    pub(crate) verification_machine: VerificationMachine,
351
352    #[cfg(feature = "experimental-x509-identity-verification")]
353    pub(crate) x509_verifier: Option<X509Verifier>,
354}
355
356impl Deref for OtherUserIdentity {
357    type Target = OtherUserIdentityData;
358
359    fn deref(&self) -> &Self::Target {
360        &self.inner
361    }
362}
363
364impl DerefMut for OtherUserIdentity {
365    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
366        &mut self.inner
367    }
368}
369
370impl OtherUserIdentity {
371    /// Is this user identity verified?
372    pub fn is_verified(&self) -> bool {
373        let is_cross_signed = self
374            .own_identity
375            .as_ref()
376            .is_some_and(|own_identity| own_identity.is_identity_verified(&self.inner));
377
378        // If we have an X.509 verifier, we can use that to verify the user
379        #[cfg(feature = "experimental-x509-identity-verification")]
380        {
381            let is_x509_signed = || {
382                self.x509_verifier.as_ref().is_some_and(|verifier| {
383                    verifier.verify_signed_object(&self.user_id, self.inner.master_key().as_ref())
384                })
385            };
386
387            is_cross_signed || is_x509_signed()
388        }
389
390        #[cfg(not(feature = "experimental-x509-identity-verification"))]
391        is_cross_signed
392    }
393
394    /// Manually verify this user.
395    ///
396    /// This method will attempt to sign the user identity using our private
397    /// cross signing key.
398    ///
399    /// This method fails if we don't have the private part of our user-signing
400    /// key.
401    ///
402    /// Returns a request that needs to be sent out for the user to be marked
403    /// as verified.
404    pub async fn verify(&self) -> Result<SignatureUploadRequest, SignatureError> {
405        if self.user_id() != self.verification_machine.own_user_id() {
406            Ok(self
407                .verification_machine
408                .store
409                .private_identity
410                .lock()
411                .await
412                .sign_user(&self.inner)
413                .await?)
414        } else {
415            Err(SignatureError::UserIdMismatch)
416        }
417    }
418
419    /// Create a [`VerificationRequest`] object after the verification request
420    /// content returned by [`OtherUserIdentity::verification_request_content`]
421    /// has been sent out.
422    pub fn request_verification(
423        &self,
424        room_id: &RoomId,
425        request_event_id: &EventId,
426        methods: Option<Vec<VerificationMethod>>,
427    ) -> VerificationRequest {
428        self.verification_machine.request_verification(
429            &self.inner,
430            room_id,
431            request_event_id,
432            methods,
433        )
434    }
435
436    /// Create a verification request to send to the given user.
437    ///
438    /// The returned content needs to be sent out into a DM room with the user.
439    ///
440    /// After the content has been sent out a [`VerificationRequest`] can be
441    /// started with the [`OtherUserIdentity::request_verification()`] method.
442    pub fn verification_request_content(
443        &self,
444        methods: Option<Vec<VerificationMethod>>,
445    ) -> MessageType {
446        MessageType::VerificationRequest(VerificationRequest::request(
447            self.verification_machine.own_user_id(),
448            self.verification_machine.own_device_id(),
449            self.user_id(),
450            methods,
451        ))
452    }
453
454    /// Pin the current identity (public part of the master signing key).
455    pub async fn pin_current_master_key(&self) -> Result<(), CryptoStoreError> {
456        info!(master_key = ?self.master_key.get_first_key(), "Pinning current identity for user '{}'", self.user_id());
457        self.inner.pin();
458        let to_save = UserIdentityData::Other(self.inner.clone());
459        let changes = Changes {
460            identities: IdentityChanges { changed: vec![to_save], ..Default::default() },
461            ..Default::default()
462        };
463        self.verification_machine.store.inner().save_changes(changes).await?;
464        Ok(())
465    }
466
467    /// Has the identity changed in a way that requires approval from the user?
468    ///
469    /// A user identity needs approval if it changed after the crypto machine
470    /// has already observed ("pinned") a different identity for that user,
471    /// unless it is an explicitly verified identity (using for example
472    /// interactive verification).
473    ///
474    /// This situation can be resolved by:
475    ///
476    /// - Verifying the new identity with
477    ///   [`OtherUserIdentity::request_verification`], or:
478    /// - Updating the pin to the new identity with
479    ///   [`OtherUserIdentity::pin_current_master_key`].
480    pub fn identity_needs_user_approval(&self) -> bool {
481        // First check if the current identity is verified.
482        if self.is_verified() {
483            return false;
484        }
485        // If not we can check the pinned identity. Verification always have
486        // higher priority than pinning.
487        self.inner.has_pin_violation()
488    }
489
490    /// Remove the requirement for this identity to be verified.
491    pub async fn withdraw_verification(&self) -> Result<(), CryptoStoreError> {
492        info!(
493            master_key = ?self.master_key.get_first_key(),
494            user = ?self.user_id(),
495            "Withdrawing verification status and pinning current identity"
496        );
497        self.inner.withdraw_verification();
498        let to_save = UserIdentityData::Other(self.inner.clone());
499        let changes = Changes {
500            identities: IdentityChanges { changed: vec![to_save], ..Default::default() },
501            ..Default::default()
502        };
503        self.verification_machine.store.inner().save_changes(changes).await?;
504        Ok(())
505    }
506
507    /// Test helper that marks that an identity has been previously verified and
508    /// persist the change in the store.
509    #[cfg(test)]
510    pub async fn mark_as_previously_verified(&self) -> Result<(), CryptoStoreError> {
511        self.inner.mark_as_previously_verified();
512
513        let to_save = UserIdentityData::Other(self.inner.clone());
514        let changes = Changes {
515            identities: IdentityChanges { changed: vec![to_save], ..Default::default() },
516            ..Default::default()
517        };
518
519        self.verification_machine.store.inner().save_changes(changes).await?;
520
521        Ok(())
522    }
523
524    /// Was this identity verified since initial observation and is not anymore?
525    ///
526    /// Such a violation should be reported to the local user by the
527    /// application, and resolved by
528    ///
529    /// - Verifying the new identity with
530    ///   [`OtherUserIdentity::request_verification`]
531    /// - Or by withdrawing the verification requirement
532    ///   [`OtherUserIdentity::withdraw_verification`].
533    pub fn has_verification_violation(&self) -> bool {
534        if !self.inner.was_previously_verified() {
535            // If that identity has never been verified it cannot be in violation.
536            return false;
537        }
538
539        !self.is_verified()
540    }
541}
542
543/// Enum over the different user identity types we can have.
544#[derive(Debug, Clone, Serialize, Deserialize)]
545pub enum UserIdentityData {
546    /// Our own user identity.
547    Own(OwnUserIdentityData),
548    /// The identity of another user.
549    Other(OtherUserIdentityData),
550}
551
552impl From<OwnUserIdentityData> for UserIdentityData {
553    fn from(identity: OwnUserIdentityData) -> Self {
554        UserIdentityData::Own(identity)
555    }
556}
557
558impl From<OtherUserIdentityData> for UserIdentityData {
559    fn from(identity: OtherUserIdentityData) -> Self {
560        UserIdentityData::Other(identity)
561    }
562}
563
564impl UserIdentityData {
565    /// The unique user id of this identity.
566    pub fn user_id(&self) -> &UserId {
567        match self {
568            UserIdentityData::Own(i) => i.user_id(),
569            UserIdentityData::Other(i) => i.user_id(),
570        }
571    }
572
573    /// Get the master key of the identity.
574    pub fn master_key(&self) -> &MasterPubkey {
575        match self {
576            UserIdentityData::Own(i) => i.master_key(),
577            UserIdentityData::Other(i) => i.master_key(),
578        }
579    }
580
581    /// Get the [`SelfSigningPubkey`] key of the identity.
582    pub fn self_signing_key(&self) -> &SelfSigningPubkey {
583        match self {
584            UserIdentityData::Own(i) => &i.self_signing_key,
585            UserIdentityData::Other(i) => &i.self_signing_key,
586        }
587    }
588
589    /// Get the user-signing key of the identity, this is only present for our
590    /// own user identity..
591    pub fn user_signing_key(&self) -> Option<&UserSigningPubkey> {
592        match self {
593            UserIdentityData::Own(i) => Some(&i.user_signing_key),
594            UserIdentityData::Other(_) => None,
595        }
596    }
597
598    /// True if we verified our own identity at some point in the past.
599    ///
600    /// To reset this latch back to `false`, one must call
601    /// [`UserIdentity::withdraw_verification()`].
602    pub fn was_previously_verified(&self) -> bool {
603        match self {
604            UserIdentityData::Own(i) => i.was_previously_verified(),
605            UserIdentityData::Other(i) => i.was_previously_verified(),
606        }
607    }
608
609    /// Convert the enum into a reference [`OwnUserIdentityData`] if it's of
610    /// the correct type.
611    pub fn own(&self) -> Option<&OwnUserIdentityData> {
612        as_variant!(self, Self::Own)
613    }
614
615    /// Convert the enum into an [`OwnUserIdentityData`] if it's of the correct
616    /// type.
617    pub(crate) fn into_own(self) -> Option<OwnUserIdentityData> {
618        as_variant!(self, Self::Own)
619    }
620
621    /// Convert the enum into a reference to [`OtherUserIdentityData`] if
622    /// it's of the correct type.
623    pub fn other(&self) -> Option<&OtherUserIdentityData> {
624        as_variant!(self, Self::Other)
625    }
626}
627
628/// Struct representing a cross signing identity of a user.
629///
630/// This is the user identity of a user that isn't our own. Other users will
631/// only contain a master key and a self signing key, meaning that only device
632/// signatures can be checked with this identity.
633///
634/// This struct also contains the currently pinned user identity (public master
635/// key) for that user and a local flag that serves as a latch to remember if an
636/// identity was verified once.
637///
638/// The first time a cryptographic user identity is seen for a given user, it
639/// will be associated with that user ("pinned"). Future interactions
640/// will expect this identity to stay the same, to avoid MITM attacks from the
641/// homeserver.
642///
643/// The user can explicitly pin the new identity to allow for legitimate
644/// identity changes (for example, in case of key material or device loss).
645///
646/// As soon as the cryptographic identity is verified (i.e. signed by our own
647/// trusted identity), a flag is set to remember it (`previously_verified`).
648/// Future interactions will expect this user to stay verified, in case of
649/// violation the user should be notified with a blocking warning when sending a
650/// message.
651#[derive(Debug, Clone, Deserialize, Serialize)]
652#[serde(try_from = "OtherUserIdentityDataSerializer", into = "OtherUserIdentityDataSerializer")]
653pub struct OtherUserIdentityData {
654    user_id: OwnedUserId,
655    pub(crate) master_key: Arc<MasterPubkey>,
656    self_signing_key: Arc<SelfSigningPubkey>,
657    pinned_master_key: Arc<RwLock<MasterPubkey>>,
658    /// This tracks whether this olm machine has already seen this user as
659    /// verified. To use it in the future to detect cases where the user has
660    /// become unverified for any reason. This can be reset using
661    /// [`OtherUserIdentityData::withdraw_verification()`].
662    previously_verified: Arc<AtomicBool>,
663}
664
665/// Intermediate struct to help serialize OtherUserIdentityData and support
666/// versioning and migration.
667///
668/// Version v1 is adding support for identity pinning (`pinned_master_key`), as
669/// part of migration we just pin the currently known public master key.
670#[derive(Deserialize, Serialize)]
671struct OtherUserIdentityDataSerializer {
672    version: Option<String>,
673    #[serde(flatten)]
674    other: Value,
675}
676
677#[derive(Debug, Deserialize, Serialize)]
678struct OtherUserIdentityDataSerializerV0 {
679    user_id: OwnedUserId,
680    master_key: MasterPubkey,
681    self_signing_key: SelfSigningPubkey,
682}
683
684#[derive(Debug, Deserialize, Serialize)]
685struct OtherUserIdentityDataSerializerV1 {
686    user_id: OwnedUserId,
687    master_key: MasterPubkey,
688    self_signing_key: SelfSigningPubkey,
689    pinned_master_key: MasterPubkey,
690}
691
692#[derive(Debug, Deserialize, Serialize)]
693struct OtherUserIdentityDataSerializerV2 {
694    user_id: OwnedUserId,
695    master_key: MasterPubkey,
696    self_signing_key: SelfSigningPubkey,
697    pinned_master_key: MasterPubkey,
698    previously_verified: bool,
699}
700
701impl TryFrom<OtherUserIdentityDataSerializer> for OtherUserIdentityData {
702    type Error = serde_json::Error;
703    fn try_from(
704        value: OtherUserIdentityDataSerializer,
705    ) -> Result<OtherUserIdentityData, Self::Error> {
706        match value.version {
707            None => {
708                // Old format, migrate the pinned identity
709                let v0: OtherUserIdentityDataSerializerV0 = serde_json::from_value(value.other)?;
710                Ok(OtherUserIdentityData {
711                    user_id: v0.user_id,
712                    master_key: Arc::new(v0.master_key.clone()),
713                    self_signing_key: Arc::new(v0.self_signing_key),
714                    // We migrate by pinning the current master key
715                    pinned_master_key: Arc::new(RwLock::new(v0.master_key)),
716                    previously_verified: Arc::new(false.into()),
717                })
718            }
719            Some(v) if v == "1" => {
720                let v1: OtherUserIdentityDataSerializerV1 = serde_json::from_value(value.other)?;
721                Ok(OtherUserIdentityData {
722                    user_id: v1.user_id,
723                    master_key: Arc::new(v1.master_key.clone()),
724                    self_signing_key: Arc::new(v1.self_signing_key),
725                    pinned_master_key: Arc::new(RwLock::new(v1.pinned_master_key)),
726                    // Put it to false. There will be a migration to mark all users as dirty, so we
727                    // will receive an update for the identity that will correctly set up the value.
728                    previously_verified: Arc::new(false.into()),
729                })
730            }
731            Some(v) if v == "2" => {
732                let v2: OtherUserIdentityDataSerializerV2 = serde_json::from_value(value.other)?;
733                Ok(OtherUserIdentityData {
734                    user_id: v2.user_id,
735                    master_key: Arc::new(v2.master_key.clone()),
736                    self_signing_key: Arc::new(v2.self_signing_key),
737                    pinned_master_key: Arc::new(RwLock::new(v2.pinned_master_key)),
738                    previously_verified: Arc::new(v2.previously_verified.into()),
739                })
740            }
741            _ => Err(serde::de::Error::custom(format!("Unsupported Version {:?}", value.version))),
742        }
743    }
744}
745
746impl From<OtherUserIdentityData> for OtherUserIdentityDataSerializer {
747    fn from(value: OtherUserIdentityData) -> Self {
748        let v2 = OtherUserIdentityDataSerializerV2 {
749            user_id: value.user_id.clone(),
750            master_key: value.master_key().to_owned(),
751            self_signing_key: value.self_signing_key().to_owned(),
752            pinned_master_key: value.pinned_master_key.read().clone(),
753            previously_verified: value.previously_verified.load(Ordering::SeqCst),
754        };
755        OtherUserIdentityDataSerializer {
756            version: Some("2".to_owned()),
757            other: serde_json::to_value(v2).unwrap(),
758        }
759    }
760}
761
762impl PartialEq for OtherUserIdentityData {
763    /// The `PartialEq` implementation compares several attributes, including
764    /// the user ID, key material, usage, and, notably, the signatures of
765    /// the master key.
766    ///
767    /// This approach contrasts with the `PartialEq` implementation of the
768    /// [`MasterPubkey`], and [`SelfSigningPubkey`] types,
769    /// where the signatures are disregarded. This distinction arises from our
770    /// treatment of identity as the combined representation of cross-signing
771    /// keys and the associated verification state.
772    ///
773    /// The verification state of an identity depends on the signatures of the
774    /// master key, requiring their inclusion in our `PartialEq` implementation.
775    fn eq(&self, other: &Self) -> bool {
776        self.user_id == other.user_id
777            && self.master_key == other.master_key
778            && self.self_signing_key == other.self_signing_key
779            && self.master_key.signatures() == other.master_key.signatures()
780    }
781}
782
783impl OtherUserIdentityData {
784    /// Create a new user identity with the given master and self signing key.
785    ///
786    /// # Arguments
787    ///
788    /// * `master_key` - The master key of the user identity.
789    ///
790    /// * `self signing key` - The self signing key of user identity.
791    ///
792    /// Returns a `SignatureError` if the self signing key fails to be correctly
793    /// verified by the given master key.
794    pub(crate) fn new(
795        master_key: MasterPubkey,
796        self_signing_key: SelfSigningPubkey,
797    ) -> Result<Self, SignatureError> {
798        master_key.verify_subkey(&self_signing_key)?;
799
800        Ok(Self {
801            user_id: master_key.user_id().into(),
802            master_key: master_key.clone().into(),
803            self_signing_key: self_signing_key.into(),
804            pinned_master_key: RwLock::new(master_key).into(),
805            previously_verified: Arc::new(false.into()),
806        })
807    }
808
809    #[cfg(test)]
810    pub(crate) async fn from_private(identity: &crate::olm::PrivateCrossSigningIdentity) -> Self {
811        let master_key = identity.master_key.lock().await.as_ref().unwrap().public_key().clone();
812        let self_signing_key =
813            identity.self_signing_key.lock().await.as_ref().unwrap().public_key().clone().into();
814
815        Self {
816            user_id: identity.user_id().into(),
817            master_key: Arc::new(master_key.clone()),
818            self_signing_key,
819            pinned_master_key: Arc::new(RwLock::new(master_key.clone())),
820            previously_verified: Arc::new(false.into()),
821        }
822    }
823
824    /// Get the user id of this identity.
825    pub fn user_id(&self) -> &UserId {
826        &self.user_id
827    }
828
829    /// Get the public master key of the identity.
830    pub fn master_key(&self) -> &MasterPubkey {
831        &self.master_key
832    }
833
834    /// Get the public self-signing key of the identity.
835    pub fn self_signing_key(&self) -> &SelfSigningPubkey {
836        &self.self_signing_key
837    }
838
839    /// Remember this identity, ensuring it does not result in a pin violation.
840    ///
841    /// When we first see a user, we assume their cryptographic identity has not
842    /// been tampered with by the homeserver or another entity with
843    /// man-in-the-middle capabilities. We remember this identity and call this
844    /// action "pinning".
845    ///
846    /// If the identity presented for the user changes later on, the newly
847    /// presented identity is considered to be in "pin violation". This
848    /// method explicitly accepts the new identity, allowing it to replace
849    /// the previously pinned one and bringing it out of pin violation.
850    ///
851    /// UIs should display a warning to the user when encountering an identity
852    /// which is not verified and is in pin violation. See
853    /// [`OtherUserIdentity::identity_needs_user_approval`].
854    pub(crate) fn pin(&self) {
855        let mut m = self.pinned_master_key.write();
856        *m = self.master_key.as_ref().clone()
857    }
858
859    /// Remember that this identity used to be verified at some point.
860    pub(crate) fn mark_as_previously_verified(&self) {
861        self.previously_verified.store(true, Ordering::SeqCst)
862    }
863
864    /// True if we verified this identity (with any own identity, at any
865    /// point).
866    ///
867    /// To set this latch back to false, call
868    /// [`OtherUserIdentityData::withdraw_verification()`].
869    pub fn was_previously_verified(&self) -> bool {
870        self.previously_verified.load(Ordering::SeqCst)
871    }
872
873    /// Remove the requirement for this identity to be verified.
874    ///
875    /// If an identity was previously verified and is not anymore it will be
876    /// reported to the user. In order to remove this notice users have to
877    /// verify again or to withdraw the verification requirement.
878    pub fn withdraw_verification(&self) {
879        // We also pin when we withdraw, since withdrawing implicitly acknowledges
880        // the identity change
881        self.pin();
882        self.previously_verified.store(false, Ordering::SeqCst)
883    }
884
885    /// Returns true if the identity has changed since we last pinned it.
886    ///
887    /// Key pinning acts as a trust on first use mechanism: the first time an
888    /// identity is known for a user it will be pinned.
889    ///
890    /// For future interaction with a user, the identity is expected to be the
891    /// one that was pinned. In case of identity change the UI client should
892    /// receive reports of pinning violation and decide to act accordingly:
893    /// accept and pin the new identity, perform a verification, or
894    /// stop communications.
895    pub(crate) fn has_pin_violation(&self) -> bool {
896        let pinned_master_key = self.pinned_master_key.read();
897        pinned_master_key.get_first_key() != self.master_key().get_first_key()
898    }
899
900    /// Update the identity with a new master key and self signing key.
901    ///
902    /// # Arguments
903    ///
904    /// * `master_key` - The new master key of the user identity.
905    ///
906    /// * `self_signing_key` - The new self signing key of user identity.
907    ///
908    /// * `maybe_verified_own_user_signing_key` - Our own user_signing_key if it
909    ///   is verified to check the identity trust status after update.
910    ///
911    /// Returns a `SignatureError` if we failed to update the identity.
912    /// Otherwise, returns `true` if there was a change to the identity and
913    /// `false` if the identity is unchanged.
914    pub(crate) fn update(
915        &mut self,
916        master_key: MasterPubkey,
917        self_signing_key: SelfSigningPubkey,
918        maybe_verified_own_user_signing_key: Option<&UserSigningPubkey>,
919    ) -> Result<bool, SignatureError> {
920        master_key.verify_subkey(&self_signing_key)?;
921
922        // We update the identity with the new master and self signing key, but we keep
923        // the previous pinned master key.
924        // This identity will have a pin violation until the new master key is pinned
925        // (see `has_pin_violation()`).
926        let pinned_master_key = self.pinned_master_key.read().clone();
927
928        // Check if the new master_key is signed by our own **verified**
929        // user_signing_key. If the identity was verified we remember it.
930        let updated_is_verified =
931            maybe_verified_own_user_signing_key.is_some_and(|own_user_signing_key| {
932                own_user_signing_key.verify_master_key(&master_key).is_ok()
933            });
934
935        let new = Self {
936            user_id: master_key.user_id().into(),
937            master_key: master_key.clone().into(),
938            self_signing_key: self_signing_key.into(),
939            pinned_master_key: RwLock::new(pinned_master_key).into(),
940            previously_verified: Arc::new(
941                (self.was_previously_verified() || updated_is_verified).into(),
942            ),
943        };
944        let changed = new != *self;
945
946        *self = new;
947        Ok(changed)
948    }
949
950    /// Check if the given device has been signed by this identity.
951    ///
952    /// The user_id of the user identity and the user_id of the device need to
953    /// match for the signature check to succeed as we don't trust users to sign
954    /// devices of other users.
955    ///
956    /// # Arguments
957    ///
958    /// * `device` - The device that should be checked for a valid signature.
959    ///
960    /// Returns `true` if the signature check succeeded, otherwise `false`.
961    pub(crate) fn is_device_signed(&self, device: &DeviceData) -> bool {
962        self.user_id() == device.user_id() && self.self_signing_key.verify_device(device).is_ok()
963    }
964}
965
966/// Struct representing a cross signing identity of our own user.
967///
968/// This is the user identity of our own user. This user identity will contain a
969/// master key, self signing key as well as a user signing key.
970///
971/// This identity can verify other identities as well as devices belonging to
972/// the identity.
973#[derive(Debug, Clone, Serialize, Deserialize)]
974pub struct OwnUserIdentityData {
975    user_id: OwnedUserId,
976    master_key: Arc<MasterPubkey>,
977    self_signing_key: Arc<SelfSigningPubkey>,
978    user_signing_key: Arc<UserSigningPubkey>,
979    #[serde(deserialize_with = "deserialize_own_user_identity_data_verified")]
980    verified: Arc<RwLock<OwnUserIdentityVerifiedState>>,
981}
982
983#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
984enum OwnUserIdentityVerifiedState {
985    /// We have never verified our own identity
986    #[default]
987    NeverVerified,
988
989    /// We previously verified this identity, but it has changed.
990    #[serde(alias = "PreviouslyVerifiedButNoLonger")]
991    VerificationViolation,
992
993    /// We have verified the current identity.
994    Verified,
995}
996
997impl PartialEq for OwnUserIdentityData {
998    /// The `PartialEq` implementation compares several attributes, including
999    /// the user ID, key material, usage, and, notably, the signatures of
1000    /// the master key.
1001    ///
1002    /// This approach contrasts with the `PartialEq` implementation of the
1003    /// [`MasterPubkey`], [`SelfSigningPubkey`] and [`UserSigningPubkey`] types,
1004    /// where the signatures are disregarded. This distinction arises from our
1005    /// treatment of identity as the combined representation of cross-signing
1006    /// keys and the associated verification state.
1007    ///
1008    /// The verification state of an identity depends on the signatures of the
1009    /// master key, requiring their inclusion in our `PartialEq` implementation.
1010    fn eq(&self, other: &Self) -> bool {
1011        self.user_id == other.user_id
1012            && self.master_key == other.master_key
1013            && self.self_signing_key == other.self_signing_key
1014            && self.user_signing_key == other.user_signing_key
1015            && *self.verified.read() == *other.verified.read()
1016            && self.master_key.signatures() == other.master_key.signatures()
1017    }
1018}
1019
1020impl OwnUserIdentityData {
1021    /// Create a new own user identity with the given master, self signing, and
1022    /// user signing key.
1023    ///
1024    /// # Arguments
1025    ///
1026    /// * `master_key` - The master key of the user identity.
1027    ///
1028    /// * `self_signing_key` - The self signing key of user identity.
1029    ///
1030    /// * `user_signing_key` - The user signing key of user identity.
1031    ///
1032    /// Returns a `SignatureError` if the self signing key fails to be correctly
1033    /// verified by the given master key.
1034    pub(crate) fn new(
1035        master_key: MasterPubkey,
1036        self_signing_key: SelfSigningPubkey,
1037        user_signing_key: UserSigningPubkey,
1038    ) -> Result<Self, SignatureError> {
1039        master_key.verify_subkey(&self_signing_key)?;
1040        master_key.verify_subkey(&user_signing_key)?;
1041
1042        Ok(Self {
1043            user_id: master_key.user_id().into(),
1044            master_key: master_key.into(),
1045            self_signing_key: self_signing_key.into(),
1046            user_signing_key: user_signing_key.into(),
1047            verified: Default::default(),
1048        })
1049    }
1050
1051    #[cfg(test)]
1052    pub(crate) async fn from_private(identity: &crate::olm::PrivateCrossSigningIdentity) -> Self {
1053        let master_key = identity.master_key.lock().await.as_ref().unwrap().public_key().clone();
1054        let self_signing_key =
1055            identity.self_signing_key.lock().await.as_ref().unwrap().public_key().clone();
1056        let user_signing_key =
1057            identity.user_signing_key.lock().await.as_ref().unwrap().public_key().clone();
1058
1059        Self {
1060            user_id: identity.user_id().into(),
1061            master_key: master_key.into(),
1062            self_signing_key: self_signing_key.into(),
1063            user_signing_key: user_signing_key.into(),
1064            verified: Default::default(),
1065        }
1066    }
1067
1068    /// Get the user id of this identity.
1069    pub fn user_id(&self) -> &UserId {
1070        &self.user_id
1071    }
1072
1073    /// Get the public master key of the identity.
1074    pub fn master_key(&self) -> &MasterPubkey {
1075        &self.master_key
1076    }
1077
1078    /// Get the public self-signing key of the identity.
1079    pub fn self_signing_key(&self) -> &SelfSigningPubkey {
1080        &self.self_signing_key
1081    }
1082
1083    /// Get the public user-signing key of the identity.
1084    pub fn user_signing_key(&self) -> &UserSigningPubkey {
1085        &self.user_signing_key
1086    }
1087
1088    /// Check if the given user identity has been verified.
1089    ///
1090    /// The identity of another user is verified iff our own identity is
1091    /// verified and if our own identity has signed the other user's
1092    /// identity.
1093    ///
1094    /// # Arguments
1095    ///
1096    /// * `identity` - The identity of another user which we want to check has
1097    ///   been verified.
1098    pub fn is_identity_verified(&self, identity: &OtherUserIdentityData) -> bool {
1099        self.is_verified() && self.is_identity_signed(identity)
1100    }
1101
1102    /// Check if the given identity has been signed by this identity.
1103    ///
1104    /// Note that, normally, you'll also want to check that the
1105    /// `OwnUserIdentityData` has been verified; for that,
1106    /// [`Self::is_identity_verified`] is more appropriate.
1107    ///
1108    /// # Arguments
1109    ///
1110    /// * `identity` - The identity of another user that we want to check if it
1111    ///   has been signed.
1112    ///
1113    /// Returns `true` if the signature check succeeded, otherwise `false`.
1114    pub(crate) fn is_identity_signed(&self, identity: &OtherUserIdentityData) -> bool {
1115        self.user_signing_key.verify_master_key(&identity.master_key).is_ok()
1116    }
1117
1118    /// Check if the given device has been signed by this identity.
1119    ///
1120    /// Only devices of our own user should be checked with this method. If a
1121    /// device of a different user is given, the signature check will always
1122    /// fail even if a valid signature exists.
1123    ///
1124    /// # Arguments
1125    ///
1126    /// * `device` - The device that should be checked for a valid signature.
1127    ///
1128    /// Returns `true` if the signature check succeeded, otherwise `false`.
1129    pub(crate) fn is_device_signed(&self, device: &DeviceData) -> bool {
1130        self.user_id() == device.user_id() && self.self_signing_key.verify_device(device).is_ok()
1131    }
1132
1133    /// Mark our identity as verified.
1134    pub fn mark_as_verified(&self) {
1135        *self.verified.write() = OwnUserIdentityVerifiedState::Verified;
1136    }
1137
1138    /// Mark our identity as unverified.
1139    pub(crate) fn mark_as_unverified(&self) {
1140        let mut guard = self.verified.write();
1141        if *guard == OwnUserIdentityVerifiedState::Verified {
1142            *guard = OwnUserIdentityVerifiedState::VerificationViolation;
1143        }
1144    }
1145
1146    /// Check if our identity is verified.
1147    pub fn is_verified(&self) -> bool {
1148        *self.verified.read() == OwnUserIdentityVerifiedState::Verified
1149    }
1150
1151    /// True if we verified our own identity at some point in the past.
1152    ///
1153    /// To reset this latch back to `false`, one must call
1154    /// [`OwnUserIdentityData::withdraw_verification()`].
1155    pub fn was_previously_verified(&self) -> bool {
1156        matches!(
1157            *self.verified.read(),
1158            OwnUserIdentityVerifiedState::Verified
1159                | OwnUserIdentityVerifiedState::VerificationViolation
1160        )
1161    }
1162
1163    /// Remove the requirement for this identity to be verified.
1164    ///
1165    /// If an identity was previously verified and is not any more it will be
1166    /// reported to the user. In order to remove this notice users have to
1167    /// verify again or to withdraw the verification requirement.
1168    pub fn withdraw_verification(&self) {
1169        let mut guard = self.verified.write();
1170        if *guard == OwnUserIdentityVerifiedState::VerificationViolation {
1171            *guard = OwnUserIdentityVerifiedState::NeverVerified;
1172        }
1173    }
1174
1175    /// Was this identity previously verified, and is no longer?
1176    ///
1177    /// Such a violation should be reported to the local user by the
1178    /// application, and resolved by
1179    ///
1180    /// - Verifying the new identity with
1181    ///   [`OwnUserIdentity::request_verification`]
1182    /// - Or by withdrawing the verification requirement
1183    ///   [`OwnUserIdentity::withdraw_verification`].
1184    pub fn has_verification_violation(&self) -> bool {
1185        *self.verified.read() == OwnUserIdentityVerifiedState::VerificationViolation
1186    }
1187
1188    /// Sign our own identity again, if our current X.509 signer has a later
1189    /// expiry than our existing X.509 signature.
1190    ///
1191    /// Returns the signature upload request to upload the new X.509 signature
1192    /// if a new one is needed.
1193    ///
1194    /// Note that this function does not update our own copy of the signature
1195    /// immediately.  Rather, after we upload the new signature, the server will
1196    /// notify us of the changed key, we will re-fetch it, and then store the
1197    /// new result at that point.
1198    #[cfg(feature = "experimental-x509-identity-verification")]
1199    pub(crate) fn refresh_x509_signature(
1200        &self,
1201        store: &Store,
1202    ) -> Result<Option<SignatureUploadRequest>, SignatureError> {
1203        // We only re-sign our identity our identity is already verified.  If it
1204        // isn't already verified, then our identity should be signed by
1205        // `OwnUserIdentity::verify()` instead.
1206        if !self.is_verified() {
1207            return Ok(None);
1208        }
1209
1210        let cross_signing_key: &CrossSigningKey = (*self.master_key).as_ref();
1211
1212        if let Some(x509_signer) = store.x509_signer()
1213            && x509_signer.has_later_expiry_than(&self.user_id, &cross_signing_key.signatures)
1214        {
1215            let mut cross_signing_key = cross_signing_key.clone();
1216            cross_signing_key.signatures.clear();
1217            x509_signer.sign_cross_signing_key(&self.user_id, &mut cross_signing_key)?;
1218
1219            let public_key = self
1220                .master_key
1221                .get_first_key()
1222                .ok_or(SignatureError::MissingSigningKey)?
1223                .to_base64()
1224                .into();
1225
1226            let mut user_signed_keys = SignedKeys::new();
1227            user_signed_keys.add_cross_signing_keys(public_key, cross_signing_key.to_raw());
1228
1229            let signed_keys = [(self.user_id.to_owned(), user_signed_keys)].into();
1230            Ok(Some(SignatureUploadRequest::new(signed_keys)))
1231        } else {
1232            Ok(None)
1233        }
1234    }
1235
1236    /// Update the identity with a new master key and self signing key.
1237    ///
1238    /// Note: This will reset the verification state if the master keys differ.
1239    ///
1240    /// # Arguments
1241    ///
1242    /// * `master_key` - The new master key of the user identity.
1243    ///
1244    /// * `self_signing_key` - The new self signing key of user identity.
1245    ///
1246    /// * `user_signing_key` - The new user signing key of user identity.
1247    ///
1248    /// Returns a `SignatureError` if we failed to update the identity.
1249    /// Otherwise, returns `true` if there was a change to the identity and
1250    /// `false` if the identity is unchanged.
1251    pub(crate) fn update(
1252        &mut self,
1253        master_key: MasterPubkey,
1254        self_signing_key: SelfSigningPubkey,
1255        user_signing_key: UserSigningPubkey,
1256    ) -> Result<bool, SignatureError> {
1257        master_key.verify_subkey(&self_signing_key)?;
1258        master_key.verify_subkey(&user_signing_key)?;
1259
1260        let old = self.clone();
1261
1262        self.self_signing_key = self_signing_key.into();
1263        self.user_signing_key = user_signing_key.into();
1264
1265        if self.master_key.as_ref() != &master_key {
1266            self.mark_as_unverified()
1267        }
1268
1269        self.master_key = master_key.into();
1270
1271        Ok(old != *self)
1272    }
1273
1274    fn filter_devices_to_request(
1275        &self,
1276        devices: HashMap<OwnedDeviceId, DeviceData>,
1277        own_device_id: &DeviceId,
1278    ) -> Vec<OwnedDeviceId> {
1279        devices
1280            .into_iter()
1281            .filter_map(|(device_id, device)| {
1282                (device_id != own_device_id && self.is_device_signed(&device)).then_some(device_id)
1283            })
1284            .collect()
1285    }
1286}
1287
1288/// Custom deserializer for [`OwnUserIdentityData::verified`].
1289///
1290/// This used to be a bool, so we need to handle that.
1291fn deserialize_own_user_identity_data_verified<'de, D>(
1292    de: D,
1293) -> Result<Arc<RwLock<OwnUserIdentityVerifiedState>>, D::Error>
1294where
1295    D: Deserializer<'de>,
1296{
1297    #[derive(Deserialize)]
1298    #[serde(untagged)]
1299    enum VerifiedStateOrBool {
1300        VerifiedState(OwnUserIdentityVerifiedState),
1301        Bool(bool),
1302    }
1303
1304    let verified_state = match VerifiedStateOrBool::deserialize(de)? {
1305        VerifiedStateOrBool::Bool(true) => OwnUserIdentityVerifiedState::Verified,
1306        VerifiedStateOrBool::Bool(false) => OwnUserIdentityVerifiedState::NeverVerified,
1307        VerifiedStateOrBool::VerifiedState(x) => x,
1308    };
1309
1310    Ok(Arc::new(RwLock::new(verified_state)))
1311}
1312
1313/// Testing Facilities
1314#[cfg(any(test, feature = "testing"))]
1315#[allow(dead_code)]
1316pub(crate) mod testing {
1317    use matrix_sdk_test::ruma_response_from_json;
1318    use ruma::{
1319        UserId,
1320        api::client::keys::{
1321            get_keys::v3::Response as KeyQueryResponse,
1322            upload_signatures::v3::Request as SignatureUploadRequest,
1323        },
1324        user_id,
1325    };
1326    use serde_json::json;
1327
1328    use super::{OtherUserIdentityData, OwnUserIdentity, OwnUserIdentityData};
1329    #[cfg(test)]
1330    use crate::{identities::manager::testing::other_user_id, olm::PrivateCrossSigningIdentity};
1331    use crate::{
1332        identities::{
1333            DeviceData,
1334            manager::testing::{other_key_query, own_key_query},
1335        },
1336        store::Store,
1337        types::CrossSigningKey,
1338        verification::VerificationMachine,
1339    };
1340
1341    /// Generate test devices from KeyQueryResponse
1342    pub fn device(response: &KeyQueryResponse) -> (DeviceData, DeviceData) {
1343        let mut devices = response.device_keys.values().next().unwrap().values();
1344        let first =
1345            DeviceData::try_from(&devices.next().unwrap().deserialize_as().unwrap()).unwrap();
1346        let second =
1347            DeviceData::try_from(&devices.next().unwrap().deserialize_as().unwrap()).unwrap();
1348        (first, second)
1349    }
1350
1351    /// Generate [`OwnUserIdentityData`] from a [`KeyQueryResponse`] for testing
1352    pub fn own_identity(response: &KeyQueryResponse) -> OwnUserIdentityData {
1353        let user_id = user_id!("@example:localhost");
1354
1355        let master_key: CrossSigningKey =
1356            response.master_keys.get(user_id).unwrap().deserialize_as().unwrap();
1357        let user_signing: CrossSigningKey =
1358            response.user_signing_keys.get(user_id).unwrap().deserialize_as().unwrap();
1359        let self_signing: CrossSigningKey =
1360            response.self_signing_keys.get(user_id).unwrap().deserialize_as().unwrap();
1361
1362        OwnUserIdentityData::new(
1363            master_key.try_into().unwrap(),
1364            self_signing.try_into().unwrap(),
1365            user_signing.try_into().unwrap(),
1366        )
1367        .unwrap()
1368    }
1369
1370    /// Generate default own identity for tests
1371    pub fn get_own_identity() -> OwnUserIdentityData {
1372        own_identity(&own_key_query())
1373    }
1374
1375    pub fn own_identity_wrapped(
1376        inner: OwnUserIdentityData,
1377        verification_machine: VerificationMachine,
1378        store: Store,
1379    ) -> OwnUserIdentity {
1380        OwnUserIdentity { inner, verification_machine, store }
1381    }
1382
1383    /// Generate default other "own" identity for tests
1384    #[cfg(test)]
1385    pub async fn get_other_own_identity() -> OwnUserIdentityData {
1386        let private_identity = PrivateCrossSigningIdentity::new(other_user_id().into());
1387        OwnUserIdentityData::from_private(&private_identity).await
1388    }
1389
1390    /// Generate default other identify for tests
1391    pub fn get_other_identity() -> OtherUserIdentityData {
1392        let user_id = user_id!("@example2:localhost");
1393        let response = other_key_query();
1394
1395        let master_key: CrossSigningKey =
1396            response.master_keys.get(user_id).unwrap().deserialize_as().unwrap();
1397        let self_signing: CrossSigningKey =
1398            response.self_signing_keys.get(user_id).unwrap().deserialize_as().unwrap();
1399
1400        OtherUserIdentityData::new(master_key.try_into().unwrap(), self_signing.try_into().unwrap())
1401            .unwrap()
1402    }
1403
1404    /// When we want to test identities that are verified, we need to simulate
1405    /// the verification process. This function supports that by simulating
1406    /// what happens when a successful verification dance happens and
1407    /// providing the /keys/query response we would get when that happened.
1408    ///
1409    /// signature_upload_request will be the result of calling
1410    /// [`super::OtherUserIdentity::verify`].
1411    ///
1412    /// # Example
1413    ///
1414    /// ```ignore
1415    /// let signature_upload_request = their_identity.verify().await.unwrap();
1416    ///
1417    /// let msk_json = json!({
1418    ///     "their_user_id": {
1419    ///         "keys": { "ed25519:blah": "blah" }
1420    ///         "signatures": {
1421    ///             "their_user_id": { "ed25519:blah": "blah", ... }
1422    ///         }
1423    ///         "usage": [ "master" ],
1424    ///         "user_id": "their_user_id"
1425    ///     }
1426    /// });
1427    ///
1428    /// let ssk_json = json!({
1429    ///     "their_user_id": {
1430    ///         "keys": { "ed25519:blah": "blah" },
1431    ///         "signatures": {
1432    ///             "their_user_id": { "ed25519:blah": "blah" }
1433    ///         },
1434    ///         "usage": [ "self_signing" ],
1435    ///         "user_id": "their_user_id"
1436    ///     }
1437    /// })
1438    ///
1439    /// let response = simulate_key_query_response_for_verification(
1440    ///     signature_upload_request,
1441    ///     my_identity,
1442    ///     my_user_id,
1443    ///     their_user_id,
1444    ///     msk_json,
1445    ///     ssk_json
1446    /// ).await;
1447    ///
1448    /// olm_machine
1449    ///     .mark_request_as_sent(
1450    ///         &TransactionId::new(),
1451    ///         crate::IncomingResponse::KeysQuery(&kq_response),
1452    ///     )
1453    ///     .await
1454    ///     .unwrap();
1455    /// ```
1456    pub fn simulate_key_query_response_for_verification(
1457        signature_upload_request: SignatureUploadRequest,
1458        my_identity: OwnUserIdentity,
1459        my_user_id: &UserId,
1460        their_user_id: &UserId,
1461        msk_json: serde_json::Value,
1462        ssk_json: serde_json::Value,
1463    ) -> KeyQueryResponse {
1464        // Find the signed key inside the SignatureUploadRequest
1465        let cross_signing_key: CrossSigningKey = serde_json::from_str(
1466            signature_upload_request
1467                .signed_keys
1468                .get(their_user_id)
1469                .expect("Signature upload request should contain a key for their user ID")
1470                .iter()
1471                .next()
1472                .expect("There should be a key in the signature upload request")
1473                .1
1474                .get(),
1475        )
1476        .expect("Should not fail to deserialize the key");
1477
1478        // Find their master key that we want to update inside their msk JSON
1479        let mut their_msk: CrossSigningKey = serde_json::from_value(
1480            msk_json.get(their_user_id.as_str()).expect("msk should contain their user ID").clone(),
1481        )
1482        .expect("Should not fail to deserialize msk");
1483
1484        // Find our own user signing key
1485        let my_user_signing_key_id = my_identity
1486            .user_signing_key()
1487            .keys()
1488            .iter()
1489            .next()
1490            .expect("There should be a user signing key")
1491            .0;
1492
1493        // Add the signature from the SignatureUploadRequest to their master key, under
1494        // our user ID
1495        their_msk.signatures.add_signature(
1496            my_user_id.to_owned(),
1497            my_user_signing_key_id.to_owned(),
1498            cross_signing_key
1499                .signatures
1500                .get_signature(my_user_id, my_user_signing_key_id)
1501                .expect("There should be a signature for our user"),
1502        );
1503
1504        // Create a JSON response as if the verification has happened
1505        ruma_response_from_json(&json!({
1506            "device_keys": {}, // Don't need devices here, even though they would exist
1507            "failures": {},
1508            "master_keys": {
1509                their_user_id: their_msk,
1510            },
1511            "self_signing_keys": ssk_json,
1512        }))
1513    }
1514}
1515
1516#[cfg(test)]
1517pub(crate) mod tests {
1518    use std::{collections::HashMap, sync::Arc};
1519
1520    use assert_matches::assert_matches;
1521    use matrix_sdk_test::{async_test, test_json};
1522    #[cfg(feature = "experimental-x509-identity-verification")]
1523    use rcgen::{Certificate, KeyPair};
1524    use ruma::{TransactionId, device_id, user_id};
1525    use serde_json::{Value, json};
1526    use tokio::sync::Mutex;
1527
1528    use super::{
1529        OtherUserIdentityDataSerializerV2, OwnUserIdentityData, OwnUserIdentityVerifiedState,
1530        UserIdentityData,
1531        testing::{device, get_other_identity, get_own_identity},
1532    };
1533    use crate::{
1534        CrossSigningKeyExport, OlmMachine, OtherUserIdentity, OtherUserIdentityData,
1535        identities::{
1536            Device,
1537            manager::testing::own_key_query,
1538            user::{
1539                OtherUserIdentityDataSerializer,
1540                testing::simulate_key_query_response_for_verification,
1541            },
1542        },
1543        olm::{Account, PrivateCrossSigningIdentity},
1544        store::{CryptoStoreWrapper, MemoryStore},
1545        types::{CrossSigningKey, MasterPubkey, SelfSigningPubkey, Signatures, UserSigningPubkey},
1546        verification::VerificationMachine,
1547    };
1548    #[cfg(feature = "experimental-x509-identity-verification")]
1549    use crate::{
1550        store::Store,
1551        x509::{
1552            RustRawX509Signer, RustRawX509Verifier, X509Signer, X509Verifier,
1553            tests::{
1554                ca_cert, cert_and_key_with_email_in_subject_distinguished_name,
1555                cert_and_key_with_email_signed_by, create_rust_signer_and_verifier,
1556            },
1557        },
1558    };
1559
1560    #[test]
1561    fn own_identity_create() {
1562        let user_id = user_id!("@example:localhost");
1563        let response = own_key_query();
1564
1565        let master_key: CrossSigningKey =
1566            response.master_keys.get(user_id).unwrap().deserialize_as().unwrap();
1567        let user_signing: CrossSigningKey =
1568            response.user_signing_keys.get(user_id).unwrap().deserialize_as().unwrap();
1569        let self_signing: CrossSigningKey =
1570            response.self_signing_keys.get(user_id).unwrap().deserialize_as().unwrap();
1571
1572        OwnUserIdentityData::new(
1573            master_key.try_into().unwrap(),
1574            self_signing.try_into().unwrap(),
1575            user_signing.try_into().unwrap(),
1576        )
1577        .unwrap();
1578    }
1579
1580    #[test]
1581    fn own_identity_partial_equality() {
1582        let user_id = user_id!("@example:localhost");
1583        let response = own_key_query();
1584
1585        let master_key: CrossSigningKey =
1586            response.master_keys.get(user_id).unwrap().deserialize_as().unwrap();
1587        let user_signing: CrossSigningKey =
1588            response.user_signing_keys.get(user_id).unwrap().deserialize_as().unwrap();
1589        let self_signing: CrossSigningKey =
1590            response.self_signing_keys.get(user_id).unwrap().deserialize_as().unwrap();
1591
1592        let identity = OwnUserIdentityData::new(
1593            master_key.clone().try_into().unwrap(),
1594            self_signing.clone().try_into().unwrap(),
1595            user_signing.clone().try_into().unwrap(),
1596        )
1597        .unwrap();
1598
1599        let mut master_key_updated_signature = master_key;
1600        master_key_updated_signature.signatures = Signatures::new();
1601
1602        let updated_identity = OwnUserIdentityData::new(
1603            master_key_updated_signature.try_into().unwrap(),
1604            self_signing.try_into().unwrap(),
1605            user_signing.try_into().unwrap(),
1606        )
1607        .unwrap();
1608
1609        assert_ne!(identity, updated_identity);
1610        assert_eq!(identity.master_key(), updated_identity.master_key());
1611    }
1612
1613    #[test]
1614    fn other_identity_create() {
1615        get_other_identity();
1616    }
1617
1618    #[test]
1619    fn deserialization_migration_test() {
1620        let serialized_value = json!({
1621                "user_id":"@example2:localhost",
1622                "master_key":{
1623                   "user_id":"@example2:localhost",
1624                   "usage":[
1625                      "master"
1626                   ],
1627                   "keys":{
1628                      "ed25519:kC/HmRYw4HNqUp/i4BkwYENrf+hd9tvdB7A1YOf5+Do":"kC/HmRYw4HNqUp/i4BkwYENrf+hd9tvdB7A1YOf5+Do"
1629                   },
1630                   "signatures":{
1631                      "@example2:localhost":{
1632                         "ed25519:SKISMLNIMH":"KdUZqzt8VScGNtufuQ8lOf25byYLWIhmUYpPENdmM8nsldexD7vj+Sxoo7PknnTX/BL9h2N7uBq0JuykjunCAw"
1633                      }
1634                   }
1635                },
1636                "self_signing_key":{
1637                   "user_id":"@example2:localhost",
1638                   "usage":[
1639                      "self_signing"
1640                   ],
1641                   "keys":{
1642                      "ed25519:ZtFrSkJ1qB8Jph/ql9Eo/lKpIYCzwvKAKXfkaS4XZNc":"ZtFrSkJ1qB8Jph/ql9Eo/lKpIYCzwvKAKXfkaS4XZNc"
1643                   },
1644                   "signatures":{
1645                      "@example2:localhost":{
1646                         "ed25519:kC/HmRYw4HNqUp/i4BkwYENrf+hd9tvdB7A1YOf5+Do":"W/O8BnmiUETPpH02mwYaBgvvgF/atXnusmpSTJZeUSH/vHg66xiZOhveQDG4cwaW8iMa+t9N4h1DWnRoHB4mCQ"
1647                      }
1648                   }
1649                }
1650        });
1651        let migrated: OtherUserIdentityData = serde_json::from_value(serialized_value).unwrap();
1652
1653        let pinned_master_key = migrated.pinned_master_key.read();
1654        assert_eq!(*pinned_master_key, migrated.master_key().clone());
1655
1656        // Serialize back
1657        let value = serde_json::to_value(migrated.clone()).unwrap();
1658
1659        // Should be serialized with latest version
1660        let _: OtherUserIdentityDataSerializerV2 =
1661            serde_json::from_value(value.clone()).expect("Should deserialize as version 2");
1662
1663        let with_serializer: OtherUserIdentityDataSerializer =
1664            serde_json::from_value(value).unwrap();
1665        assert_eq!("2", with_serializer.version.unwrap());
1666    }
1667
1668    /// [`OwnUserIdentityData::verified`] was previously an AtomicBool. Check
1669    /// that we can deserialize boolean values.
1670    #[test]
1671    fn test_deserialize_own_user_identity_bool_verified() {
1672        let mut json = own_user_identity_data();
1673
1674        // Set `"verified": false`
1675        *json.get_mut("verified").unwrap() = false.into();
1676        let id: OwnUserIdentityData = serde_json::from_value(json.clone()).unwrap();
1677        assert_eq!(*id.verified.read(), OwnUserIdentityVerifiedState::NeverVerified);
1678
1679        // Tweak the json to have `"verified": true`, and repeat
1680        *json.get_mut("verified").unwrap() = true.into();
1681        let id: OwnUserIdentityData = serde_json::from_value(json.clone()).unwrap();
1682        assert_eq!(*id.verified.read(), OwnUserIdentityVerifiedState::Verified);
1683    }
1684
1685    #[test]
1686    fn test_own_user_identity_verified_state_verification_violation_deserializes() {
1687        // Given data containing verified: VerificationViolation
1688        let mut json = own_user_identity_data();
1689        *json.get_mut("verified").unwrap() = "VerificationViolation".into();
1690
1691        // When we deserialize
1692        let id: OwnUserIdentityData = serde_json::from_value(json.clone()).unwrap();
1693
1694        // Then the value is correctly populated
1695        assert_eq!(*id.verified.read(), OwnUserIdentityVerifiedState::VerificationViolation);
1696    }
1697
1698    #[test]
1699    fn test_own_user_identity_verified_state_previously_verified_deserializes() {
1700        // Given data containing verified: PreviouslyVerifiedButNoLonger
1701        let mut json = own_user_identity_data();
1702        *json.get_mut("verified").unwrap() = "PreviouslyVerifiedButNoLonger".into();
1703
1704        // When we deserialize
1705        let id: OwnUserIdentityData = serde_json::from_value(json.clone()).unwrap();
1706
1707        // Then the old value is re-interpreted as VerificationViolation
1708        assert_eq!(*id.verified.read(), OwnUserIdentityVerifiedState::VerificationViolation);
1709    }
1710
1711    #[test]
1712    fn own_identity_check_signatures() {
1713        let response = own_key_query();
1714        let identity = get_own_identity();
1715        let (first, second) = device(&response);
1716
1717        assert!(!identity.is_device_signed(&first));
1718        assert!(identity.is_device_signed(&second));
1719
1720        let account = Account::with_device_id(second.user_id(), second.device_id());
1721        let verification_machine = get_verification_machine(&account);
1722
1723        let first = Device {
1724            inner: first,
1725            verification_machine: verification_machine.clone(),
1726            own_identity: Some(identity.clone()),
1727            device_owner_identity: Some(UserIdentityData::Own(identity.clone())),
1728        };
1729
1730        let second = Device {
1731            inner: second,
1732            verification_machine,
1733            own_identity: Some(identity.clone()),
1734            device_owner_identity: Some(UserIdentityData::Own(identity.clone())),
1735        };
1736
1737        assert!(!second.is_locally_trusted());
1738        assert!(!second.is_cross_signing_trusted());
1739
1740        assert!(!first.is_locally_trusted());
1741        assert!(!first.is_cross_signing_trusted());
1742
1743        identity.mark_as_verified();
1744        assert!(second.is_verified());
1745        assert!(!first.is_verified());
1746    }
1747
1748    #[async_test]
1749    async fn test_own_device_with_private_identity() {
1750        let response = own_key_query();
1751        let (_, device) = device(&response);
1752
1753        let account = Account::with_device_id(device.user_id(), device.device_id());
1754        let verification_machine = get_verification_machine(&account);
1755        let public_identity = verification_machine.get_own_user_identity_data().await.unwrap();
1756
1757        let mut device = Device {
1758            inner: device,
1759            verification_machine: verification_machine.clone(),
1760            own_identity: Some(public_identity.clone()),
1761            device_owner_identity: Some(public_identity.clone().into()),
1762        };
1763
1764        assert!(!device.is_verified());
1765
1766        let mut device_keys = device.as_device_keys().to_owned();
1767
1768        let identity = verification_machine.store.private_identity.lock().await;
1769        identity.sign_device_keys(&mut device_keys).await.unwrap();
1770        device.inner.update_device(&device_keys).expect("Couldn't update newly signed device keys");
1771        assert!(device.is_verified());
1772    }
1773
1774    /// Test that `CrossSigningKey` instances without a correct `usage` cannot
1775    /// be deserialized into high-level structs representing the MSK, SSK
1776    /// and USK.
1777    #[test]
1778    fn cannot_instantiate_keys_with_incorrect_usage() {
1779        let user_id = user_id!("@example:localhost");
1780        let response = own_key_query();
1781
1782        let master_key = response.master_keys.get(user_id).unwrap();
1783        let mut master_key_json: Value = master_key.deserialize_as().unwrap();
1784        let self_signing_key = response.self_signing_keys.get(user_id).unwrap();
1785        let mut self_signing_key_json: Value = self_signing_key.deserialize_as().unwrap();
1786        let user_signing_key = response.user_signing_keys.get(user_id).unwrap();
1787        let mut user_signing_key_json: Value = user_signing_key.deserialize_as().unwrap();
1788
1789        // Delete the usages.
1790        let usage = master_key_json.get_mut("usage").unwrap();
1791        *usage = json!([]);
1792        let usage = self_signing_key_json.get_mut("usage").unwrap();
1793        *usage = json!([]);
1794        let usage = user_signing_key_json.get_mut("usage").unwrap();
1795        *usage = json!([]);
1796
1797        // It should now be impossible to deserialize the keys into their corresponding
1798        // high-level cross-signing key structs.
1799        assert_matches!(serde_json::from_value::<MasterPubkey>(master_key_json.clone()), Err(_));
1800        assert_matches!(
1801            serde_json::from_value::<SelfSigningPubkey>(self_signing_key_json.clone()),
1802            Err(_)
1803        );
1804        assert_matches!(
1805            serde_json::from_value::<UserSigningPubkey>(user_signing_key_json.clone()),
1806            Err(_)
1807        );
1808
1809        // Add additional usages.
1810        let usage = master_key_json.get_mut("usage").unwrap();
1811        *usage = json!(["master", "user_signing"]);
1812        let usage = self_signing_key_json.get_mut("usage").unwrap();
1813        *usage = json!(["self_signing", "user_signing"]);
1814        let usage = user_signing_key_json.get_mut("usage").unwrap();
1815        *usage = json!(["user_signing", "self_signing"]);
1816
1817        // It should still be impossible to deserialize the keys into their
1818        // corresponding high-level cross-signing key structs.
1819        assert_matches!(serde_json::from_value::<MasterPubkey>(master_key_json.clone()), Err(_));
1820        assert_matches!(
1821            serde_json::from_value::<SelfSigningPubkey>(self_signing_key_json.clone()),
1822            Err(_)
1823        );
1824        assert_matches!(
1825            serde_json::from_value::<UserSigningPubkey>(user_signing_key_json.clone()),
1826            Err(_)
1827        );
1828    }
1829
1830    #[test]
1831    fn filter_devices_to_request() {
1832        let response = own_key_query();
1833        let identity = get_own_identity();
1834        let (first, second) = device(&response);
1835
1836        let second_device_id = second.device_id().to_owned();
1837        let unknown_device_id = device_id!("UNKNOWN");
1838
1839        let devices = HashMap::from([
1840            (first.device_id().to_owned(), first),
1841            (second.device_id().to_owned(), second),
1842        ]);
1843
1844        // Own device and devices not verified are filtered out.
1845        assert_eq!(identity.filter_devices_to_request(devices.clone(), &second_device_id).len(), 0);
1846        // Signed devices that are not our own are kept.
1847        assert_eq!(
1848            identity.filter_devices_to_request(devices, unknown_device_id),
1849            [second_device_id]
1850        );
1851    }
1852
1853    #[async_test]
1854    async fn test_resolve_identity_pin_violation_with_verification() {
1855        use test_json::keys_query_sets::IdentityChangeDataSet as DataSet;
1856
1857        let my_user_id = user_id!("@me:localhost");
1858        let machine = OlmMachine::new(my_user_id, device_id!("ABCDEFGH")).await;
1859        machine.bootstrap_cross_signing(false).await.unwrap();
1860
1861        let my_id = machine.get_identity(my_user_id, None).await.unwrap().unwrap().own().unwrap();
1862
1863        let keys_query = DataSet::key_query_with_identity_a();
1864        let txn_id = TransactionId::new();
1865        machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
1866
1867        // Simulate an identity change
1868        let keys_query = DataSet::key_query_with_identity_b();
1869        let txn_id = TransactionId::new();
1870        machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
1871
1872        let other_user_id = DataSet::user_id();
1873
1874        let other_identity =
1875            machine.get_identity(other_user_id, None).await.unwrap().unwrap().other().unwrap();
1876
1877        // The identity should need user approval now
1878        assert!(other_identity.identity_needs_user_approval());
1879
1880        // Manually verify for the purpose of this test
1881        let sig_upload = other_identity.verify().await.unwrap();
1882
1883        let kq_response = simulate_key_query_response_for_verification(
1884            sig_upload,
1885            my_id,
1886            my_user_id,
1887            other_user_id,
1888            DataSet::master_signing_keys_b(),
1889            DataSet::self_signing_keys_b(),
1890        );
1891        machine.mark_request_as_sent(&TransactionId::new(), &kq_response).await.unwrap();
1892
1893        // The identity should not need any user approval now
1894        let other_identity =
1895            machine.get_identity(other_user_id, None).await.unwrap().unwrap().other().unwrap();
1896        assert!(!other_identity.identity_needs_user_approval());
1897        // But there is still a pin violation
1898        assert!(other_identity.inner.has_pin_violation());
1899    }
1900
1901    #[async_test]
1902    async fn test_resolve_identity_pin_violation_with_withdraw_verification() {
1903        use test_json::keys_query_sets::IdentityChangeDataSet as DataSet;
1904
1905        let my_user_id = user_id!("@me:localhost");
1906        let machine = OlmMachine::new(my_user_id, device_id!("ABCDEFGH")).await;
1907        machine.bootstrap_cross_signing(false).await.unwrap();
1908
1909        let keys_query = DataSet::key_query_with_identity_a();
1910        let txn_id = TransactionId::new();
1911        machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
1912
1913        // Simulate an identity change
1914        let keys_query = DataSet::key_query_with_identity_b();
1915        let txn_id = TransactionId::new();
1916        machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
1917
1918        let other_user_id = DataSet::user_id();
1919
1920        let other_identity =
1921            machine.get_identity(other_user_id, None).await.unwrap().unwrap().other().unwrap();
1922
1923        // For testing purpose mark it as previously verified
1924        other_identity.mark_as_previously_verified().await.unwrap();
1925
1926        // The identity should need user approval now
1927        assert!(other_identity.identity_needs_user_approval());
1928
1929        // We withdraw verification
1930        other_identity.withdraw_verification().await.unwrap();
1931
1932        // The identity should not need any user approval now
1933        let other_identity =
1934            machine.get_identity(other_user_id, None).await.unwrap().unwrap().other().unwrap();
1935        assert!(!other_identity.identity_needs_user_approval());
1936        // And should not have a pin violation
1937        assert!(!other_identity.inner.has_pin_violation());
1938    }
1939
1940    #[async_test]
1941    async fn test_resolve_identity_verification_violation_with_withdraw() {
1942        use test_json::keys_query_sets::VerificationViolationTestData as DataSet;
1943
1944        let machine = OlmMachine::new(DataSet::own_id(), device_id!("LOCAL")).await;
1945
1946        let keys_query = DataSet::own_keys_query_response_1();
1947        let txn_id = TransactionId::new();
1948        machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
1949
1950        machine
1951            .import_cross_signing_keys(CrossSigningKeyExport {
1952                master_key: DataSet::MASTER_KEY_PRIVATE_EXPORT.to_owned().into(),
1953                self_signing_key: DataSet::SELF_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
1954                user_signing_key: DataSet::USER_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
1955            })
1956            .await
1957            .unwrap();
1958
1959        let keys_query = DataSet::bob_keys_query_response_rotated();
1960        let txn_id = TransactionId::new();
1961        machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
1962
1963        let bob_identity =
1964            machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
1965
1966        // For testing purpose mark it as previously verified
1967        bob_identity.mark_as_previously_verified().await.unwrap();
1968
1969        assert!(bob_identity.has_verification_violation());
1970
1971        // withdraw
1972        bob_identity.withdraw_verification().await.unwrap();
1973
1974        let bob_identity =
1975            machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
1976
1977        assert!(!bob_identity.has_verification_violation());
1978    }
1979
1980    #[async_test]
1981    async fn test_reset_own_keys_creates_verification_violation() {
1982        use test_json::keys_query_sets::VerificationViolationTestData as DataSet;
1983
1984        let machine = OlmMachine::new(DataSet::own_id(), device_id!("LOCAL")).await;
1985
1986        let keys_query = DataSet::own_keys_query_response_1();
1987        let txn_id = TransactionId::new();
1988        machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
1989
1990        machine
1991            .import_cross_signing_keys(CrossSigningKeyExport {
1992                master_key: DataSet::MASTER_KEY_PRIVATE_EXPORT.to_owned().into(),
1993                self_signing_key: DataSet::SELF_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
1994                user_signing_key: DataSet::USER_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
1995            })
1996            .await
1997            .unwrap();
1998
1999        let keys_query = DataSet::bob_keys_query_response_signed();
2000        let txn_id = TransactionId::new();
2001        machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
2002
2003        let bob_identity =
2004            machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
2005
2006        // For testing purpose mark it as previously verified
2007        bob_identity.mark_as_previously_verified().await.unwrap();
2008
2009        assert!(!bob_identity.has_verification_violation());
2010
2011        let _ = machine.bootstrap_cross_signing(true).await.unwrap();
2012
2013        let bob_identity =
2014            machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
2015
2016        assert!(bob_identity.has_verification_violation());
2017    }
2018
2019    /// Test that receiving new public keys for our own identity causes a
2020    /// verification violation on our own identity.
2021    #[async_test]
2022    async fn test_own_keys_update_creates_own_identity_verification_violation() {
2023        use test_json::keys_query_sets::VerificationViolationTestData as DataSet;
2024
2025        let machine = OlmMachine::new(DataSet::own_id(), device_id!("LOCAL")).await;
2026
2027        // Start with our own identity verified
2028        let own_keys = DataSet::own_keys_query_response_1();
2029        machine.mark_request_as_sent(&TransactionId::new(), &own_keys).await.unwrap();
2030
2031        machine
2032            .import_cross_signing_keys(CrossSigningKeyExport {
2033                master_key: DataSet::MASTER_KEY_PRIVATE_EXPORT.to_owned().into(),
2034                self_signing_key: DataSet::SELF_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
2035                user_signing_key: DataSet::USER_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
2036            })
2037            .await
2038            .unwrap();
2039
2040        // Double-check that we have a verified identity
2041        let own_identity = machine.get_identity(DataSet::own_id(), None).await.unwrap().unwrap();
2042        assert!(own_identity.is_verified());
2043        assert!(own_identity.was_previously_verified());
2044        assert!(!own_identity.has_verification_violation());
2045
2046        // Now, we receive a *different* set of public keys
2047        let own_keys = DataSet::own_keys_query_response_2();
2048        machine.mark_request_as_sent(&TransactionId::new(), &own_keys).await.unwrap();
2049
2050        // That should give an identity that is no longer verified, with a verification
2051        // violation.
2052        let own_identity = machine.get_identity(DataSet::own_id(), None).await.unwrap().unwrap();
2053        assert!(!own_identity.is_verified());
2054        assert!(own_identity.was_previously_verified());
2055        assert!(own_identity.has_verification_violation());
2056
2057        // Now check that we can withdraw verification for our own identity, and that it
2058        // becomes valid again.
2059        own_identity.withdraw_verification().await.unwrap();
2060
2061        assert!(!own_identity.is_verified());
2062        assert!(!own_identity.was_previously_verified());
2063        assert!(!own_identity.has_verification_violation());
2064    }
2065
2066    fn own_user_identity_data() -> Value {
2067        json!({
2068            "user_id": "@example:localhost",
2069            "master_key": {
2070                "user_id":"@example:localhost",
2071                "usage":["master"],
2072                "keys":{"ed25519:rJ2TAGkEOP6dX41Ksll6cl8K3J48l8s/59zaXyvl2p0":"rJ2TAGkEOP6dX41Ksll6cl8K3J48l8s/59zaXyvl2p0"},
2073            },
2074            "self_signing_key": {
2075                "user_id":"@example:localhost",
2076                "usage":["self_signing"],
2077                "keys":{"ed25519:0C8lCBxrvrv/O7BQfsKnkYogHZX3zAgw3RfJuyiq210":"0C8lCBxrvrv/O7BQfsKnkYogHZX3zAgw3RfJuyiq210"}
2078            },
2079            "user_signing_key": {
2080                "user_id":"@example:localhost",
2081                "usage":["user_signing"],
2082                "keys":{"ed25519:DU9z4gBFKFKCk7a13sW9wjT0Iyg7Hqv5f0BPM7DEhPo":"DU9z4gBFKFKCk7a13sW9wjT0Iyg7Hqv5f0BPM7DEhPo"}
2083            },
2084            "verified": false
2085        })
2086    }
2087
2088    #[async_test]
2089    async fn test_other_user_identity_verification_request_content() {
2090        let other_user_identity = other_user_identity().await;
2091        let verification_request_content = other_user_identity.verification_request_content(None);
2092        let mut verification_request_content_json =
2093            serde_json::to_value(verification_request_content)
2094                .expect("Could not serialize verification request content");
2095
2096        // Remove the body which is a pain to match
2097        let verification_request_content_object = verification_request_content_json
2098            .as_object_mut()
2099            .expect("serialized verification request was not an object");
2100        verification_request_content_object.remove("body").expect("No `body` in message content");
2101
2102        // The methods are variable too
2103        let methods = verification_request_content_object
2104            .remove("methods")
2105            .expect("No `methods` in message content");
2106        let methods = methods.as_array().expect("`methods` was not an array");
2107        assert!(methods.contains(&json!("m.sas.v1")));
2108        assert!(methods.contains(&json!("m.reciprocate.v1")));
2109
2110        assert_eq!(
2111            verification_request_content_json,
2112            json!({
2113                "msgtype": "m.key.verification.request",
2114                "from_device": "DEV123",
2115                "to": other_user_identity.user_id().to_string(),
2116            })
2117        );
2118    }
2119
2120    #[cfg(feature = "experimental-x509-identity-verification")]
2121    #[async_test]
2122    async fn test_sign_own_identity_with_x509() {
2123        let account =
2124            Account::with_device_id(user_id!("@own_user:localhost"), device_id!("DEV123"));
2125        // We create a store with an X.509 signer
2126        let (cert, signing_key) =
2127            cert_and_key_with_email_in_subject_distinguished_name("own_user@localhost");
2128
2129        let (x509_signer, x509_verifier) = create_rust_signer_and_verifier(cert, signing_key);
2130
2131        let store = create_store_with_x509(account, x509_verifier.clone(), x509_signer).await;
2132
2133        // When we verify our own identity, the uploaded identity key should be
2134        // signed using X.509.
2135        let own_identity = store
2136            .get_identity(user_id!("@own_user:localhost"))
2137            .await
2138            .unwrap()
2139            .unwrap()
2140            .own()
2141            .unwrap();
2142        let signature_upload_request = own_identity.verify().await.unwrap();
2143        let (_, signed_key) = signature_upload_request
2144            .signed_keys
2145            .get(user_id!("@own_user:localhost"))
2146            .unwrap()
2147            .iter()
2148            .next()
2149            .unwrap();
2150        let signed_key: CrossSigningKey = serde_json::from_str(signed_key.get()).unwrap();
2151
2152        assert!(x509_verifier.verify_signed_object(user_id!("@own_user:localhost"), &signed_key));
2153    }
2154
2155    #[cfg(feature = "experimental-x509-identity-verification")]
2156    #[async_test]
2157    async fn test_verify_other_identity_with_x509() {
2158        // Given that a CA exists
2159        let (ca_cert, ca_signing_key) = ca_cert();
2160
2161        // And Alice has an X.509-signed identity
2162        let alice_identity_data = signed_other_identity(&ca_cert, &ca_signing_key).await;
2163
2164        // (And Bob exists)
2165        let bob_account = Account::with_device_id(user_id!("@bob:hs.co"), device_id!("DEV123"));
2166        let bob_verification_machine = get_verification_machine(&bob_account);
2167
2168        let bob_identity_data =
2169            bob_verification_machine.get_own_user_identity_data().await.unwrap();
2170
2171        // When Bob checks Alice's identity without using X.509
2172        let mut bobs_view_of_alice = OtherUserIdentity {
2173            inner: alice_identity_data.clone(),
2174            own_identity: Some(bob_identity_data),
2175            verification_machine: bob_verification_machine.clone(),
2176            x509_verifier: None,
2177        };
2178
2179        // Then Alice is not verified
2180        assert!(!bobs_view_of_alice.is_verified());
2181
2182        // But when Bob checks Alice's identity with a proper X.509 verifier
2183        bobs_view_of_alice.x509_verifier = Some(X509Verifier::new(Arc::new(
2184            RustRawX509Verifier::new_from_pem_data(&ca_cert.pem()).unwrap(),
2185        )));
2186
2187        // Then Alice is verified
2188        assert!(bobs_view_of_alice.is_verified());
2189    }
2190
2191    #[cfg(feature = "experimental-x509-identity-verification")]
2192    #[async_test]
2193    async fn test_refresh_signature() {
2194        let user_id = user_id!("@own_user:localhost");
2195        let account = Account::with_device_id(user_id, device_id!("DEV123"));
2196
2197        // We create three signers with different validity periods: an "old" signer, a
2198        // "current" signer, and a "new" signer
2199        let (x509_signer_old, x509_signer_current, x509_signer_new) =
2200            crate::x509::tests::signers_with_different_validity();
2201
2202        // We sign our identity with the current signer.
2203        let private_identity =
2204            PrivateCrossSigningIdentity::for_account(&account, Some(&x509_signer_current)).unwrap();
2205
2206        // If we create a store with the old signer, it should not try to
2207        // re-sign our identity.
2208        let store = create_store_with_private_identity_and_x509(
2209            account.deep_clone(),
2210            private_identity.clone(),
2211            None,
2212            Some(x509_signer_old.clone()),
2213        )
2214        .await;
2215
2216        let own_identity = store.get_identity(user_id).await.unwrap().unwrap().own().unwrap();
2217        assert!(own_identity.refresh_x509_signature(&store).unwrap().is_none());
2218
2219        // If we create a store with the same signer, it should not try to
2220        // re-sign our identity.
2221        let store = create_store_with_private_identity_and_x509(
2222            account.deep_clone(),
2223            private_identity.clone(),
2224            None,
2225            Some(x509_signer_current.clone()),
2226        )
2227        .await;
2228
2229        let own_identity = store.get_identity(user_id).await.unwrap().unwrap().own().unwrap();
2230        assert!(own_identity.refresh_x509_signature(&store).unwrap().is_none());
2231
2232        // If we create a store with the newer signer, it should re-sign our
2233        // identity.
2234        let store = create_store_with_private_identity_and_x509(
2235            account.deep_clone(),
2236            private_identity.clone(),
2237            None,
2238            Some(x509_signer_new.clone()),
2239        )
2240        .await;
2241
2242        let own_identity = store.get_identity(user_id).await.unwrap().unwrap().own().unwrap();
2243        assert!(own_identity.refresh_x509_signature(&store).unwrap().is_some());
2244    }
2245
2246    /// Generate a key pair and cert, signed by the supplied certificate
2247    /// authority, and return a new user's [`OtherUserIdentityData`] whose
2248    /// master signing key is signed by them.
2249    #[cfg(feature = "experimental-x509-identity-verification")]
2250    async fn signed_other_identity(
2251        ca_cert: &Certificate,
2252        ca_signing_key: &KeyPair,
2253    ) -> OtherUserIdentityData {
2254        let (cert, signing_key) =
2255            cert_and_key_with_email_signed_by("alice@hs.co", ca_cert, ca_signing_key);
2256
2257        let x509_signer = X509Signer::new(Arc::new(
2258            RustRawX509Signer::new_from_pem_data(&cert.pem(), &signing_key.serialize_pem())
2259                .unwrap(),
2260        ));
2261
2262        let account = Account::with_device_id(user_id!("@alice:hs.co"), device_id!("DEV123"));
2263
2264        let private_identity =
2265            PrivateCrossSigningIdentity::for_account(&account, Some(&x509_signer)).unwrap();
2266
2267        let public_identity = private_identity.to_public_identity().await.unwrap();
2268
2269        OtherUserIdentityData::new(
2270            public_identity.master_key().clone(),
2271            public_identity.self_signing_key().clone(),
2272        )
2273        .unwrap()
2274    }
2275
2276    /// Create an [`OtherUserIdentity`] for use in tests
2277    async fn other_user_identity() -> OtherUserIdentity {
2278        let other_user_identity_data = get_other_identity();
2279
2280        let account =
2281            Account::with_device_id(user_id!("@own_user:localhost"), device_id!("DEV123"));
2282
2283        let verification_machine = get_verification_machine(&account);
2284        let own_identity_data = verification_machine.get_own_user_identity_data().await.unwrap();
2285
2286        OtherUserIdentity {
2287            inner: other_user_identity_data,
2288            own_identity: Some(own_identity_data),
2289            verification_machine,
2290            #[cfg(feature = "experimental-x509-identity-verification")]
2291            x509_verifier: None,
2292        }
2293    }
2294
2295    /**
2296     * Create a minimal [`VerificationMachine`] for the given account,
2297     * backed by a [`MemoryStore`].
2298     *
2299     * Creates a new private user identity for the account.
2300     */
2301    fn get_verification_machine(account: &Account) -> VerificationMachine {
2302        let private_identity = PrivateCrossSigningIdentity::for_account(
2303            account,
2304            #[cfg(feature = "experimental-x509-identity-verification")]
2305            None,
2306        )
2307        .unwrap();
2308        VerificationMachine::new(
2309            account.static_data().clone(),
2310            Arc::new(Mutex::new(private_identity)),
2311            Arc::new(CryptoStoreWrapper::new(
2312                account.user_id(),
2313                account.device_id(),
2314                MemoryStore::new(),
2315            )),
2316        )
2317    }
2318
2319    /**
2320     * Creates a crypto store, backed by a [`MemoryStore`], for the given
2321     * account, with an X.509 verifier and signer.  The private identity
2322     * will not be signed by X.509.
2323     */
2324    #[cfg(feature = "experimental-x509-identity-verification")]
2325    async fn create_store_with_x509(
2326        account: Account,
2327        x509_verifier: X509Verifier,
2328        x509_signer: X509Signer,
2329    ) -> Store {
2330        let private_identity = PrivateCrossSigningIdentity::for_account(&account, None).unwrap();
2331
2332        create_store_with_private_identity_and_x509(
2333            account,
2334            private_identity,
2335            Some(x509_verifier),
2336            Some(x509_signer),
2337        )
2338        .await
2339    }
2340
2341    /**
2342     * Creates a crypto store, backed by a [`MemoryStore`], for the given
2343     * account and private identity, with an X.509 verifier and signer.
2344     */
2345    #[cfg(feature = "experimental-x509-identity-verification")]
2346    async fn create_store_with_private_identity_and_x509(
2347        account: Account,
2348        private_identity: PrivateCrossSigningIdentity,
2349        x509_verifier: Option<X509Verifier>,
2350        x509_signer: Option<X509Signer>,
2351    ) -> Store {
2352        use crate::store::types::{Changes, IdentityChanges, PendingChanges};
2353
2354        let account_static_data = account.static_data().clone();
2355        let crypto_store_wrapper =
2356            CryptoStoreWrapper::new(account.user_id(), account.device_id(), MemoryStore::new());
2357        crypto_store_wrapper
2358            .save_pending_changes(PendingChanges { account: Some(account) })
2359            .await
2360            .unwrap();
2361        let changes = Changes {
2362            private_identity: Some(private_identity.clone()),
2363            identities: IdentityChanges {
2364                changed: vec![private_identity.to_public_identity().await.unwrap().into()],
2365                ..Default::default()
2366            },
2367            ..Default::default()
2368        };
2369        crypto_store_wrapper.save_changes(changes).await.unwrap();
2370
2371        let crypto_store_wrapper = Arc::new(crypto_store_wrapper);
2372        let private_identity = Arc::new(Mutex::new(private_identity));
2373        let verification_machine = VerificationMachine::new(
2374            account_static_data.clone(),
2375            private_identity.clone(),
2376            crypto_store_wrapper.clone(),
2377        );
2378
2379        Store::new_with_x509(
2380            account_static_data.clone(),
2381            private_identity,
2382            crypto_store_wrapper,
2383            verification_machine,
2384            x509_verifier,
2385            x509_signer,
2386        )
2387    }
2388}