crypto: Add docs to our olm-rs wrappers.
This commit is contained in:
parent
c215dfa55d
commit
9d52037b40
1 changed files with 197 additions and 7 deletions
|
@ -26,10 +26,12 @@ use olm_rs::outbound_group_session::OlmOutboundGroupSession;
|
|||
use olm_rs::session::{OlmMessage, OlmSession, PreKeyMessage};
|
||||
use olm_rs::PicklingMode;
|
||||
|
||||
use ruma_client_api::r0::keys::SignedKey;
|
||||
|
||||
use crate::api::r0::keys::SignedKey;
|
||||
use crate::identifiers::RoomId;
|
||||
|
||||
/// The Olm account.
|
||||
/// An account is the central identity for encrypted communication between two
|
||||
/// devices. It holds the two identity key pairs for a device.
|
||||
pub struct Account {
|
||||
inner: OlmAccount,
|
||||
pub(crate) shared: bool,
|
||||
|
@ -87,14 +89,34 @@ impl Account {
|
|||
self.inner.mark_keys_as_published();
|
||||
}
|
||||
|
||||
/// Sign the given string using the accounts signing key.
|
||||
///
|
||||
/// Returns the signature as a base64 encoded string.
|
||||
pub fn sign(&self, string: &str) -> String {
|
||||
self.inner.sign(string)
|
||||
}
|
||||
|
||||
/// Store the account as a base64 encoded string.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pickle_mode` - The mode that was used to pickle the account, either an
|
||||
/// unencrypted mode or an encrypted using passphrase.
|
||||
pub fn pickle(&self, pickle_mode: PicklingMode) -> String {
|
||||
self.inner.pickle(pickle_mode)
|
||||
}
|
||||
|
||||
/// Restore an account from a previously pickled string.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pickle` - The pickled string of the account.
|
||||
///
|
||||
/// * `pickle_mode` - The mode that was used to pickle the account, either an
|
||||
/// unencrypted mode or an encrypted using passphrase.
|
||||
///
|
||||
/// * `shared` - Boolean determining if the account was uploaded to the
|
||||
/// server.
|
||||
pub fn from_pickle(
|
||||
pickle: String,
|
||||
pickle_mode: PicklingMode,
|
||||
|
@ -104,6 +126,16 @@ impl Account {
|
|||
Ok(Account { inner: acc, shared })
|
||||
}
|
||||
|
||||
/// Create a new session with another account given a one-time key.
|
||||
///
|
||||
/// Returns the newly created session or a `OlmSessionError` if creating a
|
||||
/// session failed.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `their_identity_key` - The other account's identity/curve25519 key.
|
||||
///
|
||||
/// * `their_one_time_key` - A signed one-time key that the other account
|
||||
/// created and shared with us.
|
||||
pub fn create_outbound_session(
|
||||
&self,
|
||||
their_identity_key: &str,
|
||||
|
@ -123,6 +155,16 @@ impl Account {
|
|||
})
|
||||
}
|
||||
|
||||
/// Create a new session with another account given a pre-key Olm message.
|
||||
///
|
||||
/// Returns the newly created session or a `OlmSessionError` if creating a
|
||||
/// session failed.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `their_identity_key` - The other account's identitiy/curve25519 key.
|
||||
///
|
||||
/// * `message` - A pre-key Olm message that was sent to us by the other
|
||||
/// account.
|
||||
pub fn create_inbound_session_from(
|
||||
&self,
|
||||
their_identity_key: &str,
|
||||
|
@ -150,6 +192,10 @@ impl PartialEq for Account {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// The Olm Session.
|
||||
///
|
||||
/// Sessions are used to exchange encrypted messages between two
|
||||
/// accounts/devices.
|
||||
pub struct Session {
|
||||
inner: OlmSession,
|
||||
pub(crate) sender_key: String,
|
||||
|
@ -158,18 +204,44 @@ pub struct Session {
|
|||
}
|
||||
|
||||
impl Session {
|
||||
/// Decrypt the given Olm message.
|
||||
///
|
||||
/// Returns the decrypted plaintext or an `OlmSessionError` if decryption
|
||||
/// failed.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `message` - The Olm message that should be decrypted.
|
||||
pub fn decrypt(&mut self, message: OlmMessage) -> Result<String, OlmSessionError> {
|
||||
let plaintext = self.inner.decrypt(message)?;
|
||||
self.last_use_time = Instant::now();
|
||||
Ok(plaintext)
|
||||
}
|
||||
|
||||
/// Encrypt the given plaintext as a OlmMessage.
|
||||
///
|
||||
/// Returns the encrypted Olm message.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `plaintext` - The plaintext that should be encrypted.
|
||||
pub fn encrypt(&mut self, plaintext: &str) -> OlmMessage {
|
||||
let message = self.inner.encrypt(plaintext);
|
||||
self.last_use_time = Instant::now();
|
||||
message
|
||||
}
|
||||
|
||||
/// Check if a pre-key Olm message was encrypted for this session.
|
||||
///
|
||||
/// Returns true if it matches, false if not and a OlmSessionError if there
|
||||
/// was an error checking if it matches.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `their_identity_key` - The identity/curve25519 key of the account
|
||||
/// that encrypted this Olm message.
|
||||
///
|
||||
/// * `message` - The pre-key Olm message that should be checked.
|
||||
pub fn matches(
|
||||
&self,
|
||||
their_identity_key: &str,
|
||||
|
@ -179,14 +251,41 @@ impl Session {
|
|||
.matches_inbound_session_from(their_identity_key, message)
|
||||
}
|
||||
|
||||
/// Returns the unique identifier for this session.
|
||||
pub fn session_id(&self) -> String {
|
||||
self.inner.session_id()
|
||||
}
|
||||
|
||||
/// Store the session as a base64 encoded string.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pickle_mode` - The mode that was used to pickle the session, either
|
||||
/// an unencrypted mode or an encrypted using passphrase.
|
||||
pub fn pickle(&self, pickle_mode: PicklingMode) -> String {
|
||||
self.inner.pickle(pickle_mode)
|
||||
}
|
||||
|
||||
/// Restore a Session from a previously pickled string.
|
||||
///
|
||||
/// Returns the restored Olm Session or a `OlmSessionError` if there was an
|
||||
/// error.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pickle` - The pickled string of the session.
|
||||
///
|
||||
/// * `pickle_mode` - The mode that was used to pickle the session, either
|
||||
/// an unencrypted mode or an encrypted using passphrase.
|
||||
///
|
||||
/// * `sender_key` - The public curve25519 key of the account that
|
||||
/// established the session with us.
|
||||
///
|
||||
/// * `creation_time` - The timestamp that marks when the session was
|
||||
/// created.
|
||||
///
|
||||
/// * `last_use_time` - The timestamp that marks when the session was
|
||||
/// last used to encrypt or decrypt an Olm message.
|
||||
pub fn from_pickle(
|
||||
pickle: String,
|
||||
pickle_mode: PicklingMode,
|
||||
|
@ -210,6 +309,10 @@ impl PartialEq for Session {
|
|||
}
|
||||
}
|
||||
|
||||
/// Inbound group session.
|
||||
///
|
||||
/// Inbound group sessions are used to exchange room messages between a group of
|
||||
/// participants. Inbound group sessions are used to decrypt the room messages.
|
||||
pub struct InboundGroupSession {
|
||||
inner: OlmInboundGroupSession,
|
||||
pub(crate) sender_key: String,
|
||||
|
@ -219,6 +322,22 @@ pub struct InboundGroupSession {
|
|||
}
|
||||
|
||||
impl InboundGroupSession {
|
||||
/// Create a new inbound group session for the given room.
|
||||
///
|
||||
/// These sessions are used to decrypt room messages.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `sender_key` - The public curve25519 key of the account that
|
||||
/// sent us the session
|
||||
///
|
||||
/// * `signing_key` - The public ed25519 key of the account that
|
||||
/// sent us the session.
|
||||
///
|
||||
/// * `room_id` - The id of the room that the session is used in.
|
||||
///
|
||||
/// * `session_key` - The private session key that is used to decrypt
|
||||
/// messages.
|
||||
pub fn new(
|
||||
sender_key: &str,
|
||||
signing_key: &str,
|
||||
|
@ -234,6 +353,35 @@ impl InboundGroupSession {
|
|||
})
|
||||
}
|
||||
|
||||
/// Store the group session as a base64 encoded string.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pickle_mode` - The mode that was used to pickle the group session,
|
||||
/// either an unencrypted mode or an encrypted using passphrase.
|
||||
pub fn pickle(&self, pickle_mode: PicklingMode) -> String {
|
||||
self.inner.pickle(pickle_mode)
|
||||
}
|
||||
|
||||
/// Restore a Session from a previously pickled string.
|
||||
///
|
||||
/// Returns the restored group session or a `OlmGroupSessionError` if there
|
||||
/// was an error.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pickle` - The pickled string of the group session session.
|
||||
///
|
||||
/// * `pickle_mode` - The mode that was used to pickle the session, either
|
||||
/// an unencrypted mode or an encrypted using passphrase.
|
||||
///
|
||||
/// * `sender_key` - The public curve25519 key of the account that
|
||||
/// sent us the session
|
||||
///
|
||||
/// * `signing_key` - The public ed25519 key of the account that
|
||||
/// sent us the session.
|
||||
///
|
||||
/// * `room_id` - The id of the room that the session is used in.
|
||||
pub fn from_pickle(
|
||||
pickle: String,
|
||||
pickle_mode: PicklingMode,
|
||||
|
@ -251,18 +399,24 @@ impl InboundGroupSession {
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns the unique identifier for this session.
|
||||
pub fn session_id(&self) -> String {
|
||||
self.inner.session_id()
|
||||
}
|
||||
|
||||
pub fn pickle(&self, pickle_mode: PicklingMode) -> String {
|
||||
self.inner.pickle(pickle_mode)
|
||||
}
|
||||
|
||||
/// Get the first message index we know how to decrypt.
|
||||
pub fn first_known_index(&self) -> u32 {
|
||||
self.inner.first_known_index()
|
||||
}
|
||||
|
||||
/// Decrypt the given ciphertext.
|
||||
///
|
||||
/// Returns the decrypted plaintext or an `OlmGroupSessionError` if
|
||||
/// decryption failed.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `message` - The message that should be decrypted.
|
||||
pub fn decrypt(&self, message: String) -> Result<(String, u32), OlmGroupSessionError> {
|
||||
self.inner.decrypt(message)
|
||||
}
|
||||
|
@ -270,12 +424,17 @@ impl InboundGroupSession {
|
|||
|
||||
impl fmt::Debug for InboundGroupSession {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("InbounDGroupSession")
|
||||
f.debug_struct("InboundGroupSession")
|
||||
.field("session_id", &self.session_id())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Outbound group session.
|
||||
///
|
||||
/// Outbound group sessions are used to exchange room messages between a group
|
||||
/// of participants. Outbound group sessions are used to encrypt the room
|
||||
/// messages.
|
||||
#[derive(Clone)]
|
||||
pub struct OutboundGroupSession {
|
||||
inner: Arc<Mutex<OlmOutboundGroupSession>>,
|
||||
|
@ -287,6 +446,13 @@ pub struct OutboundGroupSession {
|
|||
}
|
||||
|
||||
impl OutboundGroupSession {
|
||||
/// Create a new outbound group session for the given room.
|
||||
///
|
||||
/// Outbound group sessions are used to encrypt room messages.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `room_id` - The id of the room that the session is used in.
|
||||
pub fn new(room_id: &RoomId) -> Self {
|
||||
let session = OlmOutboundGroupSession::new();
|
||||
let session_id = session.session_id();
|
||||
|
@ -301,33 +467,57 @@ impl OutboundGroupSession {
|
|||
}
|
||||
}
|
||||
|
||||
/// Encrypt the given plaintext using this session.
|
||||
///
|
||||
/// Returns the encrypted ciphertext.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `plaintext` - The plaintext that should be encrypted.
|
||||
pub async fn encrypt(&self, plaintext: String) -> String {
|
||||
let session = self.inner.lock().await;
|
||||
session.encrypt(plaintext)
|
||||
}
|
||||
|
||||
/// Check if the session has expired and if it should be rotated.
|
||||
///
|
||||
/// A session will expire after some time or if enough messages have been
|
||||
/// encrypted using it.
|
||||
pub fn expired(&self) -> bool {
|
||||
// TODO implement this.
|
||||
false
|
||||
}
|
||||
|
||||
/// Mark the session as shared.
|
||||
///
|
||||
/// Messages shouldn't be encrypted with the session before it has been
|
||||
/// shared.
|
||||
pub fn mark_as_shared(&self) {
|
||||
self.shared.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Check if the session has been marked as shared.
|
||||
pub fn shared(&self) -> bool {
|
||||
self.shared.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Get the session key of this session.
|
||||
///
|
||||
/// A session key can be used to to create an `InboundGroupSession`.
|
||||
pub async fn session_key(&self) -> String {
|
||||
let session = self.inner.lock().await;
|
||||
session.session_key()
|
||||
}
|
||||
|
||||
/// Returns the unique identifier for this session.
|
||||
pub fn session_id(&self) -> &str {
|
||||
&self.session_id
|
||||
}
|
||||
|
||||
/// Get the current message index for this session.
|
||||
///
|
||||
/// Each message is sent with an increasing index. This returns the
|
||||
/// message index that will be used for the next encrypted message.
|
||||
pub async fn message_index(&self) -> u32 {
|
||||
let session = self.inner.lock().await;
|
||||
session.session_message_index()
|
||||
|
|
Loading…
Reference in a new issue