forked from mystiq/hydrogen-web
102 lines
5.4 KiB
Markdown
102 lines
5.4 KiB
Markdown
# Implementing e2e encryption:
|
|
## Olm
|
|
- implement MemberList as ObservableMap
|
|
- make sure we have all members (as we're using lazy loading members), and store these somehow
|
|
- do we need to update /members on every limited sync response or did we find a way around this?
|
|
- implement creating/loading an olm account
|
|
- add libolm as dependency
|
|
- store pickled account
|
|
- load pickled account
|
|
- update pickled account
|
|
- add initial one-time keys
|
|
- publish keys with /keys/upload
|
|
- implement creating/loading an olm session for (userid, deviceid)
|
|
- get olm session for [(userid, deviceid), ...] (array so they can all go out in one /keys/claim call?)
|
|
- create if not exists
|
|
- claim one-time key with /keys/claim
|
|
- verify signature on key
|
|
- ??? what about inbound/outbound sessions? do they require multiple OlmSession objects?
|
|
- doesn't look like it, more like a way to start the session but once started (type=1), they are equivalent?
|
|
- for outbound, see file:///home/bwindels/Downloads/matrix-docs/End-to-End%20Encryption%20implementation%20guide%20%7C%20Matrix.org.html#starting-an-olm-session
|
|
- for inbound, see: file:///home/bwindels/Downloads/matrix-docs/End-to-End%20Encryption%20implementation%20guide%20|%20Matrix.org.html#handling-an-mroomencrypted-event
|
|
- so in this case, it would the session would be created as an outbound session.
|
|
- store pickled, index by curve25519 identity key?
|
|
- get from storage if exists and unpickle
|
|
- implement device tracking
|
|
- store users?
|
|
- needs_update (riot has status with 4 states: not tracked, pending download, downloading, up to date)
|
|
- set during sync for users that appear in device_lists.changed
|
|
- store devices
|
|
- id
|
|
- userid
|
|
- signing KP
|
|
- identity KP
|
|
- algorithms
|
|
- device name
|
|
- verified
|
|
- known? riot has this ... what does it mean exactly?
|
|
- handle device_lists.changed in /sync response
|
|
- call /keys/changed to get updated devices and store them
|
|
- handle device_lists.left in /sync response
|
|
- we can keep verified devices we don't share a room with anymore around perhaps, but
|
|
shouldn't update them ... which we won't do anyway as they won't appear in changed anymore
|
|
- when e2e is enabled, start tracking:
|
|
- call /keys/query for all members in MemberList
|
|
- verify signature on device keys
|
|
- store devices
|
|
- implement maintaining one-time keys on server
|
|
- update account with new new keys when /sync responded with device_one_time_keys_count < MAX/2
|
|
- upload new one-time keys to /keys/upload
|
|
- mark them as published in account
|
|
- update picked session in storage
|
|
- implement encrypting olm messages
|
|
- roughly file:///home/bwindels/Downloads/matrix-docs/End-to-End%20Encryption%20implementation%20guide%20|%20Matrix.org.html#encrypting-an-event-with-olm
|
|
- packaging as m.room.encrypted event
|
|
- implement decrypting olm messages
|
|
- roughly file:///home/bwindels/Downloads/matrix-docs/End-to-End%20Encryption%20implementation%20guide%20|%20Matrix.org.html#handling-an-mroomencrypted-event
|
|
- decrypt with libolm
|
|
- verify signature
|
|
- check message index, etc to detect replay attacks
|
|
- handling wedged olm sessions
|
|
- ???
|
|
|
|
|
|
## Megolm
|
|
- ??? does every sender in a room have their own megolm session (to send)? I suppose so, yes
|
|
- we need to pickle inbound and outbound sessions separately ... are they different entities?
|
|
- they are: OutboundGroupSession and InboundGroupSession
|
|
- should they be in different stores?
|
|
- e.g. we have a store for outbound sessions (to send ourselves) and one for inbound
|
|
- NO! the e2e implementation guide says specifically:
|
|
"It should store these details as an inbound session, just as it would when receiving them via an m.room_key event."
|
|
- wait, we probably have to store the session as BOTH an inbound and outbound session?
|
|
- the outbound one so we can keep using it to encrypt
|
|
- the inbound one to be able to decrypt our own messages? as we won't send a m.room_key to our own device
|
|
- so yes, we'll store our own outbound sessions. Riot doesn't do this and just starts new ones when starting the client,
|
|
but keeping this would probably give us better offline support/less network usage as we wouldn't have to create new megolm session most of the time
|
|
- and we store the inbound sessions (including the ones derived from our own outbound sessions) to be able to decrypt all messages
|
|
- create new megolm session
|
|
- create new outbound group session
|
|
- get megolm session id and key, put in m.room_key event
|
|
- store megolm session
|
|
- encrypt using olm and send as m.room.encrypted device message
|
|
- receiving new megolm session
|
|
- listen for m.room_key device message
|
|
- decrypt using olm
|
|
- create inbound group session
|
|
- store megolm session
|
|
- encrypt megolm message
|
|
- decrypt megolm message
|
|
- rotate megolm session
|
|
- ??? does this happen automatically?
|
|
- deactive sessions when members leave the room
|
|
|
|
## Verifying devices
|
|
- validate fingerprint
|
|
- have a look at SAS?
|
|
|
|
## Encrypted attachments
|
|
- use AES-CTR from https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
|
|
|
|
## Notes
|
|
- libolm api docs (also for js api) would be great
|