Subject: Re: [kitten] On mutual auth; security considerations for the BrowserID mech

From: Jeffrey Hutzelman <[email-masked]>
Date: Sun, 06 Jan 2013 16:31:51 -0500

On Sun, 2013-01-06 at 13:40 -0600, Nico Williams wrote:
> GSS_Init_sec_context() allows the initiator to specify what the
> target's name is.  There's a constant, GSS_C_NO_NAME, that should
> allow the initiator to indicate it doesn't care what the acceptor's
> name is.
> 
> One would expect that specifying a target name implies desiring mutual
> authentication

NO NO NO!

Specifying a target name means that I want Kerberos to work!
If I desire mutual auth, I'll ask for it.
If I _need_ it, I'll check to make sure I got it.

This is how the GSS-API was designed to work -- mechanisms should _not_
fail context establishment just because some potentially-desirable
service was not available.  The model has always been that the GSS does
its best to provide whatever it can, and the caller checks to make sure
the resulting context is acceptable.

> Consider Kerberos: is it really the case that the half round trip
> version of the AP exchange provides no mutual authentication?

It doesn't provide what GSS's mutual_state means.

And no, GSS doesn't provide an indicator for "sort-of-mutual-auth",
where some services are safe and others are not.  I think that's fine;
we don't need to represent every possible state.

> And if the application simply does an AP exchange and then uses no
> further confidentiality/integrity protection, then how would it help
> to have done a full round trip version of AP?  The answer is that if
> we assume no active on-path attackers then the full round trip does
> help.  But that is not the Internet threat model, so I'm tempted to
> ignore this case, or rather, to write it up as a security
> consideration.

Huh?  We certainly talk all the time about measures that help against
passive attackers but not against active attackers.  There is no such
thing as "the Internet threat model"; that's why we require documents to
discuss various threats and what, if anything, they do about them.

> This isn't to say that the full round trip AP exchange adds no value.
> The point is that it doesn't add really "mutuality", and that it'd be
> better to have a name for what it does do than to confuse the issue.

That would be fine if it were 1993, when RFC1508 was written.  At this
point, it's far too late to change what "mutual authentication" means.

>  - The BrowserID mechanism does not provide mutual authentication.  It
> can provide key confirmation.

What's "key confirmation" ?   AFAIK that's not a concept we have.
BrowserID cannot provide mutual authentication, because the mechanism
contains no way for the acceptor to prove its identity.

>  - The BrowserID mechanism does not support naming acceptors at all.

If you do that, it won't work with SSH or other applications that assume
the use of host-based service names.  Unless, of course, we give up on
the notion of a framework and just say that every application has to
have intimate knowledge of every mechanism.  But if that's the case,
what are we even doing here?

> Luke's implementation pretends to, but it's not really doing much
> (remember, the acceptor will pass in GSS_C_NO_CREDENTIAL, or a
> credential for GSS_C_NO_NAME, to GSS_Accept_sec_context(), so the
> acceptor will tend to agree to any name that the initiator might have
> called it by).

No, it does support acceptor names.  It just doesn't need the name for
anything.  I suppose in your alternate universe, that means it doesn't
"support" them because it hasn't proven the acceptor's identity.  But in
this universe, the GSS does not contain any implication that providing
an acceptor name means the initiator wants or demands that the acceptor
be authenticated.

>    It would be better to say that Luke's mechanism's
> GSS_Init_sec_context() MUST fail if target_name != GSS_C_NO_NAME!
> This would force the matter of surfacing to the application the need
> to indicate that it doesn't need mutual authentication.

If you do that, then Luke's mech will gratuitously not work with SSH,
which uses a host-based service name for the acceptor.  In fact, many
applications do that, among other reasons because if you don't then
Kerberos won't work, period, whether you want mutual auth or not.

A mechanism that doesn't care what the acceptor name is should support
all of the standard name types, and ideally should accept _any_ name, at
least to the extent that the API allows a mech to handle unknown name
types.

>  - What we need is for SASL apps to deal with the security
> considerations of lacking mutual authentication.  This means that a
> SASL API like, say, CyrusSASL's, will need a way for the client
> application to indicate that the server's name is irrelevant, or
> otherwise that mutual authentication is not required.

SASL apps generally do not care about mutual authentication.  They
really never have.  We've already established some time ago that the
notion of security layers is deprecated, which is why they are not
supported in GS2 or in other new SASL mechs.

However, SASL apps using channel bindings care about being able to rely
on channel bindings.  And yes, SASL apps nead to deal with the security
considerations of not being able to rely on channel bindings.  As it
turns out, that's pretty easy too, because it's a relatively new idea
(in the SASL community) to use channel bindings instead of just running
everything over TLS and either checking server certs or not caring.

-- Jeff

---

From: Luke Howard <[email-masked]>
Date: Mon, 7 Jan 2013 11:01:23 +1100

> what are we even doing here?

Also (see my other mail), the BrowserID mechanism not only supports but requires that acceptors be named.

-- Luke

---

From: Nico Williams <[email-masked]>
Date: Mon, 7 Jan 2013 07:26:33 -0600

>> One would expect that specifying a target name implies desiring mutual

Relax.  "One would expect..." is what I wrote because I was talking
about API design, not about the API we have.

> Specifying a target name means that I want Kerberos to work!

But not only.  It's also short-hand for "inquire the context and check
that the target name matches what I wanted".

> the resulting context is acceptable.

I know this.  Better: you know I know this.  I am, however, puzzled by
the apparent conflation of meanings in the mutual flag.

> It doesn't provide what GSS's mutual_state means.

What about what someone who's never heard of the GSS-API thinks "mutual means"?

> point, it's far too late to change what "mutual authentication" means.

I'm not proposing any changes.  I wanted to understand the meaning of
the GSS mutual auth flag and spring from there to a stab at security
considerations text for Luke's mechanism.

> contains no way for the acceptor to prove its identity.

Key confirmation is where the acceptor shows it knows the session
key(s).  E.g., the AP-REP in Kerberos.  Clearly a BrowserID-based
mechanism can do the same.

> what are we even doing here?

SSH needs mutual anyways, so it can't use BrowserID (at least not for
gsapis-keyex, but I guess it'd work fine for gssapi-with-mic, and
that's why we need the mutual flag).

> supported in GS2 or in other new SASL mechs.

DIGEST-MD5 does provide mutual.

> everything over TLS and either checking server certs or not caring.

CB doesn't get you out of wanting to know who you're speaking to
before sending sensitive data.

Nico
--

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Mon, 07 Jan 2013 11:05:14 -0500

> What about what someone who's never heard of the GSS-API thinks "mutual

Well, that's a problem, but one I gave up on 10+ years ago.

> mechanism can do the same.

Hm.  The AP-REP in Kerberos proves the acceptor knows the session key,
and therefore must be the acceptor you intended to talk to.  BrowserID
contains a DH exchange, resulting in a secret shared between the
initiator and some other party, who may or may not be the acceptor.  Or,
if you prefer, between the initiator and some party who is acting as the
acceptor, but is not authenticated and so may be anyone.

> that's why we need the mutual flag).

Exactly.  SSH needs mutual for userauth, but not for keyex.

> DIGEST-MD5 does provide mutual.

Sort of.  It provides mutual if you haven't used the same password with
more than one server.  IIRC, it also provides security layers.  But that
is not that new a mechanism.

> before sending sensitive data.

Correct.  If you're going to send sensitive data, you need to somehow
know who you're speaking to.  CB provides one way to do that, _if_ the
mech also provides mutual.

It finally occurred to me last night why mechs like SAML violate the
abstraction and try to tell GSS apps that they must use TLS.  The
problem is that a SAML assertion, or an OAUth 2.0 token, is essentially
a bearer token -- anyone who gets their hands on it can present it for
authentication, without knowing any other secrets.  So, you want to be
sure you don't send it to the wrong party.  These mechs don't have any
way to know who the party at the other end is, so they try to require
that the caller take care of that before running the mech.

The problem is, you can't place arbitrary constraints on GSS apps, and
we don't have a way in GSS to say that a mechanism has this property;
that is, that it's safe to use only over a channel to a known acceptor.

-- Jeff

---

From: [email-masked] (Martin Rex)
Date: Tue, 8 Jan 2013 20:41:00 +0100 (CET)

Nico Williams wrote:
> Jeffrey Hutzelman <[email-masked]> wrote:
>>
>> Nico Williams wrote:
>>>

The original requirement (in GSS-API v1) to always provide a target name
is really only a kludge for Kerberos.

The presence of this parameter is only to enable the 2-token context
establishment--rather than a 3-token exchange, similar to user2user,
where the target's name is discovered during the handshake.

When _not_ requesting the GSS_C_MUTUAL_FLAG on gss_init_sec_context(),
then there is *NO* guarantee that the target name will match.  That
Kerberos context establishment will fail on a mismatch is a shortcoming
of Kerberos rather than a security feature.

An implementation of Kerberos that supports user2user and does not compare
the given target name when doing a user2user exchange and the initiator
did not request GSS_C_MUTUAL_FLAG during gss_init_sec_context() would
be perfectly compliant with GSS-API v2 if it returns GSS_COMPLETE on the
final call to gss_init_sec_context() while _NOT_ showing the mutual_flag
on the resulting context attributes.

> > If I desire mutual auth, I'll ask for it.

Correct.

> > the resulting context is acceptable.

Correct.

> >> version of the AP exchange provides no mutual authentication?

The single-token Kerberos context establishment, by itself, can _not_
provide an authentication of the acceptor to the initiator.  There is
only a single call to gss_init_sec_context(), which returns
GSS_S_COMPLETE on success (when creating the AP_REQ), and the
resulting context attribute will have to be asserted by the
gssapi mechanism to the initiator along with the initial context
establishment token, at a point in time where exactly nothing is
known about the real acceptor/peer (which may not even exist at
that point).

When the application protocol uses message protection services, then
depending on the app protocol design and when(!!) it uses the message
protection services, then the app might infer an effective mutual
authentication with Kerberos after app data exchanges (at least
an app-data response) even for the single-token context establishment.
But that would happen _after_ the gssapi security context establishment.

Without some cryptographically strong uniqueness (such as tls-unique
channel bindings), there is no mutual authentication of the
acceptor to the initiator during the Kerberos gssapi context
establishment alone, even with the two-token AP_REQ/AP_REP
context establishment ("mutual").

That's a know shortcoming of rfc4559 "Negotiate", and AFAIK one of the
things that motivated the definition of the tls-unique channel bindings.

>From how it is defined, the MUTUAL (resulting) context attribute indicates
an authentication of the acceptor to the initiator during(!!) the gssapi
security context establishment token exchange.

The actualy "quality" of that mutual authentication is a seperate issue.
A number of authentication protocols are susceptible to MitM or
one-time-replay, so that at most the initiator might know that the
tokens were computed by the intended acceptor, but not that the
communication peer is the intended acceptor rather than an attacker
doing MitM on the context token exchange.

-Martin