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