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