rxgk CombineTokens and enctypes (was Re: [AFS3-std] Re: afs3-rxgk-updates for 03)

Jeffrey Hutzelman jhutz@cmu.edu
Thu, 01 Nov 2012 17:21:15 -0400


On Thu, 2012-11-01 at 11:43 +0000, Simon Wilkinson wrote:
> On 1 Nov 2012, at 02:59, Benjamin Kaduk wrote:
> 
> See my other email for comments on enctype negotiation - I just wanted
> to comment specifically on this ...
> 
> > Actually, KRB-FX-CF2 for keys calls random-to-key() and
> pseudo-random(), which depend on the enctype; random-to-key() would use
> the Kn enctype, and pseudo-random() would use the K0 and K1 enctype as
> appropriate. I'm a little uneasy using pseudo-random() from one enctype
> to produce the appropriate number of random bits for random-to-key() of
> a different enctype
> 
> I can't see any reason for unease here. These are general purpose
> building blocks. psuedo-random is defined as providing access to a
> seeded PRNG. Providing that PRNG provides at least enough bits of
> entropy for the subsequent random-to-key operation, random-to-key must
> be safe, regardless of the encryption types in play.
> 
> > (I don't have a good reason for unease, feel free to tell me I'm
> wrong); can we get away with requiring that the enctypes must be the
> same? This could result in headaches if there were two server
> principals that had different best enctypes in their key lists.
> 
> I'm not sure you understand the model in play here - perhaps we need
> more text explaining the purpose of CombineTokens. It isn't intended
> that CombineTokens be used for tokens acquired for two different
> servers. Instead, it's supposed to combine multiple user tokens (For
> example, if Alice and Bob join forces to access a particular system)
> into a single authentication entity.
> 
> Secondly, the encryption types of the server principal
> (afs3-bos/myserver.example.org or afs3-rxgk/_afs.example.org) don't
> have any relevance here. Instead, what you care about is the encryption
> type that has been negotiated between the server and client as part of
> the earlier GSSNegotiate operation, which will be chosen from the
> intersection of the list of rxgk encryption types supported by the
> client and the server. Bear in mind that rxgk is designed to be used as
> part of a GSSAPI negotiation - there's no requirement that the
> underlying mechanism is Kerberos based.

That's right.  Note that GSS-API provides a PRF operation for any
mechanism new enough to have it, not just Kerberos.  Now, it happens
that many of those turn out to use the same crypto as Kerberos under the
hood, because it was convenient to do so, but that's not a requirement.

In this case, however, the inputs to rxgk's combine-tokens are, of
course, rxgk tokens, which have RFC3961 keys.  Thus, the crypto
operations we're talking about here _are_ based on Kerberos crypto,
always.  Again, that's not too terrible in practice, even if there's no
other Kerberos in your system, because the IETF has done the same thing
in a number of other GSS-API mechanisms, reusing not only RFC3961 crypto
but also RFC4121 message tokens.


> Things do get complicated when we look at AFS specifically where there
> is an extended AFSCombineTokens RPC. This servers a number of purposes.

> Secondly, it allows user key material to be combined with cache manager
> key material to avoid the cache poisoning attack.

This, however, is just a semi-special case of the functionality offered
by the generic combine-tokens operation.  While the user/CM thing is
specific to AFS, I think the generic combine-tokens needs to be flexible
enough to meet this need directly.  Ultimately, I think that means...


The caller needs to know all of the input keys.

The output key should be a function of all input keys, so that no one
who holds only some of the input tokens can know, choose, or unduly
influence the selection of the output key.

The caller should be able to assert any identity ordering, presumably by
the order in which the input tokens are provided.  That is, if Alice and
Bob "combine forces", the caller gets to decide whether the identity
expressed by the output token is [Alice,Bob] or [Bob,Alice], and the
spec says how to do so.  Of course, the meaning of multiple identities
in a token is up to the application, and in any case, might end up being
considerably more complex than just a list.

Restrictions such as lifetime must be constrained by the values in all
input tokens.  This is separate from the question of how the lifetime of
an rxgk token relates to that of the credentials from which it was
originally derived, and also from the question of whether and to what
extent an "expired" can still be used.  An rxgk token derived from
another rxgk token must not have a lifetime longer than the original.

Choice of enctype should be by selecting the strongest available
enctype, where "available" means those enctypes both supported by the
server and known to be supported by the client, and "strongest" is up to
the server to determine. The list of enctypes could be taken from all of
the provided tokens, but I think it would be better for the caller to
provide an explicit list, as this allows upgrade to an enctype that is
supported by the caller and server but may not have been supported by
the original token issuers (or by the clients that got the tokens).

Choice of level probably wants to be the strongest of the levels of the
input tokens, or possibly a stronger (but not weaker) level requested by
the caller.  I'm not entirely sure about how this should work, though,
and I think it bears some discussion.  The issue here is you don't want
the holder of one of the tokens to be able to unilaterally reduce the
level (Bob forces clear when Alice wants crypt).  And, I'm not sure you
want the caller to be able to reduce the level either -- should a CM be
able to request cleartext communication when the user clearly wanted
encryption?

-- Jeff