blob: 473b97da74941e59e3248659ecc81d7089e513cd [file] [log] [blame] [view]
Joshua Pawlicki32ec7d82020-07-29 21:42:061# Client Update Protocol (CUP)
2
3CUP is an HTTP protocol extension used to secure communication with CUP-capable
4servers when TLS is untrustworthy or impractical for other reasons.
5
6CUP provides:
7 * Integrity of the client's request body.
8 * Integrity of the server's response body.
9 * Freshness of the server's response body.
10
11CUP does not provide:
12 * Integrity of the client's request headers or request line.
13 * Integrity of the server's response headers.
14 * Confidentiality of the client's request.
15 * Confidentiality of the server's response.
16 * Freshness of the client's request.
17
18CUP requires:
19 * Control of both the client and server.
20
21Current CUP communications are secured by an ECDSA key pair. The client has the
22public key hardcoded into the application binary. The server signs
23request-response pairs with the private key, and the client verifies using the
24public key.
25
26In Chromium, CUP keys are rotated annually. Each key pair has a corresponding
27version number. To interoperate with old clients, the server must keep all
28historical versions of the key, and be prepared to sign with any of them. The
29client should only keep a single version (whichever was most recent at compile
30time).
31
32## Details
33
34### Description
35The server publishes an elliptic curve field/equation and a public key curve
36point to be used by the client. In practice, these values are hardcoded into
37each client at compile time.
38
39For each request, the client assembles three components:
40 1. The message body (the request body to be sent to the server).
Joshua Pawlicki20800e72021-09-23 19:13:5541 2. A random value to be used as a nonce for freshness (at least 256 bits).
Joshua Pawlicki32ec7d82020-07-29 21:42:0642 3. A code to identify the public key the client will use to verify this
43 request. The client converts the public key id and nonce to a string: the
Joshua Pawlicki20800e72021-09-23 19:13:5544 public key is converted to decimal, and the nonce to any url-safe encoding.
Joshua Pawlicki32ec7d82020-07-29 21:42:0645
46The client stores the request body in a buffer, in UTF-8 format; it
47appends the keyid/nonce string to this buffer. It calculates a SHA-256 hash of
48this combined buffer, which it stores for validation later. It sends the
49request and the keyid/nonce string to the server.
50
51The server receives the request body, public key id, and nonce; it performs
52the same appending operation, and computes the SHA-256 hash of the received data
53buffer.
54
55The server attempts to find a matching ECDSA private key for the specified
56public key id, returning an HTTP error if no such private key exists. Finally,
57it assembles the response body.
58
59Before sending, the server stores the response body (also in UTF-8) in a
60buffer. It appends the computed SHA-256 hash of the request body+keyid+nonce to
61the buffer. It then calculates an ECDSA signature over that combined buffer,
62using the servers private key. It sends the ECDSA signature and the response
63body + client hash back to the user.
64
65The client receives the response body, observed client hash, and ECDSA signature.
66The client compares the observed client hash to its stored request hash. If
67there is a mismatch, then either the request or response have been tampered with
68and the response is rejected.
69
70The client concatenates the request hash to the response body, and verifies the
71signature using its public key. If verification fails, then either the request
72or response have been tampered with and the response is rejected.
73
74### HTTP Implementation
75The request body is a POST body. The key ID and nonce, are transmitted in a
76query parameter appended to the requested URL, using the format `&cup2key=%d:%u`
77where the first parameter is the key ID, the second is the freshness nonce.
78
79For debugging purposes, the request hash is sent to the server using a query
80parameter appended to the requested URL, using the format `&cup2hreq=%s` where
81%s is the lowercase hexadecimal value of the hash (in big-endian format).
82
83The server returns the ECDSA signature and the request hash it computed in at
84least one of three forms:
85 1. The `X-Cup-Server-Proof` HTTP header, with the value in the format
86 `signature:hash`.
87 2. The `ETag` HTTP header, with the value in the format of
88 `W/"signature:hash"`.
89 3. The `ETag` HTTP header, with the value in the format of `signature:hash`.
90
91If multiple forms are present in the response, clients should prefer form 1,
92falling back to form 2 only if form 1 is not present, and falling back to form 3
93only if form 1 and 2 are not present.
94
95In practice, multiple forms allow the communication to navigate different types
96of proxies that mutate request headers.
97
98In all forms, `signature` is a DER-encoded ASN.1 sequence of "R" and "S",
99rendered in lowercase hexadecimal representation.
100
101In all forms, `hash` is a 256-bit value rendered in lowercase hexadecimal
102representation (big-endian).
103
104### K-Repetition
105A grave danger in any system involving ECDSA is the danger of K repetition.
106
107Computing an ECDSA signature starts with selecting a random 256-bit integer,
108called K. The combination of K and the public key are used to produce the first
109half of the signature, called R; the values of R, K, the private key, and the
110message digest are used to compute the other half of the signature, called S.
111
112Because of this process, if the same value of K is chosen for two signatures,
113both signatures will have the same value for R. If a malicious user can acquire
114two messages that have different bodies but identical R values, a
115straightforward computation yields the server's private key.
116
117Assuming that a good PRNG is used, and properly seeded, the probability of a
118collision is small even across a large number of signatures. However, regular
119key rotation is still recommended:
120 1. Key material may be disclosed due to server compromise, and organizations
121 should be prepared to remediate by performing a key rotation. Regularly
122 exercising a key rotation process is important preparation.
123 2. PRNGs are not always perfectly secure or properly seeded.
124
125## See Also
126Previous documents describing CUP can be found at:
127 * [Original Public Design](https://github.com/google/omaha/blob/master/doc/ClientUpdateProtocol.md)
128 * [ECDSA Extension](https://github.com/google/omaha/blob/master/doc/ClientUpdateProtocolEcdsa.md)
129
130Chromium's implementation of CUP can be found in
John Palmer046f9872021-05-24 01:24:56131[components/client\_update\_protocol](https://source.chromium.org/chromium/chromium/src/+/main:components/client_update_protocol/).
Joshua Pawlicki32ec7d82020-07-29 21:42:06132