Skip to main content

tuwunel_service/server_keys/
verify.rs

1use ruma::{
2	CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, RoomVersionId, signatures::Verified,
3};
4use serde_json::value::RawValue as RawJsonValue;
5use tuwunel_core::{
6	Err, Result, implement,
7	matrix::{event::gen_event_id_canonical_json, room_version},
8};
9
10#[implement(super::Service)]
11pub async fn validate_and_add_event_id(
12	&self,
13	pdu: &RawJsonValue,
14	room_version_id: &RoomVersionId,
15) -> Result<(OwnedEventId, CanonicalJsonObject)> {
16	let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version_id)?;
17
18	if let Err(e) = self
19		.verify_event(&value, Some(room_version_id))
20		.await
21	{
22		return Err!(BadServerResponse(debug_error!(
23			"Event {event_id} failed verification: {e:?}"
24		)));
25	}
26
27	// For v3+ rooms we add the event_id, but for v1/v2 rooms it's already present.
28	if !room_version::rules(room_version_id)?
29		.event_format
30		.require_event_id
31	{
32		value.insert("event_id".into(), CanonicalJsonValue::String(event_id.as_str().into()));
33	}
34
35	Ok((event_id, value))
36}
37
38#[implement(super::Service)]
39pub async fn validate_and_add_event_id_no_fetch(
40	&self,
41	pdu: &RawJsonValue,
42	room_version_id: &RoomVersionId,
43) -> Result<(OwnedEventId, CanonicalJsonObject)> {
44	let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version_id)?;
45	let room_version_rules = room_version::rules(room_version_id)?;
46
47	if !self
48		.required_keys_exist(&value, &room_version_rules)
49		.await
50	{
51		return Err!(BadServerResponse(debug_warn!(
52			"Event {event_id} cannot be verified: missing keys."
53		)));
54	}
55
56	if let Err(e) = self
57		.verify_event(&value, Some(room_version_id))
58		.await
59	{
60		return Err!(BadServerResponse(debug_error!(
61			"Event {event_id} failed verification: {e:?}"
62		)));
63	}
64
65	// For v3+ rooms we add the event_id, but for v1/v2 rooms it's already present.
66	if !room_version_rules.event_format.require_event_id {
67		value.insert("event_id".into(), CanonicalJsonValue::String(event_id.as_str().into()));
68	}
69
70	Ok((event_id, value))
71}
72
73#[implement(super::Service)]
74pub async fn verify_event(
75	&self,
76	event: &CanonicalJsonObject,
77	room_version_id: Option<&RoomVersionId>,
78) -> Result<Verified> {
79	let room_version_id = room_version_id.unwrap_or(&RoomVersionId::V11);
80	let room_version_rules = room_version::rules(room_version_id)?;
81
82	let event_keys = self
83		.get_event_keys(event, &room_version_rules)
84		.await?;
85
86	ruma::signatures::verify_event(
87		ruma::signatures::VerifyEventPublicSigningKeys::new(&event_keys),
88		event,
89		&room_version_rules,
90	)
91	.map_err(Into::into)
92}
93
94#[implement(super::Service)]
95pub async fn verify_json(
96	&self,
97	event: &CanonicalJsonObject,
98	room_version_id: Option<&RoomVersionId>,
99) -> Result {
100	let room_version_id = room_version_id.unwrap_or(&RoomVersionId::V11);
101	let room_version_rules = room_version::rules(room_version_id)?;
102
103	let event_keys = self
104		.get_event_keys(event, &room_version_rules)
105		.await?;
106
107	ruma::signatures::verify_json(&event_keys, event).map_err(Into::into)
108}