libsignal_service/
envelope.rs

1use aes::cipher::block_padding::Pkcs7;
2use aes::cipher::{BlockDecryptMut, KeyIvInit};
3use libsignal_protocol::ServiceId;
4use prost::Message;
5
6use crate::{configuration::SignalingKey, push_service::ServiceError};
7
8pub use crate::proto::Envelope;
9
10impl Envelope {
11    #[tracing::instrument(skip(input, signaling_key), fields(signaling_key_present = signaling_key.is_some(), input_size = input.len()))]
12    pub fn decrypt(
13        input: &[u8],
14        signaling_key: Option<&SignalingKey>,
15        is_signaling_key_encrypted: bool,
16    ) -> Result<Self, ServiceError> {
17        if !is_signaling_key_encrypted {
18            tracing::trace!("Envelope::decrypt: not encrypted");
19            Ok(Envelope::decode(input)?)
20        } else {
21            let signaling_key = signaling_key
22                .expect("signaling_key required to decrypt envelopes");
23            tracing::trace!("Envelope::decrypt: decrypting");
24            if input.len() < VERSION_LENGTH
25                || input[VERSION_OFFSET] != SUPPORTED_VERSION
26            {
27                return Err(ServiceError::InvalidFrame {
28                    reason: "unsupported signaling cryptogram version",
29                });
30            }
31
32            let aes_key = &signaling_key[..CIPHER_KEY_SIZE];
33            let mac_key = &signaling_key[CIPHER_KEY_SIZE..];
34            let mac = &input[(input.len() - MAC_SIZE)..];
35            let input_for_mac = &input[..(input.len() - MAC_SIZE)];
36            let iv = &input[IV_OFFSET..(IV_OFFSET + IV_LENGTH)];
37            debug_assert_eq!(mac_key.len(), MAC_KEY_SIZE);
38            debug_assert_eq!(aes_key.len(), CIPHER_KEY_SIZE);
39            debug_assert_eq!(iv.len(), IV_LENGTH);
40
41            // Verify MAC
42            use hmac::{Hmac, Mac};
43            use sha2::Sha256;
44            let mut verifier = Hmac::<Sha256>::new_from_slice(mac_key)
45                .expect("Hmac can take any size key");
46            verifier.update(input_for_mac);
47            // XXX: possible timing attack, but we need the bytes for a
48            // truncated view...
49            let our_mac = verifier.finalize().into_bytes();
50            if &our_mac[..MAC_SIZE] != mac {
51                return Err(ServiceError::MacError);
52            }
53
54            // libsignal-service-java uses Pkcs5,
55            // but that should not matter.
56            // https://crypto.stackexchange.com/questions/9043/what-is-the-difference-between-pkcs5-padding-and-pkcs7-padding
57            let cipher =
58                cbc::Decryptor::<aes::Aes256>::new(aes_key.into(), iv.into());
59            let input = &input[CIPHERTEXT_OFFSET..(input.len() - MAC_SIZE)];
60            let input = cipher
61                .decrypt_padded_vec_mut::<Pkcs7>(input)
62                .expect("decryption");
63
64            tracing::trace!("Envelope::decrypt: decrypted, decoding");
65
66            Ok(Envelope::decode(&input as &[u8])?)
67        }
68    }
69
70    pub fn is_unidentified_sender(&self) -> bool {
71        self.r#type() == crate::proto::envelope::Type::UnidentifiedSender
72    }
73
74    pub fn is_prekey_signal_message(&self) -> bool {
75        self.r#type() == crate::proto::envelope::Type::PrekeyBundle
76    }
77
78    pub fn is_receipt(&self) -> bool {
79        self.r#type() == crate::proto::envelope::Type::Receipt
80    }
81
82    pub fn is_signal_message(&self) -> bool {
83        self.r#type() == crate::proto::envelope::Type::Ciphertext
84    }
85
86    pub fn is_urgent(&self) -> bool {
87        // SignalServiceEnvelopeEntity: return urgent == null || urgent;
88        self.urgent.unwrap_or(true)
89    }
90
91    pub fn is_story(&self) -> bool {
92        self.story.unwrap_or(false)
93    }
94
95    pub fn source_address(&self) -> ServiceId {
96        match self.source_service_id.as_deref() {
97            Some(service_id) => {
98                ServiceId::parse_from_service_id_string(service_id)
99                    .expect("invalid source ProtocolAddress UUID or prefix")
100            },
101            None => panic!("source_service_id is set"),
102        }
103    }
104
105    pub fn destination_address(&self) -> ServiceId {
106        match self.destination_service_id.as_deref() {
107            Some(service_id) => ServiceId::parse_from_service_id_string(
108                service_id,
109            )
110            .expect("invalid destination ProtocolAddress UUID or prefix"),
111            None => panic!("destination_address is set"),
112        }
113    }
114}
115
116pub(crate) const SUPPORTED_VERSION: u8 = 1;
117pub(crate) const CIPHER_KEY_SIZE: usize = 32;
118pub(crate) const MAC_KEY_SIZE: usize = 20;
119pub(crate) const MAC_SIZE: usize = 10;
120
121pub(crate) const VERSION_OFFSET: usize = 0;
122pub(crate) const VERSION_LENGTH: usize = 1;
123pub(crate) const IV_OFFSET: usize = VERSION_OFFSET + VERSION_LENGTH;
124pub(crate) const IV_LENGTH: usize = 16;
125pub(crate) const CIPHERTEXT_OFFSET: usize = IV_OFFSET + IV_LENGTH;
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[test]
132    fn decrypt_envelope() {
133        // This is a real message, reencrypted with the zero-key.
134        let body = [
135            1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 32, 12, 100,
136            26, 157, 130, 210, 254, 174, 87, 45, 238, 126, 68, 39, 188, 171,
137            156, 16, 10, 138, 233, 73, 202, 52, 125, 102, 121, 182, 71, 148, 8,
138            3, 134, 149, 154, 67, 116, 40, 146, 253, 242, 196, 139, 203, 14,
139            174, 254, 78, 27, 47, 108, 60, 202, 60, 42, 210, 242, 58, 13, 185,
140            67, 147, 166, 191, 71, 164, 128, 81, 177, 199, 147, 252, 162, 229,
141            143, 98, 141, 222, 46, 83, 109, 82, 196, 109, 161, 40, 108, 207,
142            82, 53, 162, 205, 171, 33, 140, 5, 74, 76, 150, 22, 122, 176, 189,
143            228, 176, 234, 176, 13, 118, 181, 134, 35, 133, 164, 160, 205, 176,
144            32, 188, 185, 166, 73, 24, 164, 20, 187, 2, 226, 186, 238, 98, 57,
145            51, 76, 156, 83, 113, 72, 184, 50, 220, 49, 138, 46, 36, 4, 49,
146            215, 66, 173, 58, 139, 187, 6, 252, 97, 191, 69, 246, 82, 48, 177,
147            11, 149, 168, 93, 15, 170, 125, 131, 101, 103, 253, 177, 165, 71,
148            85, 219, 207, 106, 12, 58, 47, 159, 33, 243, 107, 6, 117, 141, 209,
149            115, 207, 19, 236, 137, 195, 230, 167, 225, 172, 99, 204, 113, 125,
150            69, 125, 97, 252, 90, 248, 198, 175, 240, 187, 246, 164, 220, 102,
151            7, 224, 124, 28, 170, 6, 4, 137, 155, 233, 85, 125, 93, 119, 97,
152            183, 114, 193, 10, 184, 191, 202, 109, 97, 116, 194, 152, 40, 46,
153            202, 49, 195, 138, 14, 2, 255, 44, 107, 160, 45, 150, 6, 78, 145,
154            99,
155        ];
156
157        let signaling_key = [0u8; 52];
158        let envelope =
159            Envelope::decrypt(&body, Some(&signaling_key), true).unwrap();
160        assert_eq!(envelope.server_timestamp(), 1594373582421);
161        assert_eq!(envelope.timestamp(), 1594373580977);
162        assert_eq!(
163            envelope.content(),
164            [
165                51, 10, 33, 5, 239, 254, 183, 191, 204, 223, 85, 150, 43, 192,
166                240, 57, 46, 189, 153, 7, 48, 17, 9, 166, 185, 157, 205, 181,
167                66, 235, 99, 221, 114, 58, 187, 117, 16, 76, 24, 0, 34, 160, 1,
168                85, 61, 73, 83, 99, 213, 160, 109, 122, 125, 204, 137, 178,
169                237, 146, 87, 183, 107, 33, 213, 234, 64, 152, 132, 122, 173,
170                25, 33, 4, 65, 20, 134, 117, 62, 116, 80, 151, 18, 132, 187,
171                101, 235, 208, 74, 78, 214, 66, 59, 71, 171, 124, 167, 217,
172                157, 36, 194, 156, 12, 50, 239, 185, 230, 253, 38, 107, 106,
173                149, 194, 39, 214, 35, 245, 58, 216, 250, 225, 150, 170, 26,
174                241, 153, 133, 173, 197, 194, 27, 127, 56, 77, 119, 242, 26,
175                252, 168, 61, 221, 44, 76, 128, 69, 27, 203, 6, 173, 193, 179,
176                69, 27, 243, 36, 185, 181, 157, 41, 23, 72, 113, 40, 209, 46,
177                189, 63, 167, 156, 148, 118, 76, 153, 91, 40, 179, 180, 245,
178                193, 123, 180, 47, 115, 220, 191, 148, 245, 116, 32, 194, 232,
179                55, 13, 0, 217, 52, 116, 21, 48, 244, 17, 222, 26, 240, 31,
180                236, 199, 237, 94, 255, 93, 137, 192,
181            ]
182        );
183    }
184}