matrix-rust-sdk icon indicating copy to clipboard operation
matrix-rust-sdk copied to clipboard

The way we let users consume `m.secret.send` events is a bit magical

Open poljar opened this issue 3 years ago • 0 comments

This is mostly about receiving a backup key over m.secret.send, other secrets are handled internally and the user only gets a zeroized event.

The currently used backup isn't known to the crypto crate due to two limiting factors:

  1. The backups aren't returned in a sync response, another API needs to be polled
  2. The crypto crate can't poll the API endpoint itself

Since the backup isn't known the crypto crate itself can't decide on itself if a backup key received over m.secret.send should be used or not.

This in turn means that we need to pass the m.secret.send event to the user, this event doesn't really contain any info about the type of the secret it is carrying. Returning just the raw event becomes problematic, we need to notify the user about the type of the secret and the user then needs to perform a complex check if the key is valid for a given backup.

Such an API is error prone and hard for the user to understand.

What we should do instead is:

  1. Zeroize the event as usual, don't insert any additional data.
  2. Cache the event and the additional data to identify the type and validity of the secret
  3. Let the user inspect the cached secret
  4. Give the user an API to pass in a backup version and the cached secret to enable the backup key to be used to encrypt backups

This gives us a couple of advantages:

  1. The user has less chance to shoot themselves in the foot
  2. The secret doesn't need to cross the FFI boundary for bindings anymore, where it can be copied over in an insecure manner.
  3. All secrets we receive over to-device get zeroized when we return them to the user in the receive_sync_changes() method.

poljar avatar Sep 14 '22 08:09 poljar