1use std::collections::HashMap;
7use std::ops::Range;
8use std::sync::LazyLock;
9use std::time::SystemTime;
10
11use aes_gcm_siv::aead::generic_array::typenum::Unsigned;
12use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, KeyInit};
13use indexmap::IndexMap;
14use itertools::Itertools;
15use prost::Message;
16use proto::sealed_sender::unidentified_sender_message::message::Type as ProtoMessageType;
17use rand::{CryptoRng, Rng, TryRngCore as _};
18use subtle::{Choice, ConstantTimeEq};
19use zerocopy::{FromBytes, Immutable, KnownLayout};
20
21use crate::{
22 Aci, CiphertextMessageType, DeviceId, Direction, IdentityKey, IdentityKeyPair,
23 IdentityKeyStore, KeyPair, KyberPreKeyStore, PreKeySignalMessage, PreKeyStore, PrivateKey,
24 ProtocolAddress, PublicKey, Result, ServiceId, ServiceIdFixedWidthBinaryBytes, SessionRecord,
25 SessionStore, SignalMessage, SignalProtocolError, SignedPreKeyStore, Timestamp, crypto,
26 message_encrypt, proto, session_cipher,
27};
28
29#[derive(Debug, Clone)]
30pub struct ServerCertificate {
31 serialized: Vec<u8>,
32 key_id: u32,
33 key: PublicKey,
34 certificate: Vec<u8>,
35 signature: Vec<u8>,
36}
37
38const REVOKED_SERVER_CERTIFICATE_KEY_IDS: &[u32] = &[0xDEADC357];
47
48const KNOWN_SERVER_CERTIFICATES: &[(u32, [u8; 33], &[u8])] = &[
58 (
59 2,
60 data_encoding_macro::base64!("BYhU6tPjqP46KGZEzRs1OL4U39V5dlPJ/X09ha4rErkm"),
62 &const_str::hex!(
63 "0a25080212210539450d63ebd0752c0fd4038b9d07a916f5e174b756d409b5ca79f4c97400631e124064c5a38b1e927497d3d4786b101a623ab34a7da3954fae126b04dba9d7a3604ed88cdc8550950f0d4a9134ceb7e19b94139151d2c3d6e1c81e9d1128aafca806"
64 ),
65 ),
66 (
67 3,
68 data_encoding_macro::base64!("BUkY0I+9+oPgDCn4+Ac6Iu813yvqkDr/ga8DzLxFxuk6"),
70 &const_str::hex!(
71 "0a250803122105bc9d1d290be964810dfa7e94856480a3f7060d004c9762c24c575a1522353a5a1240c11ec3c401eb0107ab38f8600e8720a63169e0e2eb8a3fae24f63099f85ea319c3c1c46d3454706ae2a679d1fee690a488adda98a2290b66c906bb60295ed781"
72 ),
73 ),
74 (
75 0x7357C357,
77 data_encoding_macro::base64!("BS/lfaNHzWJDFSjarF+7KQcw//aEr8TPwu2QmV9Yyzt0"),
80 &const_str::hex!(
83 "0a2908d786df9a07122105847c0d2c375234f365e660955187a3735a0f7613d1609d3a6a4d8c53aeaa5a221240e0b9ebacdfc3aa2827f7924b697784d1c25e44ca05dd433e1a38dc6382eb2730d419ca9a250b1be9d5a9463e61efd6781777a91b83c97b844d014206e2829785"
84 ),
85 ),
86];
87
88const VALID_REGISTRATION_ID_MASK: u16 = 0x3FFF;
91
92impl ServerCertificate {
93 pub fn deserialize(data: &[u8]) -> Result<Self> {
94 let pb = proto::sealed_sender::ServerCertificate::decode(data)
95 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
96
97 if pb.certificate.is_none() || pb.signature.is_none() {
98 return Err(SignalProtocolError::InvalidProtobufEncoding);
99 }
100
101 let certificate = pb
102 .certificate
103 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
104 let signature = pb
105 .signature
106 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
107 let certificate_data =
108 proto::sealed_sender::server_certificate::Certificate::decode(certificate.as_ref())
109 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
110 let key = PublicKey::try_from(
111 &certificate_data
112 .key
113 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?[..],
114 )?;
115 let key_id = certificate_data
116 .id
117 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
118
119 Ok(Self {
120 serialized: data.to_vec(),
121 certificate,
122 signature,
123 key,
124 key_id,
125 })
126 }
127
128 pub fn new<R: Rng + CryptoRng>(
129 key_id: u32,
130 key: PublicKey,
131 trust_root: &PrivateKey,
132 rng: &mut R,
133 ) -> Result<Self> {
134 let certificate_pb = proto::sealed_sender::server_certificate::Certificate {
135 id: Some(key_id),
136 key: Some(key.serialize().to_vec()),
137 };
138
139 let certificate = certificate_pb.encode_to_vec();
140
141 let signature = trust_root.calculate_signature(&certificate, rng)?.to_vec();
142
143 let serialized = proto::sealed_sender::ServerCertificate {
144 certificate: Some(certificate.clone()),
145 signature: Some(signature.clone()),
146 }
147 .encode_to_vec();
148
149 Ok(Self {
150 serialized,
151 certificate,
152 signature,
153 key,
154 key_id,
155 })
156 }
157
158 pub fn validate(&self, trust_root: &PublicKey) -> Result<bool> {
159 if REVOKED_SERVER_CERTIFICATE_KEY_IDS.contains(&self.key_id()?) {
160 log::error!(
161 "received server certificate with revoked ID {:x}",
162 self.key_id()?
163 );
164 return Ok(false);
165 }
166 Ok(trust_root.verify_signature(&self.certificate, &self.signature))
167 }
168
169 pub fn key_id(&self) -> Result<u32> {
170 Ok(self.key_id)
171 }
172
173 pub fn public_key(&self) -> Result<PublicKey> {
174 Ok(self.key)
175 }
176
177 pub fn certificate(&self) -> Result<&[u8]> {
178 Ok(&self.certificate)
179 }
180
181 pub fn signature(&self) -> Result<&[u8]> {
182 Ok(&self.signature)
183 }
184
185 pub fn serialized(&self) -> Result<&[u8]> {
186 Ok(&self.serialized)
187 }
188}
189
190#[derive(Debug, Clone)]
191enum SenderCertificateSigner {
192 Embedded(ServerCertificate),
193 Reference(u32),
194}
195
196#[derive(Debug, Clone)]
197pub struct SenderCertificate {
198 signer: SenderCertificateSigner,
199 key: PublicKey,
200 sender_device_id: DeviceId,
201 sender_uuid: String,
202 sender_e164: Option<String>,
203 expiration: Timestamp,
204 serialized: Vec<u8>,
205 certificate: Vec<u8>,
206 signature: Vec<u8>,
207}
208
209impl SenderCertificate {
210 pub fn deserialize(data: &[u8]) -> Result<Self> {
211 let pb = proto::sealed_sender::SenderCertificate::decode(data)
212 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
213 let certificate = pb
214 .certificate
215 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
216 let signature = pb
217 .signature
218 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
219 let certificate_data =
220 proto::sealed_sender::sender_certificate::Certificate::decode(certificate.as_ref())
221 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
222
223 let sender_device_id: DeviceId = certificate_data
224 .sender_device
225 .and_then(|v| DeviceId::try_from(v).ok())
226 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
227 let expiration = certificate_data
228 .expires
229 .map(Timestamp::from_epoch_millis)
230 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
231 let signer = match certificate_data
232 .signer
233 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?
234 {
235 proto::sealed_sender::sender_certificate::certificate::Signer::Certificate(encoded) => {
236 SenderCertificateSigner::Embedded(ServerCertificate::deserialize(&encoded)?)
237 }
238 proto::sealed_sender::sender_certificate::certificate::Signer::Id(id) => {
239 SenderCertificateSigner::Reference(id)
240 }
241 };
242 let sender_uuid = match certificate_data
243 .sender_uuid
244 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?
245 {
246 proto::sealed_sender::sender_certificate::certificate::SenderUuid::UuidString(
247 uuid_str,
248 ) => uuid_str,
249 proto::sealed_sender::sender_certificate::certificate::SenderUuid::UuidBytes(raw) => {
250 uuid::Uuid::from_slice(&raw)
252 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?
253 .to_string()
254 }
255 };
256 let sender_e164 = certificate_data.sender_e164;
257
258 let key = PublicKey::try_from(
259 &certificate_data
260 .identity_key
261 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?[..],
262 )?;
263
264 Ok(Self {
265 signer,
266 key,
267 sender_device_id,
268 sender_uuid,
269 sender_e164,
270 expiration,
271 serialized: data.to_vec(),
272 certificate,
273 signature,
274 })
275 }
276
277 pub fn new<R: Rng + CryptoRng>(
278 sender_uuid: String,
279 sender_e164: Option<String>,
280 key: PublicKey,
281 sender_device_id: DeviceId,
282 expiration: Timestamp,
283 signer: ServerCertificate,
284 signer_key: &PrivateKey,
285 rng: &mut R,
286 ) -> Result<Self> {
287 let certificate_pb = proto::sealed_sender::sender_certificate::Certificate {
288 sender_uuid: Some(
289 proto::sealed_sender::sender_certificate::certificate::SenderUuid::UuidString(
290 sender_uuid.clone(),
291 ),
292 ),
293 sender_e164: sender_e164.clone(),
294 sender_device: Some(sender_device_id.into()),
295 expires: Some(expiration.epoch_millis()),
296 identity_key: Some(key.serialize().to_vec()),
297 signer: Some(
298 proto::sealed_sender::sender_certificate::certificate::Signer::Certificate(
299 signer.serialized()?.to_vec(),
300 ),
301 ),
302 };
303
304 let certificate = certificate_pb.encode_to_vec();
305
306 let signature = signer_key.calculate_signature(&certificate, rng)?.to_vec();
307
308 let serialized = proto::sealed_sender::SenderCertificate {
309 certificate: Some(certificate.clone()),
310 signature: Some(signature.clone()),
311 }
312 .encode_to_vec();
313
314 Ok(Self {
315 signer: SenderCertificateSigner::Embedded(signer),
316 key,
317 sender_device_id,
318 sender_uuid,
319 sender_e164,
320 expiration,
321 serialized,
322 certificate,
323 signature,
324 })
325 }
326
327 pub fn validate(&self, trust_root: &PublicKey, validation_time: Timestamp) -> Result<bool> {
328 self.validate_with_trust_roots(&[trust_root], validation_time)
329 }
330
331 pub fn validate_with_trust_roots(
332 &self,
333 trust_roots: &[impl AsRef<PublicKey>],
334 validation_time: Timestamp,
335 ) -> Result<bool> {
336 let signer = self.signer()?;
337
338 let mut any_valid = Choice::from(0u8);
340 for root in trust_roots {
341 let ok = signer.validate(root.as_ref())?;
342 any_valid |= Choice::from(u8::from(ok));
343 }
344 if !bool::from(any_valid) {
345 log::error!(
346 "sender certificate contained server certificate that wasn't signed by any trust root"
347 );
348 return Ok(false);
349 }
350
351 if !signer
352 .public_key()?
353 .verify_signature(&self.certificate, &self.signature)
354 {
355 log::error!("sender certificate not signed by server");
356 return Ok(false);
357 }
358
359 if validation_time > self.expiration {
360 log::error!(
361 "sender certificate is expired (expiration: {}, validation_time: {})",
362 self.expiration.epoch_millis(),
363 validation_time.epoch_millis()
364 );
365 return Ok(false);
366 }
367
368 Ok(true)
369 }
370
371 pub fn signer(&self) -> Result<&ServerCertificate> {
372 static CERT_MAP: LazyLock<HashMap<u32, (PublicKey, ServerCertificate)>> =
373 LazyLock::new(|| {
374 HashMap::from_iter(KNOWN_SERVER_CERTIFICATES.iter().map(
375 |(id, trust_root, cert)| {
376 (
377 *id,
378 (
379 PublicKey::deserialize(trust_root).expect("valid"),
380 ServerCertificate::deserialize(cert).expect("valid"),
381 ),
382 )
383 },
384 ))
385 });
386
387 match &self.signer {
388 SenderCertificateSigner::Embedded(cert) => Ok(cert),
389 SenderCertificateSigner::Reference(id) => CERT_MAP
390 .get(id)
391 .map(|(_trust_root, cert)| cert)
392 .ok_or_else(|| SignalProtocolError::UnknownSealedSenderServerCertificateId(*id)),
393 }
394 }
395
396 pub fn key(&self) -> Result<PublicKey> {
397 Ok(self.key)
398 }
399
400 pub fn sender_device_id(&self) -> Result<DeviceId> {
401 Ok(self.sender_device_id)
402 }
403
404 pub fn sender_uuid(&self) -> Result<&str> {
405 Ok(&self.sender_uuid)
406 }
407
408 pub fn sender_e164(&self) -> Result<Option<&str>> {
409 Ok(self.sender_e164.as_deref())
410 }
411
412 pub fn expiration(&self) -> Result<Timestamp> {
413 Ok(self.expiration)
414 }
415
416 pub fn serialized(&self) -> Result<&[u8]> {
417 Ok(&self.serialized)
418 }
419
420 pub fn certificate(&self) -> Result<&[u8]> {
421 Ok(&self.certificate)
422 }
423
424 pub fn signature(&self) -> Result<&[u8]> {
425 Ok(&self.signature)
426 }
427}
428
429impl From<ProtoMessageType> for CiphertextMessageType {
430 fn from(message_type: ProtoMessageType) -> Self {
431 let result = match message_type {
432 ProtoMessageType::Message => Self::Whisper,
433 ProtoMessageType::PrekeyMessage => Self::PreKey,
434 ProtoMessageType::SenderkeyMessage => Self::SenderKey,
435 ProtoMessageType::PlaintextContent => Self::Plaintext,
436 };
437 assert!(result == Self::PreKey || message_type as i32 == result as i32);
439 result
440 }
441}
442
443impl From<CiphertextMessageType> for ProtoMessageType {
444 fn from(message_type: CiphertextMessageType) -> Self {
445 let result = match message_type {
446 CiphertextMessageType::PreKey => Self::PrekeyMessage,
447 CiphertextMessageType::Whisper => Self::Message,
448 CiphertextMessageType::SenderKey => Self::SenderkeyMessage,
449 CiphertextMessageType::Plaintext => Self::PlaintextContent,
450 };
451 assert!(result == Self::PrekeyMessage || message_type as i32 == result as i32);
453 result
454 }
455}
456
457#[derive(Clone, Copy, PartialEq, Eq, Debug)]
458pub enum ContentHint {
459 Default,
460 Resendable,
461 Implicit,
462 Unknown(u32),
463}
464
465impl ContentHint {
466 fn to_proto(self) -> Option<i32> {
467 if self == ContentHint::Default {
468 None
469 } else {
470 Some(u32::from(self) as i32)
471 }
472 }
473
474 pub const fn to_u32(self) -> u32 {
475 use proto::sealed_sender::unidentified_sender_message::message::ContentHint as ProtoContentHint;
476 match self {
477 ContentHint::Default => 0,
478 ContentHint::Resendable => ProtoContentHint::Resendable as u32,
479 ContentHint::Implicit => ProtoContentHint::Implicit as u32,
480 ContentHint::Unknown(value) => value,
481 }
482 }
483}
484
485impl From<u32> for ContentHint {
486 fn from(raw_value: u32) -> Self {
487 use proto::sealed_sender::unidentified_sender_message::message::ContentHint as ProtoContentHint;
488 assert!(!ProtoContentHint::is_valid(0));
489 match ProtoContentHint::try_from(raw_value as i32) {
490 Err(_) if raw_value == 0 => ContentHint::Default,
491 Err(_) => ContentHint::Unknown(raw_value),
492 Ok(ProtoContentHint::Resendable) => ContentHint::Resendable,
493 Ok(ProtoContentHint::Implicit) => ContentHint::Implicit,
494 }
495 }
496}
497
498impl From<ContentHint> for u32 {
499 fn from(hint: ContentHint) -> Self {
500 hint.to_u32()
501 }
502}
503
504pub struct UnidentifiedSenderMessageContent {
505 serialized: Vec<u8>,
506 contents: Vec<u8>,
507 sender: SenderCertificate,
508 msg_type: CiphertextMessageType,
509 content_hint: ContentHint,
510 group_id: Option<Vec<u8>>,
511}
512
513impl UnidentifiedSenderMessageContent {
514 pub fn deserialize(data: &[u8]) -> Result<Self> {
515 let pb = proto::sealed_sender::unidentified_sender_message::Message::decode(data)
516 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
517
518 let msg_type = pb
519 .r#type
520 .and_then(|t| ProtoMessageType::try_from(t).ok())
521 .map(CiphertextMessageType::from)
522 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
523 let sender = pb
524 .sender_certificate
525 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
526 let contents = pb
527 .content
528 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
529 let content_hint = pb
530 .content_hint
531 .map(|raw| ContentHint::from(raw as u32))
532 .unwrap_or(ContentHint::Default);
533 let group_id = pb.group_id;
534
535 let sender = SenderCertificate::deserialize(&sender)?;
536
537 let serialized = data.to_vec();
538
539 log::info!(
540 "deserialized UnidentifiedSenderMessageContent from {}.{} with type {:?}",
541 sender.sender_uuid()?,
542 sender.sender_device_id()?,
543 msg_type,
544 );
545
546 Ok(Self {
547 serialized,
548 contents,
549 sender,
550 msg_type,
551 content_hint,
552 group_id,
553 })
554 }
555
556 pub fn new(
557 msg_type: CiphertextMessageType,
558 sender: SenderCertificate,
559 contents: Vec<u8>,
560 content_hint: ContentHint,
561 group_id: Option<Vec<u8>>,
562 ) -> Result<Self> {
563 let proto_msg_type = ProtoMessageType::from(msg_type);
564 let msg = proto::sealed_sender::unidentified_sender_message::Message {
565 content: Some(contents.clone()),
566 r#type: Some(proto_msg_type.into()),
567 sender_certificate: Some(sender.serialized()?.to_vec()),
568 content_hint: content_hint.to_proto(),
569 group_id: group_id.as_ref().and_then(|buf| {
570 if buf.is_empty() {
571 None
572 } else {
573 Some(buf.clone())
574 }
575 }),
576 };
577
578 let serialized = msg.encode_to_vec();
579
580 Ok(Self {
581 serialized,
582 msg_type,
583 sender,
584 contents,
585 content_hint,
586 group_id,
587 })
588 }
589
590 pub fn msg_type(&self) -> Result<CiphertextMessageType> {
591 Ok(self.msg_type)
592 }
593
594 pub fn sender(&self) -> Result<&SenderCertificate> {
595 Ok(&self.sender)
596 }
597
598 pub fn contents(&self) -> Result<&[u8]> {
599 Ok(&self.contents)
600 }
601
602 pub fn content_hint(&self) -> Result<ContentHint> {
603 Ok(self.content_hint)
604 }
605
606 pub fn group_id(&self) -> Result<Option<&[u8]>> {
607 Ok(self.group_id.as_deref())
608 }
609
610 pub fn serialized(&self) -> Result<&[u8]> {
611 Ok(&self.serialized)
612 }
613}
614
615enum UnidentifiedSenderMessage<'a> {
616 V1 {
617 ephemeral_public: PublicKey,
618 encrypted_static: Vec<u8>,
619 encrypted_message: Vec<u8>,
620 },
621 V2 {
622 ephemeral_public: PublicKey,
623 encrypted_message_key: &'a [u8; sealed_sender_v2::MESSAGE_KEY_LEN],
624 authentication_tag: &'a [u8; sealed_sender_v2::AUTH_TAG_LEN],
625 encrypted_message: &'a [u8],
626 },
627}
628
629const SEALED_SENDER_V1_MAJOR_VERSION: u8 = 1;
630const SEALED_SENDER_V1_FULL_VERSION: u8 = 0x11;
631const SEALED_SENDER_V2_MAJOR_VERSION: u8 = 2;
632const SEALED_SENDER_V2_UUID_FULL_VERSION: u8 = 0x22;
633const SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION: u8 = 0x23;
634
635impl<'a> UnidentifiedSenderMessage<'a> {
636 fn deserialize(data: &'a [u8]) -> Result<Self> {
637 let (version_byte, remaining) = data.split_first().ok_or_else(|| {
638 SignalProtocolError::InvalidSealedSenderMessage("Message was empty".to_owned())
639 })?;
640 let version = version_byte >> 4;
641 log::debug!("deserializing UnidentifiedSenderMessage with version {version}");
642
643 match version {
644 0 | SEALED_SENDER_V1_MAJOR_VERSION => {
645 let pb = proto::sealed_sender::UnidentifiedSenderMessage::decode(remaining)
647 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
648
649 let ephemeral_public = pb
650 .ephemeral_public
651 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
652 let encrypted_static = pb
653 .encrypted_static
654 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
655 let encrypted_message = pb
656 .encrypted_message
657 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
658
659 let ephemeral_public = PublicKey::try_from(&ephemeral_public[..])?;
660
661 Ok(Self::V1 {
662 ephemeral_public,
663 encrypted_static,
664 encrypted_message,
665 })
666 }
667 SEALED_SENDER_V2_MAJOR_VERSION => {
668 #[derive(FromBytes, Immutable, KnownLayout)]
670 #[repr(C, packed)]
671 struct PrefixRepr {
672 encrypted_message_key: [u8; sealed_sender_v2::MESSAGE_KEY_LEN],
673 encrypted_authentication_tag: [u8; sealed_sender_v2::AUTH_TAG_LEN],
674 ephemeral_public: [u8; sealed_sender_v2::PUBLIC_KEY_LEN],
675 }
676 let (prefix, encrypted_message) =
677 zerocopy::Ref::<_, PrefixRepr>::from_prefix(remaining)
678 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
679
680 let PrefixRepr {
681 encrypted_message_key,
682 encrypted_authentication_tag,
683 ephemeral_public,
684 } = zerocopy::Ref::into_ref(prefix);
685
686 Ok(Self::V2 {
687 ephemeral_public: PublicKey::from_djb_public_key_bytes(
688 ephemeral_public.as_slice(),
689 )?,
690 encrypted_message_key,
691 authentication_tag: encrypted_authentication_tag,
692 encrypted_message,
693 })
694 }
695 _ => Err(SignalProtocolError::UnknownSealedSenderVersion(version)),
696 }
697 }
698}
699
700mod sealed_sender_v1 {
701 #[cfg(test)]
702 use std::fmt;
703
704 use libsignal_core::derive_arrays;
705
706 use super::*;
707
708 pub(super) struct EphemeralKeys {
711 pub(super) chain_key: [u8; 32],
712 pub(super) cipher_key: [u8; 32],
713 pub(super) mac_key: [u8; 32],
714 }
715
716 const SALT_PREFIX: &[u8] = b"UnidentifiedDelivery";
717
718 impl EphemeralKeys {
719 pub(super) fn calculate(
722 our_keys: &KeyPair,
723 their_public: &PublicKey,
724 direction: Direction,
725 ) -> Result<Self> {
726 let our_pub_key = our_keys.public_key.serialize();
727 let their_pub_key = their_public.serialize();
728 let ephemeral_salt = match direction {
729 Direction::Sending => [SALT_PREFIX, &their_pub_key, &our_pub_key],
730 Direction::Receiving => [SALT_PREFIX, &our_pub_key, &their_pub_key],
731 }
732 .concat();
733
734 let shared_secret = our_keys.private_key.calculate_agreement(their_public)?;
735 let (chain_key, cipher_key, mac_key) = derive_arrays(|bytes| {
736 hkdf::Hkdf::<sha2::Sha256>::new(Some(&ephemeral_salt), &shared_secret)
737 .expand(&[], bytes)
738 .expect("valid output length")
739 });
740
741 Ok(Self {
742 chain_key,
743 cipher_key,
744 mac_key,
745 })
746 }
747 }
748
749 #[cfg(test)]
750 impl PartialEq for EphemeralKeys {
751 fn eq(&self, other: &Self) -> bool {
752 self.chain_key == other.chain_key
753 && self.cipher_key == other.cipher_key
754 && self.mac_key == other.mac_key
755 }
756 }
757
758 #[cfg(test)]
759 impl Eq for EphemeralKeys {}
760
761 #[cfg(test)]
762 impl fmt::Debug for EphemeralKeys {
763 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
764 write!(
765 f,
766 "EphemeralKeys {{ chain_key: {:?}, cipher_key: {:?}, mac_key: {:?} }}",
767 self.chain_key, self.cipher_key, self.mac_key
768 )
769 }
770 }
771
772 pub(super) struct StaticKeys {
774 pub(super) cipher_key: [u8; 32],
775 pub(super) mac_key: [u8; 32],
776 }
777
778 impl StaticKeys {
779 pub(super) fn calculate(
782 our_keys: &IdentityKeyPair,
783 their_key: &PublicKey,
784 chain_key: &[u8; 32],
785 ctext: &[u8],
786 ) -> Result<Self> {
787 let salt = [chain_key, ctext].concat();
788
789 let shared_secret = our_keys.private_key().calculate_agreement(their_key)?;
790 let (_, cipher_key, mac_key) = derive_arrays::<32, 32, 32>(|bytes| {
794 hkdf::Hkdf::<sha2::Sha256>::new(Some(&salt), &shared_secret)
795 .expand(&[], bytes)
796 .expect("valid output length")
797 });
798
799 Ok(Self {
800 cipher_key,
801 mac_key,
802 })
803 }
804 }
805
806 #[test]
807 fn test_agreement_and_authentication() -> Result<()> {
808 let sender_identity = IdentityKeyPair::generate(&mut rand::rng());
810 let recipient_identity = IdentityKeyPair::generate(&mut rand::rng());
811
812 let sender_ephemeral = KeyPair::generate(&mut rand::rng());
814 let ephemeral_public = sender_ephemeral.public_key;
815 let sender_eph_keys = EphemeralKeys::calculate(
817 &sender_ephemeral,
818 recipient_identity.public_key(),
819 Direction::Sending,
820 )?;
821
822 let sender_static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
824 &sender_identity.public_key().serialize(),
825 &sender_eph_keys.cipher_key,
826 &sender_eph_keys.mac_key,
827 )
828 .expect("just generated these keys, they should be correct");
829
830 let sender_static_keys = StaticKeys::calculate(
832 &sender_identity,
833 recipient_identity.public_key(),
834 &sender_eph_keys.chain_key,
835 &sender_static_key_ctext,
836 )?;
837
838 let sender_message_contents = b"this is a binary message";
839 let sender_message_data = crypto::aes256_ctr_hmacsha256_encrypt(
840 sender_message_contents,
841 &sender_static_keys.cipher_key,
842 &sender_static_keys.mac_key,
843 )
844 .expect("just generated these keys, they should be correct");
845
846 let recipient_eph_keys = EphemeralKeys::calculate(
848 &recipient_identity.into(),
849 &ephemeral_public,
850 Direction::Receiving,
851 )?;
852 assert_eq!(sender_eph_keys, recipient_eph_keys);
853
854 let recipient_message_key_bytes = crypto::aes256_ctr_hmacsha256_decrypt(
855 &sender_static_key_ctext,
856 &recipient_eph_keys.cipher_key,
857 &recipient_eph_keys.mac_key,
858 )
859 .expect("should decrypt successfully");
860 let sender_public_key: PublicKey = PublicKey::try_from(&recipient_message_key_bytes[..])?;
861 assert_eq!(sender_identity.public_key(), &sender_public_key);
862
863 let recipient_static_keys = StaticKeys::calculate(
864 &recipient_identity,
865 &sender_public_key,
866 &recipient_eph_keys.chain_key,
867 &sender_static_key_ctext,
868 )?;
869
870 let recipient_message_contents = crypto::aes256_ctr_hmacsha256_decrypt(
871 &sender_message_data,
872 &recipient_static_keys.cipher_key,
873 &recipient_static_keys.mac_key,
874 )
875 .expect("should decrypt successfully");
876 assert_eq!(recipient_message_contents, sender_message_contents);
877
878 Ok(())
879 }
880}
881
882pub async fn sealed_sender_encrypt<R: Rng + CryptoRng>(
889 destination: &ProtocolAddress,
890 sender_cert: &SenderCertificate,
891 ptext: &[u8],
892 session_store: &mut dyn SessionStore,
893 identity_store: &mut dyn IdentityKeyStore,
894 now: SystemTime,
895 rng: &mut R,
896) -> Result<Vec<u8>> {
897 let sender_address = ProtocolAddress::new(
898 sender_cert.sender_uuid()?.to_owned(),
899 sender_cert.sender_device_id()?,
900 );
901 let message = message_encrypt(
902 ptext,
903 destination,
904 &sender_address,
905 session_store,
906 identity_store,
907 now,
908 rng,
909 )
910 .await?;
911 let usmc = UnidentifiedSenderMessageContent::new(
912 message.message_type(),
913 sender_cert.clone(),
914 message.serialize().to_vec(),
915 ContentHint::Default,
916 None,
917 )?;
918 sealed_sender_encrypt_from_usmc(destination, &usmc, identity_store, rng).await
919}
920
921pub async fn sealed_sender_encrypt_from_usmc<R: Rng + CryptoRng>(
972 destination: &ProtocolAddress,
973 usmc: &UnidentifiedSenderMessageContent,
974 identity_store: &dyn IdentityKeyStore,
975 rng: &mut R,
976) -> Result<Vec<u8>> {
977 let our_identity = identity_store.get_identity_key_pair().await?;
978 let their_identity = identity_store
979 .get_identity(destination)
980 .await?
981 .ok_or_else(|| SignalProtocolError::SessionNotFound(destination.clone()))?;
982
983 let ephemeral = KeyPair::generate(rng);
984
985 let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
986 &ephemeral,
987 their_identity.public_key(),
988 Direction::Sending,
989 )?;
990
991 let static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
992 &our_identity.public_key().serialize(),
993 &eph_keys.cipher_key,
994 &eph_keys.mac_key,
995 )
996 .expect("just generated these keys, they should be correct");
997
998 let static_keys = sealed_sender_v1::StaticKeys::calculate(
999 &our_identity,
1000 their_identity.public_key(),
1001 &eph_keys.chain_key,
1002 &static_key_ctext,
1003 )?;
1004
1005 let message_data = crypto::aes256_ctr_hmacsha256_encrypt(
1006 usmc.serialized()?,
1007 &static_keys.cipher_key,
1008 &static_keys.mac_key,
1009 )
1010 .expect("just generated these keys, they should be correct");
1011
1012 let mut serialized = vec![SEALED_SENDER_V1_FULL_VERSION];
1013 let pb = proto::sealed_sender::UnidentifiedSenderMessage {
1014 ephemeral_public: Some(ephemeral.public_key.serialize().to_vec()),
1015 encrypted_static: Some(static_key_ctext),
1016 encrypted_message: Some(message_data),
1017 };
1018 pb.encode(&mut serialized)
1019 .expect("can always append to Vec");
1020
1021 Ok(serialized)
1022}
1023
1024mod sealed_sender_v2 {
1025 use super::*;
1026
1027 const LABEL_R: &[u8] = b"Sealed Sender v2: r (2023-08)";
1029 const LABEL_K: &[u8] = b"Sealed Sender v2: K";
1030 const LABEL_DH: &[u8] = b"Sealed Sender v2: DH";
1031 const LABEL_DH_S: &[u8] = b"Sealed Sender v2: DH-sender";
1032
1033 pub const MESSAGE_KEY_LEN: usize = 32;
1034 pub const CIPHER_KEY_LEN: usize =
1035 <Aes256GcmSiv as aes_gcm_siv::aead::KeySizeUser>::KeySize::USIZE;
1036 pub const AUTH_TAG_LEN: usize = 16;
1037 pub const PUBLIC_KEY_LEN: usize = 32;
1039
1040 pub(super) struct DerivedKeys {
1042 kdf: hkdf::Hkdf<sha2::Sha256>,
1043 }
1044
1045 impl DerivedKeys {
1046 pub(super) fn new(m: &[u8]) -> DerivedKeys {
1048 Self {
1049 kdf: hkdf::Hkdf::<sha2::Sha256>::new(None, m),
1050 }
1051 }
1052
1053 pub(super) fn derive_e(&self) -> KeyPair {
1055 let mut r = [0; 32];
1056 self.kdf
1057 .expand(LABEL_R, &mut r)
1058 .expect("valid output length");
1059 let e = PrivateKey::try_from(&r[..]).expect("valid PrivateKey");
1060 KeyPair::try_from(e).expect("can derive public key")
1061 }
1062
1063 pub(super) fn derive_k(&self) -> [u8; CIPHER_KEY_LEN] {
1065 let mut k = [0; CIPHER_KEY_LEN];
1066 self.kdf
1067 .expand(LABEL_K, &mut k)
1068 .expect("valid output length");
1069 k
1070 }
1071 }
1072
1073 pub(super) fn apply_agreement_xor(
1080 our_keys: &KeyPair,
1081 their_key: &PublicKey,
1082 direction: Direction,
1083 input: &[u8; MESSAGE_KEY_LEN],
1084 ) -> Result<[u8; MESSAGE_KEY_LEN]> {
1085 let agreement = our_keys.calculate_agreement(their_key)?;
1086 let agreement_key_input = match direction {
1087 Direction::Sending => [
1088 agreement,
1089 our_keys.public_key.serialize(),
1090 their_key.serialize(),
1091 ],
1092 Direction::Receiving => [
1093 agreement,
1094 their_key.serialize(),
1095 our_keys.public_key.serialize(),
1096 ],
1097 }
1098 .concat();
1099
1100 let mut result = [0; MESSAGE_KEY_LEN];
1101 hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
1102 .expand(LABEL_DH, &mut result)
1103 .expect("valid output length");
1104 result
1105 .iter_mut()
1106 .zip(input)
1107 .for_each(|(result_byte, input_byte)| *result_byte ^= input_byte);
1108 Ok(result)
1109 }
1110
1111 pub(super) fn compute_authentication_tag(
1120 our_keys: &IdentityKeyPair,
1121 their_key: &IdentityKey,
1122 direction: Direction,
1123 ephemeral_pub_key: &PublicKey,
1124 encrypted_message_key: &[u8; MESSAGE_KEY_LEN],
1125 ) -> Result<[u8; AUTH_TAG_LEN]> {
1126 let agreement = our_keys
1127 .private_key()
1128 .calculate_agreement(their_key.public_key())?;
1129 let mut agreement_key_input = agreement.into_vec();
1130 agreement_key_input.extend_from_slice(&ephemeral_pub_key.serialize());
1131 agreement_key_input.extend_from_slice(encrypted_message_key);
1132 match direction {
1133 Direction::Sending => {
1134 agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1135 agreement_key_input.extend_from_slice(&their_key.serialize());
1136 }
1137 Direction::Receiving => {
1138 agreement_key_input.extend_from_slice(&their_key.serialize());
1139 agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1140 }
1141 }
1142
1143 let mut result = [0; AUTH_TAG_LEN];
1144 hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
1145 .expand(LABEL_DH_S, &mut result)
1146 .expect("valid output length");
1147 Ok(result)
1148 }
1149
1150 #[test]
1151 fn test_agreement_and_authentication() -> Result<()> {
1152 let sender_identity = IdentityKeyPair::generate(&mut rand::rng());
1154 let recipient_identity = IdentityKeyPair::generate(&mut rand::rng());
1155
1156 let m: [u8; MESSAGE_KEY_LEN] = rand::rng().random();
1158 let ephemeral_keys = DerivedKeys::new(&m);
1160 let e = ephemeral_keys.derive_e();
1161
1162 let sender_c_0: [u8; MESSAGE_KEY_LEN] =
1164 apply_agreement_xor(&e, recipient_identity.public_key(), Direction::Sending, &m)?;
1165 let sender_at_0 = compute_authentication_tag(
1167 &sender_identity,
1168 recipient_identity.identity_key(),
1169 Direction::Sending,
1170 &e.public_key,
1171 &sender_c_0,
1172 )?;
1173
1174 let recv_m = apply_agreement_xor(
1176 &recipient_identity.into(),
1177 &e.public_key,
1178 Direction::Receiving,
1179 &sender_c_0,
1180 )?;
1181 assert_eq!(&recv_m, &m);
1182
1183 let recv_at_0 = compute_authentication_tag(
1184 &recipient_identity,
1185 sender_identity.identity_key(),
1186 Direction::Receiving,
1187 &e.public_key,
1188 &sender_c_0,
1189 )?;
1190 assert_eq!(&recv_at_0, &sender_at_0);
1191
1192 Ok(())
1193 }
1194}
1195
1196pub async fn sealed_sender_multi_recipient_encrypt<
1357 R: Rng + CryptoRng,
1358 X: IntoIterator<Item = ServiceId>,
1359>(
1360 destinations: &[&ProtocolAddress],
1361 destination_sessions: &[&SessionRecord],
1362 excluded_recipients: X,
1363 usmc: &UnidentifiedSenderMessageContent,
1364 identity_store: &dyn IdentityKeyStore,
1365 rng: &mut R,
1366) -> Result<Vec<u8>>
1367where
1368 X::IntoIter: ExactSizeIterator,
1369{
1370 sealed_sender_multi_recipient_encrypt_impl(
1371 destinations,
1372 destination_sessions,
1373 excluded_recipients,
1374 usmc,
1375 identity_store,
1376 rng,
1377 )
1378 .await
1379}
1380
1381async fn sealed_sender_multi_recipient_encrypt_impl<
1382 R: Rng + CryptoRng,
1383 X: IntoIterator<Item = ServiceId>,
1384>(
1385 destinations: &[&ProtocolAddress],
1386 destination_sessions: &[&SessionRecord],
1387 excluded_recipients: X,
1388 usmc: &UnidentifiedSenderMessageContent,
1389 identity_store: &dyn IdentityKeyStore,
1390 rng: &mut R,
1391) -> Result<Vec<u8>>
1392where
1393 X::IntoIter: ExactSizeIterator,
1394{
1395 if destinations.len() != destination_sessions.len() {
1396 return Err(SignalProtocolError::InvalidArgument(
1397 "must have the same number of destination sessions as addresses".to_string(),
1398 ));
1399 }
1400
1401 let excluded_recipients = excluded_recipients.into_iter();
1402 let our_identity = identity_store.get_identity_key_pair().await?;
1403
1404 let m: [u8; sealed_sender_v2::MESSAGE_KEY_LEN] = rng.random();
1405 let keys = sealed_sender_v2::DerivedKeys::new(&m);
1406 let e = keys.derive_e();
1407 let e_pub = &e.public_key;
1408
1409 let ciphertext = {
1411 let mut ciphertext = usmc.serialized()?.to_vec();
1412 let symmetric_authentication_tag = Aes256GcmSiv::new(&keys.derive_k().into())
1413 .encrypt_in_place_detached(
1414 &aes_gcm_siv::Nonce::default(),
1416 &[],
1418 &mut ciphertext,
1419 )
1420 .expect("AES-GCM-SIV encryption should not fail with a just-computed key");
1421 ciphertext.extend_from_slice(&symmetric_authentication_tag);
1424 ciphertext
1425 };
1426
1427 let identity_keys_and_ranges: Vec<(IdentityKey, Range<usize>)> = {
1432 let mut identity_keys_and_ranges = vec![];
1433 for (_, mut next_group) in &destinations
1434 .iter()
1435 .enumerate()
1436 .chunk_by(|(_i, next)| next.name())
1437 {
1438 let (i, &destination) = next_group
1439 .next()
1440 .expect("at least one element in every group");
1441 let count = 1 + next_group.count();
1444 let their_identity =
1445 identity_store
1446 .get_identity(destination)
1447 .await?
1448 .ok_or_else(|| {
1449 log::error!("missing identity key for {destination}");
1450 SignalProtocolError::SessionNotFound(destination.clone())
1454 })?;
1455 identity_keys_and_ranges.push((their_identity, i..i + count));
1456 }
1457 identity_keys_and_ranges
1458 };
1459
1460 let serialize_recipient_destinations_into = |serialized: &mut Vec<u8>,
1466 destinations: &[&ProtocolAddress],
1467 sessions: &[&SessionRecord],
1468 their_identity: &IdentityKey|
1469 -> Result<()> {
1470 let their_service_id = ServiceId::parse_from_service_id_string(destinations[0].name())
1471 .ok_or_else(|| {
1472 SignalProtocolError::InvalidArgument(format!(
1473 "multi-recipient sealed sender requires recipients' ServiceId (not {})",
1474 destinations[0].name()
1475 ))
1476 })?;
1477
1478 serialized.extend_from_slice(&their_service_id.service_id_fixed_width_binary());
1479
1480 debug_assert_eq!(
1481 destinations.len(),
1482 sessions.len(),
1483 "should be sliced with the same range"
1484 );
1485 let mut destinations_and_sessions = destinations.iter().zip(sessions);
1486 while let Some((&destination, session)) = destinations_and_sessions.next() {
1487 let their_registration_id = session.remote_registration_id().map_err(|_| {
1488 SignalProtocolError::InvalidState(
1489 "sealed_sender_multi_recipient_encrypt",
1490 format!(
1491 concat!(
1492 "cannot get registration ID from session with {} ",
1493 "(maybe it was recently archived)"
1494 ),
1495 destination
1496 ),
1497 )
1498 })?;
1499 if their_registration_id & u32::from(VALID_REGISTRATION_ID_MASK)
1500 != their_registration_id
1501 {
1502 return Err(SignalProtocolError::InvalidRegistrationId(
1503 destination.clone(),
1504 their_registration_id,
1505 ));
1506 }
1507 let mut their_registration_id =
1508 u16::try_from(their_registration_id).expect("just checked range");
1509 if destinations_and_sessions.len() > 0 {
1510 their_registration_id |= 0x8000;
1511 }
1512
1513 let device_id = destination.device_id();
1514 serialized.push(device_id.into());
1515 serialized.extend_from_slice(&their_registration_id.to_be_bytes());
1516 }
1517
1518 let c_i = sealed_sender_v2::apply_agreement_xor(
1519 &e,
1520 their_identity.public_key(),
1521 Direction::Sending,
1522 &m,
1523 )?;
1524 serialized.extend_from_slice(&c_i);
1525
1526 let at_i = sealed_sender_v2::compute_authentication_tag(
1527 &our_identity,
1528 their_identity,
1529 Direction::Sending,
1530 e_pub,
1531 &c_i,
1532 )?;
1533 serialized.extend_from_slice(&at_i);
1534
1535 Ok(())
1536 };
1537
1538 let process_chunk =
1539 |serialized: &mut Vec<u8>, chunk: &[(IdentityKey, Range<usize>)]| -> Result<()> {
1540 for (their_identity, destination_range) in chunk {
1541 let these_destinations = &destinations[destination_range.clone()];
1542 let these_sessions = &destination_sessions[destination_range.clone()];
1543 serialize_recipient_destinations_into(
1544 serialized,
1545 these_destinations,
1546 these_sessions,
1547 their_identity,
1548 )?;
1549 }
1550 Ok(())
1551 };
1552
1553 let mut serialized: Vec<u8> = vec![SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION];
1554
1555 let count_of_recipients = identity_keys_and_ranges.len() + excluded_recipients.len();
1556 prost::encode_length_delimiter(count_of_recipients, &mut serialized)
1557 .expect("can always resize a Vec");
1558
1559 let parallelism = std::thread::available_parallelism()
1561 .map(usize::from)
1562 .unwrap_or(1);
1563 let chunk_size = std::cmp::max(6, identity_keys_and_ranges.len().div_ceil(parallelism));
1564
1565 if parallelism == 1 || chunk_size >= identity_keys_and_ranges.len() {
1566 process_chunk(&mut serialized, &identity_keys_and_ranges)?;
1567 } else {
1568 let mut chunks = identity_keys_and_ranges.chunks(chunk_size);
1569 let first_chunk = chunks.next().expect("at least one chunk, tested above");
1571
1572 let mut all_outputs = Vec::new();
1573 all_outputs.resize_with(chunks.len(), || Ok(vec![]));
1574
1575 rayon::scope(|scope| -> Result<()> {
1576 let mut outputs = &mut all_outputs[..];
1577 for chunk in chunks {
1578 let (next_output, remaining_outputs) = outputs
1579 .split_first_mut()
1580 .expect("as many outputs as remaining chunks");
1581 scope.spawn(|_| {
1582 let mut serialized = vec![];
1583 *next_output = process_chunk(&mut serialized, chunk).map(|_| serialized);
1584 });
1585 outputs = remaining_outputs;
1586 }
1587
1588 process_chunk(&mut serialized, first_chunk)
1589 })?;
1590
1591 for output in all_outputs {
1592 serialized.extend(output?);
1593 }
1594 }
1595
1596 for excluded in excluded_recipients {
1597 serialized.extend_from_slice(&excluded.service_id_fixed_width_binary());
1598 serialized.push(0);
1599 }
1600
1601 serialized.extend_from_slice(e_pub.public_key_bytes());
1602 serialized.extend_from_slice(&ciphertext);
1603
1604 Ok(serialized)
1605}
1606
1607pub struct SealedSenderV2SentMessageRecipient<'a> {
1611 pub devices: Vec<(DeviceId, u16)>,
1613 c_and_at: &'a [u8],
1616}
1617
1618pub struct SealedSenderV2SentMessage<'a> {
1622 full_message: &'a [u8],
1624 pub version: u8,
1626 pub recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>>,
1632 shared_bytes: &'a [u8],
1634}
1635
1636impl<'a> SealedSenderV2SentMessage<'a> {
1637 pub fn parse(data: &'a [u8]) -> Result<Self> {
1639 if data.is_empty() {
1640 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1641 "Message was empty".to_owned(),
1642 ));
1643 }
1644
1645 let version = data[0];
1646 if !matches!(
1647 version,
1648 SEALED_SENDER_V2_UUID_FULL_VERSION | SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION
1649 ) {
1650 return Err(SignalProtocolError::UnknownSealedSenderVersion(version));
1651 }
1652
1653 fn advance<'a, const N: usize>(buf: &mut &'a [u8]) -> Result<&'a [u8; N]> {
1654 let (prefix, remaining) = buf
1655 .split_first_chunk()
1656 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
1657 *buf = remaining;
1658 Ok(prefix)
1659 }
1660 fn decode_varint(buf: &mut &[u8]) -> Result<u32> {
1661 let result: usize = prost::decode_length_delimiter(*buf)
1662 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1663 *buf = &buf[prost::length_delimiter_len(result)..];
1664 result
1665 .try_into()
1666 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)
1667 }
1668
1669 let mut remaining = &data[1..];
1670 let recipient_count = decode_varint(&mut remaining)?
1671 .try_into()
1672 .unwrap_or(usize::MAX);
1673
1674 let mut recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>> =
1678 IndexMap::with_capacity(std::cmp::min(recipient_count as usize, 6000));
1679 for _ in 0..recipient_count {
1680 let service_id = if version == SEALED_SENDER_V2_UUID_FULL_VERSION {
1681 ServiceId::from(Aci::from_uuid_bytes(*advance::<
1683 { std::mem::size_of::<uuid::Bytes>() },
1684 >(&mut remaining)?))
1685 } else {
1686 ServiceId::parse_from_service_id_fixed_width_binary(advance::<
1687 { std::mem::size_of::<ServiceIdFixedWidthBinaryBytes>() },
1688 >(
1689 &mut remaining
1690 )?)
1691 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?
1692 };
1693 let mut devices = Vec::new();
1694 loop {
1695 let device_id = advance::<1>(&mut remaining)?[0];
1696 if device_id == 0 {
1697 if !devices.is_empty() {
1698 return Err(SignalProtocolError::InvalidProtobufEncoding);
1699 }
1700 break;
1701 }
1702 let device_id = DeviceId::new(device_id)
1703 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1704 let registration_id_and_has_more =
1705 u16::from_be_bytes(*advance::<2>(&mut remaining)?);
1706 devices.push((
1707 device_id,
1708 registration_id_and_has_more & VALID_REGISTRATION_ID_MASK,
1709 ));
1710 let has_more = (registration_id_and_has_more & 0x8000) != 0;
1711 if !has_more {
1712 break;
1713 }
1714 }
1715
1716 let c_and_at: &[u8] = if devices.is_empty() {
1717 &[]
1718 } else {
1719 advance::<{ sealed_sender_v2::MESSAGE_KEY_LEN + sealed_sender_v2::AUTH_TAG_LEN }>(
1720 &mut remaining,
1721 )?
1722 };
1723
1724 match recipients.entry(service_id) {
1725 indexmap::map::Entry::Occupied(mut existing) => {
1726 if existing.get().devices.is_empty() || devices.is_empty() {
1727 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1728 "recipient redundantly encoded as empty".to_owned(),
1729 ));
1730 }
1731 existing.get_mut().devices.extend(devices);
1734 }
1738 indexmap::map::Entry::Vacant(entry) => {
1739 entry.insert(SealedSenderV2SentMessageRecipient { devices, c_and_at });
1740 }
1741 };
1742 }
1743
1744 if remaining.len() < sealed_sender_v2::PUBLIC_KEY_LEN {
1745 return Err(SignalProtocolError::InvalidProtobufEncoding);
1746 }
1747
1748 Ok(Self {
1749 full_message: data,
1750 version,
1751 recipients,
1752 shared_bytes: remaining,
1753 })
1754 }
1755
1756 #[inline]
1762 pub fn received_message_parts_for_recipient(
1763 &self,
1764 recipient: &SealedSenderV2SentMessageRecipient<'a>,
1765 ) -> impl AsRef<[&[u8]]> {
1766 [
1771 &[SEALED_SENDER_V2_UUID_FULL_VERSION],
1772 recipient.c_and_at,
1773 self.shared_bytes,
1774 ]
1775 }
1776
1777 #[inline]
1784 fn offset_within_full_message(&self, addr: *const u8) -> Option<usize> {
1785 let offset = (addr as usize).wrapping_sub(self.full_message.as_ptr() as usize);
1789 if offset <= self.full_message.len() {
1792 debug_assert!(
1793 offset == self.full_message.len() || std::ptr::eq(&self.full_message[offset], addr)
1794 );
1795 Some(offset)
1796 } else {
1797 None
1798 }
1799 }
1800
1801 pub fn range_for_recipient_key_material(
1808 &self,
1809 recipient: &SealedSenderV2SentMessageRecipient<'a>,
1810 ) -> Range<usize> {
1811 if recipient.c_and_at.is_empty() {
1812 return 0..0;
1813 }
1814 let offset = self
1815 .offset_within_full_message(recipient.c_and_at.as_ptr())
1816 .expect("'recipient' is not one of the recipients in this SealedSenderV2SentMessage");
1817 let end_offset = offset.saturating_add(recipient.c_and_at.len());
1818 assert!(
1819 end_offset <= self.full_message.len(),
1820 "invalid 'recipient' passed to range_for_recipient_key_material"
1821 );
1822 offset..end_offset
1823 }
1824
1825 pub fn offset_of_shared_bytes(&self) -> usize {
1830 debug_assert_eq!(
1831 self.full_message.as_ptr_range().end,
1832 self.shared_bytes.as_ptr_range().end,
1833 "SealedSenderV2SentMessage parsed incorrectly"
1834 );
1835 self.offset_within_full_message(self.shared_bytes.as_ptr())
1836 .expect("constructed correctly")
1837 }
1838}
1839
1840pub async fn sealed_sender_decrypt_to_usmc(
1845 ciphertext: &[u8],
1846 identity_store: &dyn IdentityKeyStore,
1847) -> Result<UnidentifiedSenderMessageContent> {
1848 let our_identity = identity_store.get_identity_key_pair().await?;
1849
1850 match UnidentifiedSenderMessage::deserialize(ciphertext)? {
1851 UnidentifiedSenderMessage::V1 {
1852 ephemeral_public,
1853 encrypted_static,
1854 encrypted_message,
1855 } => {
1856 let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
1857 &our_identity.into(),
1858 &ephemeral_public,
1859 Direction::Receiving,
1860 )?;
1861
1862 let message_key_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1863 &encrypted_static,
1864 &eph_keys.cipher_key,
1865 &eph_keys.mac_key,
1866 ) {
1867 Ok(plaintext) => plaintext,
1868 Err(crypto::DecryptionError::BadKeyOrIv) => {
1869 unreachable!("just derived these keys; they should be valid");
1870 }
1871 Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1872 log::error!("failed to decrypt sealed sender v1 message key: {msg}");
1873 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1874 "failed to decrypt sealed sender v1 message key".to_owned(),
1875 ));
1876 }
1877 };
1878
1879 let static_key = PublicKey::try_from(&message_key_bytes[..])?;
1880
1881 let static_keys = sealed_sender_v1::StaticKeys::calculate(
1882 &our_identity,
1883 &static_key,
1884 &eph_keys.chain_key,
1885 &encrypted_static,
1886 )?;
1887
1888 let message_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1889 &encrypted_message,
1890 &static_keys.cipher_key,
1891 &static_keys.mac_key,
1892 ) {
1893 Ok(plaintext) => plaintext,
1894 Err(crypto::DecryptionError::BadKeyOrIv) => {
1895 unreachable!("just derived these keys; they should be valid");
1896 }
1897 Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1898 log::error!("failed to decrypt sealed sender v1 message contents: {msg}");
1899 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1900 "failed to decrypt sealed sender v1 message contents".to_owned(),
1901 ));
1902 }
1903 };
1904
1905 let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1906
1907 if !bool::from(message_key_bytes.ct_eq(&usmc.sender()?.key()?.serialize())) {
1908 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1909 "sender certificate key does not match message key".to_string(),
1910 ));
1911 }
1912
1913 Ok(usmc)
1914 }
1915 UnidentifiedSenderMessage::V2 {
1916 ephemeral_public,
1917 encrypted_message_key,
1918 authentication_tag,
1919 encrypted_message,
1920 } => {
1921 let m = sealed_sender_v2::apply_agreement_xor(
1922 &our_identity.into(),
1923 &ephemeral_public,
1924 Direction::Receiving,
1925 encrypted_message_key,
1926 )?;
1927
1928 let keys = sealed_sender_v2::DerivedKeys::new(&m);
1929 if !bool::from(keys.derive_e().public_key.ct_eq(&ephemeral_public)) {
1930 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1931 "derived ephemeral key did not match key provided in message".to_string(),
1932 ));
1933 }
1934
1935 let mut message_bytes = Vec::from(encrypted_message);
1936 Aes256GcmSiv::new(&keys.derive_k().into())
1937 .decrypt_in_place(
1938 &aes_gcm_siv::Nonce::default(),
1940 &[],
1942 &mut message_bytes,
1943 )
1944 .map_err(|err| {
1945 SignalProtocolError::InvalidSealedSenderMessage(format!(
1946 "failed to decrypt inner message: {err}"
1947 ))
1948 })?;
1949
1950 let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1951
1952 let at = sealed_sender_v2::compute_authentication_tag(
1953 &our_identity,
1954 &usmc.sender()?.key()?.into(),
1955 Direction::Receiving,
1956 &ephemeral_public,
1957 encrypted_message_key,
1958 )?;
1959 if !bool::from(authentication_tag.ct_eq(&at)) {
1960 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1961 "sender certificate key does not match authentication tag".to_string(),
1962 ));
1963 }
1964
1965 Ok(usmc)
1966 }
1967 }
1968}
1969
1970#[derive(Debug)]
1971pub struct SealedSenderDecryptionResult {
1972 pub sender_uuid: String,
1973 pub sender_e164: Option<String>,
1974 pub device_id: DeviceId,
1975 pub message: Vec<u8>,
1976}
1977
1978impl SealedSenderDecryptionResult {
1979 pub fn sender_uuid(&self) -> Result<&str> {
1980 Ok(self.sender_uuid.as_ref())
1981 }
1982
1983 pub fn sender_e164(&self) -> Result<Option<&str>> {
1984 Ok(self.sender_e164.as_deref())
1985 }
1986
1987 pub fn device_id(&self) -> Result<DeviceId> {
1988 Ok(self.device_id)
1989 }
1990
1991 pub fn message(&self) -> Result<&[u8]> {
1992 Ok(self.message.as_ref())
1993 }
1994}
1995
1996#[expect(clippy::too_many_arguments)]
2004pub async fn sealed_sender_decrypt(
2005 ciphertext: &[u8],
2006 trust_root: &PublicKey,
2007 timestamp: Timestamp,
2008 local_e164: Option<String>,
2009 local_uuid: String,
2010 local_device_id: DeviceId,
2011 identity_store: &mut dyn IdentityKeyStore,
2012 session_store: &mut dyn SessionStore,
2013 pre_key_store: &mut dyn PreKeyStore,
2014 signed_pre_key_store: &dyn SignedPreKeyStore,
2015 kyber_pre_key_store: &mut dyn KyberPreKeyStore,
2016) -> Result<SealedSenderDecryptionResult> {
2017 let usmc = sealed_sender_decrypt_to_usmc(ciphertext, identity_store).await?;
2018
2019 if !usmc.sender()?.validate(trust_root, timestamp)? {
2020 return Err(SignalProtocolError::InvalidSealedSenderMessage(
2021 "trust root validation failed".to_string(),
2022 ));
2023 }
2024
2025 let is_local_uuid = local_uuid == usmc.sender()?.sender_uuid()?;
2026
2027 let is_local_e164 = match (local_e164, usmc.sender()?.sender_e164()?) {
2028 (Some(l), Some(s)) => l == s,
2029 (_, _) => false,
2030 };
2031
2032 if (is_local_e164 || is_local_uuid) && usmc.sender()?.sender_device_id()? == local_device_id {
2033 return Err(SignalProtocolError::SealedSenderSelfSend);
2034 }
2035
2036 let mut rng = rand::rngs::OsRng.unwrap_err();
2037
2038 let remote_address = ProtocolAddress::new(
2039 usmc.sender()?.sender_uuid()?.to_string(),
2040 usmc.sender()?.sender_device_id()?,
2041 );
2042 let local_address = ProtocolAddress::new(local_uuid, local_device_id);
2043
2044 let message = match usmc.msg_type()? {
2045 CiphertextMessageType::Whisper => {
2046 let ctext = SignalMessage::try_from(usmc.contents()?)?;
2047 session_cipher::message_decrypt_signal(
2048 &ctext,
2049 &remote_address,
2050 session_store,
2051 identity_store,
2052 &mut rng,
2053 )
2054 .await?
2055 }
2056 CiphertextMessageType::PreKey => {
2057 let ctext = PreKeySignalMessage::try_from(usmc.contents()?)?;
2058 session_cipher::message_decrypt_prekey(
2059 &ctext,
2060 &remote_address,
2061 &local_address,
2062 session_store,
2063 identity_store,
2064 pre_key_store,
2065 signed_pre_key_store,
2066 kyber_pre_key_store,
2067 &mut rng,
2068 )
2069 .await?
2070 }
2071 msg_type => {
2072 return Err(SignalProtocolError::InvalidMessage(
2073 msg_type,
2074 "unexpected message type for sealed_sender_decrypt",
2075 ));
2076 }
2077 };
2078
2079 Ok(SealedSenderDecryptionResult {
2080 sender_uuid: usmc.sender()?.sender_uuid()?.to_string(),
2081 sender_e164: usmc.sender()?.sender_e164()?.map(|s| s.to_string()),
2082 device_id: usmc.sender()?.sender_device_id()?,
2083 message,
2084 })
2085}
2086
2087#[test]
2088fn test_lossless_round_trip() -> Result<()> {
2089 let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
2090
2091 let certificate_data = const_str::hex!(
2144 "100119697a0000000000002221056c9d1f8deb82b9a898f9c277a1b74989ec009afb5c0acb5e8e69e3d5ca29d6322a690a2508011221053b03ca070e6f6b2f271d32f27321689cdf4e59b106c10b58fbe15063ed868a5a124024bc92954e52ad1a105b5bda85c9db410dcfeb42a671b45a523b3a46e9594a8bde0efc671d8e8e046b32c67f59b80a46ffdf24071850779bc21325107902af89322461616161616161612d373030302d313165622d623332612d333362386138613438376136ba3e136372617368696e6720726967687420646f776e"
2145 );
2146 let certificate_signature = const_str::hex!(
2147 "a22d8f86f5d00794f319add821e342c6ffffb6b34f741e569f8b321ab0255f2d1757ecf648e53a3602cae8f09b3fc80dcf27534d67efd272b6739afc31f75c8c"
2148 );
2149
2150 let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2151 certificate: Some(certificate_data.to_vec()),
2152 signature: Some(certificate_signature.to_vec()),
2153 };
2154
2155 let sender_certificate =
2156 SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2157 assert_eq!(
2158 sender_certificate.sender_uuid().expect("valid"),
2159 "aaaaaaaa-7000-11eb-b32a-33b8a8a487a6",
2160 );
2161 assert_eq!(sender_certificate.sender_e164().expect("valid"), None);
2162 assert_eq!(
2163 sender_certificate.sender_device_id().expect("valid"),
2164 DeviceId::new(1).expect("valid"),
2165 );
2166 assert_eq!(
2167 sender_certificate
2168 .expiration()
2169 .expect("valid")
2170 .epoch_millis(),
2171 31337
2172 );
2173 assert!(sender_certificate.validate(
2174 &trust_root.public_key()?,
2175 Timestamp::from_epoch_millis(31336)
2176 )?);
2177 Ok(())
2178}
2179
2180#[test]
2181fn test_uuid_bytes_representation() -> Result<()> {
2182 let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
2183
2184 let certificate_data = const_str::hex!(
2186 "100119697a000000000000222105e083a8ce423d1c1955174107a85a6a7f3bcbf566723624077f75eafe8e0a07752a690a25080112210507a24397ae27d06fa76d2f02cfb5546e0b23a7e0c3670c1eb1e73b135a8e1e4d12407d127509ae1f5e9dcaa511793d3e94350dcb269e4ca54500da6e1f4dc13d95940c15badef019edfe8666315500c54e4489d4b83f6ce79c7f65c9772a1a83d88c3a10aaaaaaaa700011ebb32a33b8a8a487a6"
2187 );
2188 let certificate_signature = const_str::hex!(
2189 "755c428e9bf6ba367152f1e545834649b4e8f70df8383a352a953fdb774862af5d42fab573fc52b90ad47c331c36f93b1a4fa7a2504917d895452ffe7f44bd0e"
2190 );
2191
2192 let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2193 certificate: Some(certificate_data.to_vec()),
2194 signature: Some(certificate_signature.to_vec()),
2195 };
2196
2197 let sender_certificate =
2198 SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2199 assert_eq!(
2200 sender_certificate.sender_uuid().expect("valid"),
2201 "aaaaaaaa-7000-11eb-b32a-33b8a8a487a6",
2202 );
2203 assert_eq!(sender_certificate.sender_e164().expect("valid"), None);
2204 assert_eq!(
2205 sender_certificate.sender_device_id().expect("valid"),
2206 DeviceId::new(1).expect("valid"),
2207 );
2208 assert_eq!(
2209 sender_certificate
2210 .expiration()
2211 .expect("valid")
2212 .epoch_millis(),
2213 31337
2214 );
2215 assert!(sender_certificate.validate(
2216 &trust_root.public_key()?,
2217 Timestamp::from_epoch_millis(31336)
2218 )?);
2219 Ok(())
2220}
2221
2222#[test]
2223fn test_known_server_cert() -> Result<()> {
2224 let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
2235 let certificate_data = const_str::hex!(
2238 "100119697a000000000000222105d75b13e15c7700079dd226f51e5a790ba395e819e88a74d0cf5cedfad8b4334840d786df9a07322461616161616161612d373030302d313165622d623332612d333362386138613438376136"
2239 );
2240 let certificate_signature = const_str::hex!(
2241 "e62667bce627caed56ca2ab309b6ae7bc890a30a7482c0e1fd77ec9c3b7528abfd45c8c42b240509a71d973ef5e0f1dbd2685fe01410f0fdbaa8fb247a67e08f"
2242 );
2243
2244 let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2245 certificate: Some(certificate_data.to_vec()),
2246 signature: Some(certificate_signature.to_vec()),
2247 };
2248
2249 let sender_certificate =
2250 SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2251 assert!(sender_certificate.validate(
2252 &trust_root.public_key()?,
2253 Timestamp::from_epoch_millis(31336)
2254 )?);
2255
2256 Ok(())
2257}
2258
2259#[test]
2260fn verify_known_certificates() {
2261 assert!(
2262 KNOWN_SERVER_CERTIFICATES
2263 .iter()
2264 .map(|(id, _trust_root, _cert)| id)
2265 .all_unique(),
2266 "all known certificate IDs must be unique"
2267 );
2268
2269 for (id, trust_root, cert) in KNOWN_SERVER_CERTIFICATES {
2270 let trust_root = PublicKey::deserialize(trust_root)
2271 .unwrap_or_else(|e| panic!("[{id:x}] has invalid trust root: {e}"));
2272 let cert = ServerCertificate::deserialize(cert)
2273 .unwrap_or_else(|e| panic!("[{id:x}] has invalid certificate data: {e}"));
2274 assert_eq!(*id, cert.key_id, "[{id:x}] mismatched certificate ID");
2275 assert!(
2276 cert.validate(&trust_root).expect("can validate"),
2277 "[{id:x}] has wrong trust root"
2278 );
2279 }
2280}