Earlier we were using asymmetric cryptography.
We were using libsodium "sealed box" which is unauthenticated
by design. The sender could have been anyone, as long as they
had the receiver's public key.
We had authenticity but only because the device's public key
is effectively kept secret. We were relying on the public key
being kept secret - which was a security risk. It's easy to
end up with code somewhere that treats the public key as public,
and can leak it.
This commit makes changes to use symmetric cryptography -
libsodium's `crypto_secretbox_easy` which provides authenticated
encryption using XSalsa20 and Poly1305.
`push_public_key` is replaced with `push_key` and it represents
a base64 encoded 33-byte value: one-byte prefix followed by 32-byte
secret key generated by the client.
The prefix `0x31` indicates the current cryptosystem in use.
It allows for future extensibility - for example, `0x32` could denote
a different cryptosystem.
Involves API changes to replace the `push_public_key` parameter
with `push_key` in `/api/v1/mobile_push/register` endpoint.
Signed-off-by: Prakhar Pratyush <prakhar@zulip.com>
This commit adds an endpoint `/mobile_push/e2ee/test_notification`
to send an end-to-end encrypted test push notification to the user's
selected mobile device or all of their mobile devices.
This commit adds support to send encrypted push notifications
to devices registered to receive encrypted notifications.
URL: `POST /api/v1/remotes/push/e2ee/notify`
payload: `realm_uuid` and `device_id_to_encrypted_data`
The POST request needs to be authenticated with the server’s
API key.
Note: For Zulip Cloud, a background fact about the push bouncer is
that it runs on the same server and database as the main application;
it’s not a separate service. So, as an optimization we directly call
'send_e2ee_push_notifications' function and skip the HTTP request.
APNs apparently treats its tokens case-insensitively; FCM does not.
Adjust the `unique_together` to instead be separate partial
constraints, keyed on the `kind` of the PushDeviceToken.
This commit adds a `PushDevice` model where each row
corresponds to an account on an install of the app
that has attempted to register with the bouncer to
receive mobile push notifications.
This is the core server table storing registrations
that are potentially registered with the mobile push
notifications bouncer service.