1mod phonenumber;
2use libsignal_core::{Aci, Pni, ServiceId};
3pub use phonenumber::*;
4use uuid::Uuid;
5
6pub const BASE64_RELAXED: base64::engine::GeneralPurpose =
10 base64::engine::GeneralPurpose::new(
11 &base64::alphabet::STANDARD,
12 base64::engine::GeneralPurposeConfig::new()
13 .with_encode_padding(true)
14 .with_decode_padding_mode(
15 base64::engine::DecodePaddingMode::Indifferent,
16 ),
17 );
18
19pub fn parse_aci_with_fallback(
20 bytes: Option<&[u8]>,
21 utf8: Option<&str>,
22) -> Option<Aci> {
23 let binary = bytes.and_then(|bytes| {
24 let bytes = bytes
25 .try_into()
26 .inspect_err(|_e| tracing::warn!("binary ACI not 16 bytes"))
27 .ok()?;
28 Some(Aci::from_uuid_bytes(bytes))
29 });
30
31 binary.or_else(|| {
32 let utf8 = utf8?;
33 match Aci::parse_from_service_id_string(utf8) {
34 Some(sid) => Some(sid),
35 None => {
36 tracing::warn!("unparseable utf8 ACI");
37 None
38 },
39 }
40 })
41}
42
43pub fn parse_pni_with_fallback(
44 bytes: Option<&[u8]>,
45 utf8: Option<&str>,
46 pni_is_uuid: bool,
47) -> Option<Pni> {
48 let binary = bytes.and_then(|bytes| {
49 let bytes = bytes
50 .try_into()
51 .inspect_err(|_e| tracing::warn!("binary PNI not 16 bytes"))
52 .ok()?;
53 Some(Pni::from_uuid_bytes(bytes))
54 });
55
56 binary.or_else(|| {
57 let utf8 = utf8?;
58 if pni_is_uuid {
59 let uuid: uuid::Uuid = utf8
60 .parse()
61 .inspect_err(|e| {
62 tracing::warn!(error = %e, "unparseable UUID");
63 })
64 .ok()?;
65 Some(Pni::from_uuid_bytes(*uuid.as_bytes()))
66 } else {
67 match Pni::parse_from_service_id_string(utf8) {
68 Some(sid) => Some(sid),
69 None => {
70 tracing::warn!("unparseable utf8 PNI");
71 None
72 },
73 }
74 }
75 })
76}
77
78pub fn deserialize_service_id<'de, D>(
81 deserializer: D,
82) -> Result<ServiceId, D::Error>
83where
84 D: serde::Deserializer<'de>,
85{
86 use serde::Deserialize;
87 let s = <&'de str>::deserialize(deserializer)?;
88 ServiceId::parse_from_service_id_string(s).ok_or_else(|| {
89 serde::de::Error::custom(format!("invalid service id: {s}"))
90 })
91}
92
93pub fn parse_service_id_with_fallback(
94 bytes: Option<&[u8]>,
95 utf8: Option<&str>,
96) -> Option<ServiceId> {
97 let binary = bytes.and_then(|bytes| {
98 match ServiceId::parse_from_service_id_binary(bytes) {
99 Some(sid) => Some(sid),
100 None => {
101 tracing::warn!("unparseable binary ServiceId");
102 None
103 },
104 }
105 });
106
107 binary.or_else(|| {
108 let utf8 = utf8?;
109 match ServiceId::parse_from_service_id_string(utf8) {
110 Some(sid) => Some(sid),
111 None => {
112 tracing::warn!("unparseable utf8 ServiceId");
113 None
114 },
115 }
116 })
117}
118
119pub fn parse_uuid_with_fallback(
123 binary: Option<&[u8]>,
124 utf8: Option<&str>,
125) -> Option<Uuid> {
126 let binary = binary
127 .map(<[u8; 16]>::try_from)
128 .transpose()
129 .inspect_err(|_e| tracing::warn!("invalid binary UUID length"))
130 .ok()
131 .flatten()
132 .map(Uuid::from_bytes);
133
134 binary.or_else(|| {
135 let utf8 = utf8?;
136 utf8.parse()
137 .inspect_err(|e| tracing::warn!(error=%e, "unparseable UUID"))
138 .ok()
139 })
140}
141
142pub fn random_length_padding<R: rand::Rng + rand::CryptoRng>(
143 csprng: &mut R,
144 max_len: usize,
145) -> Vec<u8> {
146 let length = csprng.random_range(0..max_len);
147 let mut padding = vec![0u8; length];
148 csprng.fill_bytes(&mut padding);
149 padding
150}
151
152pub mod serde_base64 {
153 use super::BASE64_RELAXED;
154 use base64::prelude::*;
155 use serde::{Deserialize, Deserializer, Serializer};
156
157 pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
158 where
159 T: AsRef<[u8]>,
160 S: Serializer,
161 {
162 serializer.serialize_str(&BASE64_RELAXED.encode(bytes.as_ref()))
163 }
164
165 pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
166 where
167 D: Deserializer<'de>,
168 {
169 use serde::de::Error;
170 <&str>::deserialize(deserializer).and_then(|string| {
171 BASE64_RELAXED
172 .decode(string)
173 .map_err(|err| Error::custom(err.to_string()))
174 })
175 }
176}
177
178pub mod serde_optional_base64 {
179 use super::BASE64_RELAXED;
180 use base64::prelude::*;
181 use serde::{Deserialize, Deserializer, Serializer};
182
183 use super::serde_base64;
184
185 pub fn serialize<T, S>(
186 bytes: &Option<T>,
187 serializer: S,
188 ) -> Result<S::Ok, S::Error>
189 where
190 T: AsRef<[u8]>,
191 S: Serializer,
192 {
193 match bytes {
194 Some(bytes) => serde_base64::serialize(bytes, serializer),
195 None => serializer.serialize_none(),
196 }
197 }
198
199 pub fn deserialize<'de, D>(
200 deserializer: D,
201 ) -> Result<Option<Vec<u8>>, D::Error>
202 where
203 D: Deserializer<'de>,
204 {
205 use serde::de::Error;
206 match Option::<String>::deserialize(deserializer)? {
207 Some(s) => BASE64_RELAXED
208 .decode(s)
209 .map_err(|err| Error::custom(err.to_string()))
210 .map(Some),
211 None => Ok(None),
212 }
213 }
214}
215
216pub mod serde_optional_base64_url_safe_no_pad {
217 use base64::{prelude::BASE64_URL_SAFE_NO_PAD, Engine};
218 use serde::{Deserialize, Deserializer, Serializer};
219
220 use super::serde_base64_url_safe_no_pad;
221
222 pub fn serialize<T, S>(
223 bytes: &Option<T>,
224 serializer: S,
225 ) -> Result<S::Ok, S::Error>
226 where
227 T: AsRef<[u8]>,
228 S: Serializer,
229 {
230 match bytes {
231 Some(bytes) => {
232 serde_base64_url_safe_no_pad::serialize(bytes, serializer)
233 },
234 None => serializer.serialize_none(),
235 }
236 }
237
238 pub fn deserialize<'de, D>(
239 deserializer: D,
240 ) -> Result<Option<Vec<u8>>, D::Error>
241 where
242 D: Deserializer<'de>,
243 {
244 use serde::de::Error;
245 match Option::<String>::deserialize(deserializer)? {
246 Some(s) => BASE64_URL_SAFE_NO_PAD
247 .decode(s)
248 .map_err(|err| Error::custom(err.to_string()))
249 .map(Some),
250 None => Ok(None),
251 }
252 }
253}
254
255pub mod serde_base64_url_safe_no_pad {
256 use base64::{prelude::BASE64_URL_SAFE_NO_PAD, Engine};
257 use serde::{Deserialize, Deserializer, Serializer};
258
259 pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
260 where
261 T: AsRef<[u8]>,
262 S: Serializer,
263 {
264 serializer.serialize_str(&BASE64_URL_SAFE_NO_PAD.encode(bytes.as_ref()))
265 }
266
267 pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
268 where
269 D: Deserializer<'de>,
270 {
271 use serde::de::Error;
272 <&str>::deserialize(deserializer).and_then(|string| {
273 BASE64_URL_SAFE_NO_PAD
274 .decode(string)
275 .map_err(|err| Error::custom(err.to_string()))
276 })
277 }
278}
279
280pub mod serde_identity_key {
281 use super::BASE64_RELAXED;
282 use base64::prelude::*;
283 use libsignal_protocol::IdentityKey;
284 use serde::{Deserialize, Deserializer, Serializer};
285
286 pub fn serialize<S>(
287 public_key: &IdentityKey,
288 serializer: S,
289 ) -> Result<S::Ok, S::Error>
290 where
291 S: Serializer,
292 {
293 let public_key = public_key.serialize();
294 serializer.serialize_str(&BASE64_RELAXED.encode(&public_key))
295 }
296
297 pub fn deserialize<'de, D>(deserializer: D) -> Result<IdentityKey, D::Error>
298 where
299 D: Deserializer<'de>,
300 {
301 IdentityKey::decode(
302 &BASE64_RELAXED
303 .decode(<&str>::deserialize(deserializer)?)
304 .map_err(serde::de::Error::custom)?,
305 )
306 .map_err(serde::de::Error::custom)
307 }
308}
309
310pub mod serde_optional_identity_key {
311 use super::BASE64_RELAXED;
312 use base64::prelude::*;
313 use libsignal_protocol::IdentityKey;
314 use serde::{Deserialize, Deserializer, Serializer};
315
316 use super::serde_identity_key;
317
318 pub fn serialize<S>(
319 public_key: &Option<IdentityKey>,
320 serializer: S,
321 ) -> Result<S::Ok, S::Error>
322 where
323 S: Serializer,
324 {
325 match public_key {
326 Some(public_key) => {
327 serde_identity_key::serialize(public_key, serializer)
328 },
329 None => serializer.serialize_none(),
330 }
331 }
332
333 pub fn deserialize<'de, D>(
334 deserializer: D,
335 ) -> Result<Option<IdentityKey>, D::Error>
336 where
337 D: Deserializer<'de>,
338 {
339 match Option::<String>::deserialize(deserializer)? {
340 Some(public_key) => Ok(Some(
341 IdentityKey::decode(
342 &BASE64_RELAXED
343 .decode(public_key)
344 .map_err(serde::de::Error::custom)?,
345 )
346 .map_err(serde::de::Error::custom)?,
347 )),
348 None => Ok(None),
349 }
350 }
351}
352
353pub mod serde_private_key {
354 use super::BASE64_RELAXED;
355 use base64::prelude::*;
356 use libsignal_protocol::PrivateKey;
357 use serde::{Deserialize, Deserializer, Serializer};
358
359 pub fn serialize<S>(
360 public_key: &PrivateKey,
361 serializer: S,
362 ) -> Result<S::Ok, S::Error>
363 where
364 S: Serializer,
365 {
366 let public_key = public_key.serialize();
367 serializer.serialize_str(&BASE64_RELAXED.encode(public_key))
368 }
369
370 pub fn deserialize<'de, D>(deserializer: D) -> Result<PrivateKey, D::Error>
371 where
372 D: Deserializer<'de>,
373 {
374 PrivateKey::deserialize(
375 &BASE64_RELAXED
376 .decode(<&str>::deserialize(deserializer)?)
377 .map_err(serde::de::Error::custom)?,
378 )
379 .map_err(serde::de::Error::custom)
380 }
381}
382
383pub mod serde_optional_private_key {
384 use super::BASE64_RELAXED;
385 use base64::prelude::*;
386 use libsignal_protocol::PrivateKey;
387 use serde::{Deserialize, Deserializer, Serializer};
388
389 use super::serde_private_key;
390
391 pub fn serialize<S>(
392 private_key: &Option<PrivateKey>,
393 serializer: S,
394 ) -> Result<S::Ok, S::Error>
395 where
396 S: Serializer,
397 {
398 match private_key {
399 Some(private_key) => {
400 serde_private_key::serialize(private_key, serializer)
401 },
402 None => serializer.serialize_none(),
403 }
404 }
405
406 pub fn deserialize<'de, D>(
407 deserializer: D,
408 ) -> Result<Option<PrivateKey>, D::Error>
409 where
410 D: Deserializer<'de>,
411 {
412 match Option::<String>::deserialize(deserializer)? {
413 Some(private_key) => Ok(Some(
414 PrivateKey::deserialize(
415 &BASE64_RELAXED
416 .decode(private_key)
417 .map_err(serde::de::Error::custom)?,
418 )
419 .map_err(serde::de::Error::custom)?,
420 )),
421 None => Ok(None),
422 }
423 }
424}
425
426pub mod serde_optional_e164 {
427 use libsignal_core::E164;
428 use serde::{Deserialize, Deserializer, Serializer};
429
430 pub fn serialize<S>(
431 phone_number: &Option<E164>,
432 serializer: S,
433 ) -> Result<S::Ok, S::Error>
434 where
435 S: Serializer,
436 {
437 match phone_number {
438 Some(p) => serializer.serialize_str(&p.to_string()),
439 None => serializer.serialize_none(),
440 }
441 }
442
443 pub fn deserialize<'de, D>(
444 deserializer: D,
445 ) -> Result<Option<E164>, D::Error>
446 where
447 D: Deserializer<'de>,
448 {
449 match Option::<String>::deserialize(deserializer)? {
450 Some(s) => s.parse().map_err(serde::de::Error::custom).map(Some),
451 None => Ok(None),
452 }
453 }
454}
455
456pub mod serde_e164 {
457 use libsignal_core::E164;
458 use serde::{Deserialize, Deserializer, Serializer};
459
460 pub fn serialize<S>(
461 phone_number: &E164,
462 serializer: S,
463 ) -> Result<S::Ok, S::Error>
464 where
465 S: Serializer,
466 {
467 serializer.serialize_str(&phone_number.to_string())
468 }
469
470 pub fn deserialize<'de, D>(deserializer: D) -> Result<E164, D::Error>
471 where
472 D: Deserializer<'de>,
473 {
474 <&str>::deserialize(deserializer)?
475 .parse()
476 .map_err(serde::de::Error::custom)
477 }
478}
479
480#[cfg(feature = "phonenumber")]
481pub mod serde_phone_number {
482 use phonenumber::PhoneNumber;
483 use serde::{Deserialize, Deserializer, Serializer};
484
485 pub fn serialize<S>(
486 phone_number: &PhoneNumber,
487 serializer: S,
488 ) -> Result<S::Ok, S::Error>
489 where
490 S: Serializer,
491 {
492 serializer.serialize_str(&phone_number.to_string())
493 }
494
495 pub fn deserialize<'de, D>(deserializer: D) -> Result<PhoneNumber, D::Error>
496 where
497 D: Deserializer<'de>,
498 {
499 phonenumber::parse(None, <&str>::deserialize(deserializer)?)
500 .map_err(serde::de::Error::custom)
501 }
502}
503
504pub mod serde_service_id {
505 use libsignal_protocol::ServiceId;
506 use serde::{Deserialize, Deserializer, Serializer};
507
508 pub fn serialize<S>(
509 service_id: &ServiceId,
510 serializer: S,
511 ) -> Result<S::Ok, S::Error>
512 where
513 S: Serializer,
514 {
515 serializer.serialize_str(&service_id.service_id_string())
516 }
517
518 pub fn deserialize<'de, D>(deserializer: D) -> Result<ServiceId, D::Error>
519 where
520 D: Deserializer<'de>,
521 {
522 ServiceId::parse_from_service_id_string(<&str>::deserialize(
523 deserializer,
524 )?)
525 .ok_or_else(|| serde::de::Error::custom("invalid service ID string"))
526 }
527}
528
529pub mod serde_aci {
530 use libsignal_core::Aci;
531 use serde::{Deserialize, Deserializer, Serializer};
532
533 pub fn serialize<S>(aci: &Aci, serializer: S) -> Result<S::Ok, S::Error>
534 where
535 S: Serializer,
536 {
537 serializer.serialize_str(&aci.service_id_string())
538 }
539
540 pub fn deserialize<'de, D>(deserializer: D) -> Result<Aci, D::Error>
541 where
542 D: Deserializer<'de>,
543 {
544 Aci::parse_from_service_id_string(<&str>::deserialize(deserializer)?)
545 .ok_or_else(|| serde::de::Error::custom("invalid ACI string"))
546 }
547}
548
549pub mod serde_device_id {
550 use libsignal_core::DeviceId;
551 use serde::{Deserialize, Deserializer, Serializer};
552
553 pub fn serialize<S>(id: &DeviceId, serializer: S) -> Result<S::Ok, S::Error>
554 where
555 S: Serializer,
556 {
557 serializer.serialize_u8(u8::from(*id))
558 }
559
560 pub fn deserialize<'de, D>(deserializer: D) -> Result<DeviceId, D::Error>
561 where
562 D: Deserializer<'de>,
563 {
564 DeviceId::try_from(u8::deserialize(deserializer)?)
565 .map_err(|_| serde::de::Error::custom("invalid device id"))
566 }
567}
568
569pub mod serde_device_id_vec {
570 use libsignal_core::DeviceId;
571 use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serializer};
572
573 pub fn serialize<S>(
574 ids: &Vec<DeviceId>,
575 serializer: S,
576 ) -> Result<S::Ok, S::Error>
577 where
578 S: Serializer,
579 {
580 let mut seq = serializer.serialize_seq(Some(ids.len()))?;
581 for id in ids {
582 seq.serialize_element(&u8::from(*id))?;
583 }
584 seq.end()
585 }
586
587 pub fn deserialize<'de, D>(
588 deserializer: D,
589 ) -> Result<Vec<DeviceId>, D::Error>
590 where
591 D: Deserializer<'de>,
592 {
593 Vec::<u8>::deserialize(deserializer)?
594 .into_iter()
595 .map(DeviceId::try_from)
596 .collect::<Result<Vec<_>, _>>()
597 .map_err(|_| serde::de::Error::custom("invalid device id"))
598 }
599}
600
601pub mod serde_prost_base64 {
602 use super::BASE64_RELAXED;
603 use base64::Engine;
604 use prost::Message;
605 use serde::{Deserialize, Deserializer, Serializer};
606
607 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
609 where
610 T: Message,
611 S: Serializer,
612 {
613 let b64 = BASE64_RELAXED.encode(value.encode_to_vec());
614 serializer.serialize_str(&b64)
615 }
616
617 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
619 where
620 T: Message + Default,
621 D: Deserializer<'de>,
622 {
623 let bytes = BASE64_RELAXED
624 .decode(<&str>::deserialize(deserializer)?)
625 .map_err(serde::de::Error::custom)?;
626
627 T::decode(bytes.as_slice()).map_err(serde::de::Error::custom)
628 }
629}
630
631pub mod serde_optional_prost_base64 {
632 use base64::Engine;
633 use prost::Message;
634 use serde::{Deserialize, Deserializer, Serializer};
635
636 use super::{serde_prost_base64, BASE64_RELAXED};
637
638 pub fn serialize<T, S>(
639 value: &Option<T>,
640 serializer: S,
641 ) -> Result<S::Ok, S::Error>
642 where
643 T: Message,
644 S: Serializer,
645 {
646 match value {
647 Some(msg) => serde_prost_base64::serialize(msg, serializer),
648 None => serializer.serialize_none(),
649 }
650 }
651
652 pub fn deserialize<'de, T, D>(
653 deserializer: D,
654 ) -> Result<Option<T>, D::Error>
655 where
656 T: Message + Default,
657 D: Deserializer<'de>,
658 {
659 match Option::<String>::deserialize(deserializer)? {
660 Some(s) => {
661 let bytes = BASE64_RELAXED
662 .decode(s)
663 .map_err(serde::de::Error::custom)?;
664 let msg = T::decode(bytes.as_slice())
665 .map_err(serde::de::Error::custom)?;
666 Ok(Some(msg))
667 },
668 None => Ok(None),
669 }
670 }
671}