Subject: Re: Feedback on draft-ssh-ext-info-00

From: Damien Miller <[email-masked]>
Date: Thu, 3 Dec 2015 15:08:32 +1100 (AEDT)

On Thu, 3 Dec 2015, denis bider wrote:

> Another possible way to use the key exchange algorithms field for an
> extension in parallel with EXT_INFO might be to change the way SSH host key
> algorithms are negotiated, for example. The current negotiation rules have
> serious drawbacks, not least that the client has no way of learning the SSH
> server's other host keys if it already trusts one.

You might be interested in:

https://anongit.mindrot.org/openssh.git/tree/PROTOCOL?id=f0191d7c8#n284

Hostkey rotation within the current protocol with no messing around
with KEXINIT.

-d

---

From: Damien Miller <[email-masked]>
Date: Thu, 3 Dec 2015 17:31:26 +1100 (AEDT)

On Thu, 3 Dec 2015, denis bider wrote:

> I have posted a new draft to address this:
> 
> https://tools.ietf.org/html/draft-ssh-ext-info-03
> 
> The difference is that there is now a "services" field in EXT_INFO:
> 
>     byte       SSH_MSG_EXT_INFO (value 7)
>     name-list  services
>     uint32     nr-extensions
>     repeat "nr-extensions" times:
>       string   extension-name
>       string   extension-value
> 
> And a section to describe it:
> 
> 3.5.  Service Negotiation
>   The client and server each include a name-list of supported services
>   in EXT_INFO. The name-lists are matched to negotiate a service in the
>   same way as name-lists are matched in KEXINIT. Clients and servers
>   that support only "ssh-userauth" MUST send this service name only.
>   Implementations supporting only one service MAY assume it will be
>   negotiated, and MAY send messages on that premise without waiting.
> 
> Would you agree this makes EXT_INFO a proper superset of SERVICE_REQUEST +
> ACCEPT?

This is over-complicated. Why add fixed-function fields to a generic
extension mechanism?

I'd support a simple magic name, offered in KEXINIT to indicate that an
implementation is prepared to accept a SSH_MSG_EXT_INFO packet.
Merely advertising a willingness to accept SSH_MSG_EXT_INFO shouldn't
have other further effects on the protocol. To do otherwise is IMO quite
surprising.

Then, if you want to define a "die-service-request-die" extension that
changes the protocol flow then you can do that without requiring other
implementations to follow suit.

-d

---

From: Damien Miller <[email-masked]>
Date: Thu, 3 Dec 2015 18:14:40 +1100 (AEDT)

On Thu, 3 Dec 2015, denis bider wrote:

> > Merely advertising a willingness to accept SSH_MSG_EXT_INFO
> > shouldn't have other further effects on the protocol. To do
> > otherwise is IMO quite surprising.
> 
> Okay, imagine this:
> 
> (1) Instead of the EXT_INFO message, we continue to send SERVICE_REQUEST +
> ACCEPT.
> 
> (2) The KEXINIT extension instead signals that extension fields can be added
> to SERVICE_REQUEST + ACCEPT.
> 
> (3) Presence of the KEXINIT extension further signals that the server can
> send a presumed SERVICE_ACCEPT, without waiting for SERVICE_REQUEST.
> 
> Do you see that this results in the same proposal, just with renamed
> messages?

At the risk of repeating myself, I think providing a simple transport
layer extension mechanism is a fantastic idea, but don't agree that
it should make other protocol changes (except, perhaps as extensions
defined in the same document).

-d

---

From: denis bider <[email-masked]>
Date: Thu, 3 Dec 2015 03:45:33 +0000

> If there's a functioning extension mechanism,
> then why would there be competition?

To extend other aspects of SSH that EXT_INFO cannot. This could be to change some aspect of algorithm negotiation, for example.

For instance, there has been a problem in how AEAD is negotiated. Besides what OpenSSH did - implementing a private algorithm for AES-GCM - another possible solution could be an extension where both client and server put something in their key exchange algorithms field. If both client and server do this, then the result of MAC negotiation is ignored if an AEAD encryption algorithm is negotiated.

But why do you even feel the need to call this out? Is it any harder to call:

    is_in_namelist(name, namelist)

instead of:

    is_at_end_of_namelist(name, namelist)

?

You are saying, "I can't envision a  usage scenario for this, so let's prevent it." This is pompous, because you implicitly consider yourself capable of predicting such scenarios. Further, you are doing this for zero benefit; as a matter of principle; and just after we've been through conversations where  I've pointed out that we cannot predict future needs, and that this attitude - "prohibit it because we can" - has already created problems.

> IIRC I've heard of at least one server that doesn't
> implement ssh-userauth.

This is possible with EXT_INFO also. Send an extension name and value informing the client of what you implement. No need to waste a round-trip for 99.999% of other users.

> I'm not sure what the gain is either compared to making
> the SSH window match the TCP window size. It's not like
> SSH can go send more data than that.

Just simplicity, for implementations that want it.

A user mode app doesn't necessarily have info about what goes on at the TCP level, and if it does, it's something a single-channel implementation doesn't want to have to bother with.

denis

----- Original Message -----
From: Damien Miller 
Sent: Wednesday, December 2, 2015 21:10
To: denis bider 
Cc: Markus Friedl ; [email-masked] 
Subject: Re: Feedback on draft-ssh-ext-info-00

On Thu, 3 Dec 2015, denis bider wrote:

> > IMO it would be best to make it a MUST that the flags
> > may only be sent as the last element. What rationale is
> > there for putting it anywhere else?
> 
> In the event that there are two or more competing extension mechanisms, only
> one of them can be last.

If there's a functioning extension mechanism, then why would there be
competition?

Even if there were, then it's up to whoever writes the second one to
deal with making their fit.

> > and don't "replace" any messages like
> > SSH_MSG_SERVICE_REQUEST.
> 
> But but but I waaaant to replace this awful SSH_MSG_SERVICE_REQUEST. :)
> 
> Does no one agree that SERVICE_REQUEST + ACCEPT are pointless?
> 
> A whole round-trip delay? For no benefit - in any known usage scenario?

IMO replacing messages in the protocol is something best saved for
SSH-3.x. IIRC I've heard of at least one server that doesn't implement
ssh-userauth.

> > OpenSSH has sent various @openssh.com global
> > requests for years, so most of the implementations
> > that violate this should have long since been shaken out.
> 
> Do you happen to know:
> 
> - Since which version the OpenSSH server has been sending global requests?

3.8ish, released early 2004

> - Since which version the OpenSSH client has been tolerating them?

at least that long :)

> There are still folks out there using OpenSSH 3.x and 4.x. I'm pretty sure I
> saw our software being connected to by a client like that in the past week.

4.x should be fine, older 3.x might have problems - I haven't checked.

Honestly though, anyone using OpenSSH 3.x has bigger problems than
channel requests upsetting their connections.

> > (e.g. it's impossible to have one channel without the
> > "handbrake" and one with normal flow control)
> 
> As discussed, this is on purpose. If you want multiplexing, implement
> multiplexing, including flow control.
> 
> If even one channel does not have flow control, this affects the transport
> layer also. It affects keep-alive mechanisms, key exchange, and flow control
> at the transport level.

Right, "no-handbrake" breaks all of these. I'm not sure what the gain is
either compared to making the SSH window match the TCP window size. It's
not like SSH can go send more data than that.

-d

---

From: denis bider <[email-masked]>
Date: Thu, 3 Dec 2015 07:11:14 +0000

> mainly so the server can send a second EXT_INFO just
> before USERAUTH_REQUEST. This way you can
> advertise extensions that alter user  auth; but you can
> also have privacy for extensions that only take effect  after.

Sorry, that should be:

"just before USERAUTH_SUCCESS"

denis bider <[email-masked]> , 12/3/2015 7:03 AM:
If after considering this, you still really want the SERVICE_REQUEST + ACCEPT round-trip, then okay. I can change the spec to not alter this part, if this way we have something we can all agree on.

But if we change it this way, when do you want EXT_INFO to be sent? What is the window in which it should be accepted?

The current proposal makes the window:

- between NEWKEYS and SERVICE_REQUEST for the client, sent one time 

- between NEWKEYS and USERAUTH_SUCCESS for the server, sent any number of times (mainly so the server can send a second EXT_INFO just before USERAUTH_REQUEST. This way you can advertise extensions that alter user auth; but you can also have privacy for extensions that only take effect after.

If we change EXT_INFO the way you propose, and keep SERVICE_REQUEST + ACCEPT as-is - are you okay with these windows?

denis bider <[email-masked]> , 12/3/2015 6:38 AM:
> Why add fixed-function fields to a generic extension mechanism? 

So as to avoid ret-conning functionality provided by SERVICE_REQUEST + ACCEPT.

These two messages always negotiate the service (e.g. "ssh-userauth"). So EXT_INFO, which is a replacement, also always negotiates the service.

This is in fact simpler than adding a "services" extension, and then mandating that this extension "MUST" be handled by all implementations. If some functionality must always be handled, a fixed field is appropriate.

Okay, imagine this:

(1) Instead of the EXT_INFO message, we continue to send SERVICE_REQUEST + ACCEPT.

(2) The KEXINIT extension instead signals that extension fields can be added to SERVICE_REQUEST + ACCEPT.

(3) Presence of the KEXINIT extension further signals that the server can send a presumed SERVICE_ACCEPT, without waiting for SERVICE_REQUEST.

Do you see that this results in the same proposal, just with renamed messages?

Damien Miller <[email-masked]> , 12/3/2015 6:31 AM:

 

-d

---

From: denis bider <[email-masked]>
Date: Thu, 3 Dec 2015 03:53:54 +0000

Another possible way to use the key exchange algorithms field for an extension in parallel with EXT_INFO might be to change the way SSH host key algorithms are negotiated, for example. The current negotiation rules have serious drawbacks, not least that the client has no way of learning the SSH server's other host keys if it already trusts one.

To solve this, I could suggest an extension that enhances all key exchange methods in the following way. Instead of sending:

string public-key

The server sends:

string:
  string negotiated-public-key
  uint32 nr-other-public-keys
  string other-public-keys[]
  uint32 nr-revoked-public-keys
  string revoked-public-key-fingerprints[]

This extension would allow the SSH Server to gracefully rollover to a new host key algorithm, or to increase key size, which it currently cannot without completely screwing up all its trust relationships with its clients.

This extension could be negotiated in the key exchange algorithms field, just like EXT_INFO; and could exist simultaneously and independently of EXT_INFO.

instead of:

?

denis

----- Original Message -----
From: Damien Miller 
Sent: Wednesday, December 2, 2015 21:10
To: denis bider 
Cc: Markus Friedl ; [email-masked] 
Subject: Re: Feedback on draft-ssh-ext-info-00

at least that long :)

-d

---

From: denis bider <[email-masked]>
Date: Thu, 3 Dec 2015 06:46:20 +0000

Okay, imagine this:

 

 
 
-d

---

From: denis bider <[email-masked]>
Date: Thu, 3 Dec 2015 05:16:09 +0000

> I'll repeat my opinion: an extension mechanism is not
> the place to fundamentally retcon parts of the protocol.

It's not intended as a retcon. It's a negotiated replacement of an existing (inflexible, inefficient, almost pointless) mechanism with a new (flexible, efficient, worthwhile) mechanism.

Compare this to SMTP HELO replaced by EHLO. This did not require bumping the SMTP protocol version.

The change is only a retcon if it removes functionality that SERVICE_REQUEST + ACCEPT have. So basically, you're saying that while the negotiation provided by SERVICE_REQUEST is pointless in the vast majority of cases, it is being relied upon by a small percentage of implementations, and this should be respected.

If that's what you're saying, you have a point. In order to be a proper replacement, and not a retcon, it has to preserve existing functionality.

3.5.  Service Negotiation  The client and server each include a name-list of supported services
  in EXT_INFO. The name-lists are matched to negotiate a service in the
  same way as name-lists are matched in KEXINIT. Clients and servers
  that support only "ssh-userauth" MUST send this service name only.
  Implementations supporting only one service MAY assume it will be
  negotiated, and MAY send messages on that premise without waiting.
Would you agree this makes EXT_INFO a proper superset of SERVICE_REQUEST + ACCEPT?

denis bider <[email-masked]> , 12/3/2015 4:14 AM:
> I'm suggesting you specify what is sent, not how
> implementations test for it. 

It is important to specify what to test for. Just weeks ago, we had a conversation about how RFC 4253 should have spelled out that the "reserved" field must be sent as zero, but must not be checked that it is zero.

It is important to specify what things implementations should not check for, when incorrect implementation may cause compatibility issues.

> The benefit is that ~ a paragraph of fairly
> useless verbiage in your spec disappears. 
 
You are losing my respect as we continue.

Damien Miller <[email-masked]> , 12/3/2015 4:06 AM:
On Thu, 3 Dec 2015, denis bider wrote: 
 
> To extend other aspects of SSH that EXT_INFO cannot. This could be to change 
> some aspect of algorithm negotiation, for example. 
>  
> For instance, there has been a problem in how AEAD is negotiated. Besides 
> what OpenSSH did - implementing a private algorithm for AES-GCM - another 
> possible solution could be an extension where both client and server put 
> something in their key exchange algorithms field. If both client and server 
> do this, then the result of MAC negotiation is ignored if an AEAD encryption 
> algorithm is negotiated. 
>  
 
I'm suggesting you specify what is sent, not how implementations test 
for it. The benefit is that ~ a paragraph of fairly useless verbiage 
in your spec disappears. 
 
> This is possible with EXT_INFO also. Send an extension name and value 
> informing the client of what you implement. No need to waste a round-trip 
> for 99.999% of other users. 
 
I'll repeat my opinion: an extension mechanism is not the place to 
fundamentally retcon parts of the protocol. It breaks orthagonality 
and turns implementations into spaghetti. 
 
Perhaps you want a "no-service-requests" extension instead? 
 
-d

---

From: denis bider <[email-masked]>
Date: Thu, 3 Dec 2015 04:16:49 +0000

-d

---

From: denis bider <[email-masked]>
Date: Thu, 3 Dec 2015 07:26:53 +0000

Okay, I'll modify the draft to this effect. This may take me a bit, I currently have a few urgent things to attend to.

I would appreciate your thoughts on the question of EXT_INFO windows for client and server.

Do you find it acceptable if the proposal requires both client and server to send their first EXT_INFO immediately after NEWKEYS?

Specifically, that the server does not wait between EXT_INFO and NEWKEYS to receive anything more from the client?

That way:
- I can then put in an extension like "assume-service";
- the client can send EXT_INFO("assume-service") + SERVICE_REQUEST;
- when the client sees the server's EXT_INFO("assume-service"), it can just continue with USERAUTH_REQUEST, and SERVICE_ACCEPT is not sent.

Damien Miller <[email-masked]> , 12/3/2015 7:14 AM:

 
-d

---

From: denis bider <[email-masked]>
Date: Thu, 3 Dec 2015 07:09:27 +0000

Okay, imagine this:

 

 
 
-d

---

From: Damien Miller <[email-masked]>
Date: Thu, 3 Dec 2015 15:05:58 +1100 (AEDT)

-d

---

From: Peter Gutmann <[email-masked]>
Date: Sat, 5 Dec 2015 23:42:30 +0000

Damien Miller <[email-masked]> writes:

>fundamentally retcon parts of the protocol. 

Why not?  I would have thought that's what it was there for.  TLS has been
using extensions to fix protocol problems for years without any real problems.
Taking one case that I'm pretty familiar with, the encrypt-then-MAC extension,
the impact was very minimal, you add an entry to an extension en/decoding
table, and then have a boolean flag to swap the order of calls to encrypt and
MAC routines.  It was, I dunno, maybe a dozen lines of code and a hour's work
to fix a problem that had been plagueing the protocol for at least fifteen
years.  It's a really easy way to fix issues in the protocol, I just wish SSH
had had an extension mechanism of the kind that Denis is working on a long
time ago.

Peter.

---

From: [email-masked] (Niels Möller)
Date: Fri, 11 Dec 2015 09:39:21 +0100

> Do you find it acceptable if the proposal requires both client and server to send their first EXT_INFO immediately after NEWKEYS?

I think that's a reasonable place to send it. I view EXT_INFO as a part
of the transport layer, and then the spec ought to not depend on messages
belonging to the ssh-userauth or the ssh-connection service. 
 
But maybe I'm missing the issue... As a client, you want to know what
extensions are supported *before* you send the SERVICE_REQUEST message?
But it it's optional, you can't know if the server is not sending any
EXT_INFO, or if it's going to send it but you haven't received it yet.

Is that right?

Since the protocol is specified as running over a byte stream, we ought
not to reason in terms of the EXT_INFO arriving in the same packet as
the NEWKEYS, even if that probably would work in practice.

To remove the ambiguity, negotiation has to be a bit more complex.
We'd need four more magic symbols,

  ext_info_{send,recv}_{c,s}

and specify that the server MUST send EXT_INFO if and only if the
client advertised ext_info_recv_c and the server advertised
ext_info_send_s. 

Then the client knows unabiguously if there will be an EXT_INFO following
the NEWKEYS.

And similarly for the other direction.

Is there any simpler way to do it?

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.

---

From: Matt Johnston <[email-masked]>
Date: Fri, 11 Dec 2015 23:31:45 +0800

> On Fri 11/12/2015, at 4:39 pm, Niels Möller <[email-masked]> wrote:
> ...

Why not keep just ext_info_{c,s} and specify that client and server both MUST send SSH_MSG_EXT_INFO immediately after SSH_NEWKEYS iff both sent ext_info_{c,s}? Then they both know what to expect.

Regarding the secondary SSH_MSG_EXT_INFO before SSH_MSG_USERAUTH_SUCCESS there's a race condition - the server can't tell if subsequent packets it receives were sent by the client prior to receiving SSH_MSG_EXT_INFO - the same as the delayed zlib race [1]. Probably won't be a problem for the current extensions but it could cause trouble if it's used for transport-level extensions.

I think "server-sig-algs" should have "auth" somewhere in the name to avoid confusion with hostkey algorithms. Not a huge deal.

As a small data point Dropbear client has been sending SERVICE_REQUEST and USERAUTH_REQUEST in the same TCP packet since 2013 (2013.57) with no reports of problems. That said Dropbear is a lot more widely used as a server than client - I'm sure there could be something that wouldn't handle it.

FWIW Dropbear is already using the kex algorithm "[email-masked]" to signal more permissive first_kex_packet_follows negotiation. [2]

Cheers,
Matt

[1] Simon's comment http://thread.gmane.org/gmane.ietf.secsh/6108/focus=6110
[2] http://www.ietf.org/mail-archive/web/secsh/current/msg00657.html

---

From: [email-masked] (Niels Möller)
Date: Sat, 12 Dec 2015 09:14:37 +0100

Matt Johnston <[email-masked]> writes:

> Why not keep just ext_info_{c,s} and specify that client and server
> both MUST send SSH_MSG_EXT_INFO immediately after SSH_NEWKEYS iff both
> sent ext_info_{c,s}? Then they both know what to expect.

Sounds ok to me.

Regards,
/Niels