libsignal_protocol/state/
bundle.rs1use std::clone::Clone;
7
8use crate::state::{PreKeyId, SignedPreKeyId};
9use crate::{kem, DeviceId, IdentityKey, KyberPreKeyId, PublicKey, Result, SignalProtocolError};
10
11#[derive(Clone)]
12struct SignedPreKey {
13 id: SignedPreKeyId,
14 public_key: PublicKey,
15 signature: Vec<u8>,
16}
17
18impl SignedPreKey {
19 fn new(id: SignedPreKeyId, public_key: PublicKey, signature: Vec<u8>) -> Self {
20 Self {
21 id,
22 public_key,
23 signature,
24 }
25 }
26}
27
28#[derive(Clone)]
29struct KyberPreKey {
30 id: KyberPreKeyId,
31 public_key: kem::PublicKey,
32 signature: Vec<u8>,
33}
34
35impl KyberPreKey {
36 fn new(id: KyberPreKeyId, public_key: kem::PublicKey, signature: Vec<u8>) -> Self {
37 Self {
38 id,
39 public_key,
40 signature,
41 }
42 }
43}
44
45pub struct PreKeyBundleContent {
50 pub registration_id: Option<u32>,
51 pub device_id: Option<DeviceId>,
52 pub pre_key_id: Option<PreKeyId>,
53 pub pre_key_public: Option<PublicKey>,
54 pub ec_pre_key_id: Option<SignedPreKeyId>,
55 pub ec_pre_key_public: Option<PublicKey>,
56 pub ec_pre_key_signature: Option<Vec<u8>>,
57 pub identity_key: Option<IdentityKey>,
58 pub kyber_pre_key_id: Option<KyberPreKeyId>,
59 pub kyber_pre_key_public: Option<kem::PublicKey>,
60 pub kyber_pre_key_signature: Option<Vec<u8>>,
61}
62
63impl From<PreKeyBundle> for PreKeyBundleContent {
64 fn from(bundle: PreKeyBundle) -> Self {
65 Self {
66 registration_id: Some(bundle.registration_id),
67 device_id: Some(bundle.device_id),
68 pre_key_id: bundle.pre_key_id,
69 pre_key_public: bundle.pre_key_public,
70 ec_pre_key_id: Some(bundle.ec_signed_pre_key.id),
71 ec_pre_key_public: Some(bundle.ec_signed_pre_key.public_key),
72 ec_pre_key_signature: Some(bundle.ec_signed_pre_key.signature),
73 identity_key: Some(bundle.identity_key),
74 kyber_pre_key_id: bundle.kyber_pre_key.as_ref().map(|kyber| kyber.id),
75 kyber_pre_key_public: bundle
76 .kyber_pre_key
77 .as_ref()
78 .map(|kyber| kyber.public_key.clone()),
79 kyber_pre_key_signature: bundle
80 .kyber_pre_key
81 .as_ref()
82 .map(|kyber| kyber.signature.clone()),
83 }
84 }
85}
86
87impl TryFrom<PreKeyBundleContent> for PreKeyBundle {
88 type Error = SignalProtocolError;
89
90 fn try_from(content: PreKeyBundleContent) -> Result<Self> {
91 let mut bundle = PreKeyBundle::new(
92 content.registration_id.ok_or_else(|| {
93 SignalProtocolError::InvalidArgument("registration_id is required".to_string())
94 })?,
95 content.device_id.ok_or_else(|| {
96 SignalProtocolError::InvalidArgument("device_id is required".to_string())
97 })?,
98 content
99 .pre_key_id
100 .and_then(|id| content.pre_key_public.map(|public| (id, public))),
101 content.ec_pre_key_id.ok_or_else(|| {
102 SignalProtocolError::InvalidArgument("signed_pre_key_id is required".to_string())
103 })?,
104 content.ec_pre_key_public.ok_or_else(|| {
105 SignalProtocolError::InvalidArgument(
106 "signed_pre_key_public is required".to_string(),
107 )
108 })?,
109 content.ec_pre_key_signature.ok_or_else(|| {
110 SignalProtocolError::InvalidArgument(
111 "signed_pre_key_signature is required".to_string(),
112 )
113 })?,
114 content.identity_key.ok_or_else(|| {
115 SignalProtocolError::InvalidArgument("identity_key is required".to_string())
116 })?,
117 )?;
118
119 fn zip3<T, U, V>(x: Option<T>, y: Option<U>, z: Option<V>) -> Option<(T, U, V)> {
120 x.zip(y).zip(z).map(|((x, y), z)| (x, y, z))
121 }
122
123 if let Some((kyber_id, kyber_public, kyber_sig)) = zip3(
124 content.kyber_pre_key_id,
125 content.kyber_pre_key_public,
126 content.kyber_pre_key_signature,
127 ) {
128 bundle = bundle.with_kyber_pre_key(kyber_id, kyber_public, kyber_sig);
129 }
130 Ok(bundle)
131 }
132}
133
134#[derive(Clone)]
135pub struct PreKeyBundle {
136 registration_id: u32,
137 device_id: DeviceId,
138 pre_key_id: Option<PreKeyId>,
139 pre_key_public: Option<PublicKey>,
140 ec_signed_pre_key: SignedPreKey,
141 identity_key: IdentityKey,
142 kyber_pre_key: Option<KyberPreKey>,
145}
146
147impl PreKeyBundle {
148 pub fn new(
149 registration_id: u32,
150 device_id: DeviceId,
151 pre_key: Option<(PreKeyId, PublicKey)>,
152 signed_pre_key_id: SignedPreKeyId,
153 signed_pre_key_public: PublicKey,
154 signed_pre_key_signature: Vec<u8>,
155 identity_key: IdentityKey,
156 ) -> Result<Self> {
157 let (pre_key_id, pre_key_public) = match pre_key {
158 None => (None, None),
159 Some((id, key)) => (Some(id), Some(key)),
160 };
161
162 let ec_signed_pre_key = SignedPreKey::new(
163 signed_pre_key_id,
164 signed_pre_key_public,
165 signed_pre_key_signature,
166 );
167
168 Ok(Self {
169 registration_id,
170 device_id,
171 pre_key_id,
172 pre_key_public,
173 ec_signed_pre_key,
174 identity_key,
175 kyber_pre_key: None,
176 })
177 }
178
179 pub fn with_kyber_pre_key(
180 mut self,
181 pre_key_id: KyberPreKeyId,
182 public_key: kem::PublicKey,
183 signature: Vec<u8>,
184 ) -> Self {
185 self.kyber_pre_key = Some(KyberPreKey::new(pre_key_id, public_key, signature));
186 self
187 }
188
189 pub fn registration_id(&self) -> Result<u32> {
190 Ok(self.registration_id)
191 }
192
193 pub fn device_id(&self) -> Result<DeviceId> {
194 Ok(self.device_id)
195 }
196
197 pub fn pre_key_id(&self) -> Result<Option<PreKeyId>> {
198 Ok(self.pre_key_id)
199 }
200
201 pub fn pre_key_public(&self) -> Result<Option<PublicKey>> {
202 Ok(self.pre_key_public)
203 }
204
205 pub fn signed_pre_key_id(&self) -> Result<SignedPreKeyId> {
206 Ok(self.ec_signed_pre_key.id)
207 }
208
209 pub fn signed_pre_key_public(&self) -> Result<PublicKey> {
210 Ok(self.ec_signed_pre_key.public_key)
211 }
212
213 pub fn signed_pre_key_signature(&self) -> Result<&[u8]> {
214 Ok(self.ec_signed_pre_key.signature.as_ref())
215 }
216
217 pub fn identity_key(&self) -> Result<&IdentityKey> {
218 Ok(&self.identity_key)
219 }
220
221 pub fn has_kyber_pre_key(&self) -> bool {
222 self.kyber_pre_key.is_some()
223 }
224
225 pub fn kyber_pre_key_id(&self) -> Result<Option<KyberPreKeyId>> {
226 Ok(self.kyber_pre_key.as_ref().map(|pre_key| pre_key.id))
227 }
228
229 pub fn kyber_pre_key_public(&self) -> Result<Option<&kem::PublicKey>> {
230 Ok(self
231 .kyber_pre_key
232 .as_ref()
233 .map(|pre_key| &pre_key.public_key))
234 }
235
236 pub fn kyber_pre_key_signature(&self) -> Result<Option<&[u8]>> {
237 Ok(self
238 .kyber_pre_key
239 .as_ref()
240 .map(|pre_key| pre_key.signature.as_ref()))
241 }
242
243 pub fn modify<F>(self, modify: F) -> Result<Self>
244 where
245 F: FnOnce(&mut PreKeyBundleContent),
246 {
247 let mut content = self.into();
248 modify(&mut content);
249 content.try_into()
250 }
251}