Matrix protocol in OCaml, Eio specialised
1(** Cross-signing and device verification.
2
3 This module implements Matrix cross-signing for identity verification:
4 - Cross-signing key management (master, self-signing, user-signing keys)
5 - Device verification (local trust, cross-signing trust)
6 - User identity verification
7 - SAS (Short Authentication String) verification protocol
8
9 @see <https://spec.matrix.org/v1.11/client-server-api/#cross-signing> Cross-Signing *)
10
11(** {1 Trust States} *)
12
13(** Local trust state for a device. *)
14type local_trust =
15 | Verified
16 | BlackListed
17 | Ignored
18 | Unset
19
20val local_trust_to_int : local_trust -> int
21(** Convert local trust to int for storage. *)
22
23val local_trust_of_int : int -> local_trust
24(** Parse local trust from int. *)
25
26(** Own user identity verification state. *)
27type own_identity_state =
28 | Never_verified
29 | Verification_violation
30 | Identity_verified
31
32(** {1 Cross-Signing Key Types} *)
33
34(** Cross-signing key usage. *)
35type key_usage =
36 | Master
37 | Self_signing
38 | User_signing
39
40val key_usage_to_string : key_usage -> string
41(** Convert key usage to string. *)
42
43val key_usage_of_string : string -> key_usage option
44(** Parse key usage from string. *)
45
46(** Public cross-signing key. *)
47type cross_signing_pubkey = {
48 user_id : Matrix_proto.Id.User_id.t;
49 usage : key_usage list;
50 keys : (string * string) list;
51 signatures : (string * (string * string) list) list;
52}
53
54val get_ed25519_key : cross_signing_pubkey -> (string * string) option
55(** Extract the first Ed25519 key from a cross-signing key. *)
56
57(** {1 Private Cross-Signing Keys} *)
58
59(** Private key for signing operations. *)
60type private_key = {
61 public_key : string;
62 secret_key : string;
63}
64
65(** Private cross-signing identity (holds the private keys). *)
66type private_cross_signing_identity = {
67 user_id : Matrix_proto.Id.User_id.t;
68 mutable master_key : private_key option;
69 mutable self_signing_key : private_key option;
70 mutable user_signing_key : private_key option;
71 mutable shared : bool;
72}
73
74val create_private_identity : user_id:Matrix_proto.Id.User_id.t -> private_cross_signing_identity
75(** Create a new private cross-signing identity. *)
76
77val generate_ed25519_key : unit -> private_key
78(** Generate a new Ed25519 key pair. *)
79
80val generate_cross_signing_keys : private_cross_signing_identity -> unit
81(** Generate all cross-signing keys for a user. *)
82
83val sign_with_key : private_key -> string -> (string, string) result
84(** Sign data with a private key. *)
85
86(** {1 Cross-Signing Public Keys} *)
87
88(** Master public key. *)
89type master_pubkey = {
90 key : cross_signing_pubkey;
91}
92
93(** Self-signing public key. *)
94type self_signing_pubkey = {
95 key : cross_signing_pubkey;
96}
97
98(** User-signing public key. *)
99type user_signing_pubkey = {
100 key : cross_signing_pubkey;
101}
102
103val pubkey_from_private :
104 user_id:Matrix_proto.Id.User_id.t ->
105 usage:key_usage ->
106 private_key ->
107 cross_signing_pubkey
108(** Create a public cross-signing key from private key. *)
109
110(** {1 Signature Verification} *)
111
112val verify_signature :
113 public_key_b64:string ->
114 signature_b64:string ->
115 data:string ->
116 bool
117(** Verify an Ed25519 signature. *)
118
119val canonicalize_json : Jsont.json -> string
120(** Canonicalize JSON for signing. *)
121
122val verify_cross_signing_signature :
123 signer_key:cross_signing_pubkey ->
124 signed_key:cross_signing_pubkey ->
125 bool
126(** Verify that a cross-signing key is signed by another key. *)
127
128(** {1 Device Verification} *)
129
130(** Device with verification state. *)
131type verified_device = {
132 user_id : Matrix_proto.Id.User_id.t;
133 device_id : Matrix_proto.Id.Device_id.t;
134 keys : (string * string) list;
135 algorithms : string list;
136 display_name : string option;
137 mutable local_trust : local_trust;
138 mutable cross_signing_trusted : bool;
139}
140
141val create_verified_device :
142 user_id:Matrix_proto.Id.User_id.t ->
143 device_id:Matrix_proto.Id.Device_id.t ->
144 keys:(string * string) list ->
145 algorithms:string list ->
146 ?display_name:string ->
147 unit ->
148 verified_device
149(** Create a verified device from device keys. *)
150
151val is_device_verified : verified_device -> bool
152(** Check if a device is verified (locally or via cross-signing). *)
153
154val set_device_local_trust : verified_device -> local_trust -> unit
155(** Set local trust state for a device. *)
156
157val verify_device_with_self_signing :
158 self_signing_key:self_signing_pubkey ->
159 device:verified_device ->
160 bool
161(** Check if device is signed by a self-signing key. *)
162
163(** {1 User Identity} *)
164
165(** Own user identity. *)
166type own_user_identity = {
167 user_id : Matrix_proto.Id.User_id.t;
168 master_key : master_pubkey;
169 self_signing_key : self_signing_pubkey;
170 user_signing_key : user_signing_pubkey;
171 mutable state : own_identity_state;
172}
173
174(** Other user identity. *)
175type other_user_identity = {
176 user_id : Matrix_proto.Id.User_id.t;
177 master_key : master_pubkey;
178 self_signing_key : self_signing_pubkey;
179 mutable pinned_master_key : master_pubkey option;
180 mutable was_previously_verified : bool;
181}
182
183(** User identity (own or other). *)
184type user_identity =
185 | Own of own_user_identity
186 | Other of other_user_identity
187
188val identity_user_id : user_identity -> Matrix_proto.Id.User_id.t
189(** Get user ID from identity. *)
190
191val is_own_identity_verified : own_user_identity -> bool
192(** Check if own identity is verified. *)
193
194val is_other_identity_verified :
195 our_user_signing_key:user_signing_pubkey ->
196 other_user_identity ->
197 bool
198(** Check if other user identity is verified by us. *)
199
200val has_identity_changed : other_user_identity -> bool
201(** Check if a user's identity has changed since we pinned it. *)
202
203val pin_master_key : other_user_identity -> unit
204(** Pin the current master key for future change detection. *)
205
206(** {1 SAS Verification Protocol} *)
207
208(** SAS verification state. *)
209type sas_state =
210 | Sas_created
211 | Sas_started
212 | Sas_accepted
213 | Sas_keys_exchanged
214 | Sas_confirmed
215 | Sas_mac_received
216 | Sas_done
217 | Sas_cancelled of string
218
219(** Short authentication string output. *)
220type sas_output =
221 | Decimal of int * int * int
222 | Emoji of (int * string) list
223
224(** SAS verification methods. *)
225type sas_method =
226 | Decimal_method
227 | Emoji_method
228
229(** SAS verification session. *)
230type sas_session = {
231 flow_id : string;
232 mutable state : sas_state;
233 our_user_id : Matrix_proto.Id.User_id.t;
234 our_device_id : Matrix_proto.Id.Device_id.t;
235 their_user_id : Matrix_proto.Id.User_id.t;
236 their_device_id : Matrix_proto.Id.Device_id.t;
237 mutable their_public_key : string option;
238 mutable our_public_key : string option;
239 mutable sas_bytes : string option;
240 mutable methods : sas_method list;
241}
242
243val generate_flow_id : unit -> string
244(** Generate a random flow ID. *)
245
246val create_sas_session :
247 our_user_id:Matrix_proto.Id.User_id.t ->
248 our_device_id:Matrix_proto.Id.Device_id.t ->
249 their_user_id:Matrix_proto.Id.User_id.t ->
250 their_device_id:Matrix_proto.Id.Device_id.t ->
251 sas_session
252(** Create a new SAS verification session. *)
253
254val sas_emoji_table : (int * string) array
255(** Standard SAS emoji table. *)
256
257val derive_sas_output : method_type:sas_method -> sas_bytes:string -> sas_output
258(** Derive SAS output from shared bytes. *)
259
260val get_sas_output : sas_session -> sas_method -> sas_output option
261(** Get SAS output for display. *)
262
263val confirm_sas : sas_session -> unit
264(** Confirm SAS match. *)
265
266val cancel_sas : sas_session -> string -> unit
267(** Cancel SAS verification. *)
268
269val is_sas_done : sas_session -> bool
270(** Check if SAS is complete. *)
271
272(** {1 QR Code Verification} *)
273
274(** QR verification mode. *)
275type qr_mode =
276 | Self_verifying_master_key_trusts_device
277 | Self_verifying_device_trusts_master_key
278 | Verifying_another_user
279
280(** QR verification state. *)
281type qr_state =
282 | Qr_started
283 | Qr_scanned
284 | Qr_confirmed
285 | Qr_reciprocated
286 | Qr_done
287 | Qr_cancelled of string
288
289(** QR verification data. *)
290type qr_verification = {
291 flow_id : string;
292 mutable state : qr_state;
293 mode : qr_mode;
294 our_user_id : Matrix_proto.Id.User_id.t;
295 their_user_id : Matrix_proto.Id.User_id.t;
296 our_master_key : string;
297 their_master_key : string option;
298 mutable secret : string option;
299}
300
301val create_self_qr_verification :
302 our_user_id:Matrix_proto.Id.User_id.t ->
303 our_master_key:string ->
304 mode:qr_mode ->
305 qr_verification
306(** Create QR verification for self-verification. *)
307
308val create_user_qr_verification :
309 our_user_id:Matrix_proto.Id.User_id.t ->
310 their_user_id:Matrix_proto.Id.User_id.t ->
311 our_master_key:string ->
312 their_master_key:string ->
313 qr_verification
314(** Create QR verification for verifying another user. *)
315
316(** {1 Verification Request} *)
317
318(** Verification request. *)
319type verification_request = {
320 flow_id : string;
321 from_user_id : Matrix_proto.Id.User_id.t;
322 to_user_id : Matrix_proto.Id.User_id.t;
323 from_device_id : Matrix_proto.Id.Device_id.t option;
324 methods : string list;
325 timestamp : int64;
326 mutable accepted : bool;
327 mutable cancelled : bool;
328}
329
330val create_verification_request :
331 from_user_id:Matrix_proto.Id.User_id.t ->
332 to_user_id:Matrix_proto.Id.User_id.t ->
333 ?from_device_id:Matrix_proto.Id.Device_id.t ->
334 unit ->
335 verification_request
336(** Create a verification request. *)
337
338val accept_verification_request : verification_request -> unit
339(** Accept a verification request. *)
340
341val cancel_verification_request : verification_request -> unit
342(** Cancel a verification request. *)
343
344(** {1 Cross-Signing Upload} *)
345
346(** Data needed to upload cross-signing keys. *)
347type cross_signing_upload = {
348 master_key : cross_signing_pubkey;
349 self_signing_key : cross_signing_pubkey;
350 user_signing_key : cross_signing_pubkey;
351}
352
353val build_cross_signing_upload : private_cross_signing_identity -> cross_signing_upload option
354(** Build upload data from private identity. *)