Difference between revisions of "Apple Push Service Protocol"

From The iPhone Wiki
Jump to: navigation, search
(Message Structure: items may repeat)
(09 Push Topics: Add more items, and explain topic hashes)
Line 85: Line 85:
 
*command ID: <code>09</code>
 
*command ID: <code>09</code>
 
*items:
 
*items:
**<code>02</code> 20-byte ID for enabled topic (like topic for push-enabled app or a specific iCloud service like Find My iPhone)
+
**<code>02</code> 20-byte hash for enabled topics
**<code>03</code> 20-byte ID for disabled topic
+
**<code>03</code> 20-byte hash for disabled topics
  +
**<code>04</code> 20-byte hash for "opportunistic" topics
  +
**<code>05</code> 20-byte hash for "paused" topics
  +
  +
Note that there are multiple items with the same numeric ID,
  +
one for each topic hash.
  +
  +
"Topic hashes" are SHA-1 hashes of the topic name (a reverse-DNS string).
  +
This can be an internal topic name used by an Apple service,
  +
or for third party apps, the app bundle ID.
  +
For example, iMessage notifications have topic hash <code>e4e6d952954168d0a5db02dbaf27cc35fc18d159</code>,
  +
which corresponds to `sha1("com.apple.madrid")`.
   
 
===0A Push Notification===
 
===0A Push Notification===

Revision as of 02:27, 11 August 2021

iOS devices connect to Apple's push servers via port 5223. The protocol is proprietary and has nothing to do with XMPP (which uses the same port to establish SSL-encrypted client connections). The Push service protocol also uses SSL encryption.

As of iOS5, Apple uses a new push protocol. The same protocol is used on the Mac too. With iOS4, the protocol used command IDs 00 to 06, while the new protocol uses command IDs starting on 07 and all fields in a message (called "items") have a consistent type-length-value encoding.

While every iOS version after that continued adding new commands and items, since iOS 10 there is another new push protocol known as "apnspack", which uses the same command and item IDs but encodes them in a completely different binary format. The client negotiates use of this new protocol with the protocol name "apns-pack-v1" in ALPN. The apnspack format is not yet documented in this page.

Message Structure

The format of the non-packed APNS protocol is as follows:

  • 1 byte message type ("command ID")
  • 4 byte payload length
  • items, all with
    • 1 byte type
    • 2 byte length
    • value

All integers are big-endian.

Example:

  • 07 command ID (Connect)
  • 00 00 00 27 39 byte payload length
  • 01 item 1
    • 00 20 32 byte length
    • 8a 73 82 00 82 ac 91 32 88 b6 aa ef 90 91 65 ce 8a 73 82 00 82 ac 91 32 88 b6 aa ef 90 91 65 ce value 1 (32-byte push token)
  • 02 item 2
    • 00 01 1 byte length
    • 01 value

Items may be repeated (multiple items with the same ID). For example, command 09 "push topics" has multiple items 02 "enabled topic", one for each topic hash to be enabled.

Commands

Note that some items are optional, either because they're only sent depending on certain conditions, or because they were introduced in a later iOS version and earlier ones don't send it. That will be documented in more detail later.

07 Connect

First command sent after SSL handshake is completed.

When a device is first activated, it doesn't have a push token yet. This command 07 is sent without a token, and the server returns a new token in its command 08 reply. In all future connections, the device sends the token in command 07, and the server doesn't return a token in command 08.

  • Direction: device to server
  • command ID: 07
  • items:
    • 01 32-byte push token
    • 02 1 byte "state" (value 01)
    • 05 4-byte flags, bitfield (example from iOS 12: 00 00 02 6a)
    • 06 1 byte interface (0: cellular, 1: Wi-Fi)
    • 08 cellular carrier name (or the string "WiFi")
    • 09 OS version (example: 12.4.8)
    • 0a OS build (example: 16G201)
    • 0b hardware version (example: iPhone6,1)
    • 0c certificate, contains the X.509 "device certificate" obtained during device activation
    • 0d 17-byte nonce, consisting of 1 byte fixed 00, 8 bytes timestamp (milliseconds since Unix epoch), 8 bytes random
    • 0e "signature", consisting of fixed bytes 01 01, followed by RSASSA-PKCS1-SHA1 signature of the nonce (0d) using the public key in the certificate (0c)
    • 10 2-byte int, possibly protocol version
    • 11 2-byte int, "redirect count"
    • 13 2-byte int, "DNS resolve time" in milliseconds
    • 14 2-byte int, "TLS handshake time" in milliseconds

08 Connect Response

  • Direction: server to device
  • command ID: 08
  • items:
    • 01 status (00 ok, 02 some error)
    • 03 32-byte push token (unless the device sent one in Connect)
    • 04 2-byte int, max message size (value 10 00)
    • 05 unknown (value 00 02)
    • 06 capabilities (bitfield)
    • 08 2-byte int, large message size
    • 0a 8-byte int, server time, milliseconds since unix epoch
    • 0b 2 bytes, geo region (country code)

The lowest significant bit in 'capabilities' seems to mean "dual channel support" (possibly related to the iPhone proxying Apple Watch notifications).

09 Push Topics

  • Direction: device to server
  • command ID: 09
  • items:
    • 02 20-byte hash for enabled topics
    • 03 20-byte hash for disabled topics
    • 04 20-byte hash for "opportunistic" topics
    • 05 20-byte hash for "paused" topics

Note that there are multiple items with the same numeric ID, one for each topic hash.

"Topic hashes" are SHA-1 hashes of the topic name (a reverse-DNS string). This can be an internal topic name used by an Apple service, or for third party apps, the app bundle ID. For example, iMessage notifications have topic hash e4e6d952954168d0a5db02dbaf27cc35fc18d159, which corresponds to `sha1("com.apple.madrid")`.

0A Push Notification

  • Direction: server to device (for iMessage and possibly others too, also the other way round)
  • command ID: 0a
  • items:
    • 01 recipient push token
    • 02 topic
    • 03 notification payload
    • 04 response token
    • 05 expiry (32-bit UNIX timestamp)
    • 06 timestamp (64-bit UNIX timestamp in nanoseconds)
    • 07 unknown (00)

0B Push Notification Response

  • Direction: server to device (for iMessage and possibly others too, also the other way round)
  • command ID: 0b
  • items:
    • 04 response token
    • 08 status (00 ok, 02 error)

0C Keep-Alive

  • Direction: device to server
  • command ID: 0c
  • items:
    • 01 connection method ("WiFi" or GSM MNC like "31038" for AT&T)
    • 02 iOS version, e.g. "5.0"
    • 03 iOS build number
    • 04 device model, e.g. "iPhone2,1"
    • 05 unknown (values like 10, 15 or 20)

0D Keep-Alive Confirmation

  • Direction: server to device
  • command ID: 0d
  • no items

0E No Storage

  • Direction: server to device
  • command ID: 0e
  • items:
    • 03 32-byte push token

0F Flush

  • Direction: both
  • command ID: 0f
  • items:
    • 2-byte integer indicating length of padding
    • padding: NULL-bytes, typical lengths are 64, 128, 256, 512

References