| | 214 | |
| | 215 | == Furlification == |
| | 216 | |
| | 217 | An authorized client will have a private key and a certificate chain that |
| | 218 | authorizes that privkey to perform some operation. Since we use Foolscap to |
| | 219 | perform storage operations, we need a way to get from the cert-chain/pubkey |
| | 220 | world to the live-{{{RemoteReference}}} world. (an alternative would be to |
| | 221 | sign each storage operation, encrypting the result to some public key for |
| | 222 | confidentiality, but we would prefer an approach that does not require quite |
| | 223 | so many expensive public-key operations on the server). This process is |
| | 224 | called "furlification", since it serves to convert the certchain+privkey into |
| | 225 | a FURL that references an object which has the delegated authority. |
| | 226 | |
| | 227 | The process starts by creating an encoded message that looks very much like |
| | 228 | the certificate described above. This message can contain any of the |
| | 229 | limitations or attenuations that the cert-chain message holds. But instead of |
| | 230 | a field named {{{delegate-pubkey}}}, it will have one named |
| | 231 | {{{beneficiary-FURL}}}. This message is signed by the private key that sits |
| | 232 | at the end of the certificate chain. Then the cert-chain, the message, the |
| | 233 | signature, a nonce, and one other argument named "precache-ignored" are all |
| | 234 | sent to the storage server's "login" facet. The return value from this |
| | 235 | message is ignored. |
| | 236 | |
| | 237 | After checking the signatures, the login facet is then required to create a |
| | 238 | new {{{foolscap.Referenceable}}} object with the given authority (called the |
| | 239 | "operational object", or "Personal Storage Server Facet"), and to send |
| | 240 | (nonce, object-FURL, object) to the client-side object designated by the |
| | 241 | beneficiary-FURL. Any successful return value from this message is ignored |
| | 242 | (although it may raise {{{AuthorityExpiredError}}}, see below). |
| | 243 | |
| | 244 | The beneficiary-FURL is used for the return path (instead of the return value |
| | 245 | from the login message) because the server that receives the signed message |
| | 246 | could easily forward it on to server2 in an attempt to steal the |
| | 247 | corresponding server2 authority. Since server2 will only send the operational |
| | 248 | object to the beneficiary, server1 cannot benefit from this sort of |
| | 249 | violation. However, to avoid a Foolscap round-trip, the beneficiary object is |
| | 250 | sent as the "precache-ignored" argument: this allows Foolscap to pre-cache |
| | 251 | the beneficiary without harming any of the security properties. |
| | 252 | |
| | 253 | The object-FURL is expected to be persistent: clients should be able to cache |
| | 254 | them for later use (to reduce the number of pubkey operations that servers |
| | 255 | are required to perform). The object itself is sent in the beneficiary |
| | 256 | message mainly to pre-fill the Foolscap table; the client is allowed to |
| | 257 | either use the object directly or to getReference the object-FURL. |
| | 258 | |
| | 259 | Servers are expected to create a FURL that contains a MAC'ed description of |
| | 260 | the object's limitations (and use Foolscap's Tub.registerNameLookupHandler), |
| | 261 | rather than maintain a big table from random swissnum to object description. |
| | 262 | Servers can include expiration times in these swissnums. If the client |
| | 263 | experiences {{{AuthorityExpiredError}}} when using their object reference (or |
| | 264 | when using getReference on the object-FURL), they must attempt the login |
| | 265 | process again with a new signed request message. If they experience |
| | 266 | {{{AuthorityExpiredError}}} during the login process, then part of their |
| | 267 | certificate chain may have expired. |
| | 268 | |