Skip to main content

p2panda_encryption/key_bundle/
mod.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! Key bundles to asynchronously receive encrypted data from others.
4//!
5//! This is for asynchronous settings where one user ("Bob") is offline but has published a key
6//! bundle (containing their identity key, pre-keys, etc.) beforehands. Another user ("Alice")
7//! wants to use that information to send encrypted data to Bob.
8//!
9//! Depending on the security of the chat group this key bundle should be _used only once_ with
10//! [`OneTimeKeyBundle`] or only within a given "lifetime" (one day, two weeks, etc.) with
11//! [`LongTermKeyBundle`]. Members need to make sure that there are always fresh key bundles from
12//! them available in the network for others.
13//!
14//! ## Forward secrecy
15//!
16//! Some applications might have very strong forward secrecy requirements and only allow "one-time"
17//! pre-keys per group. This means that we can only establish a Forward Secure (FS) communication
18//! channel with a peer if we reliably made sure to only use the pre-key exactly once. This is hard
19//! to guarantee in a decentralised setting. If we don’t care about very strong FS we can ease up
20//! on that requirement a little bit and tolerate re-use with longer-living pre-keys which get
21//! rotated frequently (every week for example).
22//!
23//! ## Public-key infrastructure (PKI)
24//!
25//! We assume that encrypted groups with strong FS guarantees using one-time key bundles only get
26//! established when peers have explicitly exchanged their one-time pre-keys with each other, for
27//! example in form of scanning QR codes.
28//!
29//! Another solution for very strong forward secrecy, where we can make sure the pre-key is only
30//! used once, is a "bilateral session state establishment" process where peers can only establish
31//! a group chat with each other after both parties have been online. They don't need to be online
32//! at the same time, just to be online at least once and receive the messages of the other party.
33//! This puts a slight restriction on the "offline-first" nature for peer-to-peer applications.
34//!
35//! Another solution is to rely on always-online and trusted key servers which maintain the
36//! pre-keys for the network, but this puts an unnecessary centralisation point into the system and
37//! seems even worse.
38//!
39//! For longer-living ("long-term") pre-key bundles we can lift the strict "use once" requirement
40//! and peers can regularly publish fresh key bundles on the network, other peers need to make
41//! sure they keep collecting the latest bundles regularly.
42//!
43//! ## Authenticated Messaging
44//!
45//! Note that while pre-keys are signed, bundles should be part of an authenticated messaging
46//! scheme where the whole payload (and thus it's lifetime and maybe one-time pre-key) is signed by
47//! the same identity to prevent replay- and impersonation attacks.
48//!
49//! Otherwise attackers might be able to re-play the same pre-key with different lifetimes.
50#[allow(clippy::module_inception)]
51mod key_bundle;
52mod lifetime;
53mod prekey;
54
55pub use key_bundle::{KeyBundleError, LongTermKeyBundle, OneTimeKeyBundle, latest_key_bundle};
56pub use lifetime::{Lifetime, LifetimeError};
57pub use prekey::{OneTimePreKey, OneTimePreKeyId, PreKey, PreKeyId, latest_prekey};