diff --git a/AccountingDesign.md b/AccountingDesign.md index 6a0b38d..140af2e 100644 --- a/AccountingDesign.md +++ b/AccountingDesign.md @@ -211,3 +211,58 @@ storage has been delegated. * `base32(pubkey): PETNAME\n` * if multiple pubkeys map to the same pet name, their usage will be added together at display time. + +## Furlification + +An authorized client will have a private key and a certificate chain that +authorizes that privkey to perform some operation. Since we use Foolscap to +perform storage operations, we need a way to get from the cert-chain/pubkey +world to the live-`RemoteReference` world. (an alternative would be to +sign each storage operation, encrypting the result to some public key for +confidentiality, but we would prefer an approach that does not require quite +so many expensive public-key operations on the server). This process is +called "furlification", since it serves to convert the certchain+privkey into +a FURL that references an object which has the delegated authority. + +The process starts by creating an encoded message that looks very much like +the certificate described above. This message can contain any of the +limitations or attenuations that the cert-chain message holds. But instead of +a field named `delegate-pubkey`, it will have one named +`beneficiary-FURL`. This message is signed by the private key that sits +at the end of the certificate chain. Then the cert-chain, the message, the +signature, a nonce, and one other argument named "precache-ignored" are all +sent to the storage server's "login" facet. The return value from this +message is ignored. + +After checking the signatures, the login facet is then required to create a +new `foolscap.Referenceable` object with the given authority (called the +"operational object", or "Personal Storage Server Facet"), and to send +(nonce, object-FURL, object) to the client-side object designated by the +beneficiary-FURL. Any successful return value from this message is ignored +(although it may raise `AuthorityExpiredError`, see below). + +The beneficiary-FURL is used for the return path (instead of the return value +from the login message) because the server that receives the signed message +could easily forward it on to server2 in an attempt to steal the +corresponding server2 authority. Since server2 will only send the operational +object to the beneficiary, server1 cannot benefit from this sort of +violation. However, to avoid a Foolscap round-trip, the beneficiary object is +sent as the "precache-ignored" argument: this allows Foolscap to pre-cache +the beneficiary without harming any of the security properties. + +The object-FURL is expected to be persistent: clients should be able to cache +them for later use (to reduce the number of pubkey operations that servers +are required to perform). The object itself is sent in the beneficiary +message mainly to pre-fill the Foolscap table; the client is allowed to +either use the object directly or to getReference the object-FURL. + +Servers are expected to create a FURL that contains a MAC'ed description of +the object's limitations (and use Foolscap's Tub.registerNameLookupHandler), +rather than maintain a big table from random swissnum to object description. +Servers can include expiration times in these swissnums. If the client +experiences `AuthorityExpiredError` when using their object reference (or +when using getReference on the object-FURL), they must attempt the login +process again with a new signed request message. If they experience +`AuthorityExpiredError` during the login process, then part of their +certificate chain may have expired. +