1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
use ;
use ;
use ;
use crateJsonError;
/// The [maximum size allowed] for a PDU.
///
/// [maximum size allowed]: https://spec.matrix.org/v1.19/client-server-api/#size-limits
const MAX_PDU_BYTES: usize = 65_535;
/// The fields to remove from a JSON object when creating a content hash of an event.
static CONTENT_HASH_FIELDS_TO_REMOVE: & = &;
/// The fields to remove from a JSON object when creating a reference hash of an event.
static REFERENCE_HASH_FIELDS_TO_REMOVE: & = &;
/// Compute and add the [content hash] to the given event.
///
/// This adds or overwrites the `sha256` key in the `hashes` object of the event.
///
/// This should only be called when creating a new event.
///
/// # Parameters
///
/// * `object`: A JSON object to be hashed according to the Matrix specification.
///
/// # Errors
///
/// Returns an error if the `hashes` key is present and is not an object.
///
/// # Examples
///
/// ```
/// use ruma_common::CanonicalJsonObject;
/// use ruma_signatures::add_content_hash_to_event;
///
/// // Deserialize an event from JSON.
/// let mut event = serde_json::from_str(
/// r#"{
/// "room_id": "!x:domain",
/// "sender": "@a:domain",
/// "origin": "domain",
/// "origin_server_ts": 1000000,
/// "type": "X",
/// "content": {},
/// "prev_events": [],
/// "auth_events": [],
/// "depth": 3
/// }"#,
/// )?;
///
/// // Hash the JSON.
/// add_content_hash_to_event(&mut event)?;
///
/// // The hash was added.
/// assert_eq!(
/// event,
/// serde_json::from_str::<CanonicalJsonObject>(
/// r#"{
/// "room_id": "!x:domain",
/// "sender": "@a:domain",
/// "origin": "domain",
/// "origin_server_ts": 1000000,
/// "type": "X",
/// "content": {},
/// "prev_events": [],
/// "auth_events": [],
/// "depth": 3,
/// "hashes": {
/// "sha256": "5jM4wQpv6lnBo7CLIghJuHdW+s2CMBJPUOGOC89ncos"
/// }
/// }"#,
/// )?
/// );
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// [content hash]: https://spec.matrix.org/v1.19/server-server-api/#calculating-the-content-hash-for-an-event
/// Computes the [content hash] of the given event.
///
/// The content hash of an event covers the complete event including the unredacted contents. It is
/// used during federation and is described in the Matrix server-server specification.
///
/// # Parameters
///
/// * `object`: A JSON object to generate a content hash for.
///
/// # Errors
///
/// Returns an error if the event is too large.
///
/// [content hash]: https://spec.matrix.org/v1.19/server-server-api/#calculating-the-content-hash-for-an-event
/// Computes the [reference hash] of the given event.
///
/// The reference hash of an event covers the essential fields of an event, including content
/// hashes.
///
/// When creating a new event, [`add_content_hash_to_event()`] must be called before this function
/// to add the content hash.
///
/// Returns the hash as a base64-encoded string, without padding. The correct character set is used
/// depending on the room version:
///
/// * For room versions 1 and 2, the standard character set is used for sending the reference hash
/// of the `auth_events` and `prev_events`.
/// * For room version 3, the standard character set is used for using the reference hash as the
/// event ID.
/// * For newer versions, the URL-safe character set is used for using the reference hash as the
/// event ID.
///
/// # Parameters
///
/// * `object`: A JSON object to generate a reference hash for.
/// * `rules`: The rules of the version of the current room.
///
/// # Errors
///
/// Returns an error if the event is too large or redaction fails.
///
/// [reference hash]: https://spec.matrix.org/v1.19/server-server-api#calculating-the-reference-hash-for-an-event