-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add encrypted http pusher (MSC3013) #11512
base: develop
Are you sure you want to change the base?
Conversation
0ffcbcb
to
dc70952
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few thoughts.
I'm not a cryptography expert, but AFAICS this implements the process described in the MSC. I don't suppose you've had a chance to test it in action?
dc70952
to
848aed2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where possible, please try to avoid a force push. It makes it harder to see what's changed between review rounds!
I think the case of a missing public_key
needs handling, and the mypy config change to get rid of the type-ignore in the code would be nice to have (but not crucial).
Otherwise LGTM. Would appreciate another pair of eyes from @matrix-org/synapse-core though---sticking it into the review queue.
oh, totally missed this, yes this is tested in action |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks sensible, will wait for the discussed changes about which library to use for the Curve25519 exchange.
Thanks!
matrix-org/olm#53 may be relevant to the discussion about curve25519; we may have boxed ourselves into a corner. This is being looked at now. |
this is completely irrelevant to us. zhat issue is about how libolm stores and restores its ed25519 keys, and we never use libolm so it doesn't matter. we just take a public key and using it encrypt stuffs.
13. 12. 2021 16:21:25 Dan Callahan ***@***.***>:
… matrix-org/olm#53[matrix-org/olm#53] may be relevant to the discussion about curve25519; we may have boxed ourselves into a corner. This is being looked at now.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub[#11512 (comment)], or unsubscribe[https://github.com/notifications/unsubscribe-auth/AASSEVAGXGHH3CV3AJU2ZWTUQYFOZANCNFSM5JOR23SA].
Triage notifications on the go with GitHub Mobile for iOS[https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675] or Android[https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub]. [data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAArSURBVHic7cEBDQAAAMKg909tDjegAAAAAAAAAAAAAAAAAAAAAAAAAAA+DFFIAAEctgHwAAAAAElFTkSuQmCC###24x24:true###][Sledovací obrázek][https://github.com/notifications/beacon/AASSEVHQNGXQWRFORAPWPYDUQYFOZA5CNFSM5JOR23SKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOHMU2RBY.gif]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad to see the dependency stuff was sorted out.
I don't think we want to merge it as-is unless:
- the MSC is accepted, or
- these changes were guarded by an experimental config flag
because this change presently enables an unstandardised feature for all Synapse deployments.
Because of stuff that came up around encrypted push and iOS needing some slight adjustments soru marked this PR as WIP again, the main part of the PR will still the same, though. Will un-mark as WIP (should soru ping someone, then?) once those are resolved. EDIT: Oh, github doesn't allow re-marking a PR as WIP |
yes it does! have done so.
no need, it should automatically come up on our review queue. |
This PR is ready for review again. There are merge conflicts in this PR by now, should soru merge in master or rebase onto master? |
:) After there's already been discussion/review, prefer merge rather than rebase so that the conversations stay in place in the history of the PR. |
And note: please merge in develop, rather than master. |
…soru/encrypted-push
devices = cleartext_notif["devices"] | ||
del cleartext_notif["devices"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use
devices = cleartext_notif["devices"] | |
del cleartext_notif["devices"] | |
devices = cleartext_notif.pop("devices") |
As in https://docs.python.org/3/library/stdtypes.html?highlight=dict%20pop#dict.pop
# create the mac | ||
mac = hmac.new(mac_key, ciphertext, hashlib.sha256).digest()[0:8] | ||
|
||
d = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have a more descriptive name than d
here? encrypted_notification
or payload_with_encryption
?
# now, if the push frame is a counts only frame, we have to respect the counts_only_type setting | ||
if counts_only: | ||
if self.counts_only_type == "boolean": | ||
d["is_counts_only"] = True | ||
elif self.counts_only_type == "full": | ||
d["counts"] = cleartext_notif["counts"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this logic belongs in a function called _encrypt_notification_dict
---this isn't doing any encryption. I take the point that this is needed to make iOS E2EE work, but doesn't this setting make sense even if we don't want to use encryption?
Put differently: why is this tied to the use of curve25519-aes-sha2
specifically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the MSC https://github.com/Sorunome/matrix-doc/blob/soru/encrypted-push/proposals/3013-encrypted-push.md#ios
Why curve25519-aes-sha2
specifically? Because only plain and curve25519-aes-sha2 exist in this PR, and it is not in plain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so maybe call the method _process_notification_dict_for_sending
instead?
# do the exchange | ||
exchanged = X25519PrivateKey.from_private_bytes( | ||
unpaddedbase64.decode_base64(private_key) | ||
).exchange(X25519PublicKey.from_public_bytes(ephemeral)) | ||
# expand with HKDF | ||
zerosalt = bytes([0] * 32) | ||
prk = hmac.new(zerosalt, exchanged, hashlib.sha256).digest() | ||
aes_key = hmac.new(prk, bytes([1]), hashlib.sha256).digest() | ||
mac_key = hmac.new(prk, aes_key + bytes([2]), hashlib.sha256).digest() | ||
aes_iv = hmac.new(prk, mac_key + bytes([3]), hashlib.sha256).digest()[0:16] | ||
# create the cleartext with AES-CBC-256 | ||
decryptor = Cipher(algorithms.AES(aes_key), modes.CBC(aes_iv)).decryptor() | ||
# AES blocksize is always 128 bits | ||
unpadder = padding.PKCS7(128).unpadder() | ||
cleartext = json.loads( | ||
( | ||
unpadder.update(decryptor.update(ciphertext) + decryptor.finalize()) | ||
+ unpadder.finalize() | ||
).decode("utf-8") | ||
) | ||
# create the mac | ||
calculated_mac = hmac.new(mac_key, ciphertext, hashlib.sha256).digest()[0:8] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This look suspiciously like a test which re-implements the function under test. What's going on here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are testing if the encrypted push frame we created is decryptable. Soru was pondering between this and just testing if the mac/cipher/ephemeral we created are strings, however this seemed to at least have a bit more integrity. Due to the nature of the push frame being encrypted, we can't test its contents without decrypting them again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We aren't 100% re-implementing it, this is a decrypt implementation while in synapse is an encrypt implementation. But yeah, soru couldn't figure out a better way to test this, sadly :/
def tests_encrypted_push_counts_only_none(self): | ||
""" | ||
The HTTP pusher will not add any extra fields to encrypted push frames if the counts_only_type | ||
is none. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is none. | |
is none. | |
is 'none'. |
To avoid confusion with the Python object None
.
@@ -591,7 +793,7 @@ def test_push_unread_count_message_count(self): | |||
self.push_attempts[5][2]["notification"]["counts"]["unread"], 4 | |||
) | |||
|
|||
def _test_push_unread_count(self): | |||
def _test_push_unread_count(self, pusher_data=None, perform_checks=True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type annotations here, please.
That said, I'm not so keen on a method called _test_...
which might not actually enforce any assertions, i.e. if perform_checks
is falsey. What is the intention here? My first thought was that it was an optimisation to not run repeated checks that don't test anything new. But I think you're specifically opting out of the the checks which interrogate the unread count---because they need to be handled differently under the proposed scheme.
I think it would make more sense to create a new helper function
- which does setup only, making no assertions
- only does the minimum required to generate a counts-only and normal push notification (the present test helper seems to make many normal notifications?)
Hi, are you still interested in working on this? |
In general yes, but sorus health does not allow working lately :/
5. 8. 2022 11:44:55 reivilibre ***@***.***>:
… Hi, are you still interested in working on this?
—
Reply to this email directly, view it on GitHub[#11512 (comment)], or unsubscribe[https://github.com/notifications/unsubscribe-auth/AASSEVBUG6R3AVVQLZLVWJDVXTPBLANCNFSM5JOR23SA].
You are receiving this because you authored the thread.[Sledovací obrázek][https://github.com/notifications/beacon/AASSEVFUGVRTRE5KRTVLNMLVXTPBLA5CNFSM5JOR23SKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOI7TAWII.gif]
|
Pull Request Checklist
Server-side implementation of MSC3013 Encrypted Push matrix-org/matrix-spec-proposals#3013
EventStore
toEventWorkerStore
.".code blocks
.(run the linters)
Signed-Off-By: Sorunome [email protected]