このページは大阪弁化フィルタによって翻訳生成されたんですわ。 |
Omaha and various other client products ping our servers for updates on a periodic basis. SSL provides the freshness and authenticity needed but comes with substantial overhead, both on the server- and client-side. We have empirical evidence that some clients are able to ping for updates over HTTP, but fail to do so over HTTPS. For embedded devices, requiring a SSL stack just to perform secure updates might not be feasible.
Client Update Protocol goals are:
Non-goals:
To securely check for and download updates we need to protect the communication. The protection needs to cover:
There are two distinct parts that need to be designed:
Client |
Messages |
Server |
Knows a public key pk[v].
Might have opaque cookie c and associated shared key sk.
|
|
Has private keys priv[].
Has server secret keys ss[].
|
r := RSApad|pk[v]|(entropy) sk' := HASH(r) w := RSAencryptpk[v](r) ?w := HASH(HASH(v|w)|HASH(req)|HASH(body)?)
Send v|w cp := SYMsignsk(0|?w|HASH(c)) Send c else cp := SYMsignsk'(3|?w) Send cp |
req, v|w, cp, [c], [body] -> |
|
|
<- sp, [c'], rsp |
?w := HASH(HASH(v|w)|HASH(req)|HASH(body)?) If request contains c cv,cd := parse c sk := SYMdecryptss[cv](cd)
If (sk && cp == SYMsignsk(0|?w|HASH(c)))
rsp := generate response for req ?m := HASH(rsp) sp := SYMsignsk(2|?w|?m) Send sp, rsp else r := RSAdecryptpriv[v](w) if (!RSAcheckpad(r)) LOG "Client does not know how to RSAencrypt!" sk' := HASH(r) If (cp != SYMsignsk'(3|?w) LOG "Client does not know how to SYMsign!" csv := current server cookie encryption key version c' := csv|SYMencryptss[csv](sk') rsp := generate response for req ?m := HASH(rsp) sp := SYMsignsk'(1|?w|?m|HASH(c')) Send sp, c', rsp |
?m := HASH(rsp) If (c' && sp == SYMsignsk'(1|?w|?m|HASH(c'))) Store sk := sk', c := c' else If (sp != SYMsignsk(2|?w|?m)) FAIL |
|
|
Freshness is achieved by having the client pick a fresh w for every request.
The client operations are efficient enough to always both RSAencrypt and SYMsign. The client accepts authenticated responses for either sk or sk'.
We can amortize the cost of RSAdecrypt on the server-side over many requests. Either the client or the server can initiate roll-over to a fresh shared secret by not sending or not honoring the cookie. Typically our client will always send the cookie and our server manages the length of the exposure.
An attacker could replay a request to the server and would get a valid response; this could pollute server statistics. Care must be taken to make sure our request handling remains essentially idem-potent.
If idem-potency is not feasible, a server-side challenge, synchronous time or server-side bookkeeping can be used to make requests be one-time events. For the envisioned update protocols this is not required. Note this is due to the protocol not authenticating the client in any shape or form.
RSApad / RSAcheckpad are not cryptographically required (compared to using |keybits| of random) but do provide a signal whether clients have the public key they claim they have and/or whether the client library is able to RSAencrypt properly.
cp (client proof) is used to tell whether the client knows the sk associated with cookie c. Having the server test this allows for more graceful fail over to a fresh sk in case the client state somehow got out of sync.
If c nor w decrypts correctly the server could return a specific response which triggers a fall-back to a SSL update protocol.
The server need not use the same ss[x] for every c' it hands out. And different servers could use different ss[x] as long as all servers in the server pool know all ss[] in circulation. Note there is no real security benefit to doing this.
An attacker could try to DoS the update servers by triggering the expensive RSAdecrypt for many requests in parallel. When under attack, the servers could throttle or reject requests that do not offer valid c and cp. Note validating c and cp requires knowledge of ss[].
Whenever a cookie (c or c') is sent over the wire, the sender includes it in the cryptographic proof along with it (cp or sp). An intermediary stuffing or removing a cookie on the wire will not achieve anything beyond failing of the proofs. The client will not store a cookie that the server did not intend to be associated with the shared secret.
The hash of the request (req) is carried through the cryptographic proofs. Results from requests for resource A cannot be mistaken for results for requests for resource B.
RSAdecrypt takes about 3 msec on a single 32-bit core. Less than half that on a 64-bit core in 64-bit mode. All other primitives (SYMdecrypt, SYMsign) take orders of magnitude less time. RSAencrypt happens on the client but is a lot less computationally intensive to start with. Probably less than 0.1 msec.