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