CloudSecureAreaProtocol

This describes the protocol (messages and constants) between the device and the server for the Cloud Secure Area.

Throughout, the term device or client is used to refer to an Mobile Application (usually a so-called Wallet App) and using a SecureArea implementation which is implementing this protocol, for example the CloudSecureArea class.

Similarly, the term server or cloud is used to refer to server-side of the Cloud Secure Area and Secure Area is used to refer to the part of this server-side which may be implemented in an isolated execution environment with additional protections.

All messages in the protocol are encoded using CBOR and is described here according to CDDL. Messages are exchanged using the HTTP protocol (HTTPS), using HTTP POST. It is not required that the client supports HTTP cookies.

One trait shared by all messages is that they are all maps and the "type" key has a tstr value used to identify which message it is, for example "RegisterRequest0" or "E2EEResponse".

The protocol consists of several flows

  • Client Registration

  • This includes the client and the server exchanging keys (DeviceBindingKey and CloudBindingKey) to be used to bootstrap end-to-end encryption between the two parties. Each key has an attestation to allow both parties to authenticate each other.

  • The server authenticates the device using Android Keystore Attestation on Android and DCAppAttestService on iOS. This enables restricting the service to only authorized mobile applications that hasn't been tampered with and is running a known good environment.

  • The device authenticates the server by inspecting the root certificate of the attestation and making sure it trusts the public key in the root certificate.

  • Detailed description in RegisterRequest0, RegisterResponse0, RegisterRequest1, and RegisterResponse1 messages below.

  • E2EE Setup

  • This involves the device and the server exchanging ephemeral keys (EDeviceKey and ECloudKey) which are signed by DeviceBindingKey and CloudBindingKey. These keys are used to derive symmetric encryption keys (SKDevice and SKCloud) used for AES-GCM-128 encryption.

  • The derived symmetric encryption keys are intended to only valid for a finite amount of time, 10 minutes for example. This is enforced by the server asking the device to go through the E2EE Setup flow again.

  • Detailed description for the E2EE setup flow is in E2EESetupRequest0, E2EESetupResponse0, E2EESetupRequest1, and E2EESetupResponse1. See E2EERequest and E2EEResponse for how the symmetric encryption keys are used.

  • Stage 2 registration

  • This runs after E2EE has been set up and allows for exchange of registration-related data which needs to be kept confidential. Currently this only includes the passphrase used to protect keys.

  • Detailed description in RegisterStage2Request0 and RegisterStage2Response0.

The following flows are all implemented on top of E2EE and requires stage 2 registration to be complete.

The protocol is designed so it's possible to implement a 100% stateless server except that the server needs to possess a symmetric encryption key which never leaves the Secure Area of the server. This key is used to encrypt/decrypt state shipped back and forth to the client.

Messages shall be sent from the device to the server as the body of a HTTP POST request and messages from the server to the device shall be in the body of the response. The server shall use HTTP status 200 for responses unless otherwise specified.

The following data types are used in the protocol:

; A chain of X.509 certificates.
;
; If the chain only contains a single certificate, a bstr with the encoded
; certificate is used. Otherwise an array of encoded certificates is used.
;
X509CertChain = bstr / [ bstr]

; A signature made with a Elliptic Curve Cryptography key.
;
EcSignature = {
"r" : bstr,
"s" : bstr
}

Types

Link copied to clipboard
data class BatchCreateKeyRequest0(val algorithm: String, val validFromMillis: Long, val validUntilMillis: Long, val passphraseRequired: Boolean, val userAuthenticationRequired: Boolean, val userAuthenticationTypes: Long, val challenge: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class BatchCreateKeyRequest1(val localKeys: List<CoseKey>, val localKeyAttestations: List<X509CertChain>, val serverState: ByteArray) : CloudSecureAreaProtocol.Command

The second request for batch creation of keys.

Link copied to clipboard
data class BatchCreateKeyResponse0(val cloudChallenge: ByteArray, val serverState: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class BatchCreateKeyResponse1(val commonCertChain: X509CertChain, val remoteKeyAttestationLeafs: List<X509Cert>, val serverStates: List<ByteArray>, val openid4vciKeyAttestationCompactSerialization: String?) : CloudSecureAreaProtocol.Command

The second and final response for batch creation of keys.

Link copied to clipboard

Checks if the given passphrase matches the registered passphrase.

Link copied to clipboard
Link copied to clipboard
sealed class Command
Link copied to clipboard
data class CreateKeyRequest0(val algorithm: String, val validFromMillis: Long, val validUntilMillis: Long, val passphraseRequired: Boolean, val userAuthenticationRequired: Boolean, val userAuthenticationTypes: Long, val challenge: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class CreateKeyRequest1(val localKey: CoseKey, val localKeyAttestation: X509CertChain?, val serverState: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class CreateKeyResponse0(val cloudChallenge: ByteArray, val serverState: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class CreateKeyResponse1(val remoteKeyAttestation: X509CertChain, val serverState: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class E2EERequest(val encryptedRequest: ByteArray, val e2eeContext: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class E2EEResponse(val encryptedResponse: ByteArray, val e2eeContext: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class E2EESetupRequest0(val registrationContext: ByteArray) : CloudSecureAreaProtocol.Command

This message is sent when the device wishes to set up end-to-end encryption to the Secure Area of the server.

Link copied to clipboard
data class E2EESetupRequest1(val eDeviceKey: CoseKey, val deviceNonce: ByteArray, val signature: EcSignature, val deviceAssertion: DeviceAssertion, val serverState: ByteArray) : CloudSecureAreaProtocol.Command

This is sent by the device in response to the E2EESetupResponse0:

Link copied to clipboard
data class E2EESetupResponse0(val cloudNonce: ByteArray, val serverState: ByteArray) : CloudSecureAreaProtocol.Command

This is sent in response to E2EESetupRequest0.

Link copied to clipboard
data class E2EESetupResponse1(val eCloudKey: CoseKey, val signature: EcSignature, val serverState: ByteArray) : CloudSecureAreaProtocol.Command

This is sent in response to E2EESetupRequest1:

Link copied to clipboard
data class KeyAgreementRequest0(val otherPublicKey: CoseKey, val keyContext: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class KeyAgreementRequest1(val signature: EcSignature, val passphrase: String?, val serverState: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class KeyAgreementResponse0(val cloudNonce: ByteArray, val serverState: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class KeyAgreementResponse1(val result: Int, val zab: ByteArray?, val waitDurationMillis: Long) : CloudSecureAreaProtocol.Command
Link copied to clipboard

Sent by device a server it has never communicated with before and it wishes to establish communications.

Link copied to clipboard
data class RegisterRequest1(val deviceChallenge: ByteArray, val deviceAttestation: DeviceAttestation, val deviceBindingKey: CoseKey, val deviceBindingKeyAttestation: X509CertChain?, val serverState: ByteArray) : CloudSecureAreaProtocol.Command

Message sent by the client to the server in response to RegisterResponse0.

Link copied to clipboard
data class RegisterResponse0(val attestationChallenge: ByteString, val cloudChallenge: ByteArray, val serverState: ByteArray) : CloudSecureAreaProtocol.Command

Message sent by the server to the device sent in response to RegisterRequest0:

Link copied to clipboard
data class RegisterResponse1(val cloudBindingKeyAttestation: X509CertChain, val serverState: ByteArray) : CloudSecureAreaProtocol.Command

Message sent by the server to the device in response to RegisterRequest1:

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
data class SignRequest0(val dataToSign: ByteArray, val keyContext: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class SignRequest1(val signature: EcSignature, val passphrase: String?, val serverState: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class SignResponse0(val cloudNonce: ByteArray, val serverState: ByteArray) : CloudSecureAreaProtocol.Command
Link copied to clipboard
data class SignResponse1(val result: Int, val signature: EcSignature?, val waitDurationMillis: Long) : CloudSecureAreaProtocol.Command

Properties

Link copied to clipboard
const val RESULT_OK: Int = 0
Link copied to clipboard