Skip to main content

palpo_core/
encryption.rs

1//! Common types for [encryption] related tasks.
2//!
3//! [encryption]: https://spec.matrix.org/latest/client-server-api/#end-to-end-encryption
4
5use std::collections::BTreeMap;
6
7use salvo::prelude::*;
8use serde::{Deserialize, Serialize};
9
10use crate::{
11    EventEncryptionAlgorithm, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, PrivOwnedStr,
12    serde::{Base64, StringEnum},
13};
14
15/// Identity keys for a device.
16#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
17pub struct DeviceKeys {
18    /// The ID of the user the device belongs to.
19    ///
20    /// Must match the user ID used when logging in.
21    pub user_id: OwnedUserId,
22
23    /// The ID of the device these keys belong to.
24    ///
25    /// Must match the device ID used when logging in.
26    pub device_id: OwnedDeviceId,
27
28    /// The encryption algorithms supported by this device.
29    pub algorithms: Vec<EventEncryptionAlgorithm>,
30
31    /// Public identity keys.
32    pub keys: BTreeMap<OwnedDeviceKeyId, String>,
33
34    /// Signatures for the device key object.
35    #[serde(default)]
36    pub signatures: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>,
37
38    /// Additional data added to the device key information by intermediate servers, and
39    /// not covered by the signatures.
40    #[serde(default, skip_serializing_if = "UnsignedDeviceInfo::is_empty")]
41    pub unsigned: UnsignedDeviceInfo,
42}
43
44impl DeviceKeys {
45    /// Creates a new `DeviceKeys` from the given user id, device id, algorithms, keys and
46    /// signatures.
47    pub fn new(
48        user_id: OwnedUserId,
49        device_id: OwnedDeviceId,
50        algorithms: Vec<EventEncryptionAlgorithm>,
51        keys: BTreeMap<OwnedDeviceKeyId, String>,
52        signatures: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>,
53    ) -> Self {
54        Self {
55            user_id,
56            device_id,
57            algorithms,
58            keys,
59            signatures,
60            unsigned: Default::default(),
61        }
62    }
63}
64
65/// Additional data added to device key information by intermediate servers.
66#[derive(ToSchema, Clone, Debug, Default, Deserialize, Serialize)]
67pub struct UnsignedDeviceInfo {
68    /// The display name which the user set on the device.
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub device_display_name: Option<String>,
71}
72
73impl UnsignedDeviceInfo {
74    /// Creates an empty `UnsignedDeviceInfo`.
75    pub fn new() -> Self {
76        Default::default()
77    }
78
79    /// Checks whether all fields are empty / `None`.
80    pub fn is_empty(&self) -> bool {
81        self.device_display_name.is_none()
82    }
83}
84
85/// Signatures for a `SignedKey` object.
86pub type SignedKeySignatures = BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>;
87
88/// A key for the SignedCurve25519 algorithm
89#[derive(ToSchema, Debug, Clone, Serialize, Deserialize)]
90pub struct SignedKey {
91    /// Base64-encoded 32-byte Curve25519 public key.
92    #[salvo(schema(value_type = String))]
93    pub key: Base64,
94
95    /// Signatures for the key object.
96    pub signatures: SignedKeySignatures,
97
98    /// Is this key considered to be a fallback key, defaults to false.
99    #[serde(default, skip_serializing_if = "crate::serde::is_default")]
100    pub fallback: bool,
101}
102
103impl SignedKey {
104    /// Creates a new `SignedKey` with the given key and signatures.
105    pub fn new(key: Base64, signatures: SignedKeySignatures) -> Self {
106        Self {
107            key,
108            signatures,
109            fallback: false,
110        }
111    }
112
113    /// Creates a new fallback `SignedKey` with the given key and signatures.
114    pub fn new_fallback(key: Base64, signatures: SignedKeySignatures) -> Self {
115        Self {
116            key,
117            signatures,
118            fallback: true,
119        }
120    }
121}
122
123/// A one-time public key for "pre-key" messages.
124#[derive(ToSchema, Debug, Clone, Serialize, Deserialize)]
125#[serde(untagged)]
126pub enum OneTimeKey {
127    /// A key containing signatures, for the SignedCurve25519 algorithm.
128    SignedKey(SignedKey),
129
130    /// A string-valued key, for the Ed25519 and Curve25519 algorithms.
131    Key(String),
132}
133
134/// Signatures for a `CrossSigningKey` object.
135pub type CrossSigningKeySignatures = BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>;
136
137/// A cross signing key.
138#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
139pub struct CrossSigningKey {
140    /// The ID of the user the key belongs to.
141    pub user_id: OwnedUserId,
142
143    /// What the key is used for.
144    pub usage: Vec<KeyUsage>,
145
146    /// The public key.
147    ///
148    /// The object must have exactly one property.
149    pub keys: BTreeMap<OwnedDeviceKeyId, String>,
150
151    /// Signatures of the key.
152    ///
153    /// Only optional for master key.
154    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
155    pub signatures: CrossSigningKeySignatures,
156}
157
158impl CrossSigningKey {
159    /// Creates a new `CrossSigningKey` with the given user ID, usage, keys and signatures.
160    pub fn new(
161        user_id: OwnedUserId,
162        usage: Vec<KeyUsage>,
163        keys: BTreeMap<OwnedDeviceKeyId, String>,
164        signatures: CrossSigningKeySignatures,
165    ) -> Self {
166        Self {
167            user_id,
168            usage,
169            keys,
170            signatures,
171        }
172    }
173}
174
175/// The usage of a cross signing key.
176#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
177#[derive(ToSchema, Clone, PartialEq, Eq, StringEnum)]
178#[palpo_enum(rename_all = "snake_case")]
179pub enum KeyUsage {
180    /// Master key.
181    Master,
182
183    /// Self-signing key.
184    SelfSigning,
185
186    /// User-signing key.
187    UserSigning,
188
189    #[doc(hidden)]
190    #[salvo(schema(skip))]
191    _Custom(PrivOwnedStr),
192}