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