libsignal_service/
utils.rs

1// Signal sometimes adds padding, sometimes it does not.
2// This requires a custom decoding engine.
3// This engine is as general as possible.
4pub const BASE64_RELAXED: base64::engine::GeneralPurpose =
5    base64::engine::GeneralPurpose::new(
6        &base64::alphabet::STANDARD,
7        base64::engine::GeneralPurposeConfig::new()
8            .with_encode_padding(true)
9            .with_decode_padding_mode(
10                base64::engine::DecodePaddingMode::Indifferent,
11            ),
12    );
13
14pub fn random_length_padding<R: rand::Rng + rand::CryptoRng>(
15    csprng: &mut R,
16    max_len: usize,
17) -> Vec<u8> {
18    let length = csprng.gen_range(0..max_len);
19    let mut padding = vec![0u8; length];
20    csprng.fill_bytes(&mut padding);
21    padding
22}
23
24pub mod serde_base64 {
25    use super::BASE64_RELAXED;
26    use base64::prelude::*;
27    use serde::{Deserialize, Deserializer, Serializer};
28
29    pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
30    where
31        T: AsRef<[u8]>,
32        S: Serializer,
33    {
34        serializer.serialize_str(&BASE64_RELAXED.encode(bytes.as_ref()))
35    }
36
37    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
38    where
39        D: Deserializer<'de>,
40    {
41        use serde::de::Error;
42        String::deserialize(deserializer).and_then(|string| {
43            BASE64_RELAXED
44                .decode(string)
45                .map_err(|err| Error::custom(err.to_string()))
46        })
47    }
48}
49
50pub mod serde_optional_base64 {
51    use super::BASE64_RELAXED;
52    use base64::prelude::*;
53    use serde::{Deserialize, Deserializer, Serializer};
54
55    use super::serde_base64;
56
57    pub fn serialize<T, S>(
58        bytes: &Option<T>,
59        serializer: S,
60    ) -> Result<S::Ok, S::Error>
61    where
62        T: AsRef<[u8]>,
63        S: Serializer,
64    {
65        match bytes {
66            Some(bytes) => serde_base64::serialize(bytes, serializer),
67            None => serializer.serialize_none(),
68        }
69    }
70
71    pub fn deserialize<'de, D>(
72        deserializer: D,
73    ) -> Result<Option<Vec<u8>>, D::Error>
74    where
75        D: Deserializer<'de>,
76    {
77        use serde::de::Error;
78        match Option::<String>::deserialize(deserializer)? {
79            Some(s) => BASE64_RELAXED
80                .decode(s)
81                .map_err(|err| Error::custom(err.to_string()))
82                .map(Some),
83            None => Ok(None),
84        }
85    }
86}
87
88pub mod serde_identity_key {
89    use super::BASE64_RELAXED;
90    use base64::prelude::*;
91    use libsignal_protocol::IdentityKey;
92    use serde::{Deserialize, Deserializer, Serializer};
93
94    pub fn serialize<S>(
95        public_key: &IdentityKey,
96        serializer: S,
97    ) -> Result<S::Ok, S::Error>
98    where
99        S: Serializer,
100    {
101        let public_key = public_key.serialize();
102        serializer.serialize_str(&BASE64_RELAXED.encode(&public_key))
103    }
104
105    pub fn deserialize<'de, D>(deserializer: D) -> Result<IdentityKey, D::Error>
106    where
107        D: Deserializer<'de>,
108    {
109        IdentityKey::decode(
110            &BASE64_RELAXED
111                .decode(String::deserialize(deserializer)?)
112                .map_err(serde::de::Error::custom)?,
113        )
114        .map_err(serde::de::Error::custom)
115    }
116}
117
118pub mod serde_optional_identity_key {
119    use super::BASE64_RELAXED;
120    use base64::prelude::*;
121    use libsignal_protocol::IdentityKey;
122    use serde::{Deserialize, Deserializer, Serializer};
123
124    use super::serde_identity_key;
125
126    pub fn serialize<S>(
127        public_key: &Option<IdentityKey>,
128        serializer: S,
129    ) -> Result<S::Ok, S::Error>
130    where
131        S: Serializer,
132    {
133        match public_key {
134            Some(public_key) => {
135                serde_identity_key::serialize(public_key, serializer)
136            },
137            None => serializer.serialize_none(),
138        }
139    }
140
141    pub fn deserialize<'de, D>(
142        deserializer: D,
143    ) -> Result<Option<IdentityKey>, D::Error>
144    where
145        D: Deserializer<'de>,
146    {
147        match Option::<String>::deserialize(deserializer)? {
148            Some(public_key) => Ok(Some(
149                IdentityKey::decode(
150                    &BASE64_RELAXED
151                        .decode(public_key)
152                        .map_err(serde::de::Error::custom)?,
153                )
154                .map_err(serde::de::Error::custom)?,
155            )),
156            None => Ok(None),
157        }
158    }
159}
160
161pub mod serde_private_key {
162    use super::BASE64_RELAXED;
163    use base64::prelude::*;
164    use libsignal_protocol::PrivateKey;
165    use serde::{Deserialize, Deserializer, Serializer};
166
167    pub fn serialize<S>(
168        public_key: &PrivateKey,
169        serializer: S,
170    ) -> Result<S::Ok, S::Error>
171    where
172        S: Serializer,
173    {
174        let public_key = public_key.serialize();
175        serializer.serialize_str(&BASE64_RELAXED.encode(public_key))
176    }
177
178    pub fn deserialize<'de, D>(deserializer: D) -> Result<PrivateKey, D::Error>
179    where
180        D: Deserializer<'de>,
181    {
182        PrivateKey::deserialize(
183            &BASE64_RELAXED
184                .decode(String::deserialize(deserializer)?)
185                .map_err(serde::de::Error::custom)?,
186        )
187        .map_err(serde::de::Error::custom)
188    }
189}
190
191pub mod serde_optional_private_key {
192    use super::BASE64_RELAXED;
193    use base64::prelude::*;
194    use libsignal_protocol::PrivateKey;
195    use serde::{Deserialize, Deserializer, Serializer};
196
197    use super::serde_private_key;
198
199    pub fn serialize<S>(
200        private_key: &Option<PrivateKey>,
201        serializer: S,
202    ) -> Result<S::Ok, S::Error>
203    where
204        S: Serializer,
205    {
206        match private_key {
207            Some(private_key) => {
208                serde_private_key::serialize(private_key, serializer)
209            },
210            None => serializer.serialize_none(),
211        }
212    }
213
214    pub fn deserialize<'de, D>(
215        deserializer: D,
216    ) -> Result<Option<PrivateKey>, D::Error>
217    where
218        D: Deserializer<'de>,
219    {
220        match Option::<String>::deserialize(deserializer)? {
221            Some(private_key) => Ok(Some(
222                PrivateKey::deserialize(
223                    &BASE64_RELAXED
224                        .decode(private_key)
225                        .map_err(serde::de::Error::custom)?,
226                )
227                .map_err(serde::de::Error::custom)?,
228            )),
229            None => Ok(None),
230        }
231    }
232}
233
234pub mod serde_signaling_key {
235    use std::convert::TryInto;
236
237    use super::BASE64_RELAXED;
238    use crate::configuration::SignalingKey;
239    use base64::prelude::*;
240    use serde::{Deserialize, Deserializer, Serializer};
241
242    pub fn serialize<S>(
243        signaling_key: &SignalingKey,
244        serializer: S,
245    ) -> Result<S::Ok, S::Error>
246    where
247        S: Serializer,
248    {
249        serializer.serialize_str(&BASE64_RELAXED.encode(signaling_key))
250    }
251
252    pub fn deserialize<'de, D>(
253        deserializer: D,
254    ) -> Result<SignalingKey, D::Error>
255    where
256        D: Deserializer<'de>,
257    {
258        BASE64_RELAXED
259            .decode(String::deserialize(deserializer)?)
260            .map_err(serde::de::Error::custom)?
261            .try_into()
262            .map_err(|buf: Vec<u8>| {
263                serde::de::Error::invalid_length(
264                    buf.len(),
265                    &"invalid signaling key length",
266                )
267            })
268    }
269}
270
271pub mod serde_phone_number {
272    use phonenumber::PhoneNumber;
273    use serde::{Deserialize, Deserializer, Serializer};
274
275    pub fn serialize<S>(
276        phone_number: &PhoneNumber,
277        serializer: S,
278    ) -> Result<S::Ok, S::Error>
279    where
280        S: Serializer,
281    {
282        serializer.serialize_str(&phone_number.to_string())
283    }
284
285    pub fn deserialize<'de, D>(deserializer: D) -> Result<PhoneNumber, D::Error>
286    where
287        D: Deserializer<'de>,
288    {
289        phonenumber::parse(None, String::deserialize(deserializer)?)
290            .map_err(serde::de::Error::custom)
291    }
292}
293
294pub mod serde_service_id {
295    use libsignal_protocol::ServiceId;
296    use serde::{Deserialize, Deserializer, Serializer};
297
298    pub fn serialize<S>(
299        service_id: &ServiceId,
300        serializer: S,
301    ) -> Result<S::Ok, S::Error>
302    where
303        S: Serializer,
304    {
305        serializer.serialize_str(&service_id.service_id_string())
306    }
307
308    pub fn deserialize<'de, D>(deserializer: D) -> Result<ServiceId, D::Error>
309    where
310        D: Deserializer<'de>,
311    {
312        ServiceId::parse_from_service_id_string(&String::deserialize(
313            deserializer,
314        )?)
315        .ok_or_else(|| serde::de::Error::custom("invalid service ID string"))
316    }
317}