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