Skip to main content

bitwarden_ipc/traits/
crypto_provider.rs

1use std::fmt::Debug;
2
3#[cfg(any(test, feature = "test-support"))]
4use super::CommunicationBackendReceiver;
5use super::{CommunicationBackend, SessionRepository};
6use crate::message::{IncomingMessage, OutgoingMessage};
7
8pub trait CryptoProvider<Com, Ses>: Send + Sync + 'static
9where
10    Com: CommunicationBackend,
11    Ses: SessionRepository<Self::Session>,
12{
13    type Session: Send + Sync + 'static;
14    type SendError: Debug + Send + Sync + 'static;
15    type ReceiveError: Debug + Send + Sync + 'static;
16
17    /// Send a message.
18    ///
19    /// Calling this function may result in multiple messages being sent, depending on the
20    /// implementation of the trait. For example, if the destination does not have a
21    /// session, the function may first send a message to establish a session and then send the
22    /// original message. The implementation of this function should handle this logic.
23    ///
24    /// An error should only be returned for fatal and unrecoverable errors e.g. if the session
25    /// storage is full or cannot be accessed. Returning an error will cause the IPC client to
26    /// stop processing messages.
27    fn send(
28        &self,
29        communication: &Com,
30        sessions: &Ses,
31        message: OutgoingMessage,
32    ) -> impl std::future::Future<Output = Result<(), Self::SendError>> + Send + Sync;
33
34    /// Receive a message.
35    ///
36    /// Calling this function may also result in messages being sent, depending on the trait
37    /// implementation. For example, if an encrypted message is received from a destination that
38    /// does not have a session. The function may then try to establish a session and then
39    /// re-request the original message. The implementation of this function should handle this
40    /// logic.
41    ///
42    /// An error should only be returned for fatal and unrecoverable errors e.g. if the session
43    /// storage is full or cannot be accessed. Returning an error will cause the IPC client to
44    /// stop processing messages.
45    fn receive(
46        &self,
47        receiver: &Com::Receiver,
48        communication: &Com,
49        sessions: &Ses,
50    ) -> impl std::future::Future<Output = Result<IncomingMessage, Self::ReceiveError>> + Send + Sync;
51}
52
53/// A no-op crypto provider that performs no encryption and simply passes messages through as-is.
54#[cfg(any(test, feature = "test-support"))]
55pub struct NoEncryptionCryptoProvider;
56
57#[cfg(any(test, feature = "test-support"))]
58impl<Com, Ses> CryptoProvider<Com, Ses> for NoEncryptionCryptoProvider
59where
60    Com: CommunicationBackend,
61    Ses: SessionRepository<()>,
62{
63    type Session = ();
64    type SendError = Com::SendError;
65    type ReceiveError = <Com::Receiver as CommunicationBackendReceiver>::ReceiveError;
66
67    async fn send(
68        &self,
69        communication: &Com,
70        _sessions: &Ses,
71        message: OutgoingMessage,
72    ) -> Result<(), Self::SendError> {
73        communication.send(message).await
74    }
75
76    async fn receive(
77        &self,
78        receiver: &Com::Receiver,
79        _communication: &Com,
80        _sessions: &Ses,
81    ) -> Result<IncomingMessage, Self::ReceiveError> {
82        receiver.receive().await
83    }
84}