1use std::ops::Range;
7use std::time::SystemTime;
8
9use aes_gcm_siv::aead::generic_array::typenum::Unsigned;
10use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, KeyInit};
11use indexmap::IndexMap;
12use itertools::Itertools;
13use prost::Message;
14use proto::sealed_sender::unidentified_sender_message::message::Type as ProtoMessageType;
15use rand::{CryptoRng, Rng, TryRngCore as _};
16use subtle::ConstantTimeEq;
17use zerocopy::{FromBytes, Immutable, KnownLayout};
18
19use crate::{
20 crypto, message_encrypt, proto, ratchet, session_cipher, Aci, CiphertextMessageType, DeviceId,
21 Direction, IdentityKey, IdentityKeyPair, IdentityKeyStore, KeyPair, KyberPreKeyStore,
22 PreKeySignalMessage, PreKeyStore, PrivateKey, ProtocolAddress, PublicKey, Result, ServiceId,
23 ServiceIdFixedWidthBinaryBytes, SessionRecord, SessionStore, SignalMessage,
24 SignalProtocolError, SignedPreKeyStore, Timestamp,
25};
26
27#[derive(Debug, Clone)]
28pub struct ServerCertificate {
29 serialized: Vec<u8>,
30 key_id: u32,
31 key: PublicKey,
32 certificate: Vec<u8>,
33 signature: Vec<u8>,
34}
35
36const REVOKED_SERVER_CERTIFICATE_KEY_IDS: &[u32] = &[0xDEADC357];
45
46const VALID_REGISTRATION_ID_MASK: u16 = 0x3FFF;
49
50impl ServerCertificate {
51 pub fn deserialize(data: &[u8]) -> Result<Self> {
52 let pb = proto::sealed_sender::ServerCertificate::decode(data)
53 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
54
55 if pb.certificate.is_none() || pb.signature.is_none() {
56 return Err(SignalProtocolError::InvalidProtobufEncoding);
57 }
58
59 let certificate = pb
60 .certificate
61 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
62 let signature = pb
63 .signature
64 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
65 let certificate_data =
66 proto::sealed_sender::server_certificate::Certificate::decode(certificate.as_ref())
67 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
68 let key = PublicKey::try_from(
69 &certificate_data
70 .key
71 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?[..],
72 )?;
73 let key_id = certificate_data
74 .id
75 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
76
77 Ok(Self {
78 serialized: data.to_vec(),
79 certificate,
80 signature,
81 key,
82 key_id,
83 })
84 }
85
86 pub fn new<R: Rng + CryptoRng>(
87 key_id: u32,
88 key: PublicKey,
89 trust_root: &PrivateKey,
90 rng: &mut R,
91 ) -> Result<Self> {
92 let certificate_pb = proto::sealed_sender::server_certificate::Certificate {
93 id: Some(key_id),
94 key: Some(key.serialize().to_vec()),
95 };
96
97 let certificate = certificate_pb.encode_to_vec();
98
99 let signature = trust_root.calculate_signature(&certificate, rng)?.to_vec();
100
101 let serialized = proto::sealed_sender::ServerCertificate {
102 certificate: Some(certificate.clone()),
103 signature: Some(signature.clone()),
104 }
105 .encode_to_vec();
106
107 Ok(Self {
108 serialized,
109 certificate,
110 signature,
111 key,
112 key_id,
113 })
114 }
115
116 pub(crate) fn to_protobuf(&self) -> Result<proto::sealed_sender::ServerCertificate> {
117 Ok(proto::sealed_sender::ServerCertificate {
118 certificate: Some(self.certificate.clone()),
119 signature: Some(self.signature.clone()),
120 })
121 }
122
123 pub fn validate(&self, trust_root: &PublicKey) -> Result<bool> {
124 if REVOKED_SERVER_CERTIFICATE_KEY_IDS.contains(&self.key_id()?) {
125 log::error!(
126 "received server certificate with revoked ID {:x}",
127 self.key_id()?
128 );
129 return Ok(false);
130 }
131 Ok(trust_root.verify_signature(&self.certificate, &self.signature))
132 }
133
134 pub fn key_id(&self) -> Result<u32> {
135 Ok(self.key_id)
136 }
137
138 pub fn public_key(&self) -> Result<PublicKey> {
139 Ok(self.key)
140 }
141
142 pub fn certificate(&self) -> Result<&[u8]> {
143 Ok(&self.certificate)
144 }
145
146 pub fn signature(&self) -> Result<&[u8]> {
147 Ok(&self.signature)
148 }
149
150 pub fn serialized(&self) -> Result<&[u8]> {
151 Ok(&self.serialized)
152 }
153}
154
155#[derive(Debug, Clone)]
156pub struct SenderCertificate {
157 signer: ServerCertificate,
158 key: PublicKey,
159 sender_device_id: DeviceId,
160 sender_uuid: String,
161 sender_e164: Option<String>,
162 expiration: Timestamp,
163 serialized: Vec<u8>,
164 certificate: Vec<u8>,
165 signature: Vec<u8>,
166}
167
168impl SenderCertificate {
169 pub fn deserialize(data: &[u8]) -> Result<Self> {
170 let pb = proto::sealed_sender::SenderCertificate::decode(data)
171 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
172 let certificate = pb
173 .certificate
174 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
175 let signature = pb
176 .signature
177 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
178 let certificate_data =
179 proto::sealed_sender::sender_certificate::Certificate::decode(certificate.as_ref())
180 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
181
182 let sender_device_id: DeviceId = certificate_data
183 .sender_device
184 .and_then(|v| DeviceId::try_from(v).ok())
185 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
186 let expiration = certificate_data
187 .expires
188 .map(Timestamp::from_epoch_millis)
189 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
190 let signer_pb = certificate_data
191 .signer
192 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
193 let sender_uuid = certificate_data
194 .sender_uuid
195 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
196 let sender_e164 = certificate_data.sender_e164;
197
198 let key = PublicKey::try_from(
199 &certificate_data
200 .identity_key
201 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?[..],
202 )?;
203
204 let signer_bits = signer_pb.encode_to_vec();
205 let signer = ServerCertificate::deserialize(&signer_bits)?;
206
207 Ok(Self {
208 signer,
209 key,
210 sender_device_id,
211 sender_uuid,
212 sender_e164,
213 expiration,
214 serialized: data.to_vec(),
215 certificate,
216 signature,
217 })
218 }
219
220 pub fn new<R: Rng + CryptoRng>(
221 sender_uuid: String,
222 sender_e164: Option<String>,
223 key: PublicKey,
224 sender_device_id: DeviceId,
225 expiration: Timestamp,
226 signer: ServerCertificate,
227 signer_key: &PrivateKey,
228 rng: &mut R,
229 ) -> Result<Self> {
230 let certificate_pb = proto::sealed_sender::sender_certificate::Certificate {
231 sender_uuid: Some(sender_uuid.clone()),
232 sender_e164: sender_e164.clone(),
233 sender_device: Some(sender_device_id.into()),
234 expires: Some(expiration.epoch_millis()),
235 identity_key: Some(key.serialize().to_vec()),
236 signer: Some(signer.to_protobuf()?),
237 };
238
239 let certificate = certificate_pb.encode_to_vec();
240
241 let signature = signer_key.calculate_signature(&certificate, rng)?.to_vec();
242
243 let serialized = proto::sealed_sender::SenderCertificate {
244 certificate: Some(certificate.clone()),
245 signature: Some(signature.clone()),
246 }
247 .encode_to_vec();
248
249 Ok(Self {
250 signer,
251 key,
252 sender_device_id,
253 sender_uuid,
254 sender_e164,
255 expiration,
256 serialized,
257 certificate,
258 signature,
259 })
260 }
261
262 pub fn validate(&self, trust_root: &PublicKey, validation_time: Timestamp) -> Result<bool> {
263 if !self.signer.validate(trust_root)? {
264 log::error!(
265 "sender certificate contained server certificate that wasn't signed by trust root"
266 );
267 return Ok(false);
268 }
269
270 if !self
271 .signer
272 .public_key()?
273 .verify_signature(&self.certificate, &self.signature)
274 {
275 log::error!("sender certificate not signed by server");
276 return Ok(false);
277 }
278
279 if validation_time > self.expiration {
280 log::error!(
281 "sender certificate is expired (expiration: {}, validation_time: {})",
282 self.expiration.epoch_millis(),
283 validation_time.epoch_millis()
284 );
285 return Ok(false);
286 }
287
288 Ok(true)
289 }
290
291 pub fn signer(&self) -> Result<&ServerCertificate> {
292 Ok(&self.signer)
293 }
294
295 pub fn key(&self) -> Result<PublicKey> {
296 Ok(self.key)
297 }
298
299 pub fn sender_device_id(&self) -> Result<DeviceId> {
300 Ok(self.sender_device_id)
301 }
302
303 pub fn sender_uuid(&self) -> Result<&str> {
304 Ok(&self.sender_uuid)
305 }
306
307 pub fn sender_e164(&self) -> Result<Option<&str>> {
308 Ok(self.sender_e164.as_deref())
309 }
310
311 pub fn expiration(&self) -> Result<Timestamp> {
312 Ok(self.expiration)
313 }
314
315 pub fn serialized(&self) -> Result<&[u8]> {
316 Ok(&self.serialized)
317 }
318
319 pub fn certificate(&self) -> Result<&[u8]> {
320 Ok(&self.certificate)
321 }
322
323 pub fn signature(&self) -> Result<&[u8]> {
324 Ok(&self.signature)
325 }
326}
327
328impl From<ProtoMessageType> for CiphertextMessageType {
329 fn from(message_type: ProtoMessageType) -> Self {
330 let result = match message_type {
331 ProtoMessageType::Message => Self::Whisper,
332 ProtoMessageType::PrekeyMessage => Self::PreKey,
333 ProtoMessageType::SenderkeyMessage => Self::SenderKey,
334 ProtoMessageType::PlaintextContent => Self::Plaintext,
335 };
336 assert!(result == Self::PreKey || message_type as i32 == result as i32);
338 result
339 }
340}
341
342impl From<CiphertextMessageType> for ProtoMessageType {
343 fn from(message_type: CiphertextMessageType) -> Self {
344 let result = match message_type {
345 CiphertextMessageType::PreKey => Self::PrekeyMessage,
346 CiphertextMessageType::Whisper => Self::Message,
347 CiphertextMessageType::SenderKey => Self::SenderkeyMessage,
348 CiphertextMessageType::Plaintext => Self::PlaintextContent,
349 };
350 assert!(result == Self::PrekeyMessage || message_type as i32 == result as i32);
352 result
353 }
354}
355
356#[derive(Clone, Copy, PartialEq, Eq, Debug)]
357pub enum ContentHint {
358 Default,
359 Resendable,
360 Implicit,
361 Unknown(u32),
362}
363
364impl ContentHint {
365 fn to_proto(self) -> Option<i32> {
366 if self == ContentHint::Default {
367 None
368 } else {
369 Some(u32::from(self) as i32)
370 }
371 }
372
373 pub const fn to_u32(self) -> u32 {
374 use proto::sealed_sender::unidentified_sender_message::message::ContentHint as ProtoContentHint;
375 match self {
376 ContentHint::Default => 0,
377 ContentHint::Resendable => ProtoContentHint::Resendable as u32,
378 ContentHint::Implicit => ProtoContentHint::Implicit as u32,
379 ContentHint::Unknown(value) => value,
380 }
381 }
382}
383
384impl From<u32> for ContentHint {
385 fn from(raw_value: u32) -> Self {
386 use proto::sealed_sender::unidentified_sender_message::message::ContentHint as ProtoContentHint;
387 assert!(!ProtoContentHint::is_valid(0));
388 match ProtoContentHint::try_from(raw_value as i32) {
389 Err(_) if raw_value == 0 => ContentHint::Default,
390 Err(_) => ContentHint::Unknown(raw_value),
391 Ok(ProtoContentHint::Resendable) => ContentHint::Resendable,
392 Ok(ProtoContentHint::Implicit) => ContentHint::Implicit,
393 }
394 }
395}
396
397impl From<ContentHint> for u32 {
398 fn from(hint: ContentHint) -> Self {
399 hint.to_u32()
400 }
401}
402
403pub struct UnidentifiedSenderMessageContent {
404 serialized: Vec<u8>,
405 contents: Vec<u8>,
406 sender: SenderCertificate,
407 msg_type: CiphertextMessageType,
408 content_hint: ContentHint,
409 group_id: Option<Vec<u8>>,
410}
411
412impl UnidentifiedSenderMessageContent {
413 pub fn deserialize(data: &[u8]) -> Result<Self> {
414 let pb = proto::sealed_sender::unidentified_sender_message::Message::decode(data)
415 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
416
417 let msg_type = pb
418 .r#type
419 .and_then(|t| ProtoMessageType::try_from(t).ok())
420 .map(CiphertextMessageType::from)
421 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
422 let sender = pb
423 .sender_certificate
424 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
425 let contents = pb
426 .content
427 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
428 let content_hint = pb
429 .content_hint
430 .map(|raw| ContentHint::from(raw as u32))
431 .unwrap_or(ContentHint::Default);
432 let group_id = pb.group_id;
433
434 let sender = SenderCertificate::deserialize(&sender)?;
435
436 let serialized = data.to_vec();
437
438 log::info!(
439 "deserialized UnidentifiedSenderMessageContent from {}.{} with type {:?}",
440 sender.sender_uuid()?,
441 sender.sender_device_id()?,
442 msg_type,
443 );
444
445 Ok(Self {
446 serialized,
447 contents,
448 sender,
449 msg_type,
450 content_hint,
451 group_id,
452 })
453 }
454
455 pub fn new(
456 msg_type: CiphertextMessageType,
457 sender: SenderCertificate,
458 contents: Vec<u8>,
459 content_hint: ContentHint,
460 group_id: Option<Vec<u8>>,
461 ) -> Result<Self> {
462 let proto_msg_type = ProtoMessageType::from(msg_type);
463 let msg = proto::sealed_sender::unidentified_sender_message::Message {
464 content: Some(contents.clone()),
465 r#type: Some(proto_msg_type.into()),
466 sender_certificate: Some(sender.serialized()?.to_vec()),
467 content_hint: content_hint.to_proto(),
468 group_id: group_id.as_ref().and_then(|buf| {
469 if buf.is_empty() {
470 None
471 } else {
472 Some(buf.clone())
473 }
474 }),
475 };
476
477 let serialized = msg.encode_to_vec();
478
479 Ok(Self {
480 serialized,
481 msg_type,
482 sender,
483 contents,
484 content_hint,
485 group_id,
486 })
487 }
488
489 pub fn msg_type(&self) -> Result<CiphertextMessageType> {
490 Ok(self.msg_type)
491 }
492
493 pub fn sender(&self) -> Result<&SenderCertificate> {
494 Ok(&self.sender)
495 }
496
497 pub fn contents(&self) -> Result<&[u8]> {
498 Ok(&self.contents)
499 }
500
501 pub fn content_hint(&self) -> Result<ContentHint> {
502 Ok(self.content_hint)
503 }
504
505 pub fn group_id(&self) -> Result<Option<&[u8]>> {
506 Ok(self.group_id.as_deref())
507 }
508
509 pub fn serialized(&self) -> Result<&[u8]> {
510 Ok(&self.serialized)
511 }
512}
513
514enum UnidentifiedSenderMessage<'a> {
515 V1 {
516 ephemeral_public: PublicKey,
517 encrypted_static: Vec<u8>,
518 encrypted_message: Vec<u8>,
519 },
520 V2 {
521 ephemeral_public: PublicKey,
522 encrypted_message_key: &'a [u8; sealed_sender_v2::MESSAGE_KEY_LEN],
523 authentication_tag: &'a [u8; sealed_sender_v2::AUTH_TAG_LEN],
524 encrypted_message: &'a [u8],
525 },
526}
527
528const SEALED_SENDER_V1_MAJOR_VERSION: u8 = 1;
529const SEALED_SENDER_V1_FULL_VERSION: u8 = 0x11;
530const SEALED_SENDER_V2_MAJOR_VERSION: u8 = 2;
531const SEALED_SENDER_V2_UUID_FULL_VERSION: u8 = 0x22;
532const SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION: u8 = 0x23;
533
534impl<'a> UnidentifiedSenderMessage<'a> {
535 fn deserialize(data: &'a [u8]) -> Result<Self> {
536 let (version_byte, remaining) = data.split_first().ok_or_else(|| {
537 SignalProtocolError::InvalidSealedSenderMessage("Message was empty".to_owned())
538 })?;
539 let version = version_byte >> 4;
540 log::debug!("deserializing UnidentifiedSenderMessage with version {version}");
541
542 match version {
543 0 | SEALED_SENDER_V1_MAJOR_VERSION => {
544 let pb = proto::sealed_sender::UnidentifiedSenderMessage::decode(remaining)
546 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
547
548 let ephemeral_public = pb
549 .ephemeral_public
550 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
551 let encrypted_static = pb
552 .encrypted_static
553 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
554 let encrypted_message = pb
555 .encrypted_message
556 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
557
558 let ephemeral_public = PublicKey::try_from(&ephemeral_public[..])?;
559
560 Ok(Self::V1 {
561 ephemeral_public,
562 encrypted_static,
563 encrypted_message,
564 })
565 }
566 SEALED_SENDER_V2_MAJOR_VERSION => {
567 #[derive(FromBytes, Immutable, KnownLayout)]
569 #[repr(C, packed)]
570 struct PrefixRepr {
571 encrypted_message_key: [u8; sealed_sender_v2::MESSAGE_KEY_LEN],
572 encrypted_authentication_tag: [u8; sealed_sender_v2::AUTH_TAG_LEN],
573 ephemeral_public: [u8; sealed_sender_v2::PUBLIC_KEY_LEN],
574 }
575 let (prefix, encrypted_message) =
576 zerocopy::Ref::<_, PrefixRepr>::from_prefix(remaining)
577 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
578
579 let PrefixRepr {
580 encrypted_message_key,
581 encrypted_authentication_tag,
582 ephemeral_public,
583 } = zerocopy::Ref::into_ref(prefix);
584
585 Ok(Self::V2 {
586 ephemeral_public: PublicKey::from_djb_public_key_bytes(
587 ephemeral_public.as_slice(),
588 )?,
589 encrypted_message_key,
590 authentication_tag: encrypted_authentication_tag,
591 encrypted_message,
592 })
593 }
594 _ => Err(SignalProtocolError::UnknownSealedSenderVersion(version)),
595 }
596 }
597}
598
599mod sealed_sender_v1 {
600 #[cfg(test)]
601 use std::fmt;
602
603 use zerocopy::IntoBytes;
604
605 use super::*;
606
607 pub(super) struct EphemeralKeys {
610 pub(super) chain_key: [u8; 32],
611 pub(super) cipher_key: [u8; 32],
612 pub(super) mac_key: [u8; 32],
613 }
614
615 const SALT_PREFIX: &[u8] = b"UnidentifiedDelivery";
616
617 impl EphemeralKeys {
618 pub(super) fn calculate(
621 our_keys: &KeyPair,
622 their_public: &PublicKey,
623 direction: Direction,
624 ) -> Result<Self> {
625 let our_pub_key = our_keys.public_key.serialize();
626 let their_pub_key = their_public.serialize();
627 let ephemeral_salt = match direction {
628 Direction::Sending => [SALT_PREFIX, &their_pub_key, &our_pub_key],
629 Direction::Receiving => [SALT_PREFIX, &our_pub_key, &their_pub_key],
630 }
631 .concat();
632
633 let shared_secret = our_keys.private_key.calculate_agreement(their_public)?;
634 #[derive(Default, KnownLayout, IntoBytes, FromBytes)]
635 #[repr(C, packed)]
636 struct DerivedValues([u8; 32], [u8; 32], [u8; 32]);
637 let mut derived_values = DerivedValues::default();
638 hkdf::Hkdf::<sha2::Sha256>::new(Some(&ephemeral_salt), &shared_secret)
639 .expand(&[], derived_values.as_mut_bytes())
640 .expect("valid output length");
641
642 let DerivedValues(chain_key, cipher_key, mac_key) = derived_values;
643
644 Ok(Self {
645 chain_key,
646 cipher_key,
647 mac_key,
648 })
649 }
650 }
651
652 #[cfg(test)]
653 impl PartialEq for EphemeralKeys {
654 fn eq(&self, other: &Self) -> bool {
655 self.chain_key == other.chain_key
656 && self.cipher_key == other.cipher_key
657 && self.mac_key == other.mac_key
658 }
659 }
660
661 #[cfg(test)]
662 impl Eq for EphemeralKeys {}
663
664 #[cfg(test)]
665 impl fmt::Debug for EphemeralKeys {
666 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
667 write!(
668 f,
669 "EphemeralKeys {{ chain_key: {:?}, cipher_key: {:?}, mac_key: {:?} }}",
670 self.chain_key, self.cipher_key, self.mac_key
671 )
672 }
673 }
674
675 pub(super) struct StaticKeys {
677 pub(super) cipher_key: [u8; 32],
678 pub(super) mac_key: [u8; 32],
679 }
680
681 impl StaticKeys {
682 pub(super) fn calculate(
685 our_keys: &IdentityKeyPair,
686 their_key: &PublicKey,
687 chain_key: &[u8; 32],
688 ctext: &[u8],
689 ) -> Result<Self> {
690 let salt = [chain_key, ctext].concat();
691
692 let shared_secret = our_keys.private_key().calculate_agreement(their_key)?;
693 #[derive(Default, KnownLayout, IntoBytes, FromBytes)]
697 #[repr(C, packed)]
698 struct DerivedValues(#[allow(unused)] [u8; 32], [u8; 32], [u8; 32]);
699 let mut derived_values = DerivedValues::default();
700 hkdf::Hkdf::<sha2::Sha256>::new(Some(&salt), &shared_secret)
701 .expand(&[], derived_values.as_mut_bytes())
702 .expect("valid output length");
703
704 let DerivedValues(_, cipher_key, mac_key) = derived_values;
705
706 Ok(Self {
707 cipher_key,
708 mac_key,
709 })
710 }
711 }
712
713 #[test]
714 fn test_agreement_and_authentication() -> Result<()> {
715 let sender_identity = IdentityKeyPair::generate(&mut rand::rng());
717 let recipient_identity = IdentityKeyPair::generate(&mut rand::rng());
718
719 let sender_ephemeral = KeyPair::generate(&mut rand::rng());
721 let ephemeral_public = sender_ephemeral.public_key;
722 let sender_eph_keys = EphemeralKeys::calculate(
724 &sender_ephemeral,
725 recipient_identity.public_key(),
726 Direction::Sending,
727 )?;
728
729 let sender_static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
731 &sender_identity.public_key().serialize(),
732 &sender_eph_keys.cipher_key,
733 &sender_eph_keys.mac_key,
734 )
735 .expect("just generated these keys, they should be correct");
736
737 let sender_static_keys = StaticKeys::calculate(
739 &sender_identity,
740 recipient_identity.public_key(),
741 &sender_eph_keys.chain_key,
742 &sender_static_key_ctext,
743 )?;
744
745 let sender_message_contents = b"this is a binary message";
746 let sender_message_data = crypto::aes256_ctr_hmacsha256_encrypt(
747 sender_message_contents,
748 &sender_static_keys.cipher_key,
749 &sender_static_keys.mac_key,
750 )
751 .expect("just generated these keys, they should be correct");
752
753 let recipient_eph_keys = EphemeralKeys::calculate(
755 &recipient_identity.into(),
756 &ephemeral_public,
757 Direction::Receiving,
758 )?;
759 assert_eq!(sender_eph_keys, recipient_eph_keys);
760
761 let recipient_message_key_bytes = crypto::aes256_ctr_hmacsha256_decrypt(
762 &sender_static_key_ctext,
763 &recipient_eph_keys.cipher_key,
764 &recipient_eph_keys.mac_key,
765 )
766 .expect("should decrypt successfully");
767 let sender_public_key: PublicKey = PublicKey::try_from(&recipient_message_key_bytes[..])?;
768 assert_eq!(sender_identity.public_key(), &sender_public_key);
769
770 let recipient_static_keys = StaticKeys::calculate(
771 &recipient_identity,
772 &sender_public_key,
773 &recipient_eph_keys.chain_key,
774 &sender_static_key_ctext,
775 )?;
776
777 let recipient_message_contents = crypto::aes256_ctr_hmacsha256_decrypt(
778 &sender_message_data,
779 &recipient_static_keys.cipher_key,
780 &recipient_static_keys.mac_key,
781 )
782 .expect("should decrypt successfully");
783 assert_eq!(recipient_message_contents, sender_message_contents);
784
785 Ok(())
786 }
787}
788
789pub async fn sealed_sender_encrypt<R: Rng + CryptoRng>(
796 destination: &ProtocolAddress,
797 sender_cert: &SenderCertificate,
798 ptext: &[u8],
799 session_store: &mut dyn SessionStore,
800 identity_store: &mut dyn IdentityKeyStore,
801 now: SystemTime,
802 rng: &mut R,
803) -> Result<Vec<u8>> {
804 let message =
805 message_encrypt(ptext, destination, session_store, identity_store, now, rng).await?;
806 let usmc = UnidentifiedSenderMessageContent::new(
807 message.message_type(),
808 sender_cert.clone(),
809 message.serialize().to_vec(),
810 ContentHint::Default,
811 None,
812 )?;
813 sealed_sender_encrypt_from_usmc(destination, &usmc, identity_store, rng).await
814}
815
816pub async fn sealed_sender_encrypt_from_usmc<R: Rng + CryptoRng>(
867 destination: &ProtocolAddress,
868 usmc: &UnidentifiedSenderMessageContent,
869 identity_store: &dyn IdentityKeyStore,
870 rng: &mut R,
871) -> Result<Vec<u8>> {
872 let our_identity = identity_store.get_identity_key_pair().await?;
873 let their_identity = identity_store
874 .get_identity(destination)
875 .await?
876 .ok_or_else(|| SignalProtocolError::SessionNotFound(destination.clone()))?;
877
878 let ephemeral = KeyPair::generate(rng);
879
880 let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
881 &ephemeral,
882 their_identity.public_key(),
883 Direction::Sending,
884 )?;
885
886 let static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
887 &our_identity.public_key().serialize(),
888 &eph_keys.cipher_key,
889 &eph_keys.mac_key,
890 )
891 .expect("just generated these keys, they should be correct");
892
893 let static_keys = sealed_sender_v1::StaticKeys::calculate(
894 &our_identity,
895 their_identity.public_key(),
896 &eph_keys.chain_key,
897 &static_key_ctext,
898 )?;
899
900 let message_data = crypto::aes256_ctr_hmacsha256_encrypt(
901 usmc.serialized()?,
902 &static_keys.cipher_key,
903 &static_keys.mac_key,
904 )
905 .expect("just generated these keys, they should be correct");
906
907 let mut serialized = vec![SEALED_SENDER_V1_FULL_VERSION];
908 let pb = proto::sealed_sender::UnidentifiedSenderMessage {
909 ephemeral_public: Some(ephemeral.public_key.serialize().to_vec()),
910 encrypted_static: Some(static_key_ctext),
911 encrypted_message: Some(message_data),
912 };
913 pb.encode(&mut serialized)
914 .expect("can always append to Vec");
915
916 Ok(serialized)
917}
918
919mod sealed_sender_v2 {
920 use super::*;
921
922 const LABEL_R: &[u8] = b"Sealed Sender v2: r (2023-08)";
924 const LABEL_K: &[u8] = b"Sealed Sender v2: K";
925 const LABEL_DH: &[u8] = b"Sealed Sender v2: DH";
926 const LABEL_DH_S: &[u8] = b"Sealed Sender v2: DH-sender";
927
928 pub const MESSAGE_KEY_LEN: usize = 32;
929 pub const CIPHER_KEY_LEN: usize =
930 <Aes256GcmSiv as aes_gcm_siv::aead::KeySizeUser>::KeySize::USIZE;
931 pub const AUTH_TAG_LEN: usize = 16;
932 pub const PUBLIC_KEY_LEN: usize = 32;
934
935 pub(super) struct DerivedKeys {
937 kdf: hkdf::Hkdf<sha2::Sha256>,
938 }
939
940 impl DerivedKeys {
941 pub(super) fn new(m: &[u8]) -> DerivedKeys {
943 Self {
944 kdf: hkdf::Hkdf::<sha2::Sha256>::new(None, m),
945 }
946 }
947
948 pub(super) fn derive_e(&self) -> KeyPair {
950 let mut r = [0; 32];
951 self.kdf
952 .expand(LABEL_R, &mut r)
953 .expect("valid output length");
954 let e = PrivateKey::try_from(&r[..]).expect("valid PrivateKey");
955 KeyPair::try_from(e).expect("can derive public key")
956 }
957
958 pub(super) fn derive_k(&self) -> [u8; CIPHER_KEY_LEN] {
960 let mut k = [0; CIPHER_KEY_LEN];
961 self.kdf
962 .expand(LABEL_K, &mut k)
963 .expect("valid output length");
964 k
965 }
966 }
967
968 pub(super) fn apply_agreement_xor(
975 our_keys: &KeyPair,
976 their_key: &PublicKey,
977 direction: Direction,
978 input: &[u8; MESSAGE_KEY_LEN],
979 ) -> Result<[u8; MESSAGE_KEY_LEN]> {
980 let agreement = our_keys.calculate_agreement(their_key)?;
981 let agreement_key_input = match direction {
982 Direction::Sending => [
983 agreement,
984 our_keys.public_key.serialize(),
985 their_key.serialize(),
986 ],
987 Direction::Receiving => [
988 agreement,
989 their_key.serialize(),
990 our_keys.public_key.serialize(),
991 ],
992 }
993 .concat();
994
995 let mut result = [0; MESSAGE_KEY_LEN];
996 hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
997 .expand(LABEL_DH, &mut result)
998 .expect("valid output length");
999 result
1000 .iter_mut()
1001 .zip(input)
1002 .for_each(|(result_byte, input_byte)| *result_byte ^= input_byte);
1003 Ok(result)
1004 }
1005
1006 pub(super) fn compute_authentication_tag(
1015 our_keys: &IdentityKeyPair,
1016 their_key: &IdentityKey,
1017 direction: Direction,
1018 ephemeral_pub_key: &PublicKey,
1019 encrypted_message_key: &[u8; MESSAGE_KEY_LEN],
1020 ) -> Result<[u8; AUTH_TAG_LEN]> {
1021 let agreement = our_keys
1022 .private_key()
1023 .calculate_agreement(their_key.public_key())?;
1024 let mut agreement_key_input = agreement.into_vec();
1025 agreement_key_input.extend_from_slice(&ephemeral_pub_key.serialize());
1026 agreement_key_input.extend_from_slice(encrypted_message_key);
1027 match direction {
1028 Direction::Sending => {
1029 agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1030 agreement_key_input.extend_from_slice(&their_key.serialize());
1031 }
1032 Direction::Receiving => {
1033 agreement_key_input.extend_from_slice(&their_key.serialize());
1034 agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1035 }
1036 }
1037
1038 let mut result = [0; AUTH_TAG_LEN];
1039 hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
1040 .expand(LABEL_DH_S, &mut result)
1041 .expect("valid output length");
1042 Ok(result)
1043 }
1044
1045 #[test]
1046 fn test_agreement_and_authentication() -> Result<()> {
1047 let sender_identity = IdentityKeyPair::generate(&mut rand::rng());
1049 let recipient_identity = IdentityKeyPair::generate(&mut rand::rng());
1050
1051 let m: [u8; MESSAGE_KEY_LEN] = rand::rng().random();
1053 let ephemeral_keys = DerivedKeys::new(&m);
1055 let e = ephemeral_keys.derive_e();
1056
1057 let sender_c_0: [u8; MESSAGE_KEY_LEN] =
1059 apply_agreement_xor(&e, recipient_identity.public_key(), Direction::Sending, &m)?;
1060 let sender_at_0 = compute_authentication_tag(
1062 &sender_identity,
1063 recipient_identity.identity_key(),
1064 Direction::Sending,
1065 &e.public_key,
1066 &sender_c_0,
1067 )?;
1068
1069 let recv_m = apply_agreement_xor(
1071 &recipient_identity.into(),
1072 &e.public_key,
1073 Direction::Receiving,
1074 &sender_c_0,
1075 )?;
1076 assert_eq!(&recv_m, &m);
1077
1078 let recv_at_0 = compute_authentication_tag(
1079 &recipient_identity,
1080 sender_identity.identity_key(),
1081 Direction::Receiving,
1082 &e.public_key,
1083 &sender_c_0,
1084 )?;
1085 assert_eq!(&recv_at_0, &sender_at_0);
1086
1087 Ok(())
1088 }
1089}
1090
1091pub async fn sealed_sender_multi_recipient_encrypt<
1252 R: Rng + CryptoRng,
1253 X: IntoIterator<Item = ServiceId>,
1254>(
1255 destinations: &[&ProtocolAddress],
1256 destination_sessions: &[&SessionRecord],
1257 excluded_recipients: X,
1258 usmc: &UnidentifiedSenderMessageContent,
1259 identity_store: &dyn IdentityKeyStore,
1260 rng: &mut R,
1261) -> Result<Vec<u8>>
1262where
1263 X::IntoIter: ExactSizeIterator,
1264{
1265 sealed_sender_multi_recipient_encrypt_impl(
1266 destinations,
1267 destination_sessions,
1268 excluded_recipients,
1269 usmc,
1270 identity_store,
1271 rng,
1272 )
1273 .await
1274}
1275
1276async fn sealed_sender_multi_recipient_encrypt_impl<
1277 R: Rng + CryptoRng,
1278 X: IntoIterator<Item = ServiceId>,
1279>(
1280 destinations: &[&ProtocolAddress],
1281 destination_sessions: &[&SessionRecord],
1282 excluded_recipients: X,
1283 usmc: &UnidentifiedSenderMessageContent,
1284 identity_store: &dyn IdentityKeyStore,
1285 rng: &mut R,
1286) -> Result<Vec<u8>>
1287where
1288 X::IntoIter: ExactSizeIterator,
1289{
1290 if destinations.len() != destination_sessions.len() {
1291 return Err(SignalProtocolError::InvalidArgument(
1292 "must have the same number of destination sessions as addresses".to_string(),
1293 ));
1294 }
1295
1296 let excluded_recipients = excluded_recipients.into_iter();
1297 let our_identity = identity_store.get_identity_key_pair().await?;
1298
1299 let m: [u8; sealed_sender_v2::MESSAGE_KEY_LEN] = rng.random();
1300 let keys = sealed_sender_v2::DerivedKeys::new(&m);
1301 let e = keys.derive_e();
1302 let e_pub = &e.public_key;
1303
1304 let ciphertext = {
1306 let mut ciphertext = usmc.serialized()?.to_vec();
1307 let symmetric_authentication_tag = Aes256GcmSiv::new(&keys.derive_k().into())
1308 .encrypt_in_place_detached(
1309 &aes_gcm_siv::Nonce::default(),
1311 &[],
1313 &mut ciphertext,
1314 )
1315 .expect("AES-GCM-SIV encryption should not fail with a just-computed key");
1316 ciphertext.extend_from_slice(&symmetric_authentication_tag);
1319 ciphertext
1320 };
1321
1322 let identity_keys_and_ranges: Vec<(IdentityKey, Range<usize>)> = {
1327 let mut identity_keys_and_ranges = vec![];
1328 for (_, mut next_group) in &destinations
1329 .iter()
1330 .enumerate()
1331 .chunk_by(|(_i, next)| next.name())
1332 {
1333 let (i, &destination) = next_group
1334 .next()
1335 .expect("at least one element in every group");
1336 let count = 1 + next_group.count();
1339 let their_identity =
1340 identity_store
1341 .get_identity(destination)
1342 .await?
1343 .ok_or_else(|| {
1344 log::error!("missing identity key for {destination}");
1345 SignalProtocolError::SessionNotFound(destination.clone())
1349 })?;
1350 identity_keys_and_ranges.push((their_identity, i..i + count));
1351 }
1352 identity_keys_and_ranges
1353 };
1354
1355 let serialize_recipient_destinations_into = |serialized: &mut Vec<u8>,
1361 destinations: &[&ProtocolAddress],
1362 sessions: &[&SessionRecord],
1363 their_identity: &IdentityKey|
1364 -> Result<()> {
1365 let their_service_id = ServiceId::parse_from_service_id_string(destinations[0].name())
1366 .ok_or_else(|| {
1367 SignalProtocolError::InvalidArgument(format!(
1368 "multi-recipient sealed sender requires recipients' ServiceId (not {})",
1369 destinations[0].name()
1370 ))
1371 })?;
1372
1373 serialized.extend_from_slice(&their_service_id.service_id_fixed_width_binary());
1374
1375 debug_assert_eq!(
1376 destinations.len(),
1377 sessions.len(),
1378 "should be sliced with the same range"
1379 );
1380 let mut destinations_and_sessions = destinations.iter().zip(sessions);
1381 while let Some((&destination, session)) = destinations_and_sessions.next() {
1382 let their_registration_id = session.remote_registration_id().map_err(|_| {
1383 SignalProtocolError::InvalidState(
1384 "sealed_sender_multi_recipient_encrypt",
1385 format!(
1386 concat!(
1387 "cannot get registration ID from session with {} ",
1388 "(maybe it was recently archived)"
1389 ),
1390 destination
1391 ),
1392 )
1393 })?;
1394 if their_registration_id & u32::from(VALID_REGISTRATION_ID_MASK)
1395 != their_registration_id
1396 {
1397 return Err(SignalProtocolError::InvalidRegistrationId(
1398 destination.clone(),
1399 their_registration_id,
1400 ));
1401 }
1402 let mut their_registration_id =
1403 u16::try_from(their_registration_id).expect("just checked range");
1404 if destinations_and_sessions.len() > 0 {
1405 their_registration_id |= 0x8000;
1406 }
1407
1408 let device_id = destination.device_id();
1409 serialized.push(device_id.into());
1410 serialized.extend_from_slice(&their_registration_id.to_be_bytes());
1411 }
1412
1413 let c_i = sealed_sender_v2::apply_agreement_xor(
1414 &e,
1415 their_identity.public_key(),
1416 Direction::Sending,
1417 &m,
1418 )?;
1419 serialized.extend_from_slice(&c_i);
1420
1421 let at_i = sealed_sender_v2::compute_authentication_tag(
1422 &our_identity,
1423 their_identity,
1424 Direction::Sending,
1425 e_pub,
1426 &c_i,
1427 )?;
1428 serialized.extend_from_slice(&at_i);
1429
1430 Ok(())
1431 };
1432
1433 let process_chunk =
1434 |serialized: &mut Vec<u8>, chunk: &[(IdentityKey, Range<usize>)]| -> Result<()> {
1435 for (their_identity, destination_range) in chunk {
1436 let these_destinations = &destinations[destination_range.clone()];
1437 let these_sessions = &destination_sessions[destination_range.clone()];
1438 serialize_recipient_destinations_into(
1439 serialized,
1440 these_destinations,
1441 these_sessions,
1442 their_identity,
1443 )?;
1444 }
1445 Ok(())
1446 };
1447
1448 let mut serialized: Vec<u8> = vec![SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION];
1449
1450 let count_of_recipients = identity_keys_and_ranges.len() + excluded_recipients.len();
1451 prost::encode_length_delimiter(count_of_recipients, &mut serialized)
1452 .expect("can always resize a Vec");
1453
1454 let parallelism = std::thread::available_parallelism()
1456 .map(usize::from)
1457 .unwrap_or(1);
1458 let chunk_size = std::cmp::max(6, identity_keys_and_ranges.len().div_ceil(parallelism));
1459
1460 if parallelism == 1 || chunk_size >= identity_keys_and_ranges.len() {
1461 process_chunk(&mut serialized, &identity_keys_and_ranges)?;
1462 } else {
1463 let mut chunks = identity_keys_and_ranges.chunks(chunk_size);
1464 let first_chunk = chunks.next().expect("at least one chunk, tested above");
1466
1467 let mut all_outputs = Vec::new();
1468 all_outputs.resize_with(chunks.len(), || Ok(vec![]));
1469
1470 rayon::scope(|scope| -> Result<()> {
1471 let mut outputs = &mut all_outputs[..];
1472 for chunk in chunks {
1473 let (next_output, remaining_outputs) = outputs
1474 .split_first_mut()
1475 .expect("as many outputs as remaining chunks");
1476 scope.spawn(|_| {
1477 let mut serialized = vec![];
1478 *next_output = process_chunk(&mut serialized, chunk).map(|_| serialized);
1479 });
1480 outputs = remaining_outputs;
1481 }
1482
1483 process_chunk(&mut serialized, first_chunk)
1484 })?;
1485
1486 for output in all_outputs {
1487 serialized.extend(output?);
1488 }
1489 }
1490
1491 for excluded in excluded_recipients {
1492 serialized.extend_from_slice(&excluded.service_id_fixed_width_binary());
1493 serialized.push(0);
1494 }
1495
1496 serialized.extend_from_slice(e_pub.public_key_bytes());
1497 serialized.extend_from_slice(&ciphertext);
1498
1499 Ok(serialized)
1500}
1501
1502pub struct SealedSenderV2SentMessageRecipient<'a> {
1506 pub devices: Vec<(DeviceId, u16)>,
1508 c_and_at: &'a [u8],
1511}
1512
1513pub struct SealedSenderV2SentMessage<'a> {
1517 full_message: &'a [u8],
1519 pub version: u8,
1521 pub recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>>,
1527 shared_bytes: &'a [u8],
1529}
1530
1531impl<'a> SealedSenderV2SentMessage<'a> {
1532 pub fn parse(data: &'a [u8]) -> Result<Self> {
1534 if data.is_empty() {
1535 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1536 "Message was empty".to_owned(),
1537 ));
1538 }
1539
1540 let version = data[0];
1541 if !matches!(
1542 version,
1543 SEALED_SENDER_V2_UUID_FULL_VERSION | SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION
1544 ) {
1545 return Err(SignalProtocolError::UnknownSealedSenderVersion(version));
1546 }
1547
1548 fn advance<'a, const N: usize>(buf: &mut &'a [u8]) -> Result<&'a [u8; N]> {
1549 let (prefix, remaining) = buf
1550 .split_first_chunk()
1551 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
1552 *buf = remaining;
1553 Ok(prefix)
1554 }
1555 fn decode_varint(buf: &mut &[u8]) -> Result<u32> {
1556 let result: usize = prost::decode_length_delimiter(*buf)
1557 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1558 *buf = &buf[prost::length_delimiter_len(result)..];
1559 result
1560 .try_into()
1561 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)
1562 }
1563
1564 let mut remaining = &data[1..];
1565 let recipient_count = decode_varint(&mut remaining)?
1566 .try_into()
1567 .unwrap_or(usize::MAX);
1568
1569 let mut recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>> =
1573 IndexMap::with_capacity(std::cmp::min(recipient_count as usize, 6000));
1574 for _ in 0..recipient_count {
1575 let service_id = if version == SEALED_SENDER_V2_UUID_FULL_VERSION {
1576 ServiceId::from(Aci::from_uuid_bytes(*advance::<
1578 { std::mem::size_of::<uuid::Bytes>() },
1579 >(&mut remaining)?))
1580 } else {
1581 ServiceId::parse_from_service_id_fixed_width_binary(advance::<
1582 { std::mem::size_of::<ServiceIdFixedWidthBinaryBytes>() },
1583 >(
1584 &mut remaining
1585 )?)
1586 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?
1587 };
1588 let mut devices = Vec::new();
1589 loop {
1590 let device_id = advance::<1>(&mut remaining)?[0];
1591 if device_id == 0 {
1592 if !devices.is_empty() {
1593 return Err(SignalProtocolError::InvalidProtobufEncoding);
1594 }
1595 break;
1596 }
1597 let device_id = DeviceId::new(device_id)
1598 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1599 let registration_id_and_has_more =
1600 u16::from_be_bytes(*advance::<2>(&mut remaining)?);
1601 devices.push((
1602 device_id,
1603 registration_id_and_has_more & VALID_REGISTRATION_ID_MASK,
1604 ));
1605 let has_more = (registration_id_and_has_more & 0x8000) != 0;
1606 if !has_more {
1607 break;
1608 }
1609 }
1610
1611 let c_and_at: &[u8] = if devices.is_empty() {
1612 &[]
1613 } else {
1614 advance::<{ sealed_sender_v2::MESSAGE_KEY_LEN + sealed_sender_v2::AUTH_TAG_LEN }>(
1615 &mut remaining,
1616 )?
1617 };
1618
1619 match recipients.entry(service_id) {
1620 indexmap::map::Entry::Occupied(mut existing) => {
1621 if existing.get().devices.is_empty() || devices.is_empty() {
1622 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1623 "recipient redundantly encoded as empty".to_owned(),
1624 ));
1625 }
1626 existing.get_mut().devices.extend(devices);
1629 }
1633 indexmap::map::Entry::Vacant(entry) => {
1634 entry.insert(SealedSenderV2SentMessageRecipient { devices, c_and_at });
1635 }
1636 };
1637 }
1638
1639 if remaining.len() < sealed_sender_v2::PUBLIC_KEY_LEN {
1640 return Err(SignalProtocolError::InvalidProtobufEncoding);
1641 }
1642
1643 Ok(Self {
1644 full_message: data,
1645 version,
1646 recipients,
1647 shared_bytes: remaining,
1648 })
1649 }
1650
1651 #[inline]
1657 pub fn received_message_parts_for_recipient(
1658 &self,
1659 recipient: &SealedSenderV2SentMessageRecipient<'a>,
1660 ) -> impl AsRef<[&[u8]]> {
1661 [
1666 &[SEALED_SENDER_V2_UUID_FULL_VERSION],
1667 recipient.c_and_at,
1668 self.shared_bytes,
1669 ]
1670 }
1671
1672 #[inline]
1679 fn offset_within_full_message(&self, addr: *const u8) -> Option<usize> {
1680 let offset = (addr as usize).wrapping_sub(self.full_message.as_ptr() as usize);
1684 if offset <= self.full_message.len() {
1687 debug_assert!(
1688 offset == self.full_message.len() || std::ptr::eq(&self.full_message[offset], addr)
1689 );
1690 Some(offset)
1691 } else {
1692 None
1693 }
1694 }
1695
1696 pub fn range_for_recipient_key_material(
1703 &self,
1704 recipient: &SealedSenderV2SentMessageRecipient<'a>,
1705 ) -> Range<usize> {
1706 if recipient.c_and_at.is_empty() {
1707 return 0..0;
1708 }
1709 let offset = self
1710 .offset_within_full_message(recipient.c_and_at.as_ptr())
1711 .expect("'recipient' is not one of the recipients in this SealedSenderV2SentMessage");
1712 let end_offset = offset.saturating_add(recipient.c_and_at.len());
1713 assert!(
1714 end_offset <= self.full_message.len(),
1715 "invalid 'recipient' passed to range_for_recipient_key_material"
1716 );
1717 offset..end_offset
1718 }
1719
1720 pub fn offset_of_shared_bytes(&self) -> usize {
1725 debug_assert_eq!(
1726 self.full_message.as_ptr_range().end,
1727 self.shared_bytes.as_ptr_range().end,
1728 "SealedSenderV2SentMessage parsed incorrectly"
1729 );
1730 self.offset_within_full_message(self.shared_bytes.as_ptr())
1731 .expect("constructed correctly")
1732 }
1733}
1734
1735pub async fn sealed_sender_decrypt_to_usmc(
1740 ciphertext: &[u8],
1741 identity_store: &dyn IdentityKeyStore,
1742) -> Result<UnidentifiedSenderMessageContent> {
1743 let our_identity = identity_store.get_identity_key_pair().await?;
1744
1745 match UnidentifiedSenderMessage::deserialize(ciphertext)? {
1746 UnidentifiedSenderMessage::V1 {
1747 ephemeral_public,
1748 encrypted_static,
1749 encrypted_message,
1750 } => {
1751 let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
1752 &our_identity.into(),
1753 &ephemeral_public,
1754 Direction::Receiving,
1755 )?;
1756
1757 let message_key_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1758 &encrypted_static,
1759 &eph_keys.cipher_key,
1760 &eph_keys.mac_key,
1761 ) {
1762 Ok(plaintext) => plaintext,
1763 Err(crypto::DecryptionError::BadKeyOrIv) => {
1764 unreachable!("just derived these keys; they should be valid");
1765 }
1766 Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1767 log::error!("failed to decrypt sealed sender v1 message key: {msg}");
1768 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1769 "failed to decrypt sealed sender v1 message key".to_owned(),
1770 ));
1771 }
1772 };
1773
1774 let static_key = PublicKey::try_from(&message_key_bytes[..])?;
1775
1776 let static_keys = sealed_sender_v1::StaticKeys::calculate(
1777 &our_identity,
1778 &static_key,
1779 &eph_keys.chain_key,
1780 &encrypted_static,
1781 )?;
1782
1783 let message_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1784 &encrypted_message,
1785 &static_keys.cipher_key,
1786 &static_keys.mac_key,
1787 ) {
1788 Ok(plaintext) => plaintext,
1789 Err(crypto::DecryptionError::BadKeyOrIv) => {
1790 unreachable!("just derived these keys; they should be valid");
1791 }
1792 Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1793 log::error!("failed to decrypt sealed sender v1 message contents: {msg}");
1794 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1795 "failed to decrypt sealed sender v1 message contents".to_owned(),
1796 ));
1797 }
1798 };
1799
1800 let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1801
1802 if !bool::from(message_key_bytes.ct_eq(&usmc.sender()?.key()?.serialize())) {
1803 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1804 "sender certificate key does not match message key".to_string(),
1805 ));
1806 }
1807
1808 Ok(usmc)
1809 }
1810 UnidentifiedSenderMessage::V2 {
1811 ephemeral_public,
1812 encrypted_message_key,
1813 authentication_tag,
1814 encrypted_message,
1815 } => {
1816 let m = sealed_sender_v2::apply_agreement_xor(
1817 &our_identity.into(),
1818 &ephemeral_public,
1819 Direction::Receiving,
1820 encrypted_message_key,
1821 )?;
1822
1823 let keys = sealed_sender_v2::DerivedKeys::new(&m);
1824 if !bool::from(keys.derive_e().public_key.ct_eq(&ephemeral_public)) {
1825 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1826 "derived ephemeral key did not match key provided in message".to_string(),
1827 ));
1828 }
1829
1830 let mut message_bytes = Vec::from(encrypted_message);
1831 Aes256GcmSiv::new(&keys.derive_k().into())
1832 .decrypt_in_place(
1833 &aes_gcm_siv::Nonce::default(),
1835 &[],
1837 &mut message_bytes,
1838 )
1839 .map_err(|err| {
1840 SignalProtocolError::InvalidSealedSenderMessage(format!(
1841 "failed to decrypt inner message: {err}"
1842 ))
1843 })?;
1844
1845 let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1846
1847 let at = sealed_sender_v2::compute_authentication_tag(
1848 &our_identity,
1849 &usmc.sender()?.key()?.into(),
1850 Direction::Receiving,
1851 &ephemeral_public,
1852 encrypted_message_key,
1853 )?;
1854 if !bool::from(authentication_tag.ct_eq(&at)) {
1855 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1856 "sender certificate key does not match authentication tag".to_string(),
1857 ));
1858 }
1859
1860 Ok(usmc)
1861 }
1862 }
1863}
1864
1865#[derive(Debug)]
1866pub struct SealedSenderDecryptionResult {
1867 pub sender_uuid: String,
1868 pub sender_e164: Option<String>,
1869 pub device_id: DeviceId,
1870 pub message: Vec<u8>,
1871}
1872
1873impl SealedSenderDecryptionResult {
1874 pub fn sender_uuid(&self) -> Result<&str> {
1875 Ok(self.sender_uuid.as_ref())
1876 }
1877
1878 pub fn sender_e164(&self) -> Result<Option<&str>> {
1879 Ok(self.sender_e164.as_deref())
1880 }
1881
1882 pub fn device_id(&self) -> Result<DeviceId> {
1883 Ok(self.device_id)
1884 }
1885
1886 pub fn message(&self) -> Result<&[u8]> {
1887 Ok(self.message.as_ref())
1888 }
1889}
1890
1891#[expect(clippy::too_many_arguments)]
1899pub async fn sealed_sender_decrypt(
1900 ciphertext: &[u8],
1901 trust_root: &PublicKey,
1902 timestamp: Timestamp,
1903 local_e164: Option<String>,
1904 local_uuid: String,
1905 local_device_id: DeviceId,
1906 identity_store: &mut dyn IdentityKeyStore,
1907 session_store: &mut dyn SessionStore,
1908 pre_key_store: &mut dyn PreKeyStore,
1909 signed_pre_key_store: &dyn SignedPreKeyStore,
1910 kyber_pre_key_store: &mut dyn KyberPreKeyStore,
1911 use_pq_ratchet: ratchet::UsePQRatchet,
1912) -> Result<SealedSenderDecryptionResult> {
1913 let usmc = sealed_sender_decrypt_to_usmc(ciphertext, identity_store).await?;
1914
1915 if !usmc.sender()?.validate(trust_root, timestamp)? {
1916 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1917 "trust root validation failed".to_string(),
1918 ));
1919 }
1920
1921 let is_local_uuid = local_uuid == usmc.sender()?.sender_uuid()?;
1922
1923 let is_local_e164 = match (local_e164, usmc.sender()?.sender_e164()?) {
1924 (Some(l), Some(s)) => l == s,
1925 (_, _) => false,
1926 };
1927
1928 if (is_local_e164 || is_local_uuid) && usmc.sender()?.sender_device_id()? == local_device_id {
1929 return Err(SignalProtocolError::SealedSenderSelfSend);
1930 }
1931
1932 let mut rng = rand::rngs::OsRng.unwrap_err();
1933
1934 let remote_address = ProtocolAddress::new(
1935 usmc.sender()?.sender_uuid()?.to_string(),
1936 usmc.sender()?.sender_device_id()?,
1937 );
1938
1939 let message = match usmc.msg_type()? {
1940 CiphertextMessageType::Whisper => {
1941 let ctext = SignalMessage::try_from(usmc.contents()?)?;
1942 session_cipher::message_decrypt_signal(
1943 &ctext,
1944 &remote_address,
1945 session_store,
1946 identity_store,
1947 &mut rng,
1948 )
1949 .await?
1950 }
1951 CiphertextMessageType::PreKey => {
1952 let ctext = PreKeySignalMessage::try_from(usmc.contents()?)?;
1953 session_cipher::message_decrypt_prekey(
1954 &ctext,
1955 &remote_address,
1956 session_store,
1957 identity_store,
1958 pre_key_store,
1959 signed_pre_key_store,
1960 kyber_pre_key_store,
1961 &mut rng,
1962 use_pq_ratchet,
1963 )
1964 .await?
1965 }
1966 msg_type => {
1967 return Err(SignalProtocolError::InvalidMessage(
1968 msg_type,
1969 "unexpected message type for sealed_sender_decrypt",
1970 ));
1971 }
1972 };
1973
1974 Ok(SealedSenderDecryptionResult {
1975 sender_uuid: usmc.sender()?.sender_uuid()?.to_string(),
1976 sender_e164: usmc.sender()?.sender_e164()?.map(|s| s.to_string()),
1977 device_id: usmc.sender()?.sender_device_id()?,
1978 message,
1979 })
1980}
1981
1982#[test]
1983fn test_lossless_round_trip() -> Result<()> {
1984 let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
1985
1986 let certificate_data_encoded = "100119697a0000000000002221056c9d1f8deb82b9a898f9c277a1b74989ec009afb5c0acb5e8e69e3d5ca29d6322a690a2508011221053b03ca070e6f6b2f271d32f27321689cdf4e59b106c10b58fbe15063ed868a5a124024bc92954e52ad1a105b5bda85c9db410dcfeb42a671b45a523b3a46e9594a8bde0efc671d8e8e046b32c67f59b80a46ffdf24071850779bc21325107902af89322461616161616161612d373030302d313165622d623332612d333362386138613438376136ba3e136372617368696e6720726967687420646f776e";
2031 let certificate_signature_encoded = "a22d8f86f5d00794f319add821e342c6ffffb6b34f741e569f8b321ab0255f2d1757ecf648e53a3602cae8f09b3fc80dcf27534d67efd272b6739afc31f75c8c";
2032
2033 let certificate_data = hex::decode(certificate_data_encoded).expect("valid hex");
2035 let certificate_signature = hex::decode(certificate_signature_encoded).expect("valid hex");
2036
2037 let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2038 certificate: Some(certificate_data),
2039 signature: Some(certificate_signature),
2040 };
2041
2042 let sender_certificate =
2043 SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2044 assert!(sender_certificate.validate(
2045 &trust_root.public_key()?,
2046 Timestamp::from_epoch_millis(31336)
2047 )?);
2048 Ok(())
2049}