Commit Graph

9 Commits

Author SHA1 Message Date
Prakhar Pratyush
7ebdca52e8 push_notification: Use symmetric cryptography to encrypt notifications.
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>
2025-11-07 12:00:39 -08:00
Prakhar Pratyush
3cbf0e70a2 push_notification: Add support to send E2EE test push notification.
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.
2025-08-13 00:13:50 -07:00
Prakhar Pratyush
7e1afa0e8a push_notification: Send end-to-end encrypted push notifications.
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.
2025-07-22 17:08:55 -07:00
Alex Vandiver
2f4dd72076 push_notifications: Adjust APNs tokens to be case-insensitive in the database.
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.
2025-07-22 14:30:13 -07:00
Prakhar Pratyush
5f8edf669d zerver: Add endpoint to register a push device to server.
This commit adds an endpoint to register a push device
to receive E2EE push notifications.
2025-07-14 14:52:39 -07:00
Prakhar Pratyush
6a4b06b6f4 zerver: Add PushDevice model.
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.
2025-07-14 14:52:38 -07:00
Anders Kaseorg
c03839f42f mypy: Reenable explicit-override for models.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-08-01 17:39:04 -07:00
Mateusz Mandera
00b8cce50e push_notifs: Rename PushDeviceToken.GCM to FCM. 2024-06-17 18:22:59 -07:00
Anders Kaseorg
5391ec99d9 models: Extract zerver.models.push_notifications.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00