-
Notifications
You must be signed in to change notification settings - Fork 0
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
WebPush over UnifiedPush #15
Comments
Links, might be useful to others or myself in the future: https://github.com/mozilla/rust-ece/ What is used for webpush crypto in firefox. https://github.com/chromium/chromium/blob/d7da0240cae77824d1eda25745c4022757499131/chrome/browser/push_messaging/push_messaging_service_impl.cc#L333 Chromium implementation |
It looks like we don't need a rewrite-proxy (https://www.rfc-editor.org/rfc/rfc8291.html#section-5) Also, we wrote the registration for android for fedilab a few months ago, it would not require a long time to use it for a library |
What is an example use case of this? What problem does it fix? Does web push on Android normally go through Google FCM? |
I guess my answer is this (from Element chat):
So UP is that single app that listens for requests |
IIRC, browsers use FCM for webpush. Also it is usefull for app implementing webpush (e.g. mastodon) |
This advantage is not necessarily for web browsers, but rather being able to use UP with application servers that already support webpush, and also benefitting from the encryption at the same time. |
There's no need for a rewrite proxy. |
Indeed. For webpush, salt, content-size and public key are sended following RFC8188 in the post data. source: RFC8291
Example:
Salt: Without a rewrite proxy, we only miss :
|
So I checked the following libraries, and they accept all 2XX status codes, don't check response headers, and don't support any advanced features (delivery receipts) of webpush based on my quick survey:
The only limitation with pywebpush is >202 response code is marked as failing. So from my rough survey, not adhering to rfc8030 super tightly (with response headers and extra but mandatory features such as receipt notifications) should be fine for most applications. i.e. another need for a reverse proxy - push response - is alleviated |
So, in terms of library API, we have two main options (if there are more good options, you can comment them below). This broadly applies to all libraries Android, Flutter, Linux IntegratedThe old API: func Register(instance string, distributor string)
func onNewEndpoint(endpoint string)
func Unregister(instance string) the new API func Register(instance string, distributor string)
func RegisterWithWebpush(instance string, distributor string)
func onNewEndpoint(endpoint string, p256dh string, auth string) // if using webpush, p256dh = auth = "" and can be ignored
func Unregister(instance string) Here, Separate libraryIn an func (webpush) generateKeys(instance string) (p256dh string, auth string) //this instance doesn't have to be the same as the UP library, but probably will be for simplicity
// it should save the private key automatically Then in func (webpush) decrypt(instance string, ciphertext []byte) (plaintext []byte)
//uses the stored keys for that instance and decrypts the text I think integrated will be simpler for devs (fewer imports, automatic decryption), but might result in more code to maintain for the core UP libraries - vice-versa for a separate library Also, if we want to encourage WebPush/encryption adoption for all UP apps, I think integrated is the way to go (since then there's one less step to take for encryption by app devs) Comments are welcome from everyone :), which do you prefer? |
The old API should be : func Register(instance string, distributor string)
func onNewEndpoint(instance string, endpoint string)
func Unregister(instance string) On my side, I see a 3rd option : a "unifiedpush_webpush" library that depends on the unifiedpush library (connector) : func Register(instance string, distributor string)
func onNewEndpoint(instance string, endpoint string, p256dh string, auth string) // if using webpush, p256dh = auth = "" and can be ignored
func Unregister(instance string) |
Changing 202 to 201 is a very insignificant change since 2xx is required to be accepted (and most webpush implementations accept 2xx anyway UnifiedPush/wishlist#15 (comment)) However, it is a minor way in which UnifiedPush can be similar to WebPush and could matter to pickier implementations. 201 is required in webpush. https://datatracker.ietf.org/doc/html/rfc8030#section-5
Changing 202 to 201 is a very insignificant change since 2xx is required to be accepted (and most webpush implementations accept 2xx anyway UnifiedPush/wishlist#15 (comment)) However, it is a minor way in which UnifiedPush can be similar to WebPush and could matter to pickier implementations. 201 is required in webpush. https://datatracker.ietf.org/doc/html/rfc8030#section-5
Just doing some reading. This was the change in (the future) RFC8188 that resulted in moving keys from headers to the body: httpwg/http-extensions#252 This is where it started affecting WebPush: https://mailarchive.ietf.org/arch/msg/webpush/aLfZBx6wZRKMZ7X2AG_t1X2TlIE/ webpush-wg/webpush-encryption#9 https://mailarchive.ietf.org/arch/msg/webpush/19pz0qIZBNN0GheAmKu72cYLr9k/
totally agree with Costin |
ok so, gateway idea: 1. DiscoveryTurn 2. Gateway operationIf Content-Encoding == "aesgcm", convert the data in "crypto-key" and "encryption" to the following body header used in aes128gcm WebPush.
OR Alternative Gateway operationIf "crypto-key" and "encryption" headers exist, simply append them to the message body. This trades server complexity for client library complexity, which then has to parse and decrypt both formats. If the "cryptokey" gateway is not supported by the endpoint, fall back to Like Matrix, this is probably simple and non-intrusive enough to be included natively in push servers. I will experiment with this stuff as soon as I have some time. |
also, a ton of application servers still use the old protocol (aesgcm) (image from March 2021, but I doubt it's changed that much) |
So, I spent way too long figuring this out So to appending headers it is. |
UP-Example now supports WebPush: https://github.com/UnifiedPush/android-example/tree/1.5.2 I don't think it is useful to have yet another lib for WebPush over UnifiedPush. What do you think about leaving flutter-connector-webpush too ? We probably can just write an example. |
Yeah, it's probably fine if we make a docs page explaining how to use the Store and WebPush classes. Maybe the actual decryption could also be a function in the library, just to create a strong boundary between the 'scary cryptography' parts and app logic? |
Hi @jrconlin 👋 UnifiedPush is an open source protocol for Android (and Linux) push notifications. As we're working on increased WebPush compatibility, I was curious as to what that graph looks like nowadays? Is aesgcm still dominant? Thanks for all your open source WebPush tooling. |
Sigh. If anything, it's gotten worse. Apparently, if you provide libraries for an early version of a protocol, expect that version to live forever. Just to recap, For Theoretically, you might be able to convert between |
🙁. Yeah, part of the issue we've noticed is on the app side too. For example, Mastodon has various WebPush -> FCM/APNS proxies that use I kinda hoped Apple, having the market power, would only support
Yes, handling headers is the main complication in adding
I tried doing that, but realized that the nonces for key derivation are different on the two standards. So, unfortunately it won't be possible to adapt on the push server (without private keys). Thanks for the information though! |
Ah, crap, you're right. I forgot about the nonces. The silly thing is that I reached out to a bunch of the library authors a couple of years ago and encouraged them to switch to (Extra fun fact: supporting both on the message server is also a serious pain. Technically, there were three standards for a while but we dropped the oldest. I would love to be able to work with the other folk at Google, Apple and Microsoft to declare |
To summarize:
IMO, it is better to stay with the webpush specification, sync on push is sufficient for applications that only support the draft specification. What do you think ? Concerning Mastodon, I think the best thing is to publish a draft-webpush gem, based on webpush gem so they can support both |
FWIW, I'm absolutely fine with only working against the RFC spec. Feel free to note that the RFC has been out for 7 years and that most major WebPush libraries support it. Make using Needless to say, I'll be cheering for y'all so that folk finally stop using the old specification. |
Considering that currently there is no WebPush support, I strongly agree with progress towards at least standards compatible WebPush support. The draft version support will hopefully become less relevant over time, and if it doesn't it can be reconsidered to be solved later? The standard support hopefully becomes more relevant over time. |
UnifiedPush is compatible with WebPush. Its support is limited (e.g. urgency is ignored) but since an accepted push message returns a 201 with |
What do you think about closing this issue ? UP supports (in a limited way, with TTL: 0) WebPush. This opened issue seems to add some confusion If someone feels the need to, maybe we can open an issue to Extend WebPush support to add TTL>0, the ability to delete messages, even urgency etc. |
I'm closing it then.
|
A compatibility layer. Needs implementations in connectors and a rewrite proxy, afaict. It would be very useful to be able to rely on all the existing crypto for an e2ee UnifiedPush experience.
The text was updated successfully, but these errors were encountered: