libsignal_service/push_service/
keys.rs1use std::collections::HashMap;
2
3use libsignal_protocol::{
4 IdentityKey, PreKeyBundle, SenderCertificate, ServiceId, ServiceIdKind,
5};
6use reqwest::Method;
7use serde::Deserialize;
8
9use crate::{
10 configuration::Endpoint,
11 pre_keys::{KyberPreKeyEntity, PreKeyState, SignedPreKeyEntity},
12 push_service::PreKeyResponse,
13 sender::OutgoingPushMessage,
14 utils::serde_base64,
15};
16
17use super::{
18 response::ReqwestExt, HttpAuthOverride, PushService, SenderCertificateJson,
19 ServiceError, VerifyAccountResponse,
20};
21
22#[derive(Debug, Deserialize, Default)]
23#[serde(rename_all = "camelCase")]
24pub struct PreKeyStatus {
25 pub count: u32,
26 pub pq_count: u32,
27}
28
29impl PushService {
30 pub async fn get_pre_key_status(
31 &mut self,
32 service_id_kind: ServiceIdKind,
33 ) -> Result<PreKeyStatus, ServiceError> {
34 self.request(
35 Method::GET,
36 Endpoint::service(format!("/v2/keys?identity={}", service_id_kind)),
37 HttpAuthOverride::NoOverride,
38 )?
39 .send()
40 .await?
41 .service_error_for_status()
42 .await?
43 .json()
44 .await
45 .map_err(Into::into)
46 }
47
48 pub async fn check_pre_keys(
58 &mut self,
59 service_id_kind: ServiceIdKind,
60 digest: &[u8; 32],
61 ) -> Result<bool, ServiceError> {
62 #[derive(serde::Serialize)]
63 #[serde(rename_all = "camelCase")]
64 struct CheckPreKeysRequest<'a> {
65 identity_type: String,
66 #[serde(with = "serde_base64")]
67 digest: &'a [u8; 32],
68 }
69
70 let req = CheckPreKeysRequest {
71 identity_type: service_id_kind.to_string(),
72 digest,
73 };
74
75 let res = self
76 .request(
77 Method::POST,
78 Endpoint::service("/v2/keys/check"),
79 HttpAuthOverride::NoOverride,
80 )?
81 .json(&req)
82 .send()
83 .await?;
84
85 if res.status() == reqwest::StatusCode::CONFLICT {
86 return Ok(false);
87 }
88
89 res.service_error_for_status().await?;
90
91 Ok(true)
92 }
93
94 pub async fn register_pre_keys(
95 &mut self,
96 service_id_kind: ServiceIdKind,
97 pre_key_state: PreKeyState,
98 ) -> Result<(), ServiceError> {
99 self.request(
100 Method::PUT,
101 Endpoint::service(format!("/v2/keys?identity={}", service_id_kind)),
102 HttpAuthOverride::NoOverride,
103 )?
104 .json(&pre_key_state)
105 .send()
106 .await?
107 .service_error_for_status()
108 .await?;
109
110 Ok(())
111 }
112
113 pub async fn get_pre_key(
114 &mut self,
115 destination: &ServiceId,
116 device_id: u32,
117 ) -> Result<PreKeyBundle, ServiceError> {
118 let path = format!(
119 "/v2/keys/{}/{}",
120 destination.service_id_string(),
121 device_id
122 );
123
124 let mut pre_key_response: PreKeyResponse = self
125 .request(
126 Method::GET,
127 Endpoint::service(path),
128 HttpAuthOverride::NoOverride,
129 )?
130 .send()
131 .await?
132 .service_error_for_status()
133 .await?
134 .json()
135 .await?;
136
137 assert!(!pre_key_response.devices.is_empty());
138
139 let identity = IdentityKey::decode(&pre_key_response.identity_key)?;
140 let device = pre_key_response.devices.remove(0);
141 Ok(device.into_bundle(identity)?)
142 }
143
144 pub(crate) async fn get_pre_keys(
145 &mut self,
146 destination: &ServiceId,
147 device_id: u32,
148 ) -> Result<Vec<PreKeyBundle>, ServiceError> {
149 let path = if device_id == 1 {
150 format!("/v2/keys/{}/*", destination.service_id_string())
151 } else {
152 format!(
153 "/v2/keys/{}/{}",
154 destination.service_id_string(),
155 device_id
156 )
157 };
158 let pre_key_response: PreKeyResponse = self
159 .request(
160 Method::GET,
161 Endpoint::service(path),
162 HttpAuthOverride::NoOverride,
163 )?
164 .send()
165 .await?
166 .service_error_for_status()
167 .await?
168 .json()
169 .await?;
170 let mut pre_keys = vec![];
171 let identity = IdentityKey::decode(&pre_key_response.identity_key)?;
172 for device in pre_key_response.devices {
173 pre_keys.push(device.into_bundle(identity)?);
174 }
175 Ok(pre_keys)
176 }
177
178 pub async fn get_sender_certificate(
179 &mut self,
180 ) -> Result<SenderCertificate, ServiceError> {
181 let cert: SenderCertificateJson = self
182 .request(
183 Method::GET,
184 Endpoint::service("/v1/certificate/delivery"),
185 HttpAuthOverride::NoOverride,
186 )?
187 .send()
188 .await?
189 .service_error_for_status()
190 .await?
191 .json()
192 .await?;
193 Ok(SenderCertificate::deserialize(&cert.certificate)?)
194 }
195
196 pub async fn get_uuid_only_sender_certificate(
197 &mut self,
198 ) -> Result<SenderCertificate, ServiceError> {
199 let cert: SenderCertificateJson = self
200 .request(
201 Method::GET,
202 Endpoint::service("/v1/certificate/delivery?includeE164=false"),
203 HttpAuthOverride::NoOverride,
204 )?
205 .send()
206 .await?
207 .service_error_for_status()
208 .await?
209 .json()
210 .await?;
211 Ok(SenderCertificate::deserialize(&cert.certificate)?)
212 }
213
214 pub async fn distribute_pni_keys(
215 &mut self,
216 pni_identity_key: &IdentityKey,
217 device_messages: Vec<OutgoingPushMessage>,
218 device_pni_signed_prekeys: HashMap<String, SignedPreKeyEntity>,
219 device_pni_last_resort_kyber_prekeys: HashMap<
220 String,
221 KyberPreKeyEntity,
222 >,
223 pni_registration_ids: HashMap<String, u32>,
224 signature_valid_on_each_signed_pre_key: bool,
225 ) -> Result<VerifyAccountResponse, ServiceError> {
226 #[derive(serde::Serialize, Debug)]
227 #[serde(rename_all = "camelCase")]
228 struct PniKeyDistributionRequest {
229 #[serde(with = "serde_base64")]
230 pni_identity_key: Vec<u8>,
231 device_messages: Vec<OutgoingPushMessage>,
232 device_pni_signed_prekeys: HashMap<String, SignedPreKeyEntity>,
233 #[serde(rename = "devicePniPqLastResortPrekeys")]
234 device_pni_last_resort_kyber_prekeys:
235 HashMap<String, KyberPreKeyEntity>,
236 pni_registration_ids: HashMap<String, u32>,
237 signature_valid_on_each_signed_pre_key: bool,
238 }
239 self.request(
240 Method::PUT,
241 Endpoint::service(
242 "/v2/accounts/phone_number_identity_key_distribution",
243 ),
244 HttpAuthOverride::NoOverride,
245 )?
246 .json(&PniKeyDistributionRequest {
247 pni_identity_key: pni_identity_key.serialize().into(),
248 device_messages,
249 device_pni_signed_prekeys,
250 device_pni_last_resort_kyber_prekeys,
251 pni_registration_ids,
252 signature_valid_on_each_signed_pre_key,
253 })
254 .send()
255 .await?
256 .service_error_for_status()
257 .await?
258 .json()
259 .await
260 .map_err(Into::into)
261 }
262}