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: &[&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)?;
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 zerocopy::IntoBytes;
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 #[derive(Default, KnownLayout, IntoBytes, FromBytes)]
736 #[repr(C, packed)]
737 struct DerivedValues([u8; 32], [u8; 32], [u8; 32]);
738 let mut derived_values = DerivedValues::default();
739 hkdf::Hkdf::<sha2::Sha256>::new(Some(&ephemeral_salt), &shared_secret)
740 .expand(&[], derived_values.as_mut_bytes())
741 .expect("valid output length");
742
743 let DerivedValues(chain_key, cipher_key, mac_key) = derived_values;
744
745 Ok(Self {
746 chain_key,
747 cipher_key,
748 mac_key,
749 })
750 }
751 }
752
753 #[cfg(test)]
754 impl PartialEq for EphemeralKeys {
755 fn eq(&self, other: &Self) -> bool {
756 self.chain_key == other.chain_key
757 && self.cipher_key == other.cipher_key
758 && self.mac_key == other.mac_key
759 }
760 }
761
762 #[cfg(test)]
763 impl Eq for EphemeralKeys {}
764
765 #[cfg(test)]
766 impl fmt::Debug for EphemeralKeys {
767 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
768 write!(
769 f,
770 "EphemeralKeys {{ chain_key: {:?}, cipher_key: {:?}, mac_key: {:?} }}",
771 self.chain_key, self.cipher_key, self.mac_key
772 )
773 }
774 }
775
776 pub(super) struct StaticKeys {
778 pub(super) cipher_key: [u8; 32],
779 pub(super) mac_key: [u8; 32],
780 }
781
782 impl StaticKeys {
783 pub(super) fn calculate(
786 our_keys: &IdentityKeyPair,
787 their_key: &PublicKey,
788 chain_key: &[u8; 32],
789 ctext: &[u8],
790 ) -> Result<Self> {
791 let salt = [chain_key, ctext].concat();
792
793 let shared_secret = our_keys.private_key().calculate_agreement(their_key)?;
794 #[derive(Default, KnownLayout, IntoBytes, FromBytes)]
798 #[repr(C, packed)]
799 struct DerivedValues(#[allow(unused)] [u8; 32], [u8; 32], [u8; 32]);
800 let mut derived_values = DerivedValues::default();
801 hkdf::Hkdf::<sha2::Sha256>::new(Some(&salt), &shared_secret)
802 .expand(&[], derived_values.as_mut_bytes())
803 .expect("valid output length");
804
805 let DerivedValues(_, cipher_key, mac_key) = derived_values;
806
807 Ok(Self {
808 cipher_key,
809 mac_key,
810 })
811 }
812 }
813
814 #[test]
815 fn test_agreement_and_authentication() -> Result<()> {
816 let sender_identity = IdentityKeyPair::generate(&mut rand::rng());
818 let recipient_identity = IdentityKeyPair::generate(&mut rand::rng());
819
820 let sender_ephemeral = KeyPair::generate(&mut rand::rng());
822 let ephemeral_public = sender_ephemeral.public_key;
823 let sender_eph_keys = EphemeralKeys::calculate(
825 &sender_ephemeral,
826 recipient_identity.public_key(),
827 Direction::Sending,
828 )?;
829
830 let sender_static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
832 &sender_identity.public_key().serialize(),
833 &sender_eph_keys.cipher_key,
834 &sender_eph_keys.mac_key,
835 )
836 .expect("just generated these keys, they should be correct");
837
838 let sender_static_keys = StaticKeys::calculate(
840 &sender_identity,
841 recipient_identity.public_key(),
842 &sender_eph_keys.chain_key,
843 &sender_static_key_ctext,
844 )?;
845
846 let sender_message_contents = b"this is a binary message";
847 let sender_message_data = crypto::aes256_ctr_hmacsha256_encrypt(
848 sender_message_contents,
849 &sender_static_keys.cipher_key,
850 &sender_static_keys.mac_key,
851 )
852 .expect("just generated these keys, they should be correct");
853
854 let recipient_eph_keys = EphemeralKeys::calculate(
856 &recipient_identity.into(),
857 &ephemeral_public,
858 Direction::Receiving,
859 )?;
860 assert_eq!(sender_eph_keys, recipient_eph_keys);
861
862 let recipient_message_key_bytes = crypto::aes256_ctr_hmacsha256_decrypt(
863 &sender_static_key_ctext,
864 &recipient_eph_keys.cipher_key,
865 &recipient_eph_keys.mac_key,
866 )
867 .expect("should decrypt successfully");
868 let sender_public_key: PublicKey = PublicKey::try_from(&recipient_message_key_bytes[..])?;
869 assert_eq!(sender_identity.public_key(), &sender_public_key);
870
871 let recipient_static_keys = StaticKeys::calculate(
872 &recipient_identity,
873 &sender_public_key,
874 &recipient_eph_keys.chain_key,
875 &sender_static_key_ctext,
876 )?;
877
878 let recipient_message_contents = crypto::aes256_ctr_hmacsha256_decrypt(
879 &sender_message_data,
880 &recipient_static_keys.cipher_key,
881 &recipient_static_keys.mac_key,
882 )
883 .expect("should decrypt successfully");
884 assert_eq!(recipient_message_contents, sender_message_contents);
885
886 Ok(())
887 }
888}
889
890pub async fn sealed_sender_encrypt<R: Rng + CryptoRng>(
897 destination: &ProtocolAddress,
898 sender_cert: &SenderCertificate,
899 ptext: &[u8],
900 session_store: &mut dyn SessionStore,
901 identity_store: &mut dyn IdentityKeyStore,
902 now: SystemTime,
903 rng: &mut R,
904) -> Result<Vec<u8>> {
905 let message =
906 message_encrypt(ptext, destination, session_store, identity_store, now, rng).await?;
907 let usmc = UnidentifiedSenderMessageContent::new(
908 message.message_type(),
909 sender_cert.clone(),
910 message.serialize().to_vec(),
911 ContentHint::Default,
912 None,
913 )?;
914 sealed_sender_encrypt_from_usmc(destination, &usmc, identity_store, rng).await
915}
916
917pub async fn sealed_sender_encrypt_from_usmc<R: Rng + CryptoRng>(
968 destination: &ProtocolAddress,
969 usmc: &UnidentifiedSenderMessageContent,
970 identity_store: &dyn IdentityKeyStore,
971 rng: &mut R,
972) -> Result<Vec<u8>> {
973 let our_identity = identity_store.get_identity_key_pair().await?;
974 let their_identity = identity_store
975 .get_identity(destination)
976 .await?
977 .ok_or_else(|| SignalProtocolError::SessionNotFound(destination.clone()))?;
978
979 let ephemeral = KeyPair::generate(rng);
980
981 let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
982 &ephemeral,
983 their_identity.public_key(),
984 Direction::Sending,
985 )?;
986
987 let static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
988 &our_identity.public_key().serialize(),
989 &eph_keys.cipher_key,
990 &eph_keys.mac_key,
991 )
992 .expect("just generated these keys, they should be correct");
993
994 let static_keys = sealed_sender_v1::StaticKeys::calculate(
995 &our_identity,
996 their_identity.public_key(),
997 &eph_keys.chain_key,
998 &static_key_ctext,
999 )?;
1000
1001 let message_data = crypto::aes256_ctr_hmacsha256_encrypt(
1002 usmc.serialized()?,
1003 &static_keys.cipher_key,
1004 &static_keys.mac_key,
1005 )
1006 .expect("just generated these keys, they should be correct");
1007
1008 let mut serialized = vec![SEALED_SENDER_V1_FULL_VERSION];
1009 let pb = proto::sealed_sender::UnidentifiedSenderMessage {
1010 ephemeral_public: Some(ephemeral.public_key.serialize().to_vec()),
1011 encrypted_static: Some(static_key_ctext),
1012 encrypted_message: Some(message_data),
1013 };
1014 pb.encode(&mut serialized)
1015 .expect("can always append to Vec");
1016
1017 Ok(serialized)
1018}
1019
1020mod sealed_sender_v2 {
1021 use super::*;
1022
1023 const LABEL_R: &[u8] = b"Sealed Sender v2: r (2023-08)";
1025 const LABEL_K: &[u8] = b"Sealed Sender v2: K";
1026 const LABEL_DH: &[u8] = b"Sealed Sender v2: DH";
1027 const LABEL_DH_S: &[u8] = b"Sealed Sender v2: DH-sender";
1028
1029 pub const MESSAGE_KEY_LEN: usize = 32;
1030 pub const CIPHER_KEY_LEN: usize =
1031 <Aes256GcmSiv as aes_gcm_siv::aead::KeySizeUser>::KeySize::USIZE;
1032 pub const AUTH_TAG_LEN: usize = 16;
1033 pub const PUBLIC_KEY_LEN: usize = 32;
1035
1036 pub(super) struct DerivedKeys {
1038 kdf: hkdf::Hkdf<sha2::Sha256>,
1039 }
1040
1041 impl DerivedKeys {
1042 pub(super) fn new(m: &[u8]) -> DerivedKeys {
1044 Self {
1045 kdf: hkdf::Hkdf::<sha2::Sha256>::new(None, m),
1046 }
1047 }
1048
1049 pub(super) fn derive_e(&self) -> KeyPair {
1051 let mut r = [0; 32];
1052 self.kdf
1053 .expand(LABEL_R, &mut r)
1054 .expect("valid output length");
1055 let e = PrivateKey::try_from(&r[..]).expect("valid PrivateKey");
1056 KeyPair::try_from(e).expect("can derive public key")
1057 }
1058
1059 pub(super) fn derive_k(&self) -> [u8; CIPHER_KEY_LEN] {
1061 let mut k = [0; CIPHER_KEY_LEN];
1062 self.kdf
1063 .expand(LABEL_K, &mut k)
1064 .expect("valid output length");
1065 k
1066 }
1067 }
1068
1069 pub(super) fn apply_agreement_xor(
1076 our_keys: &KeyPair,
1077 their_key: &PublicKey,
1078 direction: Direction,
1079 input: &[u8; MESSAGE_KEY_LEN],
1080 ) -> Result<[u8; MESSAGE_KEY_LEN]> {
1081 let agreement = our_keys.calculate_agreement(their_key)?;
1082 let agreement_key_input = match direction {
1083 Direction::Sending => [
1084 agreement,
1085 our_keys.public_key.serialize(),
1086 their_key.serialize(),
1087 ],
1088 Direction::Receiving => [
1089 agreement,
1090 their_key.serialize(),
1091 our_keys.public_key.serialize(),
1092 ],
1093 }
1094 .concat();
1095
1096 let mut result = [0; MESSAGE_KEY_LEN];
1097 hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
1098 .expand(LABEL_DH, &mut result)
1099 .expect("valid output length");
1100 result
1101 .iter_mut()
1102 .zip(input)
1103 .for_each(|(result_byte, input_byte)| *result_byte ^= input_byte);
1104 Ok(result)
1105 }
1106
1107 pub(super) fn compute_authentication_tag(
1116 our_keys: &IdentityKeyPair,
1117 their_key: &IdentityKey,
1118 direction: Direction,
1119 ephemeral_pub_key: &PublicKey,
1120 encrypted_message_key: &[u8; MESSAGE_KEY_LEN],
1121 ) -> Result<[u8; AUTH_TAG_LEN]> {
1122 let agreement = our_keys
1123 .private_key()
1124 .calculate_agreement(their_key.public_key())?;
1125 let mut agreement_key_input = agreement.into_vec();
1126 agreement_key_input.extend_from_slice(&ephemeral_pub_key.serialize());
1127 agreement_key_input.extend_from_slice(encrypted_message_key);
1128 match direction {
1129 Direction::Sending => {
1130 agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1131 agreement_key_input.extend_from_slice(&their_key.serialize());
1132 }
1133 Direction::Receiving => {
1134 agreement_key_input.extend_from_slice(&their_key.serialize());
1135 agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1136 }
1137 }
1138
1139 let mut result = [0; AUTH_TAG_LEN];
1140 hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
1141 .expand(LABEL_DH_S, &mut result)
1142 .expect("valid output length");
1143 Ok(result)
1144 }
1145
1146 #[test]
1147 fn test_agreement_and_authentication() -> Result<()> {
1148 let sender_identity = IdentityKeyPair::generate(&mut rand::rng());
1150 let recipient_identity = IdentityKeyPair::generate(&mut rand::rng());
1151
1152 let m: [u8; MESSAGE_KEY_LEN] = rand::rng().random();
1154 let ephemeral_keys = DerivedKeys::new(&m);
1156 let e = ephemeral_keys.derive_e();
1157
1158 let sender_c_0: [u8; MESSAGE_KEY_LEN] =
1160 apply_agreement_xor(&e, recipient_identity.public_key(), Direction::Sending, &m)?;
1161 let sender_at_0 = compute_authentication_tag(
1163 &sender_identity,
1164 recipient_identity.identity_key(),
1165 Direction::Sending,
1166 &e.public_key,
1167 &sender_c_0,
1168 )?;
1169
1170 let recv_m = apply_agreement_xor(
1172 &recipient_identity.into(),
1173 &e.public_key,
1174 Direction::Receiving,
1175 &sender_c_0,
1176 )?;
1177 assert_eq!(&recv_m, &m);
1178
1179 let recv_at_0 = compute_authentication_tag(
1180 &recipient_identity,
1181 sender_identity.identity_key(),
1182 Direction::Receiving,
1183 &e.public_key,
1184 &sender_c_0,
1185 )?;
1186 assert_eq!(&recv_at_0, &sender_at_0);
1187
1188 Ok(())
1189 }
1190}
1191
1192pub async fn sealed_sender_multi_recipient_encrypt<
1353 R: Rng + CryptoRng,
1354 X: IntoIterator<Item = ServiceId>,
1355>(
1356 destinations: &[&ProtocolAddress],
1357 destination_sessions: &[&SessionRecord],
1358 excluded_recipients: X,
1359 usmc: &UnidentifiedSenderMessageContent,
1360 identity_store: &dyn IdentityKeyStore,
1361 rng: &mut R,
1362) -> Result<Vec<u8>>
1363where
1364 X::IntoIter: ExactSizeIterator,
1365{
1366 sealed_sender_multi_recipient_encrypt_impl(
1367 destinations,
1368 destination_sessions,
1369 excluded_recipients,
1370 usmc,
1371 identity_store,
1372 rng,
1373 )
1374 .await
1375}
1376
1377async fn sealed_sender_multi_recipient_encrypt_impl<
1378 R: Rng + CryptoRng,
1379 X: IntoIterator<Item = ServiceId>,
1380>(
1381 destinations: &[&ProtocolAddress],
1382 destination_sessions: &[&SessionRecord],
1383 excluded_recipients: X,
1384 usmc: &UnidentifiedSenderMessageContent,
1385 identity_store: &dyn IdentityKeyStore,
1386 rng: &mut R,
1387) -> Result<Vec<u8>>
1388where
1389 X::IntoIter: ExactSizeIterator,
1390{
1391 if destinations.len() != destination_sessions.len() {
1392 return Err(SignalProtocolError::InvalidArgument(
1393 "must have the same number of destination sessions as addresses".to_string(),
1394 ));
1395 }
1396
1397 let excluded_recipients = excluded_recipients.into_iter();
1398 let our_identity = identity_store.get_identity_key_pair().await?;
1399
1400 let m: [u8; sealed_sender_v2::MESSAGE_KEY_LEN] = rng.random();
1401 let keys = sealed_sender_v2::DerivedKeys::new(&m);
1402 let e = keys.derive_e();
1403 let e_pub = &e.public_key;
1404
1405 let ciphertext = {
1407 let mut ciphertext = usmc.serialized()?.to_vec();
1408 let symmetric_authentication_tag = Aes256GcmSiv::new(&keys.derive_k().into())
1409 .encrypt_in_place_detached(
1410 &aes_gcm_siv::Nonce::default(),
1412 &[],
1414 &mut ciphertext,
1415 )
1416 .expect("AES-GCM-SIV encryption should not fail with a just-computed key");
1417 ciphertext.extend_from_slice(&symmetric_authentication_tag);
1420 ciphertext
1421 };
1422
1423 let identity_keys_and_ranges: Vec<(IdentityKey, Range<usize>)> = {
1428 let mut identity_keys_and_ranges = vec![];
1429 for (_, mut next_group) in &destinations
1430 .iter()
1431 .enumerate()
1432 .chunk_by(|(_i, next)| next.name())
1433 {
1434 let (i, &destination) = next_group
1435 .next()
1436 .expect("at least one element in every group");
1437 let count = 1 + next_group.count();
1440 let their_identity =
1441 identity_store
1442 .get_identity(destination)
1443 .await?
1444 .ok_or_else(|| {
1445 log::error!("missing identity key for {destination}");
1446 SignalProtocolError::SessionNotFound(destination.clone())
1450 })?;
1451 identity_keys_and_ranges.push((their_identity, i..i + count));
1452 }
1453 identity_keys_and_ranges
1454 };
1455
1456 let serialize_recipient_destinations_into = |serialized: &mut Vec<u8>,
1462 destinations: &[&ProtocolAddress],
1463 sessions: &[&SessionRecord],
1464 their_identity: &IdentityKey|
1465 -> Result<()> {
1466 let their_service_id = ServiceId::parse_from_service_id_string(destinations[0].name())
1467 .ok_or_else(|| {
1468 SignalProtocolError::InvalidArgument(format!(
1469 "multi-recipient sealed sender requires recipients' ServiceId (not {})",
1470 destinations[0].name()
1471 ))
1472 })?;
1473
1474 serialized.extend_from_slice(&their_service_id.service_id_fixed_width_binary());
1475
1476 debug_assert_eq!(
1477 destinations.len(),
1478 sessions.len(),
1479 "should be sliced with the same range"
1480 );
1481 let mut destinations_and_sessions = destinations.iter().zip(sessions);
1482 while let Some((&destination, session)) = destinations_and_sessions.next() {
1483 let their_registration_id = session.remote_registration_id().map_err(|_| {
1484 SignalProtocolError::InvalidState(
1485 "sealed_sender_multi_recipient_encrypt",
1486 format!(
1487 concat!(
1488 "cannot get registration ID from session with {} ",
1489 "(maybe it was recently archived)"
1490 ),
1491 destination
1492 ),
1493 )
1494 })?;
1495 if their_registration_id & u32::from(VALID_REGISTRATION_ID_MASK)
1496 != their_registration_id
1497 {
1498 return Err(SignalProtocolError::InvalidRegistrationId(
1499 destination.clone(),
1500 their_registration_id,
1501 ));
1502 }
1503 let mut their_registration_id =
1504 u16::try_from(their_registration_id).expect("just checked range");
1505 if destinations_and_sessions.len() > 0 {
1506 their_registration_id |= 0x8000;
1507 }
1508
1509 let device_id = destination.device_id();
1510 serialized.push(device_id.into());
1511 serialized.extend_from_slice(&their_registration_id.to_be_bytes());
1512 }
1513
1514 let c_i = sealed_sender_v2::apply_agreement_xor(
1515 &e,
1516 their_identity.public_key(),
1517 Direction::Sending,
1518 &m,
1519 )?;
1520 serialized.extend_from_slice(&c_i);
1521
1522 let at_i = sealed_sender_v2::compute_authentication_tag(
1523 &our_identity,
1524 their_identity,
1525 Direction::Sending,
1526 e_pub,
1527 &c_i,
1528 )?;
1529 serialized.extend_from_slice(&at_i);
1530
1531 Ok(())
1532 };
1533
1534 let process_chunk =
1535 |serialized: &mut Vec<u8>, chunk: &[(IdentityKey, Range<usize>)]| -> Result<()> {
1536 for (their_identity, destination_range) in chunk {
1537 let these_destinations = &destinations[destination_range.clone()];
1538 let these_sessions = &destination_sessions[destination_range.clone()];
1539 serialize_recipient_destinations_into(
1540 serialized,
1541 these_destinations,
1542 these_sessions,
1543 their_identity,
1544 )?;
1545 }
1546 Ok(())
1547 };
1548
1549 let mut serialized: Vec<u8> = vec![SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION];
1550
1551 let count_of_recipients = identity_keys_and_ranges.len() + excluded_recipients.len();
1552 prost::encode_length_delimiter(count_of_recipients, &mut serialized)
1553 .expect("can always resize a Vec");
1554
1555 let parallelism = std::thread::available_parallelism()
1557 .map(usize::from)
1558 .unwrap_or(1);
1559 let chunk_size = std::cmp::max(6, identity_keys_and_ranges.len().div_ceil(parallelism));
1560
1561 if parallelism == 1 || chunk_size >= identity_keys_and_ranges.len() {
1562 process_chunk(&mut serialized, &identity_keys_and_ranges)?;
1563 } else {
1564 let mut chunks = identity_keys_and_ranges.chunks(chunk_size);
1565 let first_chunk = chunks.next().expect("at least one chunk, tested above");
1567
1568 let mut all_outputs = Vec::new();
1569 all_outputs.resize_with(chunks.len(), || Ok(vec![]));
1570
1571 rayon::scope(|scope| -> Result<()> {
1572 let mut outputs = &mut all_outputs[..];
1573 for chunk in chunks {
1574 let (next_output, remaining_outputs) = outputs
1575 .split_first_mut()
1576 .expect("as many outputs as remaining chunks");
1577 scope.spawn(|_| {
1578 let mut serialized = vec![];
1579 *next_output = process_chunk(&mut serialized, chunk).map(|_| serialized);
1580 });
1581 outputs = remaining_outputs;
1582 }
1583
1584 process_chunk(&mut serialized, first_chunk)
1585 })?;
1586
1587 for output in all_outputs {
1588 serialized.extend(output?);
1589 }
1590 }
1591
1592 for excluded in excluded_recipients {
1593 serialized.extend_from_slice(&excluded.service_id_fixed_width_binary());
1594 serialized.push(0);
1595 }
1596
1597 serialized.extend_from_slice(e_pub.public_key_bytes());
1598 serialized.extend_from_slice(&ciphertext);
1599
1600 Ok(serialized)
1601}
1602
1603pub struct SealedSenderV2SentMessageRecipient<'a> {
1607 pub devices: Vec<(DeviceId, u16)>,
1609 c_and_at: &'a [u8],
1612}
1613
1614pub struct SealedSenderV2SentMessage<'a> {
1618 full_message: &'a [u8],
1620 pub version: u8,
1622 pub recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>>,
1628 shared_bytes: &'a [u8],
1630}
1631
1632impl<'a> SealedSenderV2SentMessage<'a> {
1633 pub fn parse(data: &'a [u8]) -> Result<Self> {
1635 if data.is_empty() {
1636 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1637 "Message was empty".to_owned(),
1638 ));
1639 }
1640
1641 let version = data[0];
1642 if !matches!(
1643 version,
1644 SEALED_SENDER_V2_UUID_FULL_VERSION | SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION
1645 ) {
1646 return Err(SignalProtocolError::UnknownSealedSenderVersion(version));
1647 }
1648
1649 fn advance<'a, const N: usize>(buf: &mut &'a [u8]) -> Result<&'a [u8; N]> {
1650 let (prefix, remaining) = buf
1651 .split_first_chunk()
1652 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
1653 *buf = remaining;
1654 Ok(prefix)
1655 }
1656 fn decode_varint(buf: &mut &[u8]) -> Result<u32> {
1657 let result: usize = prost::decode_length_delimiter(*buf)
1658 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1659 *buf = &buf[prost::length_delimiter_len(result)..];
1660 result
1661 .try_into()
1662 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)
1663 }
1664
1665 let mut remaining = &data[1..];
1666 let recipient_count = decode_varint(&mut remaining)?
1667 .try_into()
1668 .unwrap_or(usize::MAX);
1669
1670 let mut recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>> =
1674 IndexMap::with_capacity(std::cmp::min(recipient_count as usize, 6000));
1675 for _ in 0..recipient_count {
1676 let service_id = if version == SEALED_SENDER_V2_UUID_FULL_VERSION {
1677 ServiceId::from(Aci::from_uuid_bytes(*advance::<
1679 { std::mem::size_of::<uuid::Bytes>() },
1680 >(&mut remaining)?))
1681 } else {
1682 ServiceId::parse_from_service_id_fixed_width_binary(advance::<
1683 { std::mem::size_of::<ServiceIdFixedWidthBinaryBytes>() },
1684 >(
1685 &mut remaining
1686 )?)
1687 .ok_or(SignalProtocolError::InvalidProtobufEncoding)?
1688 };
1689 let mut devices = Vec::new();
1690 loop {
1691 let device_id = advance::<1>(&mut remaining)?[0];
1692 if device_id == 0 {
1693 if !devices.is_empty() {
1694 return Err(SignalProtocolError::InvalidProtobufEncoding);
1695 }
1696 break;
1697 }
1698 let device_id = DeviceId::new(device_id)
1699 .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1700 let registration_id_and_has_more =
1701 u16::from_be_bytes(*advance::<2>(&mut remaining)?);
1702 devices.push((
1703 device_id,
1704 registration_id_and_has_more & VALID_REGISTRATION_ID_MASK,
1705 ));
1706 let has_more = (registration_id_and_has_more & 0x8000) != 0;
1707 if !has_more {
1708 break;
1709 }
1710 }
1711
1712 let c_and_at: &[u8] = if devices.is_empty() {
1713 &[]
1714 } else {
1715 advance::<{ sealed_sender_v2::MESSAGE_KEY_LEN + sealed_sender_v2::AUTH_TAG_LEN }>(
1716 &mut remaining,
1717 )?
1718 };
1719
1720 match recipients.entry(service_id) {
1721 indexmap::map::Entry::Occupied(mut existing) => {
1722 if existing.get().devices.is_empty() || devices.is_empty() {
1723 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1724 "recipient redundantly encoded as empty".to_owned(),
1725 ));
1726 }
1727 existing.get_mut().devices.extend(devices);
1730 }
1734 indexmap::map::Entry::Vacant(entry) => {
1735 entry.insert(SealedSenderV2SentMessageRecipient { devices, c_and_at });
1736 }
1737 };
1738 }
1739
1740 if remaining.len() < sealed_sender_v2::PUBLIC_KEY_LEN {
1741 return Err(SignalProtocolError::InvalidProtobufEncoding);
1742 }
1743
1744 Ok(Self {
1745 full_message: data,
1746 version,
1747 recipients,
1748 shared_bytes: remaining,
1749 })
1750 }
1751
1752 #[inline]
1758 pub fn received_message_parts_for_recipient(
1759 &self,
1760 recipient: &SealedSenderV2SentMessageRecipient<'a>,
1761 ) -> impl AsRef<[&[u8]]> {
1762 [
1767 &[SEALED_SENDER_V2_UUID_FULL_VERSION],
1768 recipient.c_and_at,
1769 self.shared_bytes,
1770 ]
1771 }
1772
1773 #[inline]
1780 fn offset_within_full_message(&self, addr: *const u8) -> Option<usize> {
1781 let offset = (addr as usize).wrapping_sub(self.full_message.as_ptr() as usize);
1785 if offset <= self.full_message.len() {
1788 debug_assert!(
1789 offset == self.full_message.len() || std::ptr::eq(&self.full_message[offset], addr)
1790 );
1791 Some(offset)
1792 } else {
1793 None
1794 }
1795 }
1796
1797 pub fn range_for_recipient_key_material(
1804 &self,
1805 recipient: &SealedSenderV2SentMessageRecipient<'a>,
1806 ) -> Range<usize> {
1807 if recipient.c_and_at.is_empty() {
1808 return 0..0;
1809 }
1810 let offset = self
1811 .offset_within_full_message(recipient.c_and_at.as_ptr())
1812 .expect("'recipient' is not one of the recipients in this SealedSenderV2SentMessage");
1813 let end_offset = offset.saturating_add(recipient.c_and_at.len());
1814 assert!(
1815 end_offset <= self.full_message.len(),
1816 "invalid 'recipient' passed to range_for_recipient_key_material"
1817 );
1818 offset..end_offset
1819 }
1820
1821 pub fn offset_of_shared_bytes(&self) -> usize {
1826 debug_assert_eq!(
1827 self.full_message.as_ptr_range().end,
1828 self.shared_bytes.as_ptr_range().end,
1829 "SealedSenderV2SentMessage parsed incorrectly"
1830 );
1831 self.offset_within_full_message(self.shared_bytes.as_ptr())
1832 .expect("constructed correctly")
1833 }
1834}
1835
1836pub async fn sealed_sender_decrypt_to_usmc(
1841 ciphertext: &[u8],
1842 identity_store: &dyn IdentityKeyStore,
1843) -> Result<UnidentifiedSenderMessageContent> {
1844 let our_identity = identity_store.get_identity_key_pair().await?;
1845
1846 match UnidentifiedSenderMessage::deserialize(ciphertext)? {
1847 UnidentifiedSenderMessage::V1 {
1848 ephemeral_public,
1849 encrypted_static,
1850 encrypted_message,
1851 } => {
1852 let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
1853 &our_identity.into(),
1854 &ephemeral_public,
1855 Direction::Receiving,
1856 )?;
1857
1858 let message_key_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1859 &encrypted_static,
1860 &eph_keys.cipher_key,
1861 &eph_keys.mac_key,
1862 ) {
1863 Ok(plaintext) => plaintext,
1864 Err(crypto::DecryptionError::BadKeyOrIv) => {
1865 unreachable!("just derived these keys; they should be valid");
1866 }
1867 Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1868 log::error!("failed to decrypt sealed sender v1 message key: {msg}");
1869 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1870 "failed to decrypt sealed sender v1 message key".to_owned(),
1871 ));
1872 }
1873 };
1874
1875 let static_key = PublicKey::try_from(&message_key_bytes[..])?;
1876
1877 let static_keys = sealed_sender_v1::StaticKeys::calculate(
1878 &our_identity,
1879 &static_key,
1880 &eph_keys.chain_key,
1881 &encrypted_static,
1882 )?;
1883
1884 let message_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1885 &encrypted_message,
1886 &static_keys.cipher_key,
1887 &static_keys.mac_key,
1888 ) {
1889 Ok(plaintext) => plaintext,
1890 Err(crypto::DecryptionError::BadKeyOrIv) => {
1891 unreachable!("just derived these keys; they should be valid");
1892 }
1893 Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1894 log::error!("failed to decrypt sealed sender v1 message contents: {msg}");
1895 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1896 "failed to decrypt sealed sender v1 message contents".to_owned(),
1897 ));
1898 }
1899 };
1900
1901 let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1902
1903 if !bool::from(message_key_bytes.ct_eq(&usmc.sender()?.key()?.serialize())) {
1904 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1905 "sender certificate key does not match message key".to_string(),
1906 ));
1907 }
1908
1909 Ok(usmc)
1910 }
1911 UnidentifiedSenderMessage::V2 {
1912 ephemeral_public,
1913 encrypted_message_key,
1914 authentication_tag,
1915 encrypted_message,
1916 } => {
1917 let m = sealed_sender_v2::apply_agreement_xor(
1918 &our_identity.into(),
1919 &ephemeral_public,
1920 Direction::Receiving,
1921 encrypted_message_key,
1922 )?;
1923
1924 let keys = sealed_sender_v2::DerivedKeys::new(&m);
1925 if !bool::from(keys.derive_e().public_key.ct_eq(&ephemeral_public)) {
1926 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1927 "derived ephemeral key did not match key provided in message".to_string(),
1928 ));
1929 }
1930
1931 let mut message_bytes = Vec::from(encrypted_message);
1932 Aes256GcmSiv::new(&keys.derive_k().into())
1933 .decrypt_in_place(
1934 &aes_gcm_siv::Nonce::default(),
1936 &[],
1938 &mut message_bytes,
1939 )
1940 .map_err(|err| {
1941 SignalProtocolError::InvalidSealedSenderMessage(format!(
1942 "failed to decrypt inner message: {err}"
1943 ))
1944 })?;
1945
1946 let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1947
1948 let at = sealed_sender_v2::compute_authentication_tag(
1949 &our_identity,
1950 &usmc.sender()?.key()?.into(),
1951 Direction::Receiving,
1952 &ephemeral_public,
1953 encrypted_message_key,
1954 )?;
1955 if !bool::from(authentication_tag.ct_eq(&at)) {
1956 return Err(SignalProtocolError::InvalidSealedSenderMessage(
1957 "sender certificate key does not match authentication tag".to_string(),
1958 ));
1959 }
1960
1961 Ok(usmc)
1962 }
1963 }
1964}
1965
1966#[derive(Debug)]
1967pub struct SealedSenderDecryptionResult {
1968 pub sender_uuid: String,
1969 pub sender_e164: Option<String>,
1970 pub device_id: DeviceId,
1971 pub message: Vec<u8>,
1972}
1973
1974impl SealedSenderDecryptionResult {
1975 pub fn sender_uuid(&self) -> Result<&str> {
1976 Ok(self.sender_uuid.as_ref())
1977 }
1978
1979 pub fn sender_e164(&self) -> Result<Option<&str>> {
1980 Ok(self.sender_e164.as_deref())
1981 }
1982
1983 pub fn device_id(&self) -> Result<DeviceId> {
1984 Ok(self.device_id)
1985 }
1986
1987 pub fn message(&self) -> Result<&[u8]> {
1988 Ok(self.message.as_ref())
1989 }
1990}
1991
1992#[expect(clippy::too_many_arguments)]
2000pub async fn sealed_sender_decrypt(
2001 ciphertext: &[u8],
2002 trust_root: &PublicKey,
2003 timestamp: Timestamp,
2004 local_e164: Option<String>,
2005 local_uuid: String,
2006 local_device_id: DeviceId,
2007 identity_store: &mut dyn IdentityKeyStore,
2008 session_store: &mut dyn SessionStore,
2009 pre_key_store: &mut dyn PreKeyStore,
2010 signed_pre_key_store: &dyn SignedPreKeyStore,
2011 kyber_pre_key_store: &mut dyn KyberPreKeyStore,
2012) -> Result<SealedSenderDecryptionResult> {
2013 let usmc = sealed_sender_decrypt_to_usmc(ciphertext, identity_store).await?;
2014
2015 if !usmc.sender()?.validate(trust_root, timestamp)? {
2016 return Err(SignalProtocolError::InvalidSealedSenderMessage(
2017 "trust root validation failed".to_string(),
2018 ));
2019 }
2020
2021 let is_local_uuid = local_uuid == usmc.sender()?.sender_uuid()?;
2022
2023 let is_local_e164 = match (local_e164, usmc.sender()?.sender_e164()?) {
2024 (Some(l), Some(s)) => l == s,
2025 (_, _) => false,
2026 };
2027
2028 if (is_local_e164 || is_local_uuid) && usmc.sender()?.sender_device_id()? == local_device_id {
2029 return Err(SignalProtocolError::SealedSenderSelfSend);
2030 }
2031
2032 let mut rng = rand::rngs::OsRng.unwrap_err();
2033
2034 let remote_address = ProtocolAddress::new(
2035 usmc.sender()?.sender_uuid()?.to_string(),
2036 usmc.sender()?.sender_device_id()?,
2037 );
2038
2039 let message = match usmc.msg_type()? {
2040 CiphertextMessageType::Whisper => {
2041 let ctext = SignalMessage::try_from(usmc.contents()?)?;
2042 session_cipher::message_decrypt_signal(
2043 &ctext,
2044 &remote_address,
2045 session_store,
2046 identity_store,
2047 &mut rng,
2048 )
2049 .await?
2050 }
2051 CiphertextMessageType::PreKey => {
2052 let ctext = PreKeySignalMessage::try_from(usmc.contents()?)?;
2053 session_cipher::message_decrypt_prekey(
2054 &ctext,
2055 &remote_address,
2056 session_store,
2057 identity_store,
2058 pre_key_store,
2059 signed_pre_key_store,
2060 kyber_pre_key_store,
2061 &mut rng,
2062 )
2063 .await?
2064 }
2065 msg_type => {
2066 return Err(SignalProtocolError::InvalidMessage(
2067 msg_type,
2068 "unexpected message type for sealed_sender_decrypt",
2069 ));
2070 }
2071 };
2072
2073 Ok(SealedSenderDecryptionResult {
2074 sender_uuid: usmc.sender()?.sender_uuid()?.to_string(),
2075 sender_e164: usmc.sender()?.sender_e164()?.map(|s| s.to_string()),
2076 device_id: usmc.sender()?.sender_device_id()?,
2077 message,
2078 })
2079}
2080
2081#[test]
2082fn test_lossless_round_trip() -> Result<()> {
2083 let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
2084
2085 let certificate_data = const_str::hex!(
2138 "100119697a0000000000002221056c9d1f8deb82b9a898f9c277a1b74989ec009afb5c0acb5e8e69e3d5ca29d6322a690a2508011221053b03ca070e6f6b2f271d32f27321689cdf4e59b106c10b58fbe15063ed868a5a124024bc92954e52ad1a105b5bda85c9db410dcfeb42a671b45a523b3a46e9594a8bde0efc671d8e8e046b32c67f59b80a46ffdf24071850779bc21325107902af89322461616161616161612d373030302d313165622d623332612d333362386138613438376136ba3e136372617368696e6720726967687420646f776e"
2139 );
2140 let certificate_signature = const_str::hex!(
2141 "a22d8f86f5d00794f319add821e342c6ffffb6b34f741e569f8b321ab0255f2d1757ecf648e53a3602cae8f09b3fc80dcf27534d67efd272b6739afc31f75c8c"
2142 );
2143
2144 let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2145 certificate: Some(certificate_data.to_vec()),
2146 signature: Some(certificate_signature.to_vec()),
2147 };
2148
2149 let sender_certificate =
2150 SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2151 assert_eq!(
2152 sender_certificate.sender_uuid().expect("valid"),
2153 "aaaaaaaa-7000-11eb-b32a-33b8a8a487a6",
2154 );
2155 assert_eq!(sender_certificate.sender_e164().expect("valid"), None);
2156 assert_eq!(
2157 sender_certificate.sender_device_id().expect("valid"),
2158 DeviceId::new(1).expect("valid"),
2159 );
2160 assert_eq!(
2161 sender_certificate
2162 .expiration()
2163 .expect("valid")
2164 .epoch_millis(),
2165 31337
2166 );
2167 assert!(sender_certificate.validate(
2168 &trust_root.public_key()?,
2169 Timestamp::from_epoch_millis(31336)
2170 )?);
2171 Ok(())
2172}
2173
2174#[test]
2175fn test_uuid_bytes_representation() -> Result<()> {
2176 let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
2177
2178 let certificate_data = const_str::hex!(
2180 "100119697a000000000000222105e083a8ce423d1c1955174107a85a6a7f3bcbf566723624077f75eafe8e0a07752a690a25080112210507a24397ae27d06fa76d2f02cfb5546e0b23a7e0c3670c1eb1e73b135a8e1e4d12407d127509ae1f5e9dcaa511793d3e94350dcb269e4ca54500da6e1f4dc13d95940c15badef019edfe8666315500c54e4489d4b83f6ce79c7f65c9772a1a83d88c3a10aaaaaaaa700011ebb32a33b8a8a487a6"
2181 );
2182 let certificate_signature = const_str::hex!(
2183 "755c428e9bf6ba367152f1e545834649b4e8f70df8383a352a953fdb774862af5d42fab573fc52b90ad47c331c36f93b1a4fa7a2504917d895452ffe7f44bd0e"
2184 );
2185
2186 let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2187 certificate: Some(certificate_data.to_vec()),
2188 signature: Some(certificate_signature.to_vec()),
2189 };
2190
2191 let sender_certificate =
2192 SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2193 assert_eq!(
2194 sender_certificate.sender_uuid().expect("valid"),
2195 "aaaaaaaa-7000-11eb-b32a-33b8a8a487a6",
2196 );
2197 assert_eq!(sender_certificate.sender_e164().expect("valid"), None);
2198 assert_eq!(
2199 sender_certificate.sender_device_id().expect("valid"),
2200 DeviceId::new(1).expect("valid"),
2201 );
2202 assert_eq!(
2203 sender_certificate
2204 .expiration()
2205 .expect("valid")
2206 .epoch_millis(),
2207 31337
2208 );
2209 assert!(sender_certificate.validate(
2210 &trust_root.public_key()?,
2211 Timestamp::from_epoch_millis(31336)
2212 )?);
2213 Ok(())
2214}
2215
2216#[test]
2217fn test_known_server_cert() -> Result<()> {
2218 let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
2229 let certificate_data = const_str::hex!(
2232 "100119697a000000000000222105d75b13e15c7700079dd226f51e5a790ba395e819e88a74d0cf5cedfad8b4334840d786df9a07322461616161616161612d373030302d313165622d623332612d333362386138613438376136"
2233 );
2234 let certificate_signature = const_str::hex!(
2235 "e62667bce627caed56ca2ab309b6ae7bc890a30a7482c0e1fd77ec9c3b7528abfd45c8c42b240509a71d973ef5e0f1dbd2685fe01410f0fdbaa8fb247a67e08f"
2236 );
2237
2238 let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2239 certificate: Some(certificate_data.to_vec()),
2240 signature: Some(certificate_signature.to_vec()),
2241 };
2242
2243 let sender_certificate =
2244 SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2245 assert!(sender_certificate.validate(
2246 &trust_root.public_key()?,
2247 Timestamp::from_epoch_millis(31336)
2248 )?);
2249
2250 Ok(())
2251}
2252
2253#[test]
2254fn verify_known_certificates() {
2255 assert!(
2256 KNOWN_SERVER_CERTIFICATES
2257 .iter()
2258 .map(|(id, _trust_root, _cert)| id)
2259 .all_unique(),
2260 "all known certificate IDs must be unique"
2261 );
2262
2263 for (id, trust_root, cert) in KNOWN_SERVER_CERTIFICATES {
2264 let trust_root = PublicKey::deserialize(trust_root)
2265 .unwrap_or_else(|e| panic!("[{id:x}] has invalid trust root: {e}"));
2266 let cert = ServerCertificate::deserialize(cert)
2267 .unwrap_or_else(|e| panic!("[{id:x}] has invalid certificate data: {e}"));
2268 assert_eq!(*id, cert.key_id, "[{id:x}] mismatched certificate ID");
2269 assert!(
2270 cert.validate(&trust_root).expect("can validate"),
2271 "[{id:x}] has wrong trust root"
2272 );
2273 }
2274}