Add support for pushing secrets and receiving secret pushes#6164
Add support for pushing secrets and receiving secret pushes#6164uhoreg wants to merge 3 commits intomatrix-org:mainfrom
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6164 +/- ##
==========================================
- Coverage 89.81% 89.80% -0.01%
==========================================
Files 376 376
Lines 102469 102586 +117
Branches 102469 102586 +117
==========================================
+ Hits 92030 92130 +100
- Misses 6855 6860 +5
- Partials 3584 3596 +12 ☔ View full report in Codecov by Sentry. |
richvdh
left a comment
There was a problem hiding this comment.
A couple of initial thoughts.
| /// Get all the pushed secrets with the given [`SecretName`] we have | ||
| /// currently stored. | ||
| #[cfg(feature = "experimental-push-secrets")] | ||
| async fn get_pushed_secrets_from_inbox( | ||
| &self, | ||
| secret_name: &SecretName, | ||
| ) -> Result<Vec<SecretPushContent>, Self::Error>; |
There was a problem hiding this comment.
do we not need to call this in matrix-sdk somewhere? Is that planned for a future PR?
There was a problem hiding this comment.
Yes, that is a future PR. I wrote this PR first, then worked on the js-sdk parts, and then worked on the matrix-sdk parts. I could add the matrix-sdk parts to this PR, but I kind of feel like it's cleaner keeping them separate. But I'm not entirely sure, and am willing to be convinced otherwise.
There was a problem hiding this comment.
ah, no worries. Could I ask you to try and make that sort of thing clear (e.g. in the description) for future PRs?
richvdh
left a comment
There was a problem hiding this comment.
also, needs more CHANGELOG.md
rather than a full `GossippedSecret` struct
|
I believe this is ready for re-review |
| keys::SECRETS_INBOX, | ||
| (secret.secret_name.as_str(), secret.event.content.request_id.as_str()), | ||
| keys::SECRETS_INBOX_V2, | ||
| (secret.secret_name.as_str(), secret.secret.as_str()), |
There was a problem hiding this comment.
why is the secret value used as part of the key?
There was a problem hiding this comment.
If we get sent two different secrets for the same name, we need to keep both of them, so that we can check which one is correct.
There was a problem hiding this comment.
Speaking of which, I need to add a test to make sure that things don't explode when you receive the same secret twice.
There was a problem hiding this comment.
If we get sent two different secrets for the same name, we need to keep both of them, so that we can check which one is correct.
Ah ok. It would be good to note that as a comment somewhere.
| pub(crate) async fn data_migrate(name: &str, serializer: &SafeEncodeSerializer) -> Result<()> { | ||
| let db = MigrationDb::new(name, 11).await?; | ||
|
|
||
| // The new store has been made for inbound group sessions; time to populate it. |
| /// The contents of the secret. | ||
| #[serde( | ||
| serialize_with = "zeroizing_string_serializer", | ||
| deserialize_with = "zeroizing_string_deserializer" | ||
| )] |
There was a problem hiding this comment.
this is a bit of a pain. I'm not really seeing why we need to implement Serialize for SecretsInboxItem?
Assuming we do need to implement it, it might be cleaner instead to make secret a regular String and then make SecretsInboxItem [#derive(Zeroize,ZeroizeOnDrop)]
| CREATE TABLE "secrets_inbox" ( | ||
| "secret_name" BLOB NOT NULL, | ||
| "secret" BLOB NOT NULL | ||
| ); |
There was a problem hiding this comment.
probably needs an index on secret_name
There was a problem hiding this comment.
Yeah, probably. I just copied the old schema and forgot about that. The table will likely be small enough that it won't make a difference in practice, but I should add one anyways.
| /// | ||
| /// This must be done before creating the store cipher, because the store cipher | ||
| /// requires the `kv` table. | ||
| pub(crate) async fn initialize_store(conn: &SqliteAsyncConn, version: u8) -> Result<u8> { |
| - [**breaking**] `CryptoStore::get_secrets_from_inbox` now returns a `Vec` of | ||
| the secrets as strings, rather than a `Vec` of `GossippedSecret` structs. | ||
| ([#6164](https://github.com/matrix-org/matrix-rust-sdk/pull/6164)) |
There was a problem hiding this comment.
Also: newest entries go at the top, in the same way that newest releases go at the top.
| let encrypted_event_type = content.event_type().to_owned(); | ||
| let request = ToDeviceRequest::new( | ||
| device.user_id(), | ||
| device.device_id().to_owned(), | ||
| &encrypted_event_type, | ||
| content.cast(), | ||
| ); | ||
| let request = OutgoingRequest { | ||
| request_id: request.txn_id.clone(), | ||
| request: Arc::new(request.into()), | ||
| }; | ||
| self.inner | ||
| .outgoing_requests | ||
| .write() | ||
| .insert(request.request_id.clone(), request); |
There was a problem hiding this comment.
do the messages and their msgids get logged anywhere, so we can see what is going on?
| impl Drop for SecretPushContent { | ||
| fn drop(&mut self) { | ||
| self.zeroize() | ||
| } | ||
| } |
There was a problem hiding this comment.
you could use derive(ZeroizeOnDrop) for this
| - Add support for MSC4385. | ||
| - Add new method `OlmMachine::push_secret_to_verified_devices`. |
There was a problem hiding this comment.
again, wrong place. Also, needs a PR link.
| if sender != self.user_id() { | ||
| // Ignore if sent from a different user | ||
| error!(?sender, "Received secret push from a different user"); | ||
| return Ok(()); | ||
| } | ||
| let Some(device) = self.inner.store.get_device_from_curve_key(sender, *sender_key).await? | ||
| else { | ||
| error!(?sender, ?sender_key, "Received secret push from unknown device"); | ||
| return Ok(()); | ||
| }; | ||
| if !device.is_verified() { | ||
| error!(?sender, device_id = ?device.device_id(), "Received secret push from unverified device"); | ||
| return Ok(()); | ||
| } |
There was a problem hiding this comment.
I think these should be warnings rather than errors, since they can be caused by other users or devices doing unexpected things, rather than necessarily reflecting an internal error on our side?
see MSC4385
Pushing secrets allow devices to send secrets to other devices without waiting for a secret request.
closes #6040
Signed-off-by: