@@ -25,6 +25,8 @@ use std::{
25
25
} ;
26
26
27
27
use matrix_sdk_common:: { deserialized_responses:: WithheldCode , locks:: RwLock as StdRwLock } ;
28
+ #[ cfg( feature = "experimental-encrypted-state-events" ) ]
29
+ use ruma:: events:: AnyStateEventContent ;
28
30
use ruma:: {
29
31
events:: {
30
32
room:: { encryption:: RoomEncryptionEventContent , history_visibility:: HistoryVisibility } ,
@@ -458,6 +460,50 @@ impl OutboundGroupSession {
458
460
session. encrypt ( & plaintext)
459
461
}
460
462
463
+ /// Encrypt an arbitrary event for the given room.
464
+ ///
465
+ /// Beware that a room key needs to be shared before this method
466
+ /// can be called using the `share_room_key()` method.
467
+ ///
468
+ /// # Arguments
469
+ ///
470
+ /// * `payload` - The plaintext content of the event that should be
471
+ /// encrypted in raw JSON form.
472
+ ///
473
+ /// # Panics
474
+ ///
475
+ /// Panics if the content can't be serialized.
476
+ async fn encrypt_inner < T : Serialize > (
477
+ & self ,
478
+ payload : & T ,
479
+ relates_to : Option < serde_json:: Value > ,
480
+ ) -> Raw < RoomEncryptedEventContent > {
481
+ let ciphertext = self
482
+ . encrypt_helper (
483
+ serde_json:: to_string ( payload) . expect ( "payload serialization never fails" ) ,
484
+ )
485
+ . await ;
486
+ let scheme: RoomEventEncryptionScheme = match self . settings . algorithm {
487
+ EventEncryptionAlgorithm :: MegolmV1AesSha2 => MegolmV1AesSha2Content {
488
+ ciphertext,
489
+ sender_key : Some ( self . account_identity_keys . curve25519 ) ,
490
+ session_id : self . session_id ( ) . to_owned ( ) ,
491
+ device_id : Some ( self . device_id . clone ( ) ) ,
492
+ }
493
+ . into ( ) ,
494
+ #[ cfg( feature = "experimental-algorithms" ) ]
495
+ EventEncryptionAlgorithm :: MegolmV2AesSha2 => {
496
+ MegolmV2AesSha2Content { ciphertext, session_id : self . session_id ( ) . to_owned ( ) }
497
+ . into ( )
498
+ }
499
+ _ => unreachable ! (
500
+ "An outbound group session is always using one of the supported algorithms"
501
+ ) ,
502
+ } ;
503
+ let content = RoomEncryptedEventContent { scheme, relates_to, other : Default :: default ( ) } ;
504
+ Raw :: new ( & content) . expect ( "m.room.encrypted event content can always be serialized" )
505
+ }
506
+
461
507
/// Encrypt a room message for the given room.
462
508
///
463
509
/// Beware that a room key needs to be shared before this method
@@ -488,35 +534,51 @@ impl OutboundGroupSession {
488
534
}
489
535
490
536
let payload = Payload { event_type, content, room_id : & self . room_id } ;
491
- let payload_json =
492
- serde_json:: to_string ( & payload) . expect ( "payload serialization never fails" ) ;
493
537
494
538
let relates_to = content
495
539
. get_field :: < serde_json:: Value > ( "m.relates_to" )
496
540
. expect ( "serde_json::Value deserialization with valid JSON input never fails" ) ;
497
541
498
- let ciphertext = self . encrypt_helper ( payload_json) . await ;
499
- let scheme: RoomEventEncryptionScheme = match self . settings . algorithm {
500
- EventEncryptionAlgorithm :: MegolmV1AesSha2 => MegolmV1AesSha2Content {
501
- ciphertext,
502
- sender_key : Some ( self . account_identity_keys . curve25519 ) ,
503
- session_id : self . session_id ( ) . to_owned ( ) ,
504
- device_id : Some ( self . device_id . clone ( ) ) ,
505
- }
506
- . into ( ) ,
507
- #[ cfg( feature = "experimental-algorithms" ) ]
508
- EventEncryptionAlgorithm :: MegolmV2AesSha2 => {
509
- MegolmV2AesSha2Content { ciphertext, session_id : self . session_id ( ) . to_owned ( ) }
510
- . into ( )
511
- }
512
- _ => unreachable ! (
513
- "An outbound group session is always using one of the supported algorithms"
514
- ) ,
515
- } ;
542
+ self . encrypt_inner ( & payload, relates_to) . await
543
+ }
516
544
517
- let content = RoomEncryptedEventContent { scheme, relates_to, other : Default :: default ( ) } ;
545
+ /// Encrypt a room state event for the given room.
546
+ ///
547
+ /// Beware that a room key needs to be shared before this method
548
+ /// can be called using the `share_room_key()` method.
549
+ ///
550
+ /// # Arguments
551
+ ///
552
+ /// * `event_type` - The plaintext type of the event, the outer type of the
553
+ /// event will become `m.room.encrypted`.
554
+ ///
555
+ /// * `state_key` - The plaintext state key of the event, the outer state
556
+ /// key will be derived from this and the event type.
557
+ ///
558
+ /// * `content` - The plaintext content of the message that should be
559
+ /// encrypted in raw JSON form.
560
+ ///
561
+ /// # Panics
562
+ ///
563
+ /// Panics if the content can't be serialized.
564
+ #[ cfg( feature = "experimental-encrypted-state-events" ) ]
565
+ pub async fn encrypt_state (
566
+ & self ,
567
+ event_type : & str ,
568
+ state_key : & str ,
569
+ content : & Raw < AnyStateEventContent > ,
570
+ ) -> Raw < RoomEncryptedEventContent > {
571
+ #[ derive( Serialize ) ]
572
+ struct Payload < ' a > {
573
+ #[ serde( rename = "type" ) ]
574
+ event_type : & ' a str ,
575
+ state_key : & ' a str ,
576
+ content : & ' a Raw < AnyStateEventContent > ,
577
+ room_id : & ' a RoomId ,
578
+ }
518
579
519
- Raw :: new ( & content) . expect ( "m.room.encrypted event content can always be serialized" )
580
+ let payload = Payload { event_type, state_key, content, room_id : & self . room_id } ;
581
+ self . encrypt_inner ( & payload, None ) . await . cast_unchecked ( )
520
582
}
521
583
522
584
fn elapsed ( & self ) -> bool {
0 commit comments