[AFS3-std] draft-wilkinson-afs3-rxgk-afs-01 comments

Simon Wilkinson simon@sxw.org.uk
Thu, 7 Jun 2012 17:42:09 +0100


Rather than reply point by point, I thought it might be helpful to =
clarify the security model that this draft is aiming for, and then we =
can address the best way of modifying the language in the draft to =
better communicate this.

In a single user cache manager, we don't really care about the existence =
of the cache manager. Any data which is requested by a user is for the =
use of that user only. Similarly, any data returned by extended callback =
breaks is also only for that user's attention.=20

In a multi user cache manager, on the other hand, data requests are on =
behalf of both the user (who will consume that data immediately), and =
the cache manager (which will store the returned data, and possibly =
supply it to other users). In this case, both are party to the initial =
request, and both have an interest in the validity of both the initial =
data set, and any data contained in later callback breaks. This is where =
the AFSCombineTokens operation comes in to play. It allows both the =
user, and the cache manager to authenticate both the request, and the =
response. Because the call is secured using a combination of the user =
and CM keys, the user can't forge fileserver responses in order to feed =
bogus data to the cache manager.

For the purposes of this discussion, we are only interested in the =
security of extended callbacks. An attacker who can forge conventional =
callback breaks can only cause performance degradation to a client. An =
attacker who can forge extended callback breaks can insert arbitrary =
data into a clients cache. When talking about security, we are actually =
interested in two distinct properties. Firstly, it must be impossible =
for an attacker to forge callback breaks, and so corrupt the contents of =
the cache. Secondly, it must be impossible for an attacker to read =
callback breaks that are destined for another client. Extended callbacks =
may contain sensitive file, or directory information that shouldn't be =
disclosed to eavesdroppers.

At the moment, clients are identified by means of either a UUID or a =
host/port pair. There's no cryptographically strong binding between the =
UUID and per-client-key. In a world in which all clients were centrally =
registered, we could create this binding by means of an identity (for =
example, each client has an afs-client/<hostname>@REALM Kerberos =
principal). However, we want to be able to support anonymous clients, so =
there's no need for central client registration. In this world, the only =
way in which a UUID and key can be associated together is through an =
assertion. In order to support truly anonymous schemes (where there =
isn't even a unique ID provided with each key), we're also not relying =
on individual cache manager identities.

SetCallbackKey provides the mechanism for performing that assertion. =
However, because we have no trust in what has been asserted, we need to =
protect against two different scenarios. Firstly, an attacker that gets =
there before the current client, shouldn't be able to assert a key that =
then prevents a client from using extended callbacks. Secondly, an =
attacker who arrives after the current client shouldn't be able to =
assert a new key, and in doing so, gain the ability to read all of the =
client's outstanding callback breaks.

The language contained in the draft was an attempt to balance these =
security requirements against implementation complexity.

However, thinking about things further, I think there is an exploitable =
race between a client making a request, and an attacker performing a =
forged SetCallbackKey with the client's UUID. In order to prevent this =
race, we need to only permit anonymous identities with a unique (or hard =
to collide) identifier.=20

In this model, each time we receive a SetCallbackKey, we would record =
the rxgk client identity which authenticated the RPC, and the key used. =
We could maintain a LRU style list of these, up to some (implementation =
defined) limit. When an identity is about to be removed for this list, =
any callbacks held by that identity have to be transitioned to "normal" =
callbacks.

Only RPCs which are authenticated with identities on this list would be =
eligible for extended callbacks. RPCs with different client identities, =
or which are issued over non-rxgk security classes, would not receive =
extended callbacks. Where we have callbacks for the same object =
requested by multiple different client identities, the key of the most =
recent identity used would be used to encrypt the callback.

Making all of this work complicates things significantly at the client, =
which must now maintain an rxgk token signing service, so that it can =
issue a proper token to the server for each key that it has in play, =
such that it can then pull the key out of that token.

Does that make sense?

Cheers,

Simon.