GPG
GPG key management
To ensure all updates are signed, yet allow us to allow external entities to sign updates and handle the case where our key is compromised, the following GPG setup will be implemented.
Two different bits need to do GPG verification:
- Update client (validate channels.json, index.json and all files)
- Upgrader (validate all files)
The following GPG key chain will be used:
MASTER: 3F272F5B 2007-11-09 Ubuntu Archive Master Signing Key <ftpmaster@ubuntu.com>
PHABLET MASTER: Ubuntu Phablet Master Signing Key <phablet@ubuntu.com>
PHABLET SIGNING: Ubuntu Phablet Signing Key (2013) <phablet@ubuntu.com>
The phablet image will ship with both the MASTER and PHABLET MASTER keys in its keyring. The recovery image will ship with only the MASTER key in its keyring.
The client has 4 keyrings:
- master - mandatory, persistent, contains the MASTER key (never changes)
- phablet - mandatory, persistent, contains PHABLET MASTER keys (in theory, never changes)
- signing - mandatory, persistent, contains PHABLET SIGNING keys (are rotated occasionally)
- device - optional, temporary, contains the keys valid for the index.json and update files for the device
Images will contain the current keys in master, phablet and signing to avoid useless re-downloads.
The client pushes the phablet, signing and device (if present) keyrings to the cache partition for the upgrader to use.
The upgrader also uses all 4 keyrings but only stores the master keyring, all the others are read from the update location (android:/cache).
Files
https://server/gpg/keys.crl contains a list of revocation certificates. Signed DIRECTLY by the PHABLET MASTER key for all keys but the PHABLET MASTER itself which needs to be signed DIRECTLY by the MASTER key.
https://server/gpg/phablet.gpg is a GPG keyring DIRECTLY signed by the MASTER key.
https://server/gpg/signing.gpg is a GPG keyring DIRECTLY signed by the PHABLET MASTER key.
https://server/channels.json is ALWAYS DIRECTLY signed by the current PHABLET SIGNING key.
https://server/<channel>/<device>/index.json is ALWAYS DIRECTLY signed by a key contained in the keyring linked from channels.json or if no keyring linked, by the current PHABLET SIGNING key.
https://server/<channel>/<device>/device.gpg is a GPG keyring DIRECTLY signed by the current PHABLET SIGNING key.
Use cases
Standard update
- The client has the MASTER key, the current PHABLET MASTER key and the current PHABLET SIGNING key in its keyring.
The client downloads the CRL from https://server/gpg/keys.crl
The client attempts to grab https://server/channels.json, validates that it's DIRECTLY signed by a key contained in the signing keyring which needs to be DIRECTLY signed by a key contained in the phablet keyring which in turns needs to be DIRECTLY signed by a key in the master keyring.
- The client looks for the entry for the channel and device in use, if present it looks for and downloads a signed GPG keyring, validates it's DIRECTLY signed by a key contained in the signing keyring and makes it the device keyring.
The client then downloads and validates https://server/<channel>/<device>/index.json against the device keyring (if present) and the signing keyring.
- The update is then resolved, all files downloaded and validated against the device keyring (if present) and the signing keyring and copied to android:/cache/.
- The client then exports PHABLET MASTER as android:/cache/phablet.gpg
- The client then exports PHABLET SIGNING as android:/cache/signing.gpg
- The client then exports the device keyring as android:/cache/device.gpg (if present)
- The client writes the CRL into the recovery partition
- The upgrader loads the CRL
- {for every file}
- The upgrader checks that the file is DIRECTLY signed by a key stored in either device.gpg (if present) or signing.gpg
- If device.gpg is present, and the file is signed by a device key, the upgrader checks that the device key is DIRECTLY signed by a key stored in signing.gpg
- The upgrader checks that the signing key is DIRECTLY signed by a key stored in phablet.gpg
- The upgrader checks that the phablet key is DIRECTLY signed by the MASTER key which it has locally.
- Once all checks pass, the file is unpacked and applied
Revocation of a device key
- The revoked key is added to the CRL on the server (entry signed by the PHABLET MASTER key)
The client downloads https://server/gpg/keys.crl and validates it against the MASTER key
- The client pushes the CRL to the recovery partition
- Everything continues as usual
Revocation of a signing key
- The revoked key is added to the CRL on the server (entry signed by the PHABLET MASTER key)
The client downloads https://server/gpg/keys.crl and validates it against the MASTER key
- The client pushes the CRL to the recovery partition
The client will fail to validate https://server/channels.json and grab the new signing key from https://server/gpg/signing.gpg, validate it against the master keyring and load it
- Everything continues as usual
Revocation of the PHABLET MASTER key
- The revoked key is added to the CRL on the server (entry signed by the MASTER key)
The client downloads https://server/gpg/keys.crl and validates it against the MASTER key
- The client pushes the CRL to the recovery partition
The client will fail to validate https://server/channels.json and grab the new signing key from https://server/gpg/signing.gpg, try to validate it and fail.
The client will then grab https://server/gpg/phablet.gpg validate it against the master keyring and load it.
The client will then retry the new https://server/gpg/signing.gpg validate it against the master keyring and load it.
- Everything continues as usual