async fn decrypt_olm_message(
        &self,
        sender: &UserId,
        sender_key: &str,
        message: OlmMessage,
    ) -> OlmResult<(SessionType, Raw<AnyToDeviceEvent>, String)> {
        // First try to decrypt using an existing session.
        let (session, plaintext) = if let Some(d) =
            self.decrypt_with_existing_sessions(sender, sender_key, &message).await?
        {
            // Decryption succeeded, de-structure the session/plaintext out of
            // the Option.
            (SessionType::Existing(d.0), d.1)
        } else {
            // Decryption failed with every known session, let's try to create a
            // new session.
            let mut session = match &message {
                // A new session can only be created using a pre-key message,
                // return with an error if it isn't one.
                OlmMessage::Message(_) => {
                    warn!(
                        sender = sender.as_str(),
                        sender_key = sender_key,
                        "Failed to decrypt a non-pre-key message with all \
                        available sessions",
                    );
                    return Err(OlmError::SessionWedged(sender.to_owned(), sender_key.to_owned()));
                }

                OlmMessage::PreKey(m) => {
                    // Create the new session.
                    let session =
                        match self.inner.create_inbound_session(sender_key, m.clone()).await {
                            Ok(s) => s,
                            Err(e) => {
                                warn!(
                                    sender = sender.as_str(),
                                    sender_key = sender_key,
                                    error =? e,
                                    "Failed to create a new Olm session from a \
                                    prekey message",
                                );
                                return Err(OlmError::SessionWedged(
                                    sender.to_owned(),
                                    sender_key.to_owned(),
                                ));
                            }
                        };

                    session
                }
            };

            // Decrypt our message, this shouldn't fail since we're using a
            // newly created Session.
            let plaintext = session.decrypt(message).await?;

            // We need to add the new session to the session cache, otherwise
            // we might try to create the same session again.
            // TODO separate the session cache from the storage so we only add
            // it to the cache but don't store it.
            let changes = Changes {
                account: Some(self.inner.clone()),
                sessions: vec![session.clone()],
                ..Default::default()
            };
            self.store.save_changes(changes).await?;

            (SessionType::New(session), plaintext)
        };

        trace!(
            sender = sender.as_str(),
            sender_key = sender_key,
            "Successfully decrypted an Olm message"
        );

        match self.parse_decrypted_to_device_event(sender, plaintext) {
            Ok((event, signing_key)) => Ok((session, event, signing_key)),
            Err(e) => {
                // We might created a new session but decryption might still
                // have failed, store it for the error case here, this is fine
                // since we don't expect this to happen often or at all.
                match session {
                    SessionType::New(s) => {
                        let changes = Changes {
                            account: Some(self.inner.clone()),
                            sessions: vec![s],
                            ..Default::default()
                        };
                        self.store.save_changes(changes).await?;
                    }
                    SessionType::Existing(s) => {
                        self.store.save_sessions(&[s]).await?;
                    }
                }

                warn!(
                    sender = sender.as_str(),
                    sender_key = sender_key,
                    error =? e,
                    "A to-device message was successfully decrypted but \
                    parsing and checking the event fields failed"
                );

                Err(e)
            }
        }
    }
/// Decrypt an Olm message, creating a new Olm session if possible.
Decrypt an Olm message, creating a new Olm session if possible.
Decrypt an Olm message creating a new Olm session if possible .
async fn decrypt_olm_message(
        &self,
        sender: &UserId,
        sender_key: &str,
        message: OlmMessage,
    ) -> OlmResult<(SessionType, Raw<AnyToDeviceEvent>, String)> {
        // First try to decrypt using an existing session.
        let (session, plaintext) = if let Some(d) =
            self.decrypt_with_existing_sessions(sender, sender_key, &message).await?
        {
            // Decryption succeeded, de-structure the session/plaintext out of
            // the Option.
            (SessionType::Existing(d.0), d.1)
        } else {
            // Decryption failed with every known session, let's try to create a
            // new session.
            let mut session = match &message {
                // A new session can only be created using a pre-key message,
                // return with an error if it isn't one.
                OlmMessage::Message(_) => {
                    warn!(
                        sender = sender.as_str(),
                        sender_key = sender_key,
                        "Failed to decrypt a non-pre-key message with all \
                        available sessions",
                    );
                    return Err(OlmError::SessionWedged(sender.to_owned(), sender_key.to_owned()));
                }
                OlmMessage::PreKey(m) => {
                    // Create the new session.
                    let session =
                        match self.inner.create_inbound_session(sender_key, m.clone()).await {
                            Ok(s) => s,
                            Err(e) => {
                                warn!(
                                    sender = sender.as_str(),
                                    sender_key = sender_key,
                                    error =? e,
                                    "Failed to create a new Olm session from a \
                                    prekey message",
                                );
                                return Err(OlmError::SessionWedged(
                                    sender.to_owned(),
                                    sender_key.to_owned(),
                                ));
                            }
                        };
                    session
                }
            };
            // Decrypt our message, this shouldn't fail since we're using a
            // newly created Session.
            let plaintext = session.decrypt(message).await?;
            // We need to add the new session to the session cache, otherwise
            // we might try to create the same session again.
            // TODO separate the session cache from the storage so we only add
            // it to the cache but don't store it.
            let changes = Changes {
                account: Some(self.inner.clone()),
                sessions: vec![session.clone()],
                ..Default::default()
            };
            self.store.save_changes(changes).await?;
            (SessionType::New(session), plaintext)
        };
        trace!(
            sender = sender.as_str(),
            sender_key = sender_key,
            "Successfully decrypted an Olm message"
        );
        match self.parse_decrypted_to_device_event(sender, plaintext) {
            Ok((event, signing_key)) => Ok((session, event, signing_key)),
            Err(e) => {
                // We might created a new session but decryption might still
                // have failed, store it for the error case here, this is fine
                // since we don't expect this to happen often or at all.
                match session {
                    SessionType::New(s) => {
                        let changes = Changes {
                            account: Some(self.inner.clone()),
                            sessions: vec![s],
                            ..Default::default()
                        };
                        self.store.save_changes(changes).await?;
                    }
                    SessionType::Existing(s) => {
                        self.store.save_sessions(&[s]).await?;
                    }
                }
                warn!(
                    sender = sender.as_str(),
                    sender_key = sender_key,
                    error =? e,
                    "A to-device message was successfully decrypted but \
                    parsing and checking the event fields failed"
                );
                Err(e)
            }
        }
    }
async fn decrypt_olm_message ( & self , sender : & UserId , sender_key : & str , message : OlmMessage , ) -> OlmResult < ( SessionType , Raw < AnyToDeviceEvent > , String ) > { // First try to decrypt using an existing session. let ( session , plaintext ) = if let Some ( d ) = self . decrypt_with_existing_sessions ( sender , sender_key , & message ) . await ? { // Decryption succeeded, de-structure the session/plaintext out of // the Option. ( SessionType :: Existing ( d . 0 ) , d . 1 ) } else { // Decryption failed with every known session, let's try to create a // new session. let mut session = match & message { // A new session can only be created using a pre-key message, // return with an error if it isn't one. OlmMessage :: Message ( _ ) => { warn ! ( sender sender as_str ( ) sender_key sender_key " \
 " ) ; return Err ( OlmError :: SessionWedged ( sender . to_owned ( ) , sender_key . to_owned ( ) ) ) ; } OlmMessage :: PreKey ( m ) => { // Create the new session. let session = match self . inner . create_inbound_session ( sender_key , m . clone ( ) ) . await { Ok ( s ) => s , Err ( e ) => { warn ! ( sender sender as_str ( ) sender_key sender_key error e " \
 " ) ; return Err ( OlmError :: SessionWedged ( sender . to_owned ( ) , sender_key . to_owned ( ) , ) ) ; } } ; session } } ; // Decrypt our message, this shouldn't fail since we're using a // newly created Session. let plaintext = session . decrypt ( message ) . await ? ; // We need to add the new session to the session cache, otherwise // we might try to create the same session again. // TODO separate the session cache from the storage so we only add // it to the cache but don't store it. let changes = Changes { account : Some ( self . inner . clone ( ) ) , sessions : vec ! [ session clone ( ) ] , .. Default :: default ( ) } ; self . store . save_changes ( changes ) . await ? ; ( SessionType :: New ( session ) , plaintext ) } ; trace ! ( sender sender as_str ( ) sender_key sender_key " " ) ; match self . parse_decrypted_to_device_event ( sender , plaintext ) { Ok ( ( event , signing_key ) ) => Ok ( ( session , event , signing_key ) ) , Err ( e ) => { // We might created a new session but decryption might still // have failed, store it for the error case here, this is fine // since we don't expect this to happen often or at all. match session { SessionType :: New ( s ) => { let changes = Changes { account : Some ( self . inner . clone ( ) ) , sessions : vec ! [ s ] , .. Default :: default ( ) } ; self . store . save_changes ( changes ) . await ? ; } SessionType :: Existing ( s ) => { self . store . save_sessions ( & [ s ] ) . await ? ; } } warn ! ( sender sender as_str ( ) sender_key sender_key error e " \
 " ) ; Err ( e ) } } }
Decrypt an Olm message, creating a new Olm session if possible.
Decrypt an Olm message creating a new Olm session if possible .
&self
sender
&UserId
sender_key
&str
message
OlmMessage
&self
sender
&UserId
sender_key
&str
message
OlmMessage