d2m.proto 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. syntax = "proto3";
  2. package d2m;
  3. option java_package = "ch.threema.protobuf.d2m";
  4. // Device to Mediator Protocol
  5. // ===========================
  6. //
  7. // General Information
  8. // -------------------
  9. //
  10. // Encryption format: 24 byte nonce prepended, followed by an NaCl box.
  11. //
  12. // All strings are UTF-8 encoded.
  13. //
  14. // Terminology
  15. // -----------
  16. //
  17. // - `MK`: Mediator Key (Client)
  18. // - `MPK`: Mediator Path Key (Client)
  19. // - `TPK`: Temporary Path Key (Server)
  20. // - `Box(A, B)`: A NaCl box encrypted with A and B
  21. // - `Device ID`: Refers to the *Mediator Device ID*
  22. //
  23. // Common Header
  24. // -------------
  25. //
  26. // 0 1 2 3
  27. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  28. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  29. // | Type | Reserved |
  30. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  31. // | Payload ...
  32. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  33. //
  34. // Type: 1 byte (u8)
  35. //
  36. // Identifies the payload type contained in the `Payload` field.
  37. //
  38. // Reserved: 3 byte
  39. //
  40. // Should be set to all `0`s and ignored by the receiver.
  41. //
  42. // Payload: 0..65532 byte
  43. //
  44. // A payload, which can look differently depending on the payload type.
  45. // Send along client information when connecting to the mediator server.
  46. //
  47. // This message is serialized, hex-encoded (lowercase) and then used as the
  48. // WebSocket path.
  49. //
  50. // Type: n/a
  51. // Direction: Client -> Server
  52. message ClientUrlInfo {
  53. // 32 byte mediator path public key
  54. bytes mpk = 1;
  55. // Server group, as assigned by the server when the Threema identity has
  56. // been created.
  57. uint32 server_group = 2;
  58. }
  59. // Proxy a message to/from the chat server.
  60. //
  61. // Name: Proxy
  62. // Type: 0x00
  63. // Direction: Client <-> Server
  64. //
  65. // 0 1 2 3
  66. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  67. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  68. // | Data ...
  69. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  70. //
  71. // Data: 0..65532 byte
  72. //
  73. // The data to be proxied to/from the chat server, encrypted by following
  74. // the Chat Server Protocol.
  75. // Initial message from the server, containing an authentication challenge.
  76. //
  77. // Type: 0x10
  78. // Direction: Client <-- Server
  79. message ServerHello {
  80. // Highest protocol version the server supports
  81. uint32 version = 1;
  82. // 32 byte temporary public key
  83. bytes tpk = 2;
  84. // 32 byte random challenge
  85. bytes challenge = 3;
  86. }
  87. // Policy determining the device slot's lifetime.
  88. enum DeviceSlotExpirationPolicy {
  89. // The device slot should be removed shortly after the device
  90. // disconnected. However, there should be a delay of several minutes to
  91. // ensure that the device can reconnect if it disconnected unintentionally.
  92. VOLATILE = 0;
  93. // The device slot should be kept as long as possible
  94. PERSISTENT = 1;
  95. }
  96. // Initial message from the client, containing the authentication challenge
  97. // response and additional login information.
  98. //
  99. // Type: 0x11
  100. // Direction: Client --> Server
  101. message ClientHello {
  102. // Protocol version which the client has selected
  103. uint32 version = 1;
  104. // Challenge response (72 bytes) for authentication.
  105. //
  106. // The response is created using NaCl box encryption:
  107. //
  108. // Box(MPK.secret, TPK.public)
  109. // .encrypt(data=<challenge>, nonce=<random>)
  110. //
  111. // The nonce is then prepended to the encrypted challenge.
  112. //
  113. // nonce (24 bytes) || encrypted-box (16 + 32 bytes)
  114. bytes response = 2;
  115. // Unique device id
  116. fixed64 device_id = 3;
  117. // Policy to be applied in case the device id is not registered on the server
  118. // and all device slots have been exhausted.
  119. enum DeviceSlotsExhaustedPolicy {
  120. // Terminate the connection
  121. REJECT = 0;
  122. // Drop the least recently used device
  123. DROP_LEAST_RECENT = 1;
  124. }
  125. DeviceSlotsExhaustedPolicy device_slots_exhausted_policy = 4;
  126. // Policy determining the device slot's lifetime
  127. DeviceSlotExpirationPolicy device_slot_expiration_policy = 5;
  128. // Device info (`d2d.DeviceInfo`), encrypted by `MK.secret`
  129. bytes encrypted_device_info = 6;
  130. }
  131. // Parts of the server's configuration and the device slot state.
  132. //
  133. // Type: 0x12
  134. // Direction: Client <-- Server
  135. message ServerInfo {
  136. // Maximum number of device slots
  137. uint32 max_device_slots = 1;
  138. // Informs the device about its device slot state on the server
  139. enum DeviceSlotState {
  140. // A new device slot has been allocated for the device (i.e. the device's
  141. // id was not registered on the server).
  142. NEW = 0;
  143. // An existing device slot has been reused for the device (i.e. the
  144. // device's id is already registered on the server).
  145. EXISTING = 1;
  146. }
  147. DeviceSlotState device_slot_state = 2;
  148. // Device data shared among devices (`SharedDeviceData`), encrypted by
  149. // `MK.secret`.
  150. bytes encrypted_shared_device_data = 3;
  151. }
  152. // The device's reflection queue on the server has been fully transmitted to
  153. // the device.
  154. //
  155. // Note: This does not mean that reflected messages have already been
  156. // acknowledged by the device!
  157. //
  158. // Type: 0x20
  159. // Direction: Client <-- Server
  160. message ReflectionQueueDry {
  161. }
  162. // The device's role has been promoted to leader, indicating that the device
  163. // should now request to receive and reflect messages from the chat server.
  164. //
  165. // Type: 0x21
  166. // Direction: Client <-- Server
  167. message RolePromotedToLeader {
  168. }
  169. // Request device information of all devices.
  170. //
  171. // Type: 0x30
  172. // Direction: Client --> Server
  173. message GetDevicesInfo {
  174. }
  175. // Device information of all devices.
  176. //
  177. // Type: 0x31
  178. // Direction: Client <-- Server
  179. message DevicesInfo {
  180. // Device id to (augmented) device info map of all devices.
  181. message AugmentedDeviceInfo {
  182. // Device info (`d2d.DeviceInfo`), encrypted by `MK.secret`.
  183. bytes encrypted_device_info = 1;
  184. // Unix-ish timestamp in milliseconds containing the most recent login
  185. // time of the device.
  186. uint64 last_login_at = 2;
  187. // Expiration policy of the device.
  188. DeviceSlotExpirationPolicy device_slot_expiration_policy = 3;
  189. }
  190. map<fixed64, AugmentedDeviceInfo> augmented_device_info = 1;
  191. }
  192. // Request to drop a device and free its device slot.
  193. //
  194. // Type: 0x32
  195. // Direction: Client --> Server
  196. message DropDevice {
  197. // Unique device id
  198. fixed64 device_id = 1;
  199. }
  200. // Acknowledges that a device has been dropped and the device slot has been
  201. // free'd.
  202. //
  203. // Type: 0x33
  204. // Direction: Client <-- Server
  205. message DropDeviceAck {
  206. // Unique device id
  207. fixed64 device_id = 1;
  208. }
  209. // Set the shared device data which is being sent to each device during login.
  210. //
  211. // Type: 0x34
  212. // Direction: Client --> Server
  213. message SetSharedDeviceData {
  214. // Device data shared among devices (`SharedDeviceData`), encrypted by
  215. // `MK.secret`.
  216. bytes encrypted_shared_device_data = 1;
  217. }
  218. // Acquires a device group lock for an atomic operation shared across the
  219. // device group.
  220. //
  221. // Reflection messages from the device to the mediator server will only be
  222. // reflected once the transaction is committed.
  223. //
  224. // Type: 0x40
  225. // Direction: Client --> Server
  226. message BeginTransaction {
  227. // The transaction scope (`TransactionScope` in D2D), encrypted by
  228. // `MK.secret`
  229. bytes encrypted_scope = 1;
  230. }
  231. // Acknowledges that the device group lock has been acquired and that the
  232. // transaction has been started.
  233. //
  234. // Type: 0x41
  235. // Direction: Client <-- Server
  236. message BeginTransactionAck {
  237. }
  238. // Commits a transaction, releases a device group lock.
  239. //
  240. // Type: 0x42
  241. // Direction: Client --> Server
  242. message CommitTransaction {
  243. }
  244. // Acknowledges that the transaction has been committed and that the device
  245. // group lock has been released.
  246. //
  247. // Type: 0x43
  248. // Direction: Client <-- Server
  249. message CommitTransactionAck {
  250. }
  251. // A `BeginTransaction` request is rejected because another transaction is
  252. // already in process.
  253. //
  254. // Type: 0x44
  255. // Direction: Client <-- Server
  256. message TransactionRejected {
  257. // The device that currently holds the lock
  258. fixed64 device_id = 1;
  259. // The encrypted transaction scope associated with the currently locked transaction
  260. bytes encrypted_scope = 2;
  261. }
  262. // When a transaction ends (either because it was committed or because the
  263. // device disconnected), this message is sent to all connected devices except
  264. // for the device that committed the transaction.
  265. //
  266. // This can be used by the other devices as a "retry signal" if a previous
  267. // "BeginTransaction" attempt was unsuccessful.
  268. //
  269. // Type: 0x45
  270. // Direction: Client <-- Server
  271. message TransactionEnded {
  272. // The device that held the lock up until now
  273. fixed64 device_id = 1;
  274. // The encrypted transaction scope associated with the transaction that just ended
  275. bytes encrypted_scope = 2;
  276. }
  277. // Reflect a message into the reflection queue of all other devices.
  278. //
  279. // Name: Reflect
  280. // Type: 0x80
  281. // Direction: Client --> Server
  282. //
  283. // 0 1 2 3
  284. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  285. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  286. // | HL = 8 | Reserved |
  287. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  288. // | Reflect ID |
  289. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  290. // | Envelope ...
  291. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  292. //
  293. // Header Length (HL): 1 byte (u8)
  294. //
  295. // Contains the length of the header, including the header length field
  296. // itself (but not the common header), excluding the envelope.
  297. // Currently, this value will always be set to `8`.
  298. //
  299. // Reserved: 3 byte
  300. //
  301. // Should be set to all `0`s and ignored by the receiver.
  302. //
  303. // Reflect ID: 4 byte (u32, little endian)
  304. //
  305. // Unique number (per connection) used for acknowledgement.
  306. //
  307. // Envelope: 0..65276 byte
  308. //
  309. // The protobuf-encoded and encrypted data to be reflected, encrypted by `MK.secret`.
  310. // See `d2d.proto` for details on the `Envelope` contents.
  311. // Acknowledges that a message to be reflected to all other devices has been
  312. // stored in their respective reflection queues.
  313. //
  314. // Name: ReflectAck
  315. // Type: 0x81
  316. // Direction: Client <-- Server
  317. //
  318. // 0 1 2 3
  319. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  320. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  321. // | Reserved |
  322. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  323. // | Reflect ID |
  324. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  325. // | Timestamp |
  326. // | |
  327. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  328. //
  329. // Reserved: 4 byte
  330. //
  331. // Should be set to all `0`s and ignored by the receiver.
  332. //
  333. // Reflect ID: 4 byte (u32, little endian)
  334. //
  335. // Refers to the `Reflect ID` as sent in the `Reflect` message.
  336. //
  337. // Timestamp: 8 byte (u64, little endian)
  338. //
  339. // Unix-ish timestamp in milliseconds when the message has been stored in
  340. // the reflection queue of the mediator server.
  341. // Deliver a message from the device's reflection queue.
  342. //
  343. // Name: Reflected
  344. // Type: 0x82
  345. // Direction: Client <-- Server
  346. //
  347. // 0 1 2 3
  348. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  349. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  350. // | HL = 8 | Reserved |
  351. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  352. // | Reflected ID |
  353. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  354. // | Timestamp |
  355. // | |
  356. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  357. // | Envelope ...
  358. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  359. //
  360. // Header Length (HL): 1 byte (u8)
  361. //
  362. // Contains the length of the header, including the header length field
  363. // itself (but not the common header), excluding the envelope.
  364. // Currently, this value will always be set to `16`.
  365. //
  366. // Reserved: 3 byte
  367. //
  368. // Should be set to all `0`s and ignored by the receiver.
  369. //
  370. // Reflected ID: 4 byte (u32, little endian)
  371. //
  372. // Monotonically increasing unique number (per device slot) used for
  373. // acknowledgement. May wrap.
  374. //
  375. // Timestamp: 8 byte (u64, little endian)
  376. //
  377. // Unix-ish timestamp in milliseconds when the message has been stored in
  378. // the reflection queue of the mediator server.
  379. //
  380. // Envelope: 0..65276 byte
  381. //
  382. // The protobuf-encoded and encrypted data to be reflected, encrypted by `MK.secret`.
  383. // See `d2d.proto` for details on the `Envelope` contents.
  384. // Acknowledges that a reflected message has been processed by the device.
  385. //
  386. // Name: ReflectedAck
  387. // Type: 0x83
  388. // Direction: Client --> Server
  389. //
  390. // 0 1 2 3
  391. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  392. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  393. // | Reserved |
  394. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  395. // | Reflected ID |
  396. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  397. //
  398. // Reserved: 4 byte
  399. //
  400. // Should be set to all `0`s and ignored by the receiver.
  401. //
  402. // Reflected ID: 4 byte (u32, little endian)
  403. //
  404. // Refers to the `Reflected ID` as sent in the `Reflected` message.