Subject: gssapi host key algorithm usage

From: "Joel N. Weber II" <[email-masked]>
Date: Tue, 24 Jun 2003 09:21:00 -0400

The secsh transport draft suggests that there can be different kinds
of host key algorithms, and that some key exchange operations may
support different host key algorithms than others.

The idea that GSS mechanisms don't have host keys strikes me as
confused.  As far as I can tell, if I have a Kerberos 5 principal
named host/[email-masked] and I store that encryption key
in /etc/krb5.keytab on the host foo.example.com, it is very much the
case that that krb5.keytab is a form of a host key.  As far as I know,
all GSS mechanisms that anyone cares about for use with ssh do support
host keys, albeit abstracted away to the point where ssh protocol
designers and implementers don't directly deal with them.

On furthur thought, I don't really understand why gss-group1-sha1-*
has to be defined as gss-group1-sha1-*.  Wouldn't it have been cleaner
to define it as gss-group1-sha1 and then put information on which gss
mechanism is being used in the host key algorithm field?

It may well be too late to change now for gss-group1-sha1 (on the
other hand, sxw's patches seem to have survived a change in the
OID->string conversion), but if gss-group-exchange-sha1 gets defined,
I hope it will use the host key field to specify which GSS mechanism
to use.

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 24 Jun 2003 07:42:56 -0700

> designers and implementers don't directly deal with them.

You're confused.  When using the GSS-API for SSHv2 key-exchange what you
don't need is "SSHv2 host keys" - you know, RSA and DSA host keys, the
keys that go into the known_hosts public keys file.

> mechanism is being used in the host key algorithm field?

No, it wouldn't because a client and server might first both agree that
they can use the GSS-API and then realize that they have no mechanisms
in common, by which time the key exchange has to fail because the SSHv2
keyex phase cannot be re-tried in one connection.  By putting the
mechanism name into the keyex method name the client and server can
fully negotiate between all the keyx methods, including GSS-API
mechanism available.

> I hope it will use the host key field to specify which GSS mechanism

Why would you want to make such a change?  What would you gain?

Simon Wilkinson's patches for OpenSSH are not the only implementation of
draft-ietf-secsh-gsskeyex-06, so changing the spec now sure would hurt,
and there'd be nothing to gain from what you suggest.

Cheers,

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 24 Jun 2003 11:53:19 -0500

> fully negotiate between all the keyx methods, including GSS-API

Also, I happen to find the way GSS-API mechanism negotiation for keyex
is specified in draft-ietf-secsh-gsskeyex is quite elegant.  It is
simple (simpler than SPNEGO, for example), it fits right into the SSHv2
keyex model and it is secure (because of the way the session ID is
derived as a hash of data that includes the KEXINIT messages) without
suffering from the unfortunate problems that have arisen with SPNEGO[1].

There really is no alternative if you wish for clients and servers with
non-overlapping supported GSS-API mechanisms[2] to be able to
successfully complete key exchanges without user input; the only
alternative would have been to have the basic SSHv2 keyex protocol
modified so that keyex could be re-tried without having to restart the
connection.

[1] Long story.  Suffice it to say that it is not currently possible to
    implement SPNEGO correctly and also interoperate with deployed
    implementations without also fixing the deployed SPNEGO
    implementations.

[2] And note that what matters is not so much what GSS-API mechs are
    supported by the client and server implementations as which ones
    they have initiator and acceptor credentials for, respectively.

Nico
--

---

From: "Joel N. Weber II" <[email-masked]>
Date: Tue, 24 Jun 2003 16:10:11 -0400

> keys that go into the known_hosts public keys file.

The implementation of pgp-sign-{dss,rsa} that I wrote uses things that
I guess you are calling ``SSHv2 host keys'' which don't go into the
known_hosts file.  It certainly uses the same key exchange algorithms
that ssh-rsa uses.  (Of course, it should make a known_hosts file
entry, so that a MitM who offers a bare ssh-rsa or ssh-dss key doesn't
cause prompting about a brand new host with an unknown key, but sxw's
GSS patches have the same problem.)

> fully negotiate between all the keyx methods, including GSS-API

I think you're confused.  Consider this part of the transport draft:

         Choose the first algorithm that satisfies the following
         conditions:
         +  the server also supports the algorithm,
         +  if the algorithm requires an encryption-capable host key,
            there is an encryption-capable algorithm on the server's
            server_host_key_algorithms that is also supported by the
            client, and
         +  if the algorithm requires a signature-capable host key,
            there is a signature-capable algorithm on the server's
            server_host_key_algorithms that is also supported by the
            client.
         +  If no algorithm satisfying all these conditions can be
            found, the connection fails, and both sides MUST disconnect.

It's clearly the case that you ignore a key exchange algorithm and
pick the next one if the subnegotiation on the host key finds that
there's no compatible key.  So if GSS defined one keyex method and
used the host key type to specify which GSS mechanism to use, the
problem you describe doesn't really exist, near as I can tell.

But I've realized another potential problem: there is no way to
specify that your first preference is to use a pgp-sign-{dss,rsa} key,
your second preference is a GSSAPI method, and your third perference
is ssh-{dss,rsa}.

A cleaner algorithm would be:

Choose the first host key type on the client's list that is also on
the server's list.  Choose the first host key algorithm on the
client's list that's also on the server's list that supports the host
key type choosen.  (Actually, this will work regardless of which field
you use to encode which GSS mechanism you're using, but if you want it
all in the key exchange field you'd have to define gssapi as a host
key type, and then you'd lose the ability to mix non-GSS methods in
between the GSS methods in the priority list.)

The ssh v2.1 protocol could be defined to negotiate in this new
fashion if both client and server claimed to have a version of at
least 2.1, otherwise using the old method.  And maybe we could define
a 1.991 protocol version value for those people who want to support
v2.1, v2, and v1, or something.

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 24 Jun 2003 13:26:33 -0700

> problem you describe doesn't really exist, near as I can tell.

I don't see how this could be called more elegant, or even as elegant as
the current draft.  And it's clear that it is much, much too late to
change the draft should we all agree that this is approach is better.

> between the GSS methods in the priority list.)

Why so complicated?  The current approach to negotiating GSS-API
mechanisms is simple, it works, it's elegant.

And the GSS-API is not about "host key types" - it's about mechanisms.
Why conflate the two?

> v2.1, v2, and v1, or something.

Why bother?

Cheers,

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 24 Jun 2003 17:03:19 -0500

Joel points out that one cannot specify a preference such as:

 - 1st, pubkey keyex with pgp-sign-{dss,rsa} keys
 - 2nd, gss keyex with some mechanism
 - 3rd, pubkey keyex with ssh-{dss,rsa} keys

I think Joel's right.

Joel's proposed solution, i.e., treating the GSS-API mechanisms as host
key algorithms (which I find to be conceptually incorrect) would not
work, I think.

The KEXINIT packets probably should have, from the get go, negotiated

{keyex method, <keyex method specific arguments (host keys, GSS mechs)>}

tuples, but it doesn't.

One solution might be to add aliases of the pubkey keyex methods (e.g.,
diffie-hellman-group1-sha1) for use with PGP and other non-ssh-{dss,rsa}
host key types.  I think this would solve the problem.

I'll think about it more when I have the time for it.

Cheers,

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 26 Jun 2003 08:48:46 -0700

Joel,

I've thought more about it and I see but one easy way to get the ability
to specify preferences such as:

without breaking existing deployed systems.

That would be to add aliases of the "pubkey" keyex methods
("diffie-hellman-group1-sha1" and "diffie-hellman-group-exchange-sha1")
which are understood to be usable only with a subset of the host key
algorithms normally usable with those kex methods.

Thus the preferences in the above scenario could be expressed as follows:

 - kex methods:

   diffie-hellman-group1-sha1-pgp,gss-group1-sha1-XYZ,diffie-hellman-group1-sha1

 - host key algorithms:

   pgp-sign-rsa,pgp-sign-dss,ssh-dss,ssh-rsa

[The nice thing about these kex method aliases is that their use would
 not break existing implementations.]

Treating the GSS-API mechanisms as host key algorithms wouldn't solve
the problem because of the way that the key exchange method is to be
picked as per draft-ietf-secsh-transport-15.  That is, something like
this in the client's KEXINIT:

 - kex methods:

   diffie-hellman-group1-sha1,gss-group1-sha1

 - host key algorithms:

   pgp-sign-rsa,pgp-sign-dss,gss-api-XYZ,ssh-dss,ssh-rsa

would lead to the selection of diffie-hellman-group1-sha1 whenever the
server offers it and any of the pgp-sign-*,ssh-* host key algorithms.

The kex method selection algorithm could be specified in such a way that
draft-ietf-secsh-gsskeyex could have treated GSS-API mechanisms as host
key algorithms and so that the second example above would have worked.
But it wasn't.

What's clear to me is that this issue was not caused by the introduction
of draft-ietf-secsh-gsskeyex - it was there all along and all that had
to happen for it to annoy someone was for some kex method to be
introduced with a host key algorithm set disjoint with respect to the
original kex method's.  In fact, even without GSS-API in the picture
there are preferences that you can't specify (though no one would want
to specify such preferences), such as:

  - 1st, diffie-hellman-group-exchange-sha1 keyex with pgp-sign-{dss,rsa} keys
  - 3rd, diffie-hellman-group1-sha1 keyex with ssh-{dss,rsa} keys
  - 2nd, diffie-hellman-group-exchange-sha1 keyex with ssh-{dss,rsa} keys

No amount of tinkering with draft-ietf-secsh-gsskeyex will fix the
underlying problem because the underlying problem is in
draft-ietf-secsh-transport.

Cheers,

Nico