mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-03-31 01:05:57 +00:00
421 lines
16 KiB
Markdown
421 lines
16 KiB
Markdown
Version 3, 2025-01-24
|
||
|
||
# Overview of push notifications for SimpleX Messaging Routers
|
||
|
||
This document describes Notification Router protocol version 3. Version history:
|
||
- v1: initial version
|
||
- v2: authenticated commands, command batching
|
||
- v3: detailed invalid token reason
|
||
|
||
## Table of contents
|
||
|
||
- [Introduction](#introduction)
|
||
- [Participating routers](#participating-routers)
|
||
- [Register device token to receive push notifications](#register-device-token-to-receive-push-notifications)
|
||
- [Subscribe to connection notifications](#subscribe-to-connection-notifications)
|
||
- [SimpleX Notification Router protocol](#simplex-notification-router-protocol)
|
||
- [Register new notification token](#register-new-notification-token)
|
||
- [Verify notification token](#verify-notification-token)
|
||
- [Check notification token status](#check-notification-token-status)
|
||
- [Replace notification token](#replace-notification-token)
|
||
- [Delete notification token](#delete-notification-token)
|
||
- [Subscribe to periodic notifications](#subscribe-to-periodic-notifications)
|
||
- [Create SMP message notification subscription](#create-smp-message-notification-subscription)
|
||
- [Check notification subscription status](#check-notification-subscription-status)
|
||
- [Delete notification subscription](#delete-notification-subscription)
|
||
- [Error responses](#error-responses)
|
||
- [Threat model](#threat-model)
|
||
|
||
## Introduction
|
||
|
||
SimpleX Messaging routers already operate as push routers and deliver the messages to subscribed clients as soon as they are sent to the routers.
|
||
|
||
The reason for push notifications is to support instant message notifications on iOS that does not allow background services.
|
||
|
||
## Participating routers
|
||
|
||
The diagram below shows which routers participate in message notification delivery.
|
||
|
||
While push provider (e.g., APN) can learn how many notifications are delivered to the user, it cannot access message content, even encrypted, or any message metadata - the notifications are e2e encrypted between SimpleX Notification Router and the user's device.
|
||
|
||
```
|
||
User's iOS device Internet Routers
|
||
--------------------- . ------------------------ . -----------------------------
|
||
. .
|
||
. . can be self-hosted now
|
||
+--------------+ . . +----------------+
|
||
| SimpleX Chat | -------------- TLS --------------- | SimpleX |
|
||
| client |------> SimpleX Messaging Protocol (SMP) ------> | Messaging |
|
||
+--------------+ ---------------------------------- | Router |
|
||
^ | . . +----------------+
|
||
| | . . . . . | . . .
|
||
| | . . | V |
|
||
| | . . |SMP| TLS
|
||
| | . . | | | SimpleX
|
||
| | . . . . . V . . . NTF Router
|
||
| | . . +----------------------------------+
|
||
| | . . | +---------------+ |
|
||
| | -------------- TLS --------------- | | SimpleX | can be |
|
||
| |-----------> Notification Router Protocol -----> | | Notifications | self-hosted |
|
||
| ---------------------------------- | | Subscriber | in the future |
|
||
| . . | +---------------+ |
|
||
| . . | | |
|
||
| . . | V |
|
||
| . . | +---------------+ |
|
||
| . . | | SimpleX | |
|
||
| . . | | Push | |
|
||
| . . | | Router | |
|
||
| . . | +---------------+ |
|
||
| . . +----------------------------------+
|
||
| . . . . . | . . .
|
||
| . . | V |
|
||
| . . |SMP| TLS
|
||
| . . | | |
|
||
| . . . . . V . . .
|
||
| -------------- TLS --------------- +-----------------+
|
||
|----------------- Notification delivery <-------| Apple PN server |
|
||
---------------------------------- +-----------------+
|
||
. .
|
||
```
|
||
|
||
## Register device token to receive push notifications
|
||
|
||
This diagram shows the process of registering a device to receive PUSH notifications via Apple Push Notification (APN) servers.
|
||
|
||

|
||
|
||
## Subscribe to connection notifications
|
||
|
||
This diagram shows the process of subscription to notifications, notification delivery and device token update.
|
||
|
||

|
||
|
||
## SimpleX Notification Router protocol
|
||
|
||
To manage notification subscriptions to SMP routers, SimpleX Notification Router provides an RPC protocol with a similar design to SimpleX Messaging Protocol router.
|
||
|
||
This protocol sends requests and responses in a fixed size blocks of 512 bytes over TLS, uses the same [syntax of protocol transmissions](./simplex-messaging.md#smp-transmission-and-transport-block-structure) as SMP protocol, and has the same transport [handshake syntax](./simplex-messaging.md#transport-handshake) (except the router certificate is not included in the handshake).
|
||
|
||
The client and router use ALPN extension with `ntf/1` protocol name to agree handshake version.
|
||
|
||
Protocol commands have this syntax:
|
||
|
||
```abnf
|
||
ntfRouterTransmission = authorization corrId entityId ntfRouterCmd
|
||
; same transmission structure as SMP, see simplex-messaging.md
|
||
ntfRouterCmd = newTokenCmd / verifyTokenCmd / checkTokenCmd /
|
||
replaceTokenCmd / deleteTokenCmd / cronCmd /
|
||
newSubCmd / checkSubCmd / deleteSubCmd / pingCmd
|
||
```
|
||
### Register new notification token
|
||
|
||
This command should be used after the client app obtains a token from push notifications provider to register the token with the router.
|
||
|
||
Having received this command the router will deliver a test notification via the push provider to validate that the client has this token.
|
||
|
||
The command syntax:
|
||
|
||
```abnf
|
||
newTokenCmd = %s"TNEW" SP newToken
|
||
newToken = %s"T" deviceToken authPubKey clientDhPubKey
|
||
deviceToken = pushProvider tokenString
|
||
pushProvider = apnsDev / apnsProd / apnsTest / apnsNull
|
||
apnsDev = "AD" ; APNS token for development environment
|
||
apnsProd = "AP" ; APNS token for production environment
|
||
apnsTest = "AT" ; APNS token for test environment (mock server)
|
||
apnsNull = "AN" ; token that does not trigger any notification delivery - used for router testing
|
||
tokenString = shortString
|
||
authPubKey = length x509encoded ; Ed25519 key used to verify clients commands
|
||
clientDhPubKey = length x509encoded ; X25519 key to agree e2e encryption between the router and client
|
||
shortString = length *OCTET
|
||
length = 1*1 OCTET
|
||
```
|
||
|
||
The router response syntax:
|
||
|
||
```abnf
|
||
tokenIdResp = %s"IDTKN" SP entityId routerDhPubKey
|
||
entityId = shortString
|
||
routerDhPubKey = length x509encoded ; X25519 key to agree e2e encryption between the router and client
|
||
```
|
||
|
||
### Verify notification token
|
||
|
||
This command is used to verify the token after the device receives the test notification from the push provider.
|
||
|
||
The command syntax:
|
||
|
||
```abnf
|
||
verifyTokenCmd = %s"TVFY" SP regCode
|
||
regCode = shortString
|
||
```
|
||
|
||
The response to this command is `okResp` or `errorResp`
|
||
|
||
```abnf
|
||
okResp = %s"OK"
|
||
```
|
||
|
||
### Check notification token status
|
||
|
||
This command is used to check the token status:
|
||
|
||
```abnf
|
||
checkTokenCmd = %s"TCHK"
|
||
```
|
||
|
||
The response to this command:
|
||
|
||
```abnf
|
||
tokenStatusResp = %s"TKN" SP tokenStatus
|
||
tokenStatus = %s"NEW" / %s"REGISTERED" / tokenInvalid / %s"CONFIRMED" / %s"ACTIVE" / %s"EXPIRED"
|
||
tokenInvalid = %s"INVALID" ["," invalidReason] ; optional reason added in v3
|
||
invalidReason = %s"BAD" / %s"TOPIC" / %s"EXPIRED" / %s"UNREGISTERED"
|
||
```
|
||
|
||
### Replace notification token
|
||
|
||
This command should be used when push provider issues a new notification token.
|
||
|
||
It happens when:
|
||
- the app data is migrated to another device.
|
||
- the app is re-installed on the same device.
|
||
- can happen periodically, at push provider discretion.
|
||
|
||
This command allows to replace the token without re-registering and re-subscribing all notification subscriptions.
|
||
|
||
Using this command triggers the same verification flow as registering a new token.
|
||
|
||
The command syntax:
|
||
|
||
```abnf
|
||
replaceTokenCmd = %s"TRPL" SP deviceToken
|
||
```
|
||
|
||
The response to this command is `okResp` or `errorResp`.
|
||
|
||
### Delete notification token
|
||
|
||
The command syntax:
|
||
|
||
```abnf
|
||
deleteTokenCmd = %s"TDEL"
|
||
```
|
||
|
||
The response to this command is `okResp` or `errorResp`.
|
||
|
||
After this command all message notification subscriptions will be removed and no more notifications will be sent.
|
||
|
||
### Subscribe to periodic notifications
|
||
|
||
This command enables or disables periodic notifications sent to the client device irrespective of message notifications.
|
||
|
||
This is useful for two reasons:
|
||
- it provides better privacy from notification router, as while the router learns the device token, it doesn't learn anything else about user communications.
|
||
- it allows to receive messages when notifications were dropped by push provider, e.g. while the device was offline, or lost by notification router, e.g. while it was restarting.
|
||
|
||
The command syntax:
|
||
|
||
```abnf
|
||
cronCmd = %s"TCRN" SP interval
|
||
interval = 2*2 OCTET ; Word16, minutes
|
||
```
|
||
|
||
The interval for periodic notifications is set in minutes, with the minimum of 20 minutes. The client should pass `0` to disable periodic notifications.
|
||
|
||
### Create SMP message notification subscription
|
||
|
||
This command makes notification router subscribe to message notifications from SMP router and to deliver them to push provider:
|
||
|
||
```abnf
|
||
newSubCmd = %s"SNEW" SP newSub
|
||
newSub = %s"S" tokenId smpRouter notifierId notifierKey
|
||
tokenId = shortString ; returned in response to `TNEW` command
|
||
smpRouter = hosts port fingerprint
|
||
hosts = length 1*host
|
||
host = shortString
|
||
port = shortString
|
||
fingerprint = shortString
|
||
notifierId = shortString ; returned by SMP router in response to `NKEY` SMP command
|
||
notifierKey = length x509encoded ; private key used to authorize requests to subscribe to message notifications
|
||
```
|
||
|
||
The response syntax:
|
||
|
||
```abnf
|
||
subIdResp = %s"IDSUB" SP entityId
|
||
```
|
||
|
||
### Check notification subscription status
|
||
|
||
This command syntax:
|
||
|
||
```abnf
|
||
checkSubCmd = %s"SCHK"
|
||
```
|
||
|
||
The response:
|
||
|
||
```abnf
|
||
subStatusResp = %s"SUB" SP subStatus
|
||
subStatus = %s"NEW" / %s"PENDING" / ; e.g., after SMP router disconnect/timeout while ntf router is retrying to connect
|
||
%s"ACTIVE" / %s"INACTIVE" / %s"END" / ; if another router subscribed to notifications
|
||
%s"AUTH" / %s"DELETED" / %s"SERVICE" / subErrStatus
|
||
subErrStatus = %s"ERR" SP *OCTET
|
||
```
|
||
|
||
### Delete notification subscription
|
||
|
||
The command syntax:
|
||
|
||
```abnf
|
||
deleteSubCmd = %s"SDEL"
|
||
```
|
||
|
||
The response to this command is `okResp` or `errorResp`.
|
||
|
||
After this command no more message notifications will be sent from this queue.
|
||
|
||
### Keep-alive command
|
||
|
||
To keep the transport connection alive the clients should use `PING` command:
|
||
|
||
```abnf
|
||
pingCmd = %s"PING"
|
||
pongResp = %s"PONG"
|
||
```
|
||
|
||
This command is sent unsigned and without entity ID.
|
||
|
||
### Error responses
|
||
|
||
All commands can return error response:
|
||
|
||
```abnf
|
||
errorResp = %s"ERR" SP errorType
|
||
```
|
||
|
||
Where `errorType` has the same syntax as in [SimpleX Messaging Protocol](./simplex-messaging.md#error-responses)
|
||
|
||
## Threat Model
|
||
|
||
This threat model compliments SimpleX Messaging Protocol [threat model](./security.md#threat-model)
|
||
|
||
#### A passive adversary able to monitor the traffic of one user
|
||
|
||
*can:*
|
||
|
||
- identify that and a user is using SimpleX push notifications.
|
||
|
||
*cannot:*
|
||
|
||
- determine which routers a user subscribed to the notifications from.
|
||
|
||
#### A passive adversary able to monitor a set of senders and recipients
|
||
|
||
*can:*
|
||
|
||
- perform more efficient traffic correlation attacks against senders and recipients and correlate senders and recipients within the monitored set, frustrated by the number of users on the routers.
|
||
|
||
#### SimpleX Messaging Protocol router
|
||
|
||
*can:*
|
||
|
||
- learn which messages trigger push notifications.
|
||
|
||
- learn IP address of SimpleX notification routers used by the user.
|
||
|
||
- drop message notifications.
|
||
|
||
- spam a user with invalid notifications.
|
||
|
||
*cannot:*
|
||
|
||
- learn user device token for push notifications.
|
||
|
||
- learn which queues belong to the same users with any additional efficiency compared with not using push notifications.
|
||
|
||
#### SimpleX Notification Router subscribed to message notifications
|
||
|
||
*can:*
|
||
|
||
- learn a user device token.
|
||
|
||
- learn how many messaging queues and routers a user receives messages from.
|
||
|
||
- learn how many message notifications are delivered to the user from each queue.
|
||
|
||
- undetectably drop notifications.
|
||
|
||
- spam a user with background notifications.
|
||
|
||
*cannot:*
|
||
|
||
- learn queue addresses for receiving or sending messages.
|
||
|
||
- learn the contents or type of messages (not even encrypted).
|
||
|
||
- learn anything about messages sent without notification flag.
|
||
|
||
- spam a user with visible notifications (provided the client app can filter push notifications).
|
||
|
||
- add, duplicate, or corrupt individual messages that will be shown to the user.
|
||
|
||
#### SimpleX Notification Router subscribed ONLY to periodic notifications
|
||
|
||
*can:*
|
||
|
||
- learn a user device token.
|
||
|
||
- drop periodic notifications.
|
||
|
||
- spam a user with background notifications.
|
||
|
||
*cannot:*
|
||
|
||
- learn how many messaging queues and routers a user receives messages from.
|
||
|
||
- learn how many message notifications are delivered to the user from each queue.
|
||
|
||
- learn queue addresses for receiving or sending messages.
|
||
|
||
- learn the contents or type of messages (not even encrypted).
|
||
|
||
- learn anything about messages sent without notification flag.
|
||
|
||
- spam a user with visible notifications (provided the client app can filter push notifications).
|
||
|
||
- add, duplicate, or corrupt individual messages that will be shown to the user.
|
||
|
||
#### A user’s contact
|
||
|
||
*cannot:*
|
||
|
||
- determine if a user uses push notifications or not.
|
||
|
||
#### Push notification provider (e.g., APN)
|
||
|
||
*can:*
|
||
|
||
- learn that a user uses SimpleX app.
|
||
|
||
- learn how many notifications are delivered to user's device.
|
||
|
||
- drop notifications (in fact, APN coalesces notifications delivered while user's device is offline, delivering only the last one).
|
||
|
||
*cannot:*
|
||
|
||
- learn which SimpleX Messaging Protocol routers are used by a user (notifications are e2e encrypted).
|
||
|
||
- learn which or how many messaging queues a user receives notifications from.
|
||
|
||
- learn the contents or type of messages (not even encrypted, notifications only contain encrypted metadata).
|
||
|
||
#### An attacker with Internet access
|
||
|
||
*cannot:*
|
||
|
||
- register notification token not present on attacker's device.
|
||
|
||
- enumerate tokens or subscriptions on a SimpleX Notification Router.
|