@@ -397,6 +397,103 @@ async fn test_own_verification() {
397397 assert_eq ! ( alice. encryption( ) . verification_state( ) . get( ) , VerificationState :: Verified ) ;
398398}
399399
400+ #[ async_test]
401+ async fn test_reset_cross_signing_resets_verification ( ) {
402+ let mut server = MockedServer :: new ( ) . await ;
403+
404+ let user_id = owned_user_id ! ( "@alice:example.org" ) ;
405+ let device_id = owned_device_id ! ( "4L1C3" ) ;
406+ let alice = Client :: builder ( )
407+ . homeserver_url ( server. server . uri ( ) )
408+ . server_versions ( [ MatrixVersion :: V1_0 ] )
409+ . request_config ( RequestConfig :: new ( ) . disable_retry ( ) )
410+ . build ( )
411+ . await
412+ . unwrap ( ) ;
413+ alice
414+ . restore_session ( MatrixSession {
415+ meta : SessionMeta { user_id : user_id. clone ( ) , device_id : device_id. clone ( ) } ,
416+ tokens : MatrixSessionTokens { access_token : "1234" . to_owned ( ) , refresh_token : None } ,
417+ } )
418+ . await
419+ . unwrap ( ) ;
420+
421+ // Subscribe to verification state updates
422+ let mut verification_state_subscriber = alice. encryption ( ) . verification_state ( ) ;
423+ assert_eq ! ( alice. encryption( ) . verification_state( ) . get( ) , VerificationState :: Unknown ) ;
424+
425+ server. add_known_device ( & device_id) ;
426+
427+ // Have Alice bootstrap cross-signing.
428+ bootstrap_cross_signing ( & alice) . await ;
429+
430+ // The device is not considered cross signed yet
431+ assert_eq ! (
432+ verification_state_subscriber. next( ) . await . unwrap_or( VerificationState :: Unknown ) ,
433+ VerificationState :: Unverified
434+ ) ;
435+ assert_eq ! ( alice. encryption( ) . verification_state( ) . get( ) , VerificationState :: Unverified ) ;
436+
437+ // Force a keys query to pick up the cross-signing state
438+ let mut sync_response_builder = SyncResponseBuilder :: new ( ) ;
439+ sync_response_builder. add_change_device ( & user_id) ;
440+
441+ {
442+ let _scope = mock_sync_scoped (
443+ & server. server ,
444+ sync_response_builder. build_json_sync_response ( ) ,
445+ None ,
446+ )
447+ . await ;
448+ alice. sync_once ( Default :: default ( ) ) . await . unwrap ( ) ;
449+ }
450+
451+ // The device should now be cross-signed
452+ assert_eq ! (
453+ verification_state_subscriber. next( ) . now_or_never( ) . unwrap( ) . unwrap( ) ,
454+ VerificationState :: Verified
455+ ) ;
456+ assert_eq ! ( alice. encryption( ) . verification_state( ) . get( ) , VerificationState :: Verified ) ;
457+
458+ let device_id = owned_device_id ! ( "AliceDevice2" ) ;
459+ let alice2 = Client :: builder ( )
460+ . homeserver_url ( server. server . uri ( ) )
461+ . server_versions ( [ MatrixVersion :: V1_0 ] )
462+ . request_config ( RequestConfig :: new ( ) . disable_retry ( ) )
463+ . build ( )
464+ . await
465+ . unwrap ( ) ;
466+ alice2
467+ . restore_session ( MatrixSession {
468+ meta : SessionMeta { user_id : user_id. clone ( ) , device_id : device_id. clone ( ) } ,
469+ tokens : MatrixSessionTokens { access_token : "1234" . to_owned ( ) , refresh_token : None } ,
470+ } )
471+ . await
472+ . unwrap ( ) ;
473+
474+ server. add_known_device ( & device_id) ;
475+
476+ // Have Alice bootstrap cross-signing again, this time on her second device.
477+ bootstrap_cross_signing ( & alice2) . await ;
478+
479+ {
480+ let _scope = mock_sync_scoped (
481+ & server. server ,
482+ sync_response_builder. build_json_sync_response ( ) ,
483+ None ,
484+ )
485+ . await ;
486+ alice. sync_once ( Default :: default ( ) ) . await . unwrap ( ) ;
487+ }
488+
489+ // The device shouldn't be cross-signed anymore.
490+ assert_eq ! ( alice. encryption( ) . verification_state( ) . get( ) , VerificationState :: Unverified ) ;
491+ assert_eq ! (
492+ verification_state_subscriber. next( ) . now_or_never( ) . unwrap( ) . unwrap( ) ,
493+ VerificationState :: Unverified
494+ ) ;
495+ }
496+
400497#[ async_test]
401498async fn test_unchecked_mutual_verification ( ) {
402499 let mut server = MockedServer :: new ( ) . await ;
0 commit comments