@@ -375,6 +375,24 @@ pub struct ReadOnlyUserIdentity {
375
375
user_id : OwnedUserId ,
376
376
pub ( crate ) master_key : Arc < MasterPubkey > ,
377
377
self_signing_key : Arc < SelfSigningPubkey > ,
378
+ /// The first time an identity is seen for a given user it will be marked as
379
+ /// tofu trusted. If a new identity is detected for that user, we must
380
+ /// ensure that this change has been shown and validated by the user. If
381
+ /// this boolean is set to `false`, sharing room keys to this user might
382
+ /// fail depending on the room key sharing strategy.
383
+ #[ serde(
384
+ default = "tofu_trusted_default" ,
385
+ serialize_with = "atomic_bool_serializer" ,
386
+ deserialize_with = "atomic_bool_deserializer"
387
+ ) ]
388
+ tofu_trusted : Arc < AtomicBool > ,
389
+ }
390
+
391
+ // The tofu_trusted field introduced a new field in the database
392
+ // schema, for backwards compatibility we assume that if the identity is
393
+ // already in the database we considered it as tofu trusted.
394
+ fn tofu_trusted_default ( ) -> Arc < AtomicBool > {
395
+ Arc :: new ( true . into ( ) )
378
396
}
379
397
380
398
impl PartialEq for ReadOnlyUserIdentity {
@@ -395,6 +413,7 @@ impl PartialEq for ReadOnlyUserIdentity {
395
413
&& self . master_key == other. master_key
396
414
&& self . self_signing_key == other. self_signing_key
397
415
&& self . master_key . signatures ( ) == other. master_key . signatures ( )
416
+ && self . is_tofu_trusted ( ) == other. is_tofu_trusted ( )
398
417
}
399
418
}
400
419
@@ -406,19 +425,22 @@ impl ReadOnlyUserIdentity {
406
425
/// * `master_key` - The master key of the user identity.
407
426
///
408
427
/// * `self signing key` - The self signing key of user identity.
428
+ /// * `tofu_trusted` - Is this identity tofu trusted.
409
429
///
410
430
/// Returns a `SignatureError` if the self signing key fails to be correctly
411
431
/// verified by the given master key.
412
432
pub ( crate ) fn new (
413
433
master_key : MasterPubkey ,
414
434
self_signing_key : SelfSigningPubkey ,
435
+ tofu_trusted : bool ,
415
436
) -> Result < Self , SignatureError > {
416
437
master_key. verify_subkey ( & self_signing_key) ?;
417
438
418
439
Ok ( Self {
419
440
user_id : master_key. user_id ( ) . into ( ) ,
420
441
master_key : master_key. into ( ) ,
421
442
self_signing_key : self_signing_key. into ( ) ,
443
+ tofu_trusted : AtomicBool :: new ( tofu_trusted) . into ( ) ,
422
444
} )
423
445
}
424
446
@@ -429,7 +451,12 @@ impl ReadOnlyUserIdentity {
429
451
let self_signing_key =
430
452
identity. self_signing_key . lock ( ) . await . as_ref ( ) . unwrap ( ) . public_key ( ) . clone ( ) . into ( ) ;
431
453
432
- Self { user_id : identity. user_id ( ) . into ( ) , master_key, self_signing_key }
454
+ Self {
455
+ user_id : identity. user_id ( ) . into ( ) ,
456
+ master_key,
457
+ self_signing_key,
458
+ tofu_trusted : AtomicBool :: new ( true ) . into ( ) ,
459
+ }
433
460
}
434
461
435
462
/// Get the user id of this identity.
@@ -447,6 +474,21 @@ impl ReadOnlyUserIdentity {
447
474
& self . self_signing_key
448
475
}
449
476
477
+ /// Check if our identity is verified.
478
+ pub fn is_tofu_trusted ( & self ) -> bool {
479
+ self . tofu_trusted . load ( Ordering :: SeqCst )
480
+ }
481
+
482
+ /// Mark this identity as tofu trusted by the user
483
+ pub fn mark_as_tofu_trusted ( & self ) {
484
+ self . tofu_trusted . store ( true , Ordering :: SeqCst )
485
+ }
486
+
487
+ #[ cfg( test) ]
488
+ pub fn mark_as_not_tofu_trusted ( & self ) {
489
+ self . tofu_trusted . store ( false , Ordering :: SeqCst )
490
+ }
491
+
450
492
/// Update the identity with a new master key and self signing key.
451
493
///
452
494
/// # Arguments
@@ -465,7 +507,7 @@ impl ReadOnlyUserIdentity {
465
507
) -> Result < bool , SignatureError > {
466
508
master_key. verify_subkey ( & self_signing_key) ?;
467
509
468
- let new = Self :: new ( master_key, self_signing_key) ?;
510
+ let new = Self :: new ( master_key, self_signing_key, false ) ?;
469
511
let changed = new != * self ;
470
512
471
513
* self = new;
@@ -776,8 +818,12 @@ pub(crate) mod testing {
776
818
let self_signing: CrossSigningKey =
777
819
response. self_signing_keys . get ( user_id) . unwrap ( ) . deserialize_as ( ) . unwrap ( ) ;
778
820
779
- ReadOnlyUserIdentity :: new ( master_key. try_into ( ) . unwrap ( ) , self_signing. try_into ( ) . unwrap ( ) )
780
- . unwrap ( )
821
+ ReadOnlyUserIdentity :: new (
822
+ master_key. try_into ( ) . unwrap ( ) ,
823
+ self_signing. try_into ( ) . unwrap ( ) ,
824
+ true ,
825
+ )
826
+ . unwrap ( )
781
827
}
782
828
}
783
829
0 commit comments