vector-im-hydrogen-web/doc/e2e.md
2019-10-23 09:42:44 +02:00

5.4 KiB

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

Notes

  • libolm api docs (also for js api) would be great