libsignal_protocol/
sealed_sender.rs

1//
2// Copyright 2020-2022 Signal Messenger, LLC.
3// SPDX-License-Identifier: AGPL-3.0-only
4//
5
6use std::ops::Range;
7use std::time::SystemTime;
8
9use aes_gcm_siv::aead::generic_array::typenum::Unsigned;
10use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, KeyInit};
11use arrayref::array_ref;
12use indexmap::IndexMap;
13use itertools::Itertools;
14use prost::Message;
15use proto::sealed_sender::unidentified_sender_message::message::Type as ProtoMessageType;
16use rand::{CryptoRng, Rng};
17use subtle::ConstantTimeEq;
18
19use crate::{
20    crypto, curve, message_encrypt, proto, session_cipher, Aci, CiphertextMessageType, DeviceId,
21    Direction, IdentityKey, IdentityKeyPair, IdentityKeyStore, KeyPair, KyberPreKeyStore,
22    PreKeySignalMessage, PreKeyStore, PrivateKey, ProtocolAddress, PublicKey, Result, ServiceId,
23    ServiceIdFixedWidthBinaryBytes, SessionRecord, SessionStore, SignalMessage,
24    SignalProtocolError, SignedPreKeyStore, Timestamp,
25};
26
27#[derive(Debug, Clone)]
28pub struct ServerCertificate {
29    serialized: Vec<u8>,
30    key_id: u32,
31    key: PublicKey,
32    certificate: Vec<u8>,
33    signature: Vec<u8>,
34}
35
36/*
370xDEADC357 is a server certificate ID which is used to test the
38revocation logic. As of this writing, no prod server certificates have
39been revoked. If one ever does, add its key ID here.
40
41If a production server certificate is ever generated which collides
42with this test certificate ID, Bad Things will happen.
43*/
44const REVOKED_SERVER_CERTIFICATE_KEY_IDS: &[u32] = &[0xDEADC357];
45
46// Valid registration IDs fit in 14 bits.
47// TODO: move this into a RegistrationId strong type.
48const VALID_REGISTRATION_ID_MASK: u16 = 0x3FFF;
49
50// TODO: validate this as part of constructing DeviceId.
51const MAX_VALID_DEVICE_ID: u32 = 127;
52
53impl ServerCertificate {
54    pub fn deserialize(data: &[u8]) -> Result<Self> {
55        let pb = proto::sealed_sender::ServerCertificate::decode(data)
56            .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
57
58        if pb.certificate.is_none() || pb.signature.is_none() {
59            return Err(SignalProtocolError::InvalidProtobufEncoding);
60        }
61
62        let certificate = pb
63            .certificate
64            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
65        let signature = pb
66            .signature
67            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
68        let certificate_data =
69            proto::sealed_sender::server_certificate::Certificate::decode(certificate.as_ref())
70                .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
71        let key = PublicKey::try_from(
72            &certificate_data
73                .key
74                .ok_or(SignalProtocolError::InvalidProtobufEncoding)?[..],
75        )?;
76        let key_id = certificate_data
77            .id
78            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
79
80        Ok(Self {
81            serialized: data.to_vec(),
82            certificate,
83            signature,
84            key,
85            key_id,
86        })
87    }
88
89    pub fn new<R: Rng + CryptoRng>(
90        key_id: u32,
91        key: PublicKey,
92        trust_root: &PrivateKey,
93        rng: &mut R,
94    ) -> Result<Self> {
95        let certificate_pb = proto::sealed_sender::server_certificate::Certificate {
96            id: Some(key_id),
97            key: Some(key.serialize().to_vec()),
98        };
99
100        let certificate = certificate_pb.encode_to_vec();
101
102        let signature = trust_root.calculate_signature(&certificate, rng)?.to_vec();
103
104        let serialized = proto::sealed_sender::ServerCertificate {
105            certificate: Some(certificate.clone()),
106            signature: Some(signature.clone()),
107        }
108        .encode_to_vec();
109
110        Ok(Self {
111            serialized,
112            certificate,
113            signature,
114            key,
115            key_id,
116        })
117    }
118
119    pub(crate) fn to_protobuf(&self) -> Result<proto::sealed_sender::ServerCertificate> {
120        Ok(proto::sealed_sender::ServerCertificate {
121            certificate: Some(self.certificate.clone()),
122            signature: Some(self.signature.clone()),
123        })
124    }
125
126    pub fn validate(&self, trust_root: &PublicKey) -> Result<bool> {
127        if REVOKED_SERVER_CERTIFICATE_KEY_IDS.contains(&self.key_id()?) {
128            log::error!(
129                "received server certificate with revoked ID {:x}",
130                self.key_id()?
131            );
132            return Ok(false);
133        }
134        trust_root.verify_signature(&self.certificate, &self.signature)
135    }
136
137    pub fn key_id(&self) -> Result<u32> {
138        Ok(self.key_id)
139    }
140
141    pub fn public_key(&self) -> Result<PublicKey> {
142        Ok(self.key)
143    }
144
145    pub fn certificate(&self) -> Result<&[u8]> {
146        Ok(&self.certificate)
147    }
148
149    pub fn signature(&self) -> Result<&[u8]> {
150        Ok(&self.signature)
151    }
152
153    pub fn serialized(&self) -> Result<&[u8]> {
154        Ok(&self.serialized)
155    }
156}
157
158#[derive(Debug, Clone)]
159pub struct SenderCertificate {
160    signer: ServerCertificate,
161    key: PublicKey,
162    sender_device_id: DeviceId,
163    sender_uuid: String,
164    sender_e164: Option<String>,
165    expiration: Timestamp,
166    serialized: Vec<u8>,
167    certificate: Vec<u8>,
168    signature: Vec<u8>,
169}
170
171impl SenderCertificate {
172    pub fn deserialize(data: &[u8]) -> Result<Self> {
173        let pb = proto::sealed_sender::SenderCertificate::decode(data)
174            .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
175        let certificate = pb
176            .certificate
177            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
178        let signature = pb
179            .signature
180            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
181        let certificate_data =
182            proto::sealed_sender::sender_certificate::Certificate::decode(certificate.as_ref())
183                .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
184
185        let sender_device_id: DeviceId = certificate_data
186            .sender_device
187            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?
188            .into();
189        let expiration = certificate_data
190            .expires
191            .map(Timestamp::from_epoch_millis)
192            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
193        let signer_pb = certificate_data
194            .signer
195            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
196        let sender_uuid = certificate_data
197            .sender_uuid
198            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
199        let sender_e164 = certificate_data.sender_e164;
200
201        let key = PublicKey::try_from(
202            &certificate_data
203                .identity_key
204                .ok_or(SignalProtocolError::InvalidProtobufEncoding)?[..],
205        )?;
206
207        let signer_bits = signer_pb.encode_to_vec();
208        let signer = ServerCertificate::deserialize(&signer_bits)?;
209
210        Ok(Self {
211            signer,
212            key,
213            sender_device_id,
214            sender_uuid,
215            sender_e164,
216            expiration,
217            serialized: data.to_vec(),
218            certificate,
219            signature,
220        })
221    }
222
223    pub fn new<R: Rng + CryptoRng>(
224        sender_uuid: String,
225        sender_e164: Option<String>,
226        key: PublicKey,
227        sender_device_id: DeviceId,
228        expiration: Timestamp,
229        signer: ServerCertificate,
230        signer_key: &PrivateKey,
231        rng: &mut R,
232    ) -> Result<Self> {
233        let certificate_pb = proto::sealed_sender::sender_certificate::Certificate {
234            sender_uuid: Some(sender_uuid.clone()),
235            sender_e164: sender_e164.clone(),
236            sender_device: Some(sender_device_id.into()),
237            expires: Some(expiration.epoch_millis()),
238            identity_key: Some(key.serialize().to_vec()),
239            signer: Some(signer.to_protobuf()?),
240        };
241
242        let certificate = certificate_pb.encode_to_vec();
243
244        let signature = signer_key.calculate_signature(&certificate, rng)?.to_vec();
245
246        let serialized = proto::sealed_sender::SenderCertificate {
247            certificate: Some(certificate.clone()),
248            signature: Some(signature.clone()),
249        }
250        .encode_to_vec();
251
252        Ok(Self {
253            signer,
254            key,
255            sender_device_id,
256            sender_uuid,
257            sender_e164,
258            expiration,
259            serialized,
260            certificate,
261            signature,
262        })
263    }
264
265    pub fn validate(&self, trust_root: &PublicKey, validation_time: Timestamp) -> Result<bool> {
266        if !self.signer.validate(trust_root)? {
267            log::error!(
268                "sender certificate contained server certificate that wasn't signed by trust root"
269            );
270            return Ok(false);
271        }
272
273        if !self
274            .signer
275            .public_key()?
276            .verify_signature(&self.certificate, &self.signature)?
277        {
278            log::error!("sender certificate not signed by server");
279            return Ok(false);
280        }
281
282        if validation_time > self.expiration {
283            log::error!(
284                "sender certificate is expired (expiration: {}, validation_time: {})",
285                self.expiration.epoch_millis(),
286                validation_time.epoch_millis()
287            );
288            return Ok(false);
289        }
290
291        Ok(true)
292    }
293
294    pub fn signer(&self) -> Result<&ServerCertificate> {
295        Ok(&self.signer)
296    }
297
298    pub fn key(&self) -> Result<PublicKey> {
299        Ok(self.key)
300    }
301
302    pub fn sender_device_id(&self) -> Result<DeviceId> {
303        Ok(self.sender_device_id)
304    }
305
306    pub fn sender_uuid(&self) -> Result<&str> {
307        Ok(&self.sender_uuid)
308    }
309
310    pub fn sender_e164(&self) -> Result<Option<&str>> {
311        Ok(self.sender_e164.as_deref())
312    }
313
314    pub fn expiration(&self) -> Result<Timestamp> {
315        Ok(self.expiration)
316    }
317
318    pub fn serialized(&self) -> Result<&[u8]> {
319        Ok(&self.serialized)
320    }
321
322    pub fn certificate(&self) -> Result<&[u8]> {
323        Ok(&self.certificate)
324    }
325
326    pub fn signature(&self) -> Result<&[u8]> {
327        Ok(&self.signature)
328    }
329}
330
331impl From<ProtoMessageType> for CiphertextMessageType {
332    fn from(message_type: ProtoMessageType) -> Self {
333        let result = match message_type {
334            ProtoMessageType::Message => Self::Whisper,
335            ProtoMessageType::PrekeyMessage => Self::PreKey,
336            ProtoMessageType::SenderkeyMessage => Self::SenderKey,
337            ProtoMessageType::PlaintextContent => Self::Plaintext,
338        };
339        // Keep raw values in sync from now on, for efficient codegen.
340        assert!(result == Self::PreKey || message_type as i32 == result as i32);
341        result
342    }
343}
344
345impl From<CiphertextMessageType> for ProtoMessageType {
346    fn from(message_type: CiphertextMessageType) -> Self {
347        let result = match message_type {
348            CiphertextMessageType::PreKey => Self::PrekeyMessage,
349            CiphertextMessageType::Whisper => Self::Message,
350            CiphertextMessageType::SenderKey => Self::SenderkeyMessage,
351            CiphertextMessageType::Plaintext => Self::PlaintextContent,
352        };
353        // Keep raw values in sync from now on, for efficient codegen.
354        assert!(result == Self::PrekeyMessage || message_type as i32 == result as i32);
355        result
356    }
357}
358
359#[derive(Clone, Copy, PartialEq, Eq, Debug)]
360pub enum ContentHint {
361    Default,
362    Resendable,
363    Implicit,
364    Unknown(u32),
365}
366
367impl ContentHint {
368    fn to_proto(self) -> Option<i32> {
369        if self == ContentHint::Default {
370            None
371        } else {
372            Some(u32::from(self) as i32)
373        }
374    }
375
376    pub const fn to_u32(self) -> u32 {
377        use proto::sealed_sender::unidentified_sender_message::message::ContentHint as ProtoContentHint;
378        match self {
379            ContentHint::Default => 0,
380            ContentHint::Resendable => ProtoContentHint::Resendable as u32,
381            ContentHint::Implicit => ProtoContentHint::Implicit as u32,
382            ContentHint::Unknown(value) => value,
383        }
384    }
385}
386
387impl From<u32> for ContentHint {
388    fn from(raw_value: u32) -> Self {
389        use proto::sealed_sender::unidentified_sender_message::message::ContentHint as ProtoContentHint;
390        assert!(!ProtoContentHint::is_valid(0));
391        match ProtoContentHint::try_from(raw_value as i32) {
392            Err(_) if raw_value == 0 => ContentHint::Default,
393            Err(_) => ContentHint::Unknown(raw_value),
394            Ok(ProtoContentHint::Resendable) => ContentHint::Resendable,
395            Ok(ProtoContentHint::Implicit) => ContentHint::Implicit,
396        }
397    }
398}
399
400impl From<ContentHint> for u32 {
401    fn from(hint: ContentHint) -> Self {
402        hint.to_u32()
403    }
404}
405
406pub struct UnidentifiedSenderMessageContent {
407    serialized: Vec<u8>,
408    contents: Vec<u8>,
409    sender: SenderCertificate,
410    msg_type: CiphertextMessageType,
411    content_hint: ContentHint,
412    group_id: Option<Vec<u8>>,
413}
414
415impl UnidentifiedSenderMessageContent {
416    pub fn deserialize(data: &[u8]) -> Result<Self> {
417        let pb = proto::sealed_sender::unidentified_sender_message::Message::decode(data)
418            .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
419
420        let msg_type = pb
421            .r#type
422            .and_then(|t| ProtoMessageType::try_from(t).ok())
423            .map(CiphertextMessageType::from)
424            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
425        let sender = pb
426            .sender_certificate
427            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
428        let contents = pb
429            .content
430            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
431        let content_hint = pb
432            .content_hint
433            .map(|raw| ContentHint::from(raw as u32))
434            .unwrap_or(ContentHint::Default);
435        let group_id = pb.group_id;
436
437        let sender = SenderCertificate::deserialize(&sender)?;
438
439        let serialized = data.to_vec();
440
441        log::info!(
442            "deserialized UnidentifiedSenderMessageContent from {}.{} with type {:?}",
443            sender.sender_uuid()?,
444            sender.sender_device_id()?,
445            msg_type,
446        );
447
448        Ok(Self {
449            serialized,
450            contents,
451            sender,
452            msg_type,
453            content_hint,
454            group_id,
455        })
456    }
457
458    pub fn new(
459        msg_type: CiphertextMessageType,
460        sender: SenderCertificate,
461        contents: Vec<u8>,
462        content_hint: ContentHint,
463        group_id: Option<Vec<u8>>,
464    ) -> Result<Self> {
465        let proto_msg_type = ProtoMessageType::from(msg_type);
466        let msg = proto::sealed_sender::unidentified_sender_message::Message {
467            content: Some(contents.clone()),
468            r#type: Some(proto_msg_type.into()),
469            sender_certificate: Some(sender.serialized()?.to_vec()),
470            content_hint: content_hint.to_proto(),
471            group_id: group_id.as_ref().and_then(|buf| {
472                if buf.is_empty() {
473                    None
474                } else {
475                    Some(buf.clone())
476                }
477            }),
478        };
479
480        let serialized = msg.encode_to_vec();
481
482        Ok(Self {
483            serialized,
484            msg_type,
485            sender,
486            contents,
487            content_hint,
488            group_id,
489        })
490    }
491
492    pub fn msg_type(&self) -> Result<CiphertextMessageType> {
493        Ok(self.msg_type)
494    }
495
496    pub fn sender(&self) -> Result<&SenderCertificate> {
497        Ok(&self.sender)
498    }
499
500    pub fn contents(&self) -> Result<&[u8]> {
501        Ok(&self.contents)
502    }
503
504    pub fn content_hint(&self) -> Result<ContentHint> {
505        Ok(self.content_hint)
506    }
507
508    pub fn group_id(&self) -> Result<Option<&[u8]>> {
509        Ok(self.group_id.as_deref())
510    }
511
512    pub fn serialized(&self) -> Result<&[u8]> {
513        Ok(&self.serialized)
514    }
515}
516
517enum UnidentifiedSenderMessage {
518    V1 {
519        ephemeral_public: PublicKey,
520        encrypted_static: Vec<u8>,
521        encrypted_message: Vec<u8>,
522    },
523    V2 {
524        ephemeral_public: PublicKey,
525        encrypted_message_key: Box<[u8]>,
526        authentication_tag: Box<[u8]>,
527        encrypted_message: Box<[u8]>,
528    },
529}
530
531const SEALED_SENDER_V1_MAJOR_VERSION: u8 = 1;
532const SEALED_SENDER_V1_FULL_VERSION: u8 = 0x11;
533const SEALED_SENDER_V2_MAJOR_VERSION: u8 = 2;
534const SEALED_SENDER_V2_UUID_FULL_VERSION: u8 = 0x22;
535const SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION: u8 = 0x23;
536
537impl UnidentifiedSenderMessage {
538    fn deserialize(data: &[u8]) -> Result<Self> {
539        if data.is_empty() {
540            return Err(SignalProtocolError::InvalidSealedSenderMessage(
541                "Message was empty".to_owned(),
542            ));
543        }
544        let version = data[0] >> 4;
545        log::debug!(
546            "deserializing UnidentifiedSenderMessage with version {}",
547            version
548        );
549
550        match version {
551            0 | SEALED_SENDER_V1_MAJOR_VERSION => {
552                // XXX should we really be accepted version == 0 here?
553                let pb = proto::sealed_sender::UnidentifiedSenderMessage::decode(&data[1..])
554                    .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
555
556                let ephemeral_public = pb
557                    .ephemeral_public
558                    .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
559                let encrypted_static = pb
560                    .encrypted_static
561                    .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
562                let encrypted_message = pb
563                    .encrypted_message
564                    .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
565
566                let ephemeral_public = PublicKey::try_from(&ephemeral_public[..])?;
567
568                Ok(Self::V1 {
569                    ephemeral_public,
570                    encrypted_static,
571                    encrypted_message,
572                })
573            }
574            SEALED_SENDER_V2_MAJOR_VERSION => {
575                // Uses a flat representation: C || AT || E.pub || ciphertext
576                let remaining = &data[1..];
577                if remaining.len()
578                    < sealed_sender_v2::MESSAGE_KEY_LEN
579                        + sealed_sender_v2::AUTH_TAG_LEN
580                        + curve::curve25519::PUBLIC_KEY_LENGTH
581                {
582                    return Err(SignalProtocolError::InvalidProtobufEncoding);
583                }
584                let (encrypted_message_key, remaining) =
585                    remaining.split_at(sealed_sender_v2::MESSAGE_KEY_LEN);
586                let (encrypted_authentication_tag, remaining) =
587                    remaining.split_at(sealed_sender_v2::AUTH_TAG_LEN);
588                let (ephemeral_public, encrypted_message) =
589                    remaining.split_at(curve::curve25519::PUBLIC_KEY_LENGTH);
590
591                Ok(Self::V2 {
592                    ephemeral_public: PublicKey::from_djb_public_key_bytes(ephemeral_public)?,
593                    encrypted_message_key: encrypted_message_key.into(),
594                    authentication_tag: encrypted_authentication_tag.into(),
595                    encrypted_message: encrypted_message.into(),
596                })
597            }
598            _ => Err(SignalProtocolError::UnknownSealedSenderVersion(version)),
599        }
600    }
601}
602
603mod sealed_sender_v1 {
604    #[cfg(test)]
605    use std::fmt;
606
607    use super::*;
608
609    /// A symmetric cipher key and a MAC key, along with a "chain key" consumed in
610    /// [`StaticKeys::calculate`].
611    pub(super) struct EphemeralKeys {
612        pub(super) chain_key: [u8; 32],
613        pub(super) cipher_key: [u8; 32],
614        pub(super) mac_key: [u8; 32],
615    }
616
617    const SALT_PREFIX: &[u8] = b"UnidentifiedDelivery";
618    const EPHEMERAL_KEYS_KDF_LEN: usize = 96;
619
620    impl EphemeralKeys {
621        /// Derive a set of symmetric keys from the key agreement between the sender and
622        /// recipient's identities.
623        pub(super) fn calculate(
624            our_keys: &KeyPair,
625            their_public: &PublicKey,
626            direction: Direction,
627        ) -> Result<Self> {
628            let our_pub_key = our_keys.public_key.serialize();
629            let their_pub_key = their_public.serialize();
630            let ephemeral_salt = match direction {
631                Direction::Sending => [SALT_PREFIX, &their_pub_key, &our_pub_key],
632                Direction::Receiving => [SALT_PREFIX, &our_pub_key, &their_pub_key],
633            }
634            .concat();
635
636            let shared_secret = our_keys.private_key.calculate_agreement(their_public)?;
637            let mut derived_values = [0; EPHEMERAL_KEYS_KDF_LEN];
638            hkdf::Hkdf::<sha2::Sha256>::new(Some(&ephemeral_salt), &shared_secret)
639                .expand(&[], &mut derived_values)
640                .expect("valid output length");
641
642            Ok(Self {
643                chain_key: *array_ref![&derived_values, 0, 32],
644                cipher_key: *array_ref![&derived_values, 32, 32],
645                mac_key: *array_ref![&derived_values, 64, 32],
646            })
647        }
648    }
649
650    #[cfg(test)]
651    impl PartialEq for EphemeralKeys {
652        fn eq(&self, other: &Self) -> bool {
653            self.chain_key == other.chain_key
654                && self.cipher_key == other.cipher_key
655                && self.mac_key == other.mac_key
656        }
657    }
658
659    #[cfg(test)]
660    impl Eq for EphemeralKeys {}
661
662    #[cfg(test)]
663    impl fmt::Debug for EphemeralKeys {
664        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
665            write!(
666                f,
667                "EphemeralKeys {{ chain_key: {:?}, cipher_key: {:?}, mac_key: {:?} }}",
668                self.chain_key, self.cipher_key, self.mac_key
669            )
670        }
671    }
672
673    /// A symmetric cipher key and a MAC key.
674    pub(super) struct StaticKeys {
675        pub(super) cipher_key: [u8; 32],
676        pub(super) mac_key: [u8; 32],
677    }
678
679    impl StaticKeys {
680        /// Derive a set of symmetric keys from the agreement between the sender and
681        /// recipient's identities, as well as [`EphemeralKeys::chain_key`].
682        pub(super) fn calculate(
683            our_keys: &IdentityKeyPair,
684            their_key: &PublicKey,
685            chain_key: &[u8; 32],
686            ctext: &[u8],
687        ) -> Result<Self> {
688            let salt = [chain_key, ctext].concat();
689
690            let shared_secret = our_keys.private_key().calculate_agreement(their_key)?;
691            // 96 bytes are derived, but the first 32 are discarded/unused. This is intended to
692            // mirror the way the EphemeralKeys are derived, even though StaticKeys does not end up
693            // requiring a third "chain key".
694            let mut derived_values = [0; 96];
695            hkdf::Hkdf::<sha2::Sha256>::new(Some(&salt), &shared_secret)
696                .expand(&[], &mut derived_values)
697                .expect("valid output length");
698
699            Ok(Self {
700                cipher_key: *array_ref![&derived_values, 32, 32],
701                mac_key: *array_ref![&derived_values, 64, 32],
702            })
703        }
704    }
705
706    #[test]
707    fn test_agreement_and_authentication() -> Result<()> {
708        // The sender and recipient each have a long-term identity key pair.
709        let sender_identity = IdentityKeyPair::generate(&mut rand::thread_rng());
710        let recipient_identity = IdentityKeyPair::generate(&mut rand::thread_rng());
711
712        // Generate an ephemeral key pair.
713        let sender_ephemeral = KeyPair::generate(&mut rand::thread_rng());
714        let ephemeral_public = sender_ephemeral.public_key;
715        // Generate ephemeral cipher, chain, and MAC keys.
716        let sender_eph_keys = EphemeralKeys::calculate(
717            &sender_ephemeral,
718            recipient_identity.public_key(),
719            Direction::Sending,
720        )?;
721
722        // Encrypt the sender's public key with AES-256 CTR and a MAC.
723        let sender_static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
724            &sender_identity.public_key().serialize(),
725            &sender_eph_keys.cipher_key,
726            &sender_eph_keys.mac_key,
727        )
728        .expect("just generated these keys, they should be correct");
729
730        // Generate another cipher and MAC key.
731        let sender_static_keys = StaticKeys::calculate(
732            &sender_identity,
733            recipient_identity.public_key(),
734            &sender_eph_keys.chain_key,
735            &sender_static_key_ctext,
736        )?;
737
738        let sender_message_contents = b"this is a binary message";
739        let sender_message_data = crypto::aes256_ctr_hmacsha256_encrypt(
740            sender_message_contents,
741            &sender_static_keys.cipher_key,
742            &sender_static_keys.mac_key,
743        )
744        .expect("just generated these keys, they should be correct");
745
746        // The message recipient calculates the ephemeral key and the sender's public key.
747        let recipient_eph_keys = EphemeralKeys::calculate(
748            &recipient_identity.into(),
749            &ephemeral_public,
750            Direction::Receiving,
751        )?;
752        assert_eq!(sender_eph_keys, recipient_eph_keys);
753
754        let recipient_message_key_bytes = crypto::aes256_ctr_hmacsha256_decrypt(
755            &sender_static_key_ctext,
756            &recipient_eph_keys.cipher_key,
757            &recipient_eph_keys.mac_key,
758        )
759        .expect("should decrypt successfully");
760        let sender_public_key: PublicKey = PublicKey::try_from(&recipient_message_key_bytes[..])?;
761        assert_eq!(sender_identity.public_key(), &sender_public_key);
762
763        let recipient_static_keys = StaticKeys::calculate(
764            &recipient_identity,
765            &sender_public_key,
766            &recipient_eph_keys.chain_key,
767            &sender_static_key_ctext,
768        )?;
769
770        let recipient_message_contents = crypto::aes256_ctr_hmacsha256_decrypt(
771            &sender_message_data,
772            &recipient_static_keys.cipher_key,
773            &recipient_static_keys.mac_key,
774        )
775        .expect("should decrypt successfully");
776        assert_eq!(recipient_message_contents, sender_message_contents);
777
778        Ok(())
779    }
780}
781
782/// Encrypt the plaintext message `ptext`, generate an [`UnidentifiedSenderMessageContent`], then
783/// pass the result to [`sealed_sender_encrypt_from_usmc`].
784///
785/// This is a simple way to encrypt a message in a 1:1 using [Sealed Sender v1].
786///
787/// [Sealed Sender v1]: sealed_sender_encrypt_from_usmc
788pub async fn sealed_sender_encrypt<R: Rng + CryptoRng>(
789    destination: &ProtocolAddress,
790    sender_cert: &SenderCertificate,
791    ptext: &[u8],
792    session_store: &mut dyn SessionStore,
793    identity_store: &mut dyn IdentityKeyStore,
794    now: SystemTime,
795    rng: &mut R,
796) -> Result<Vec<u8>> {
797    let message = message_encrypt(ptext, destination, session_store, identity_store, now).await?;
798    let usmc = UnidentifiedSenderMessageContent::new(
799        message.message_type(),
800        sender_cert.clone(),
801        message.serialize().to_vec(),
802        ContentHint::Default,
803        None,
804    )?;
805    sealed_sender_encrypt_from_usmc(destination, &usmc, identity_store, rng).await
806}
807
808/// This method implements the single-key single-recipient [KEM] described in [this Signal blog
809/// post], a.k.a. Sealed Sender v1.
810///
811/// [KEM]: https://en.wikipedia.org/wiki/Key_encapsulation
812/// [this Signal blog post]: https://signal.org/blog/sealed-sender/
813///
814/// [`sealed_sender_decrypt`] is used in the client to decrypt the Sealed Sender message produced by
815/// this method.
816///
817/// # Contrast with Sealed Sender v2
818/// The *single-recipient* KEM scheme implemented by this method partially derives the encryption
819/// key from the recipient's identity key, which would then require re-encrypting the same message
820/// multiple times to send to multiple recipients. In contrast,
821/// [Sealed Sender v2](sealed_sender_multi_recipient_encrypt) uses a *multi-recipient* KEM scheme
822/// which avoids this repeated work, but makes a few additional design tradeoffs.
823///
824/// # High-level algorithmic overview
825/// The KEM scheme implemented by this method is described in [this Signal blog post]. The
826/// high-level steps of this process are listed below:
827/// 1. Generate a random key pair.
828/// 2. Derive a symmetric chain key, cipher key, and MAC key from the recipient's public key and the
829///    sender's public/private key pair.
830/// 3. Symmetrically encrypt the sender's public key using the cipher key and MAC key from (2) with
831///    AES-256 in CTR mode.
832/// 4. Derive a second symmetric cipher key and MAC key from the sender's private key, the
833///    recipient's public key, and the chain key from (2).
834/// 5. Symmetrically encrypt the underlying [`UnidentifiedSenderMessageContent`] using the cipher key
835///    and MAC key from (4) with AES-256 in CTR mode.
836/// 6. Send the ephemeral public key from (1) and the encrypted public key from (3) to the
837///    recipient, along with the encrypted message (5).
838///
839/// ## Pseudocode
840///```text
841/// e_pub, e_priv                  = X25519.generateEphemeral()
842/// e_chain, e_cipherKey, e_macKey = HKDF(salt="UnidentifiedDelivery" || recipientIdentityPublic || e_pub, ikm=ECDH(recipientIdentityPublic, e_priv), info="")
843/// e_ciphertext                   = AES_CTR(key=e_cipherKey, input=senderIdentityPublic)
844/// e_mac                          = Hmac256(key=e_macKey, input=e_ciphertext)
845///
846/// s_cipherKey, s_macKey = HKDF(salt=e_chain || e_ciphertext || e_mac, ikm=ECDH(recipientIdentityPublic, senderIdentityPrivate), info="")
847/// s_ciphertext          = AES_CTR(key=s_cipherKey, input=sender_certificate || message_ciphertext)
848/// s_mac                 = Hmac256(key=s_macKey, input=s_ciphertext)
849///
850/// message_to_send = s_ciphertext || s_mac
851///```
852///
853/// # Wire Format
854/// The output of this method is encoded as an `UnidentifiedSenderMessage.Message` from
855/// `sealed_sender.proto`, prepended with an additional byte to indicate the version of Sealed
856/// Sender in use (see [further documentation on the version
857/// byte](sealed_sender_multi_recipient_encrypt#the-version-byte)).
858pub async fn sealed_sender_encrypt_from_usmc<R: Rng + CryptoRng>(
859    destination: &ProtocolAddress,
860    usmc: &UnidentifiedSenderMessageContent,
861    identity_store: &dyn IdentityKeyStore,
862    rng: &mut R,
863) -> Result<Vec<u8>> {
864    let our_identity = identity_store.get_identity_key_pair().await?;
865    let their_identity = identity_store
866        .get_identity(destination)
867        .await?
868        .ok_or_else(|| SignalProtocolError::SessionNotFound(destination.clone()))?;
869
870    let ephemeral = KeyPair::generate(rng);
871
872    let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
873        &ephemeral,
874        their_identity.public_key(),
875        Direction::Sending,
876    )?;
877
878    let static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
879        &our_identity.public_key().serialize(),
880        &eph_keys.cipher_key,
881        &eph_keys.mac_key,
882    )
883    .expect("just generated these keys, they should be correct");
884
885    let static_keys = sealed_sender_v1::StaticKeys::calculate(
886        &our_identity,
887        their_identity.public_key(),
888        &eph_keys.chain_key,
889        &static_key_ctext,
890    )?;
891
892    let message_data = crypto::aes256_ctr_hmacsha256_encrypt(
893        usmc.serialized()?,
894        &static_keys.cipher_key,
895        &static_keys.mac_key,
896    )
897    .expect("just generated these keys, they should be correct");
898
899    let mut serialized = vec![SEALED_SENDER_V1_FULL_VERSION];
900    let pb = proto::sealed_sender::UnidentifiedSenderMessage {
901        ephemeral_public: Some(ephemeral.public_key.serialize().to_vec()),
902        encrypted_static: Some(static_key_ctext),
903        encrypted_message: Some(message_data),
904    };
905    pb.encode(&mut serialized)
906        .expect("can always append to Vec");
907
908    Ok(serialized)
909}
910
911mod sealed_sender_v2 {
912    use super::*;
913
914    // Static byte strings used as part of a MAC in HKDF.
915    const LABEL_R: &[u8] = b"Sealed Sender v2: r (2023-08)";
916    const LABEL_K: &[u8] = b"Sealed Sender v2: K";
917    const LABEL_DH: &[u8] = b"Sealed Sender v2: DH";
918    const LABEL_DH_S: &[u8] = b"Sealed Sender v2: DH-sender";
919
920    pub const MESSAGE_KEY_LEN: usize = 32;
921    pub const CIPHER_KEY_LEN: usize =
922        <Aes256GcmSiv as aes_gcm_siv::aead::KeySizeUser>::KeySize::USIZE;
923    pub const AUTH_TAG_LEN: usize = 16;
924
925    /// An asymmetric and a symmetric cipher key.
926    pub(super) struct DerivedKeys {
927        kdf: hkdf::Hkdf<sha2::Sha256>,
928    }
929
930    impl DerivedKeys {
931        /// Initialize from a slice of random bytes `m`.
932        pub(super) fn new(m: &[u8]) -> DerivedKeys {
933            Self {
934                kdf: hkdf::Hkdf::<sha2::Sha256>::new(None, m),
935            }
936        }
937
938        /// Derive the ephemeral asymmetric keys.
939        pub(super) fn derive_e(&self) -> KeyPair {
940            let mut r = [0; 32];
941            self.kdf
942                .expand(LABEL_R, &mut r)
943                .expect("valid output length");
944            let e = PrivateKey::try_from(&r[..]).expect("valid PrivateKey");
945            KeyPair::try_from(e).expect("can derive public key")
946        }
947
948        /// Derive the symmetric cipher key.
949        pub(super) fn derive_k(&self) -> [u8; CIPHER_KEY_LEN] {
950            let mut k = [0; CIPHER_KEY_LEN];
951            self.kdf
952                .expand(LABEL_K, &mut k)
953                .expect("valid output length");
954            k
955        }
956    }
957
958    /// Encrypt or decrypt a slice of random bytes `input` using a shared secret derived from
959    /// `our_keys` and `their_key`.
960    ///
961    /// The output of this method when called with [`Direction::Sending`] can be inverted to produce
962    /// the original `input` bytes if called with [`Direction::Receiving`] with `our_keys` and
963    /// `their_key` swapped.
964    pub(super) fn apply_agreement_xor(
965        our_keys: &KeyPair,
966        their_key: &PublicKey,
967        direction: Direction,
968        input: &[u8; MESSAGE_KEY_LEN],
969    ) -> Result<[u8; MESSAGE_KEY_LEN]> {
970        let agreement = our_keys.calculate_agreement(their_key)?;
971        let agreement_key_input = match direction {
972            Direction::Sending => [
973                agreement,
974                our_keys.public_key.serialize(),
975                their_key.serialize(),
976            ],
977            Direction::Receiving => [
978                agreement,
979                their_key.serialize(),
980                our_keys.public_key.serialize(),
981            ],
982        }
983        .concat();
984
985        let mut result = [0; MESSAGE_KEY_LEN];
986        hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
987            .expand(LABEL_DH, &mut result)
988            .expect("valid output length");
989        result
990            .iter_mut()
991            .zip(input)
992            .for_each(|(result_byte, input_byte)| *result_byte ^= input_byte);
993        Ok(result)
994    }
995
996    /// Compute an [authentication tag] for the bytes `encrypted_message_key` using a shared secret
997    /// derived from `our_keys` and `their_key`.
998    ///
999    /// [authentication tag]: https://en.wikipedia.org/wiki/Message_authentication_code
1000    ///
1001    /// The output of this method with [`Direction::Sending`] should be the same bytes produced by
1002    /// calling this method with [`Direction::Receiving`] with `our_keys` and `their_key`
1003    /// swapped, if `ephemeral_pub_key` and `encrypted_message_key` are the same.
1004    pub(super) fn compute_authentication_tag(
1005        our_keys: &IdentityKeyPair,
1006        their_key: &IdentityKey,
1007        direction: Direction,
1008        ephemeral_pub_key: &PublicKey,
1009        encrypted_message_key: &[u8; MESSAGE_KEY_LEN],
1010    ) -> Result<[u8; AUTH_TAG_LEN]> {
1011        let agreement = our_keys
1012            .private_key()
1013            .calculate_agreement(their_key.public_key())?;
1014        let mut agreement_key_input = agreement.into_vec();
1015        agreement_key_input.extend_from_slice(&ephemeral_pub_key.serialize());
1016        agreement_key_input.extend_from_slice(encrypted_message_key);
1017        match direction {
1018            Direction::Sending => {
1019                agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1020                agreement_key_input.extend_from_slice(&their_key.serialize());
1021            }
1022            Direction::Receiving => {
1023                agreement_key_input.extend_from_slice(&their_key.serialize());
1024                agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1025            }
1026        }
1027
1028        let mut result = [0; AUTH_TAG_LEN];
1029        hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
1030            .expand(LABEL_DH_S, &mut result)
1031            .expect("valid output length");
1032        Ok(result)
1033    }
1034
1035    #[test]
1036    fn test_agreement_and_authentication() -> Result<()> {
1037        // The sender and recipient each have a long-term identity key pair.
1038        let sender_identity = IdentityKeyPair::generate(&mut rand::thread_rng());
1039        let recipient_identity = IdentityKeyPair::generate(&mut rand::thread_rng());
1040
1041        // Generate random bytes used for our multi-recipient encoding scheme.
1042        let m: [u8; MESSAGE_KEY_LEN] = rand::thread_rng().gen();
1043        // Derive an ephemeral key pair from those random bytes.
1044        let ephemeral_keys = DerivedKeys::new(&m);
1045        let e = ephemeral_keys.derive_e();
1046
1047        // Encrypt the ephemeral key pair.
1048        let sender_c_0: [u8; MESSAGE_KEY_LEN] =
1049            apply_agreement_xor(&e, recipient_identity.public_key(), Direction::Sending, &m)?;
1050        // Compute an authentication tag for the encrypted key pair.
1051        let sender_at_0 = compute_authentication_tag(
1052            &sender_identity,
1053            recipient_identity.identity_key(),
1054            Direction::Sending,
1055            &e.public_key,
1056            &sender_c_0,
1057        )?;
1058
1059        // The message recipient calculates the original random bytes and authenticates the result.
1060        let recv_m = apply_agreement_xor(
1061            &recipient_identity.into(),
1062            &e.public_key,
1063            Direction::Receiving,
1064            &sender_c_0,
1065        )?;
1066        assert_eq!(&recv_m, &m);
1067
1068        let recv_at_0 = compute_authentication_tag(
1069            &recipient_identity,
1070            sender_identity.identity_key(),
1071            Direction::Receiving,
1072            &e.public_key,
1073            &sender_c_0,
1074        )?;
1075        assert_eq!(&recv_at_0, &sender_at_0);
1076
1077        Ok(())
1078    }
1079}
1080
1081/// This method implements a single-key multi-recipient [KEM] as defined in Manuel Barbosa's
1082/// ["Randomness Reuse: Extensions and Improvements"], a.k.a. Sealed Sender v2.
1083///
1084/// [KEM]: https://en.wikipedia.org/wiki/Key_encapsulation
1085/// ["Randomness Reuse: Extensions and Improvements"]: https://haslab.uminho.pt/mbb/files/reuse.pdf
1086///
1087/// # Contrast with Sealed Sender v1
1088/// The KEM scheme implemented by this method uses the "Generic Construction" in `4.1` of [Barbosa's
1089/// paper]["Randomness Reuse: Extensions and Improvements"], instantiated with [ElGamal encryption].
1090/// This technique enables reusing a single sequence of random bytes across multiple messages with
1091/// the same content, which reduces computation time for clients sending the same message to
1092/// multiple recipients (without compromising the message security).
1093///
1094/// There are a few additional design tradeoffs this method makes vs [Sealed Sender v1] which may
1095/// make it comparatively unwieldy for certain scenarios:
1096/// 1. it requires a [`SessionRecord`] to exist already for the recipient, i.e. that a Double
1097///    Ratchet message chain has previously been established in the [`SessionStore`] via
1098///    [`process_prekey_bundle`][crate::process_prekey_bundle] after an initial
1099///    [`PreKeySignalMessage`] is received.
1100/// 2. it ferries a lot of additional information in its encoding which makes the resulting message
1101///    bulkier than the message produced by [Sealed Sender v1]. For sending, this will generally
1102///    still be more compact than sending the same message N times, but on the receiver side the
1103///    message is slightly larger.
1104/// 3. unlike other message types sent over the wire, the encoded message returned by this method
1105///    does not use protobuf, in order to avoid inefficiencies produced by protobuf's packing (see
1106///    **[Wire Format]**).
1107///
1108/// [ElGamal encryption]: https://en.wikipedia.org/wiki/ElGamal_encryption
1109/// [Sealed Sender v1]: sealed_sender_encrypt_from_usmc
1110/// [Wire Format]: #wire-format
1111///
1112/// # High-level algorithmic overview
1113/// The high-level steps of this process are summarized below:
1114/// 1. Generate a series of random bytes.
1115/// 2. Derive an ephemeral key pair from (1).
1116/// 3. *Once per recipient:* Encrypt (1) using a shared secret derived from the private ephemeral
1117///    key (2) and the recipient's public identity key.
1118/// 4. *Once per recipient:* Add an authentication tag for (3) using a secret derived from the
1119///    sender's private identity key and the recipient's public identity key.
1120/// 5. Generate a symmetric key from (1) and use it to symmetrically encrypt the underlying
1121///    [`UnidentifiedSenderMessageContent`] via [AEAD encryption]. *This step is only performed once
1122///    per message, regardless of the number of recipients.*
1123/// 6. Send the public ephemeral key (2) to the server, along with the sequence of encrypted random
1124///    bytes (3) and authentication tags (4), and the single encrypted message (5).
1125///
1126/// [AEAD encryption]:
1127///    https://en.wikipedia.org/wiki/Authenticated_encryption#Authenticated_encryption_with_associated_data_(AEAD)
1128///
1129/// ## Pseudocode
1130///```text
1131/// ENCRYPT(message, R_i):
1132///     M = Random(32)
1133///     r = KDF(label_r, M, len=32)
1134///     K = KDF(label_K, M, len=32)
1135///     E = DeriveKeyPair(r)
1136///     for i in num_recipients:
1137///         C_i = KDF(label_DH, DH(E, R_i) || E.public || R_i.public, len=32) XOR M
1138///         AT_i = KDF(label_DH_s, DH(S, R_i) || E.public || C_i || S.public || R_i.public, len=16)
1139///     ciphertext = AEAD_Encrypt(K, message)
1140///     return E.public, C_i, AT_i, ciphertext
1141///
1142/// DECRYPT(E.public, C, AT, ciphertext):
1143///     M = KDF(label_DH, DH(E, R) || E.public || R.public, len=32) xor C
1144///     r = KDF(label_r, M, len=32)
1145///     K = KDF(label_K, M, len=32)
1146///     E' = DeriveKeyPair(r)
1147///     if E.public != E'.public:
1148///         return DecryptionError
1149///     message = AEAD_Decrypt(K, ciphertext) // includes S.public
1150///     AT' = KDF(label_DH_s, DH(S, R) || E.public || C || S.public || R.public, len=16)
1151///     if AT != AT':
1152///         return DecryptionError
1153///     return message
1154///```
1155///
1156/// # Routing messages to recipients
1157///
1158/// The server will split up the set of messages and securely route each individual [received
1159/// message][receiving] to its intended recipient. [`SealedSenderV2SentMessage`] can perform this
1160/// fan-out operation.
1161///
1162/// # Wire Format
1163/// Multi-recipient sealed-sender does not use protobufs for its payload format. Instead, it uses a
1164/// flat format marked with a [version byte](#the-version-byte). The format is different for
1165/// [sending] and [receiving]. The decrypted content is a protobuf-encoded
1166/// `UnidentifiedSenderMessage.Message` from `sealed_sender.proto`.
1167///
1168/// The public key used in Sealed Sender v2 is always a Curve25519 DJB key.
1169///
1170/// [sending]: #sent-messages
1171/// [receiving]: #received-messages
1172///
1173/// ## The version byte
1174///
1175/// Sealed sender messages (v1 and v2) in serialized form begin with a version [byte][u8]. This byte
1176/// has the form:
1177///
1178/// ```text
1179/// (requiredVersion << 4) | currentVersion
1180/// ```
1181///
1182/// v1 messages thus have a version byte of `0x11`. v2 messages have a version byte of `0x22` or
1183/// `0x23`. A hypothetical version byte `0x34` would indicate a message encoded as Sealed Sender v4,
1184/// but decodable by any client that supports Sealed Sender v3.
1185///
1186/// ## Received messages
1187///
1188/// ```text
1189/// ReceivedMessage {
1190///     version_byte: u8,
1191///     c: [u8; 32],
1192///     at: [u8; 16],
1193///     e_pub: [u8; 32],
1194///     message: [u8] // remaining bytes
1195/// }
1196/// ```
1197///
1198/// Each individual Sealed Sender message received from the server is decoded in the Signal client
1199/// by calling [`sealed_sender_decrypt`].
1200///
1201/// ## Sent messages
1202///
1203/// ```text
1204/// SentMessage {
1205///     version_byte: u8,
1206///     count: varint,
1207///     recipients: [PerRecipientData | ExcludedRecipient; count],
1208///     e_pub: [u8; 32],
1209///     message: [u8] // remaining bytes
1210/// }
1211///
1212/// PerRecipientData {
1213///     recipient: Recipient,
1214///     devices: [DeviceList], // last element's has_more = 0
1215///     c: [u8; 32],
1216///     at: [u8; 16],
1217/// }
1218///
1219/// ExcludedRecipient {
1220///     recipient: Recipient,
1221///     no_devices_marker: u8 = 0, // never a valid device ID
1222/// }
1223///
1224/// DeviceList {
1225///     device_id: u8,
1226///     has_more: u1, // high bit of following field
1227///     unused: u1,   // high bit of following field
1228///     registration_id: u14,
1229/// }
1230///
1231/// Recipient {
1232///     service_id_fixed_width_binary: [u8; 17],
1233/// }
1234/// ```
1235///
1236/// The varint encoding used is the same as [protobuf's][varint]. Values are unsigned.
1237/// Fixed-width-binary encoding is used for the [ServiceId] values.
1238/// Fixed-width integers are unaligned and in network byte order (big-endian).
1239///
1240/// [varint]: https://developers.google.com/protocol-buffers/docs/encoding#varints
1241pub async fn sealed_sender_multi_recipient_encrypt<
1242    R: Rng + CryptoRng,
1243    X: IntoIterator<Item = ServiceId>,
1244>(
1245    destinations: &[&ProtocolAddress],
1246    destination_sessions: &[&SessionRecord],
1247    excluded_recipients: X,
1248    usmc: &UnidentifiedSenderMessageContent,
1249    identity_store: &dyn IdentityKeyStore,
1250    rng: &mut R,
1251) -> Result<Vec<u8>>
1252where
1253    X::IntoIter: ExactSizeIterator,
1254{
1255    sealed_sender_multi_recipient_encrypt_impl(
1256        destinations,
1257        destination_sessions,
1258        excluded_recipients,
1259        usmc,
1260        identity_store,
1261        rng,
1262    )
1263    .await
1264}
1265
1266async fn sealed_sender_multi_recipient_encrypt_impl<
1267    R: Rng + CryptoRng,
1268    X: IntoIterator<Item = ServiceId>,
1269>(
1270    destinations: &[&ProtocolAddress],
1271    destination_sessions: &[&SessionRecord],
1272    excluded_recipients: X,
1273    usmc: &UnidentifiedSenderMessageContent,
1274    identity_store: &dyn IdentityKeyStore,
1275    rng: &mut R,
1276) -> Result<Vec<u8>>
1277where
1278    X::IntoIter: ExactSizeIterator,
1279{
1280    if destinations.len() != destination_sessions.len() {
1281        return Err(SignalProtocolError::InvalidArgument(
1282            "must have the same number of destination sessions as addresses".to_string(),
1283        ));
1284    }
1285
1286    let excluded_recipients = excluded_recipients.into_iter();
1287    let our_identity = identity_store.get_identity_key_pair().await?;
1288
1289    let m: [u8; sealed_sender_v2::MESSAGE_KEY_LEN] = rng.gen();
1290    let keys = sealed_sender_v2::DerivedKeys::new(&m);
1291    let e = keys.derive_e();
1292    let e_pub = &e.public_key;
1293
1294    // Encrypt the shared ciphertext using AES-GCM-SIV.
1295    let ciphertext = {
1296        let mut ciphertext = usmc.serialized()?.to_vec();
1297        let symmetric_authentication_tag = Aes256GcmSiv::new(&keys.derive_k().into())
1298            .encrypt_in_place_detached(
1299                // There's no nonce because the key is already one-use.
1300                &aes_gcm_siv::Nonce::default(),
1301                // And there's no associated data.
1302                &[],
1303                &mut ciphertext,
1304            )
1305            .expect("AES-GCM-SIV encryption should not fail with a just-computed key");
1306        // AES-GCM-SIV expects the authentication tag to be at the end of the ciphertext
1307        // when decrypting.
1308        ciphertext.extend_from_slice(&symmetric_authentication_tag);
1309        ciphertext
1310    };
1311
1312    // Group the destinations by name, and fetch identity keys once for each name. This optimizes
1313    // for the common case where all of a recipient's devices are included contiguously in the
1314    // destination list. (If the caller *doesn't* do this, that's on them; the message will still be
1315    // valid but some key material will be redundantly computed and encoded in the output.)
1316    let identity_keys_and_ranges: Vec<(IdentityKey, Range<usize>)> = {
1317        let mut identity_keys_and_ranges = vec![];
1318        for (_, mut next_group) in &destinations
1319            .iter()
1320            .enumerate()
1321            .chunk_by(|(_i, next)| next.name())
1322        {
1323            let (i, &destination) = next_group
1324                .next()
1325                .expect("at least one element in every group");
1326            // We can't put this before the call to `next()` because `count` consumes the rest of
1327            // the iterator.
1328            let count = 1 + next_group.count();
1329            let their_identity =
1330                identity_store
1331                    .get_identity(destination)
1332                    .await?
1333                    .ok_or_else(|| {
1334                        log::error!("missing identity key for {}", destination);
1335                        // Returned as a SessionNotFound error because (a) we don't have an identity
1336                        // error that includes the address, and (b) re-establishing the session should
1337                        // re-fetch the identity.
1338                        SignalProtocolError::SessionNotFound(destination.clone())
1339                    })?;
1340            identity_keys_and_ranges.push((their_identity, i..i + count));
1341        }
1342        identity_keys_and_ranges
1343    };
1344
1345    // Next, fan out the work of generating the per-recipient to multiple cores, since we do two key
1346    // agreements per recipient (though not per device) and those are CPU-bound.
1347
1348    // I know this looks complicated enough to pull out into a separate function altogether, but it
1349    // also depends on a bunch of local state: our identity, E and E_pub, and M.
1350    let serialize_recipient_destinations_into = |serialized: &mut Vec<u8>,
1351                                                 destinations: &[&ProtocolAddress],
1352                                                 sessions: &[&SessionRecord],
1353                                                 their_identity: &IdentityKey|
1354     -> Result<()> {
1355        let their_service_id = ServiceId::parse_from_service_id_string(destinations[0].name())
1356            .ok_or_else(|| {
1357                SignalProtocolError::InvalidArgument(format!(
1358                    "multi-recipient sealed sender requires recipients' ServiceId (not {})",
1359                    destinations[0].name()
1360                ))
1361            })?;
1362
1363        serialized.extend_from_slice(&their_service_id.service_id_fixed_width_binary());
1364
1365        debug_assert_eq!(
1366            destinations.len(),
1367            sessions.len(),
1368            "should be sliced with the same range"
1369        );
1370        let mut destinations_and_sessions = destinations.iter().zip(sessions);
1371        while let Some((&destination, session)) = destinations_and_sessions.next() {
1372            let their_registration_id = session.remote_registration_id().map_err(|_| {
1373                SignalProtocolError::InvalidState(
1374                    "sealed_sender_multi_recipient_encrypt",
1375                    format!(
1376                        concat!(
1377                            "cannot get registration ID from session with {} ",
1378                            "(maybe it was recently archived)"
1379                        ),
1380                        destination
1381                    ),
1382                )
1383            })?;
1384            if their_registration_id & u32::from(VALID_REGISTRATION_ID_MASK)
1385                != their_registration_id
1386            {
1387                return Err(SignalProtocolError::InvalidRegistrationId(
1388                    destination.clone(),
1389                    their_registration_id,
1390                ));
1391            }
1392            let mut their_registration_id =
1393                u16::try_from(their_registration_id).expect("just checked range");
1394            if destinations_and_sessions.len() > 0 {
1395                their_registration_id |= 0x8000;
1396            }
1397
1398            let device_id: u32 = destination.device_id().into();
1399            if device_id == 0 || device_id > MAX_VALID_DEVICE_ID {
1400                return Err(SignalProtocolError::InvalidState(
1401                    "sealed_sender_multi_recipient_encrypt",
1402                    format!("destination {destination} has invalid device ID"),
1403                ));
1404            }
1405            serialized.push(device_id.try_into().expect("just checked range"));
1406            serialized.extend_from_slice(&their_registration_id.to_be_bytes());
1407        }
1408
1409        let c_i = sealed_sender_v2::apply_agreement_xor(
1410            &e,
1411            their_identity.public_key(),
1412            Direction::Sending,
1413            &m,
1414        )?;
1415        serialized.extend_from_slice(&c_i);
1416
1417        let at_i = sealed_sender_v2::compute_authentication_tag(
1418            &our_identity,
1419            their_identity,
1420            Direction::Sending,
1421            e_pub,
1422            &c_i,
1423        )?;
1424        serialized.extend_from_slice(&at_i);
1425
1426        Ok(())
1427    };
1428
1429    let process_chunk =
1430        |serialized: &mut Vec<u8>, chunk: &[(IdentityKey, Range<usize>)]| -> Result<()> {
1431            for (their_identity, destination_range) in chunk {
1432                let these_destinations = &destinations[destination_range.clone()];
1433                let these_sessions = &destination_sessions[destination_range.clone()];
1434                serialize_recipient_destinations_into(
1435                    serialized,
1436                    these_destinations,
1437                    these_sessions,
1438                    their_identity,
1439                )?;
1440            }
1441            Ok(())
1442        };
1443
1444    let mut serialized: Vec<u8> = vec![SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION];
1445
1446    let count_of_recipients = identity_keys_and_ranges.len() + excluded_recipients.len();
1447    prost::encode_length_delimiter(count_of_recipients, &mut serialized)
1448        .expect("can always resize a Vec");
1449
1450    // Fan out to N threads, like Rayon would. But don't bother for less than 6 items.
1451    let parallelism = std::thread::available_parallelism()
1452        .map(usize::from)
1453        .unwrap_or(1);
1454    let chunk_size = std::cmp::max(
1455        6,
1456        crate::utils::div_ceil(identity_keys_and_ranges.len(), parallelism),
1457    );
1458
1459    if parallelism == 1 || chunk_size >= identity_keys_and_ranges.len() {
1460        process_chunk(&mut serialized, &identity_keys_and_ranges)?;
1461    } else {
1462        let mut chunks = identity_keys_and_ranges.chunks(chunk_size);
1463        // We'll process the first chunk on the current thread once we've spawned all the others.
1464        let first_chunk = chunks.next().expect("at least one chunk, tested above");
1465
1466        let mut all_outputs = Vec::new();
1467        all_outputs.resize_with(chunks.len(), || Ok(vec![]));
1468
1469        rayon::scope(|scope| -> Result<()> {
1470            let mut outputs = &mut all_outputs[..];
1471            for chunk in chunks {
1472                let (next_output, remaining_outputs) = outputs
1473                    .split_first_mut()
1474                    .expect("as many outputs as remaining chunks");
1475                scope.spawn(|_| {
1476                    let mut serialized = vec![];
1477                    *next_output = process_chunk(&mut serialized, chunk).map(|_| serialized);
1478                });
1479                outputs = remaining_outputs;
1480            }
1481
1482            process_chunk(&mut serialized, first_chunk)
1483        })?;
1484
1485        for output in all_outputs {
1486            serialized.extend(output?);
1487        }
1488    }
1489
1490    for excluded in excluded_recipients {
1491        serialized.extend_from_slice(&excluded.service_id_fixed_width_binary());
1492        serialized.push(0);
1493    }
1494
1495    serialized.extend_from_slice(e_pub.public_key_bytes()?);
1496    serialized.extend_from_slice(&ciphertext);
1497
1498    Ok(serialized)
1499}
1500
1501/// Represents a single recipient in an SSv2 SentMessage.
1502///
1503/// See [`SealedSenderV2SentMessage`].
1504pub struct SealedSenderV2SentMessageRecipient<'a> {
1505    /// The recipient's devices and their registration IDs. May be empty.
1506    pub devices: Vec<(DeviceId, u16)>,
1507    /// A concatenation of the `C_i` and `AT_i` SSv2 fields for this recipient, or an empty slice if
1508    /// the recipient has no devices.
1509    c_and_at: &'a [u8],
1510}
1511
1512/// A parsed representation of a Sealed Sender v2 SentMessage.
1513///
1514/// This only parses enough to fan out the message as a series of ReceivedMessages.
1515pub struct SealedSenderV2SentMessage<'a> {
1516    /// The full message, for calculating offsets.
1517    full_message: &'a [u8],
1518    /// The version byte at the head of the message.
1519    pub version: u8,
1520    /// The parsed list of recipients, grouped by ServiceId.
1521    ///
1522    /// The map is ordered by when a recipient first appears in the full message, even if they
1523    /// appear again later with more devices. This makes iteration over the full set of recipients
1524    /// deterministic.
1525    pub recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>>,
1526    /// A concatenation of the `e_pub` and `message` SSv2 fields for this recipient.
1527    shared_bytes: &'a [u8],
1528}
1529
1530impl<'a> SealedSenderV2SentMessage<'a> {
1531    /// Parses the message, or produces an error if the message is invalid.
1532    pub fn parse(data: &'a [u8]) -> Result<Self> {
1533        if data.is_empty() {
1534            return Err(SignalProtocolError::InvalidSealedSenderMessage(
1535                "Message was empty".to_owned(),
1536            ));
1537        }
1538
1539        let version = data[0];
1540        if !matches!(
1541            version,
1542            SEALED_SENDER_V2_UUID_FULL_VERSION | SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION
1543        ) {
1544            return Err(SignalProtocolError::UnknownSealedSenderVersion(version));
1545        }
1546
1547        fn advance<'a, const N: usize>(buf: &mut &'a [u8]) -> Result<&'a [u8; N]> {
1548            if N > buf.len() {
1549                return Err(SignalProtocolError::InvalidProtobufEncoding);
1550            }
1551            // TODO: Replace with split_array_ref or split_first_chunk when stabilized.
1552            let (prefix, remaining) = buf.split_at(N);
1553            *buf = remaining;
1554            Ok(prefix.try_into().expect("checked length"))
1555        }
1556        fn decode_varint(buf: &mut &[u8]) -> Result<u32> {
1557            let result: usize = prost::decode_length_delimiter(*buf)
1558                .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1559            *buf = &buf[prost::length_delimiter_len(result)..];
1560            result
1561                .try_into()
1562                .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)
1563        }
1564
1565        let mut remaining = &data[1..];
1566        let recipient_count = decode_varint(&mut remaining)?
1567            .try_into()
1568            .unwrap_or(usize::MAX);
1569
1570        // Cap our preallocated capacity; anything higher than this is *probably* a mistake, but
1571        // could just be a very large message.
1572        // (Callers can of course refuse to process messages with too many recipients.)
1573        let mut recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>> =
1574            IndexMap::with_capacity(std::cmp::min(recipient_count as usize, 6000));
1575        for _ in 0..recipient_count {
1576            let service_id = if version == SEALED_SENDER_V2_UUID_FULL_VERSION {
1577                // The original version of SSv2 assumed ACIs here, and only encoded the raw UUID.
1578                ServiceId::from(Aci::from_uuid_bytes(*advance::<
1579                    { std::mem::size_of::<uuid::Bytes>() },
1580                >(&mut remaining)?))
1581            } else {
1582                ServiceId::parse_from_service_id_fixed_width_binary(advance::<
1583                    { std::mem::size_of::<ServiceIdFixedWidthBinaryBytes>() },
1584                >(
1585                    &mut remaining
1586                )?)
1587                .ok_or(SignalProtocolError::InvalidProtobufEncoding)?
1588            };
1589            let mut devices = Vec::new();
1590            loop {
1591                let device_id: u32 = advance::<1>(&mut remaining)?[0].into();
1592                if device_id == 0 {
1593                    if !devices.is_empty() {
1594                        return Err(SignalProtocolError::InvalidProtobufEncoding);
1595                    }
1596                    break;
1597                }
1598                if device_id > MAX_VALID_DEVICE_ID {
1599                    return Err(SignalProtocolError::InvalidProtobufEncoding);
1600                }
1601                let registration_id_and_has_more =
1602                    u16::from_be_bytes(*advance::<2>(&mut remaining)?);
1603                devices.push((
1604                    device_id.into(),
1605                    registration_id_and_has_more & VALID_REGISTRATION_ID_MASK,
1606                ));
1607                let has_more = (registration_id_and_has_more & 0x8000) != 0;
1608                if !has_more {
1609                    break;
1610                }
1611            }
1612
1613            let c_and_at: &[u8] = if devices.is_empty() {
1614                &[]
1615            } else {
1616                advance::<{ sealed_sender_v2::MESSAGE_KEY_LEN + sealed_sender_v2::AUTH_TAG_LEN }>(
1617                    &mut remaining,
1618                )?
1619            };
1620
1621            match recipients.entry(service_id) {
1622                indexmap::map::Entry::Occupied(mut existing) => {
1623                    if existing.get().devices.is_empty() || devices.is_empty() {
1624                        return Err(SignalProtocolError::InvalidSealedSenderMessage(
1625                            "recipient redundantly encoded as empty".to_owned(),
1626                        ));
1627                    }
1628                    // We don't unique the recipient devices; the server is going to check this
1629                    // against the account's canonical list of devices anyway.
1630                    existing.get_mut().devices.extend(devices);
1631                    // Note that we don't check that c_and_at matches. Any case where it doesn't
1632                    // match would already result in a decryption error for at least one of the
1633                    // recipient's devices, though.
1634                }
1635                indexmap::map::Entry::Vacant(entry) => {
1636                    entry.insert(SealedSenderV2SentMessageRecipient { devices, c_and_at });
1637                }
1638            };
1639        }
1640
1641        if remaining.len() < curve::curve25519::PUBLIC_KEY_LENGTH {
1642            return Err(SignalProtocolError::InvalidProtobufEncoding);
1643        }
1644
1645        Ok(Self {
1646            full_message: data,
1647            version,
1648            recipients,
1649            shared_bytes: remaining,
1650        })
1651    }
1652
1653    /// Returns a slice of slices that, when concatenated, form the ReceivedMessage appropriate for
1654    /// `recipient`.
1655    ///
1656    /// If `recipient` is not one of the recipients in `self`, the resulting message will not be
1657    /// decryptable.
1658    #[inline]
1659    pub fn received_message_parts_for_recipient(
1660        &self,
1661        recipient: &SealedSenderV2SentMessageRecipient<'a>,
1662    ) -> impl AsRef<[&[u8]]> {
1663        // Why not use `IntoIterator<Item = &[u8]>` as the result? Because the `concat` method on
1664        // slices is more efficient when the caller just wants a `Vec<u8>`.
1665        // Why use SEALED_SENDER_V2_UUID_FULL_VERSION as the version? Because the ReceivedMessage
1666        // format hasn't changed since then.
1667        [
1668            &[SEALED_SENDER_V2_UUID_FULL_VERSION],
1669            recipient.c_and_at,
1670            self.shared_bytes,
1671        ]
1672    }
1673
1674    /// Returns the offset of `addr` within `self.full_message`, or `None` if `addr` does not lie
1675    /// within `self.full_message`.
1676    ///
1677    /// A stripped-down version of [a dormant Rust RFC][subslice-offset].
1678    ///
1679    /// [subslice-offset]: https://github.com/rust-lang/rfcs/pull/2796
1680    #[inline]
1681    fn offset_within_full_message(&self, addr: *const u8) -> Option<usize> {
1682        // Arithmetic on addresses is valid for offsets within a byte array.
1683        // If addr < start, we'll wrap around to a very large value, which will be out of range just
1684        // like if addr > end.
1685        let offset = (addr as usize).wrapping_sub(self.full_message.as_ptr() as usize);
1686        // We *do* want to allow the "one-past-the-end" offset here, because the offset might be
1687        // used as part of a range (e.g. 0..end).
1688        if offset <= self.full_message.len() {
1689            debug_assert!(
1690                offset == self.full_message.len() || std::ptr::eq(&self.full_message[offset], addr)
1691            );
1692            Some(offset)
1693        } else {
1694            None
1695        }
1696    }
1697
1698    /// Returns the range within the full message of `recipient`'s user-specific key material.
1699    ///
1700    /// This can be concatenated as `[version, recipient_key_material, shared_bytes]` to produce a
1701    /// valid SSv2 ReceivedMessage, the payload delivered to recipients.
1702    ///
1703    /// **Panics** if `recipient` is not one of the recipients in `self`.
1704    pub fn range_for_recipient_key_material(
1705        &self,
1706        recipient: &SealedSenderV2SentMessageRecipient<'a>,
1707    ) -> Range<usize> {
1708        if recipient.c_and_at.is_empty() {
1709            return 0..0;
1710        }
1711        let offset = self
1712            .offset_within_full_message(recipient.c_and_at.as_ptr())
1713            .expect("'recipient' is not one of the recipients in this SealedSenderV2SentMessage");
1714        let end_offset = offset.saturating_add(recipient.c_and_at.len());
1715        assert!(
1716            end_offset <= self.full_message.len(),
1717            "invalid 'recipient' passed to range_for_recipient_key_material"
1718        );
1719        offset..end_offset
1720    }
1721
1722    /// Returns the offset of the shared bytes within the full message.
1723    ///
1724    /// This can be concatenated as `[version, recipient_key_material, shared_bytes]` to produce a
1725    /// valid SSv2 ReceivedMessage, the payload delivered to recipients.
1726    pub fn offset_of_shared_bytes(&self) -> usize {
1727        debug_assert_eq!(
1728            self.full_message.as_ptr_range().end,
1729            self.shared_bytes.as_ptr_range().end,
1730            "SealedSenderV2SentMessage parsed incorrectly"
1731        );
1732        self.offset_within_full_message(self.shared_bytes.as_ptr())
1733            .expect("constructed correctly")
1734    }
1735}
1736
1737/// Decrypt the payload of a sealed-sender message in either the v1 or v2 format.
1738///
1739/// [`sealed_sender_decrypt`] consumes the output of this method to validate the sender's identity
1740/// before decrypting the underlying message.
1741pub async fn sealed_sender_decrypt_to_usmc(
1742    ciphertext: &[u8],
1743    identity_store: &dyn IdentityKeyStore,
1744) -> Result<UnidentifiedSenderMessageContent> {
1745    let our_identity = identity_store.get_identity_key_pair().await?;
1746
1747    match UnidentifiedSenderMessage::deserialize(ciphertext)? {
1748        UnidentifiedSenderMessage::V1 {
1749            ephemeral_public,
1750            encrypted_static,
1751            encrypted_message,
1752        } => {
1753            let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
1754                &our_identity.into(),
1755                &ephemeral_public,
1756                Direction::Receiving,
1757            )?;
1758
1759            let message_key_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1760                &encrypted_static,
1761                &eph_keys.cipher_key,
1762                &eph_keys.mac_key,
1763            ) {
1764                Ok(plaintext) => plaintext,
1765                Err(crypto::DecryptionError::BadKeyOrIv) => {
1766                    unreachable!("just derived these keys; they should be valid");
1767                }
1768                Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1769                    log::error!("failed to decrypt sealed sender v1 message key: {}", msg);
1770                    return Err(SignalProtocolError::InvalidSealedSenderMessage(
1771                        "failed to decrypt sealed sender v1 message key".to_owned(),
1772                    ));
1773                }
1774            };
1775
1776            let static_key = PublicKey::try_from(&message_key_bytes[..])?;
1777
1778            let static_keys = sealed_sender_v1::StaticKeys::calculate(
1779                &our_identity,
1780                &static_key,
1781                &eph_keys.chain_key,
1782                &encrypted_static,
1783            )?;
1784
1785            let message_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1786                &encrypted_message,
1787                &static_keys.cipher_key,
1788                &static_keys.mac_key,
1789            ) {
1790                Ok(plaintext) => plaintext,
1791                Err(crypto::DecryptionError::BadKeyOrIv) => {
1792                    unreachable!("just derived these keys; they should be valid");
1793                }
1794                Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1795                    log::error!(
1796                        "failed to decrypt sealed sender v1 message contents: {}",
1797                        msg
1798                    );
1799                    return Err(SignalProtocolError::InvalidSealedSenderMessage(
1800                        "failed to decrypt sealed sender v1 message contents".to_owned(),
1801                    ));
1802                }
1803            };
1804
1805            let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1806
1807            if !bool::from(message_key_bytes.ct_eq(&usmc.sender()?.key()?.serialize())) {
1808                return Err(SignalProtocolError::InvalidSealedSenderMessage(
1809                    "sender certificate key does not match message key".to_string(),
1810                ));
1811            }
1812
1813            Ok(usmc)
1814        }
1815        UnidentifiedSenderMessage::V2 {
1816            ephemeral_public,
1817            encrypted_message_key,
1818            authentication_tag,
1819            encrypted_message,
1820        } => {
1821            let encrypted_message_key: [u8; sealed_sender_v2::MESSAGE_KEY_LEN] =
1822                encrypted_message_key.as_ref().try_into().map_err(|_| {
1823                    SignalProtocolError::InvalidSealedSenderMessage(format!(
1824                        "encrypted message key had incorrect length {} (should be {})",
1825                        encrypted_message_key.len(),
1826                        sealed_sender_v2::MESSAGE_KEY_LEN
1827                    ))
1828                })?;
1829            let m = sealed_sender_v2::apply_agreement_xor(
1830                &our_identity.into(),
1831                &ephemeral_public,
1832                Direction::Receiving,
1833                &encrypted_message_key,
1834            )?;
1835
1836            let keys = sealed_sender_v2::DerivedKeys::new(&m);
1837            if !bool::from(keys.derive_e().public_key.ct_eq(&ephemeral_public)) {
1838                return Err(SignalProtocolError::InvalidSealedSenderMessage(
1839                    "derived ephemeral key did not match key provided in message".to_string(),
1840                ));
1841            }
1842
1843            let mut message_bytes = encrypted_message.into_vec();
1844            Aes256GcmSiv::new(&keys.derive_k().into())
1845                .decrypt_in_place(
1846                    // There's no nonce because the key is already one-use.
1847                    &aes_gcm_siv::Nonce::default(),
1848                    // And there's no associated data.
1849                    &[],
1850                    &mut message_bytes,
1851                )
1852                .map_err(|err| {
1853                    SignalProtocolError::InvalidSealedSenderMessage(format!(
1854                        "failed to decrypt inner message: {}",
1855                        err
1856                    ))
1857                })?;
1858
1859            let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1860
1861            let at = sealed_sender_v2::compute_authentication_tag(
1862                &our_identity,
1863                &usmc.sender()?.key()?.into(),
1864                Direction::Receiving,
1865                &ephemeral_public,
1866                &encrypted_message_key,
1867            )?;
1868            if !bool::from(authentication_tag.ct_eq(&at)) {
1869                return Err(SignalProtocolError::InvalidSealedSenderMessage(
1870                    "sender certificate key does not match authentication tag".to_string(),
1871                ));
1872            }
1873
1874            Ok(usmc)
1875        }
1876    }
1877}
1878
1879#[derive(Debug)]
1880pub struct SealedSenderDecryptionResult {
1881    pub sender_uuid: String,
1882    pub sender_e164: Option<String>,
1883    pub device_id: DeviceId,
1884    pub message: Vec<u8>,
1885}
1886
1887impl SealedSenderDecryptionResult {
1888    pub fn sender_uuid(&self) -> Result<&str> {
1889        Ok(self.sender_uuid.as_ref())
1890    }
1891
1892    pub fn sender_e164(&self) -> Result<Option<&str>> {
1893        Ok(self.sender_e164.as_deref())
1894    }
1895
1896    pub fn device_id(&self) -> Result<DeviceId> {
1897        Ok(self.device_id)
1898    }
1899
1900    pub fn message(&self) -> Result<&[u8]> {
1901        Ok(self.message.as_ref())
1902    }
1903}
1904
1905/// Decrypt a Sealed Sender message `ciphertext` in either the v1 or v2 format, validate its sender
1906/// certificate, and then decrypt the inner message payload.
1907///
1908/// This method calls [`sealed_sender_decrypt_to_usmc`] to extract the sender information, including
1909/// the embedded [`SenderCertificate`]. The sender certificate (signed by the [`ServerCertificate`])
1910/// is then validated against the `trust_root` baked into the client to ensure that the sender's
1911/// identity was not forged.
1912#[allow(clippy::too_many_arguments)]
1913pub async fn sealed_sender_decrypt(
1914    ciphertext: &[u8],
1915    trust_root: &PublicKey,
1916    timestamp: Timestamp,
1917    local_e164: Option<String>,
1918    local_uuid: String,
1919    local_device_id: DeviceId,
1920    identity_store: &mut dyn IdentityKeyStore,
1921    session_store: &mut dyn SessionStore,
1922    pre_key_store: &mut dyn PreKeyStore,
1923    signed_pre_key_store: &dyn SignedPreKeyStore,
1924    kyber_pre_key_store: &mut dyn KyberPreKeyStore,
1925) -> Result<SealedSenderDecryptionResult> {
1926    let usmc = sealed_sender_decrypt_to_usmc(ciphertext, identity_store).await?;
1927
1928    if !usmc.sender()?.validate(trust_root, timestamp)? {
1929        return Err(SignalProtocolError::InvalidSealedSenderMessage(
1930            "trust root validation failed".to_string(),
1931        ));
1932    }
1933
1934    let is_local_uuid = local_uuid == usmc.sender()?.sender_uuid()?;
1935
1936    let is_local_e164 = match (local_e164, usmc.sender()?.sender_e164()?) {
1937        (Some(l), Some(s)) => l == s,
1938        (_, _) => false,
1939    };
1940
1941    if (is_local_e164 || is_local_uuid) && usmc.sender()?.sender_device_id()? == local_device_id {
1942        return Err(SignalProtocolError::SealedSenderSelfSend);
1943    }
1944
1945    let mut rng = rand::rngs::OsRng;
1946
1947    let remote_address = ProtocolAddress::new(
1948        usmc.sender()?.sender_uuid()?.to_string(),
1949        usmc.sender()?.sender_device_id()?,
1950    );
1951
1952    let message = match usmc.msg_type()? {
1953        CiphertextMessageType::Whisper => {
1954            let ctext = SignalMessage::try_from(usmc.contents()?)?;
1955            session_cipher::message_decrypt_signal(
1956                &ctext,
1957                &remote_address,
1958                session_store,
1959                identity_store,
1960                &mut rng,
1961            )
1962            .await?
1963        }
1964        CiphertextMessageType::PreKey => {
1965            let ctext = PreKeySignalMessage::try_from(usmc.contents()?)?;
1966            session_cipher::message_decrypt_prekey(
1967                &ctext,
1968                &remote_address,
1969                session_store,
1970                identity_store,
1971                pre_key_store,
1972                signed_pre_key_store,
1973                kyber_pre_key_store,
1974                &mut rng,
1975            )
1976            .await?
1977        }
1978        msg_type => {
1979            return Err(SignalProtocolError::InvalidMessage(
1980                msg_type,
1981                "unexpected message type for sealed_sender_decrypt",
1982            ));
1983        }
1984    };
1985
1986    Ok(SealedSenderDecryptionResult {
1987        sender_uuid: usmc.sender()?.sender_uuid()?.to_string(),
1988        sender_e164: usmc.sender()?.sender_e164()?.map(|s| s.to_string()),
1989        device_id: usmc.sender()?.sender_device_id()?,
1990        message,
1991    })
1992}
1993
1994#[test]
1995fn test_lossless_round_trip() -> Result<()> {
1996    let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
1997
1998    // To test a hypothetical addition of a new field:
1999    //
2000    // Step 1: temporarily add a new field to the .proto.
2001    //
2002    //    --- a/rust/protocol/src/proto/sealed_sender.proto
2003    //    +++ b/rust/protocol/src/proto/sealed_sender.proto
2004    //    @@ -26,3 +26,4 @@ message SenderCertificate {
2005    //             optional bytes             identityKey   = 4;
2006    //             optional ServerCertificate signer        = 5;
2007    //    +        optional string someFakeField = 999;
2008    //     }
2009    //
2010    // Step 2: Add `some_fake_field: None` to the above construction of
2011    // proto::sealed_sender::sender_certificate::Certificate.
2012    //
2013    // Step 3: Serialize and print out the new fixture data (uncomment the following)
2014    //
2015    // let mut rng = rand::rngs::OsRng;
2016    // let server_key = KeyPair::generate(&mut rng);
2017    // let sender_key = KeyPair::generate(&mut rng);
2018    //
2019    // let server_cert =
2020    //     ServerCertificate::new(1, server_key.public_key, &trust_root, &mut rng)?;
2021    //
2022    // let sender_cert = proto::sealed_sender::sender_certificate::Certificate {
2023    //     sender_uuid: Some("aaaaaaaa-7000-11eb-b32a-33b8a8a487a6".to_string()),
2024    //     sender_e164: None,
2025    //     sender_device: Some(1),
2026    //     expires: Some(31337),
2027    //     identity_key: Some(sender_key.public_key.serialize().to_vec()),
2028    //     signer: Some(server_cert.to_protobuf()?),
2029    //     some_fake_field: Some("crashing right down".to_string()),
2030    // };
2031    //
2032    // eprintln!("<SNIP>");
2033    // let serialized_certificate_data = sender_cert.encode_to_vec();
2034    // let certificate_data_encoded = hex::encode(&serialized_certificate_data);
2035    // eprintln!("let certificate_data_encoded = \"{}\";", certificate_data_encoded);
2036    //
2037    // let certificate_signature = server_key.calculate_signature(&serialized_certificate_data, &mut rng)?;
2038    // let certificate_signature_encoded = hex::encode(certificate_signature);
2039    // eprintln!("let certificate_signature_encoded = \"{}\";", certificate_signature_encoded);
2040
2041    // Step 4: update the following *_encoded fixture data with the new values from above.
2042    let certificate_data_encoded = "100119697a0000000000002221056c9d1f8deb82b9a898f9c277a1b74989ec009afb5c0acb5e8e69e3d5ca29d6322a690a2508011221053b03ca070e6f6b2f271d32f27321689cdf4e59b106c10b58fbe15063ed868a5a124024bc92954e52ad1a105b5bda85c9db410dcfeb42a671b45a523b3a46e9594a8bde0efc671d8e8e046b32c67f59b80a46ffdf24071850779bc21325107902af89322461616161616161612d373030302d313165622d623332612d333362386138613438376136ba3e136372617368696e6720726967687420646f776e";
2043    let certificate_signature_encoded = "a22d8f86f5d00794f319add821e342c6ffffb6b34f741e569f8b321ab0255f2d1757ecf648e53a3602cae8f09b3fc80dcf27534d67efd272b6739afc31f75c8c";
2044
2045    // The rest of the test should be stable.
2046    let certificate_data = hex::decode(certificate_data_encoded).expect("valid hex");
2047    let certificate_signature = hex::decode(certificate_signature_encoded).expect("valid hex");
2048
2049    let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2050        certificate: Some(certificate_data),
2051        signature: Some(certificate_signature),
2052    };
2053
2054    let sender_certificate =
2055        SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2056    assert!(sender_certificate.validate(
2057        &trust_root.public_key()?,
2058        Timestamp::from_epoch_millis(31336)
2059    )?);
2060    Ok(())
2061}