tuwunel_service/server_keys/
get.rs1use std::borrow::Borrow;
8
9use ruma::{
10 CanonicalJsonObject, ServerName, ServerSigningKeyId, api::federation::discovery::VerifyKey,
11 room_version_rules::RoomVersionRules,
12};
13use tuwunel_core::{Err, Result, implement};
14
15use super::{PubKeyMap, PubKeys, extract_key};
16
17#[implement(super::Service)]
22pub async fn get_event_keys(
23 &self,
24 object: &CanonicalJsonObject,
25 version: &RoomVersionRules,
26) -> Result<PubKeyMap> {
27 use ruma::signatures::required_keys;
28
29 let required = match required_keys(object, &version.signatures) {
30 | Ok(required) => required,
31 | Err(e) => {
32 return Err!(BadServerResponse("Failed to determine keys required to verify: {e}"));
33 },
34 };
35
36 let batch = required
37 .iter()
38 .map(|(s, ids)| (s.borrow(), ids.iter().map(Borrow::borrow)));
39
40 Ok(self.get_pubkeys(batch).await)
41}
42
43#[implement(super::Service)]
48pub async fn get_pubkeys<'a, S, K>(&self, batch: S) -> PubKeyMap
49where
50 S: Iterator<Item = (&'a ServerName, K)> + Send,
51 K: Iterator<Item = &'a ServerSigningKeyId> + Send,
52{
53 let mut keys = PubKeyMap::new();
54 for (server, key_ids) in batch {
55 let pubkeys = self.get_pubkeys_for(server, key_ids).await;
56 keys.insert(server.as_str().into(), pubkeys);
57 }
58
59 keys
60}
61
62#[implement(super::Service)]
67pub async fn get_pubkeys_for<'a, I>(&self, origin: &ServerName, key_ids: I) -> PubKeys
68where
69 I: Iterator<Item = &'a ServerSigningKeyId> + Send,
70{
71 let mut keys = PubKeys::new();
72 for key_id in key_ids {
73 if let Ok(verify_key) = self.get_verify_key(origin, key_id).await {
74 keys.insert(key_id.as_str().into(), verify_key.key);
75 }
76 }
77
78 keys
79}
80
81#[implement(super::Service)]
86pub async fn get_verify_key(
87 &self,
88 origin: &ServerName,
89 key_id: &ServerSigningKeyId,
90) -> Result<VerifyKey> {
91 let notary_first = self
92 .services
93 .server
94 .config
95 .query_trusted_key_servers_first;
96
97 let notary_only = self
98 .services
99 .server
100 .config
101 .only_query_trusted_key_servers;
102
103 if let Some(result) = self.verify_keys_for(origin).await.remove(key_id) {
104 return Ok(result);
105 }
106
107 if notary_first
108 && let Ok(result) = self
109 .get_verify_key_from_notaries(origin, key_id)
110 .await
111 {
112 return Ok(result);
113 }
114
115 if !notary_only
116 && let Ok(result) = self
117 .get_verify_key_from_origin(origin, key_id)
118 .await
119 {
120 return Ok(result);
121 }
122
123 if !notary_first
124 && let Ok(result) = self
125 .get_verify_key_from_notaries(origin, key_id)
126 .await
127 {
128 return Ok(result);
129 }
130
131 Err!(BadServerResponse(debug_error!(
132 ?key_id,
133 ?origin,
134 "Failed to fetch federation signing-key"
135 )))
136}
137
138#[implement(super::Service)]
139async fn get_verify_key_from_notaries(
140 &self,
141 origin: &ServerName,
142 key_id: &ServerSigningKeyId,
143) -> Result<VerifyKey> {
144 for notary in &self.services.config.trusted_servers {
145 if let Ok(server_keys) = self.notary_request(notary, origin).await {
146 for server_key in server_keys.clone() {
147 self.add_signing_keys(server_key).await;
148 }
149
150 for server_key in server_keys {
151 if let Some(result) = extract_key(server_key, key_id) {
152 return Ok(result);
153 }
154 }
155 }
156 }
157
158 Err!(Request(NotFound("Failed to fetch signing-key from notaries")))
159}
160
161#[implement(super::Service)]
162async fn get_verify_key_from_origin(
163 &self,
164 origin: &ServerName,
165 key_id: &ServerSigningKeyId,
166) -> Result<VerifyKey> {
167 if let Ok(server_key) = self.server_request(origin).await {
168 self.add_signing_keys(server_key.clone()).await;
169 if let Some(result) = extract_key(server_key, key_id) {
170 return Ok(result);
171 }
172 }
173
174 Err!(Request(NotFound("Failed to fetch signing-key from origin")))
175}