Module olm

Source
Expand description

An implementation of the Olm double ratchet.

§Overview

The core component of the crate is the Account, representing a single Olm participant. An Olm Account consists of a collection of key pairs, though often documentation will shorten this to just “keys”. These are:

  1. An Ed25519 signing key pair representing the stable cryptographic identity of the participant (the participant’s “fingerprint”).
  2. A Curve25519 sender key pair (also sometimes called the identity key pair, somewhat confusingly).
  3. A number of one-time key pairs.
  4. A current and previous (if any) “fallback” key pair.

While the key in 1 is used for signing but not encryption, the keys in 2-4 participate in a triple Diffie-Hellman key exchange (3DH) with another Olm participant, thereby establishing an Olm session on each side of the communication channel. Ultimately, this session is used for deriving the concrete encryption keys for a particular message.

Olm sessions are represented by the Session struct. Such a session is created by calling Account::create_outbound_session on one of the participating accounts, passing it the Curve25519 sender key and one Curve25519 one-time key of the other side. The protocol is asynchronous, so the participant can start sending messages to the other side even before the other side has created a session, producing so-called pre-key messages (see PreKeyMessage).

Once the other participant receives such a pre-key message, they can create their own matching session by calling Account::create_inbound_session and passing it the pre-key message they received and the Curve25519 sender key of the other side. This completes the establishment of the Olm communication channel.

use anyhow::Result;
use vodozemac::olm::{Account, InboundCreationResult, OlmMessage, SessionConfig};

fn main() -> Result<()> {
    let alice = Account::new();
    let mut bob = Account::new();

    bob.generate_one_time_keys(1);
    let bob_otk = *bob.one_time_keys().values().next().unwrap();

    let mut alice_session = alice
        .create_outbound_session(SessionConfig::version_2(), bob.curve25519_key(), bob_otk);

    bob.mark_keys_as_published();

    let message = "Keep it between us, OK?";
    let alice_msg = alice_session.encrypt(message);

    if let OlmMessage::PreKey(m) = alice_msg.clone() {
        let result = bob.create_inbound_session(alice.curve25519_key(), &m)?;

        let mut bob_session = result.session;
        let what_bob_received = result.plaintext;

        assert_eq!(alice_session.session_id(), bob_session.session_id());

        assert_eq!(message.as_bytes(), what_bob_received);

        let bob_reply = "Yes. Take this, it's dangerous out there!";
        let bob_encrypted_reply = bob_session.encrypt(bob_reply).into();

        let what_alice_received = alice_session
            .decrypt(&bob_encrypted_reply)?;
        assert_eq!(what_alice_received, bob_reply.as_bytes());
    }

    Ok(())
}

§Sending messages

To encrypt a message, just call Session::encrypt(). This will either produce an OlmMessage::PreKey or OlmMessage::Normal depending on whether the session is fully established. A session is fully established once you receive (and decrypt) at least one message from the other side.

Structs§

Account
An Olm Account manages all cryptographic keys used on a device.
AccountPickle
A format suitable for serialization which implements serde::Serialize and serde::Deserialize. Obtainable by calling Account::pickle.
IdentityKeys
Struct holding the two public identity keys of an Account.
InboundCreationResult
Return type for the creation of inbound Session objects.
Message
An encrypted Olm message.
OneTimeKeyGenerationResult
The result type for the one-time key generation operation.
PreKeyMessage
An encrypted Olm pre-key message.
RatchetPublicKey
The public part of a [RatchetKey].
Session
An Olm session represents one end of an encrypted communication channel between two participants.
SessionConfig
A struct to configure how Olm sessions should work under the hood. Currently only the MAC truncation behaviour can be configured.
SessionKeys
The set of keys that were used to establish the Olm Session,
SessionPickle
A format suitable for serialization which implements serde::Serialize and serde::Deserialize. Obtainable by calling Session::pickle.

Enums§

DecryptionError
Error type for Olm-based decryption failures.
MessageType
An enum over the two supported message types.
OlmMessage
Enum over the different Olm message types.
SessionCreationError
Error describing failure modes when creating a Olm Session from an incoming Olm message.