Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed device keys in Olm-encrypted messages #3517

Merged
merged 22 commits into from
Jun 27, 2024

Conversation

uhoreg
Copy link
Member

@uhoreg uhoreg commented Jun 6, 2024

  • Public API changes documented in changelogs (optional)

Signed-off-by:

@uhoreg
Copy link
Member Author

uhoreg commented Jun 6, 2024

A couple issues with the current approach:

  • we don't seem to have the cross-signed device key available, so we need to re-cross-sign it every time, but that's an async operation, so it makes a bunch of things async. Is there a better way?
  • the function for cross-signing is only available within the crypto crate, but I'd rather do the signing in the storage crates so that we only need to do the signing once (and avoid some complexity), but I'm not sure what are the implications of changing the function from pub(crate) to pub

@poljar
Copy link
Contributor

poljar commented Jun 7, 2024

  • we don't seem to have the cross-signed device key available, so we need to re-cross-sign it every time, but that's an async operation, so it makes a bunch of things async. Is there a better way?

We do, well we do if a /keys/query has been done. It's part of the Device in the store. You'll have the same async problem though, since the Device isn't cached. I think re-cross-signing the device keys is not a good idea. We should use this signature iff it has been published to the server and it has to be the exact same signature that was published to the server, otherwise we'll just confuse ourselves. We'll have multiple valid, albeit different signatures for the same device keys.

  • the function for cross-signing is only available within the crypto crate, but I'd rather do the signing in the storage crates so that we only need to do the signing once (and avoid some complexity), but I'm not sure what are the implications of changing the function from pub(crate) to pub

I think that letting stores cross-sign should not happen at all, we don't control all store implementations and this is an obvious shift of responsiblity where store implementations need to care about cryptography to get things working correctly.

@uhoreg
Copy link
Member Author

uhoreg commented Jun 11, 2024

I think that this is ready to be reviewed now.

@uhoreg uhoreg marked this pull request as ready for review June 11, 2024 19:23
@uhoreg uhoreg requested a review from a team as a code owner June 11, 2024 19:23
@uhoreg uhoreg requested review from andybalaam and removed request for a team June 11, 2024 19:23
Copy link
Contributor

@andybalaam andybalaam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, with some minor comments and questions scattered around.

My main question is: if we don't find the device keys in the store, we generate them. Shouldn't we save them to the store at that point, so we don't end up generating them multiple times and risking inconsistency as @poljar mentioned in his previous comment?

I don't feel confident to give this full approval so will ask @poljar to take a look.

crates/matrix-sdk-crypto/src/olm/account.rs Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/account.rs Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/session.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/session.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/session.rs Show resolved Hide resolved
crates/matrix-sdk-indexeddb/src/crypto_store/mod.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-sqlite/src/crypto_store.rs Show resolved Hide resolved
@@ -1377,6 +1409,42 @@ mod encrypted_tests {
);
}

#[async_test]
async fn cache_cleared_after_device_update() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some test we can add to cryptostore_integration_tests for this? Then it would cover indexeddb, which I think is not covered so far in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can add this to cryptostore_integration_tests because memorystore works differently, and always keeps the sessions in cache (the cache can't be cleared). (But yes, I should add a test for indexeddb -- once I figure out how to run the indexeddb tests locally)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is now I ran the tests locally here:

cd crates/matrix-sdk-indexeddb/
WASM_BINDGEN_TEST_TIMEOUT=2400 CARGO_TARGET_DIR=/tmp/andyb-rust-target wasm-pack test --firefox --headless -- --no-default-features --features e2e-encryption

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that, but it gave me an error saying:

Try find `webdriver.json` for configure browser's capabilities:
Not found
driver status: signal: 9 (SIGKILL)

I wrote a test anyways and it seems to pass CI, so I'll ignore it for now, and try to figure it out later if needed.

@andybalaam andybalaam requested a review from poljar June 12, 2024 09:51
@poljar
Copy link
Contributor

poljar commented Jun 12, 2024

My main question is: if we don't find the device keys in the store, we generate them.

Have not looked at the whole PR yet, but please take a look at our constructor:

let device = ReadOnlyDevice::from_account(&account);
// We just created this device from our own Olm `Account`. Since we are the
// owners of the private keys of this device we can safely mark
// the device as verified.
device.set_trust_state(LocalTrust::Verified);
let changes = Changes {
devices: DeviceChanges { new: vec![device], ..Default::default() },
..Default::default()
};
store.save_changes(changes).await?;
store.save_pending_changes(PendingChanges { account: Some(account) }).await?;
debug!("Created a new Olm account");

We are guaranteed to have our own device keys and device in the store. We can add a method to the store called get_own_device() which will always return a device to make this clearer. Of course, this does not mean that we're guaranteed to have the cross-signing keys attached to our device.

@uhoreg uhoreg requested a review from andybalaam June 14, 2024 01:34
@uhoreg
Copy link
Member Author

uhoreg commented Jun 14, 2024

@andybalaam I think that I've addressed your comments. There's some CI issues that I still need to look into, but it should be reviewable otherwise.

Oh, I also need to change it to not generate a device key, since we're always guaranteed to have our own device key in the store.

Copy link
Contributor

@andybalaam andybalaam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good from my point of view, when the not generating device key part is done. Thanks!

Copy link

codecov bot commented Jun 14, 2024

Codecov Report

Attention: Patch coverage is 84.90566% with 8 lines in your changes missing coverage. Please review.

Project coverage is 84.11%. Comparing base (ed9ab87) to head (fc1dabf).

Files Patch % Lines
crates/matrix-sdk-crypto/src/olm/session.rs 66.66% 4 Missing ⚠️
crates/matrix-sdk-crypto/src/olm/account.rs 75.00% 3 Missing ⚠️
crates/matrix-sdk-sqlite/src/crypto_store.rs 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3517      +/-   ##
==========================================
- Coverage   84.14%   84.11%   -0.04%     
==========================================
  Files         255      255              
  Lines       26345    26369      +24     
==========================================
+ Hits        22168    22180      +12     
- Misses       4177     4189      +12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@uhoreg
Copy link
Member Author

uhoreg commented Jun 17, 2024

@poljar I think this is ready for review from you now. Some notes

  • It currently just uses the device keys from storage, and assumes that it will get updated after cross-signing is done, to include the cross-signing signatures. Is this true, or is there anything else that needs to be done? Is there a test that I should write to make sure that it gets updated?
  • Can you give your opinion on Embed device keys in Olm-encrypted messages #3517 (comment) ?
  • I'm currently not refreshing the sessions in memorystore with the device keys. Do I need to? Is memorystore used for any real purposes, or is it just for testing.

Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the general direction is good, left some questions/nits/suggestions.

crates/matrix-sdk-crypto/src/store/traits.rs Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/account.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/account.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/account.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/session.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/session.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/session.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-crypto/src/olm/session.rs Outdated Show resolved Hide resolved
crates/matrix-sdk-sqlite/src/crypto_store.rs Show resolved Hide resolved
crates/matrix-sdk-sqlite/src/crypto_store.rs Show resolved Hide resolved
Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some final nits, we should revert the SQLite query patch since it doesn't help.

Approving ahead of time, feel free to merge once the final nits have been resolved.

/// Error type describing different errors that can happen when we create an
/// Olm session from a pickle.
#[derive(Error, Debug)]
pub enum SessionPickleError {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think SessionUnpickleError might be marginally better, feel free to disagree.

crates/matrix-sdk-sqlite/src/crypto_store.rs Show resolved Hide resolved
@uhoreg
Copy link
Member Author

uhoreg commented Jun 26, 2024

I think I've addressed all outstanding comments. I don't have permissions to hit the merge button. Can someone do so for me?

},
"device_keys": self.our_device_keys,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this property need a different name:

Until this MSC is accepted, the new property should be named org.matrix.msc4147.device_keys.

We can do this in a follow up, so we don't risk more merge conflicts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@poljar poljar merged commit d41af39 into matrix-org:main Jun 27, 2024
38 checks passed
uhoreg added a commit to uhoreg/matrix-rust-sdk that referenced this pull request Jun 27, 2024
poljar pushed a commit that referenced this pull request Jul 1, 2024
It was added as a regular dependency in #3517
but it is only used in tests.

Signed-off-by: Kévin Commaille <[email protected]>
@richvdh
Copy link
Member

richvdh commented Jul 1, 2024

For some reason it doesn't seem to be mentioned in the PR 😠 but I believe this is implementing MSC4147.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants