Subject: [TLS] permitted client behaviour when rejecting renegotiation

From: Martin Rex <[email-masked]>
Date: Wed, 20 Jan 2010 02:51:05 +0100 (MET)

Considering the guidance in draft-ietf-tls-renegotiation-03.txt
and the specification of HelloRequest starting with rfc-2246 (TLSv1.0)
http://tools.ietf.org/html/rfc2246#section-7.4.1.1

I'm a little confused about a sensible client behaviour.

TLSv1.0 and newer say this:

   Meaning of this message:
       Hello request is a simple notification that the client should
       begin the negotiation process anew by sending a client hello
       message when convenient. This message will be ignored by the
       client if the client is currently negotiating a session.
                                                                 This
       message may be ignored by the client if it does not wish to
       renegotiate a session, or the client may, if it wishes, respond
       with a no_renegotiation alert.

SSLv3 does not have that _general_ permission to ignore this handshake
message.

If a client wants to abort the handshake (for whatever reason) it
should IMHO send a fatal "handshake_failure" alert *WITHOUT* a
prior warning "no_renegotiation" alert.

My impression from my testing with openssl-0.9.8l was that it may have
a server-side problem with a client ignoring HelloRequest.

Question to implementors: what will your TLS servers do when a client
simply ignores HelloRequest--a behaviour that has been allowed by all
existing TLS specs for 10 years?

-Martin

---

From: Nikos Mavrogiannopoulos <[email-masked]>
Date: Wed, 20 Jan 2010 16:56:04 +0100

> http://tools.ietf.org/html/rfc2246#section-7.4.1.1
[...]
> existing TLS specs for 10 years?

I always wondered how this behavior was supposed to work. For gnutls an
error is returned if the request is ignored.  I think the use cases of
these packets for renegotiation should be clearly defined (i.e. why send
this packets and what should be expected from peer). I don't know how
easy it is to implement the semantics precisely, but so far I didn't see
any compelling reason to do so.

regards,
Nikos

---

From: Martin Rex <[email-masked]>
Date: Wed, 20 Jan 2010 17:58:25 +0100 (MET)

> any compelling reason to do so.

To me, this sounds like the server's gnuTLS switches to half-duplex
communication when it _sends_ a HelloRequest and expects the next
_received_ TLS record to carry a ClientHello handshake message
(or a warning-level no_renegotiation alert).

Can you describe/confirm the exact behaviour for gnuTLS?

>From its design, the TLS protocol is full-duplex, so such behaviour
would not be compliant to any existing SSL/TLS protocol spec.

The full-duplex requirement, which is implied by the definition
of the HelloRequest message in SSLv3 already is probably the reason
why the "may ignore" was written out for TLS:

   The hello request message may be sent by the server at any time,
   but will be ignored by the client if the handshake protocol is
   already underway.  It is a simple notification that the client
   should begin the negotiation process anew by sending a client hello
   message when convenient.

That "when convenient" accounts to the fact that the (app) client
may be writing and the TLS implementation therefore not even
looking (read) whether there might be a HelloRequest handshake
message waiting -- and continue sending application data.

-Martin

---

From: Nikos Mavrogiannopoulos <[email-masked]>
Date: Wed, 20 Jan 2010 18:43:19 +0100

> Can you describe/confirm the exact behaviour for gnuTLS?

Indeed, and this is intentional. I decided to error on any received
application data, because the only use case of renegotiation I had so
far seen was the client authentication upgrade. In that case I had no
easy way to distinguish data received on the previous session and
"client authenticated" data received on the session after renegotiation.

>    should begin the negotiation process anew by sending a client hello

Then you have the issue to distinguish data on the session "before" and
the session "after" which is doable but not trivial (and probably
depends on the application layer to interpret this information as well).

> message waiting -- and continue sending application data.

My limited experience with renegotiation shows that it is used in
coordination with the application layer to upgrade the session with new
security parameters. This is typically done on a silent phase of the
application protocol (not during a file transfer that would require full
duplex communication). Thus my decision was to implement this use case
of renegotiation and wait for some compelling reasons (use cases) to
implement the rest, which as I mentioned is not trivial.

best regards,
Nikos

---

From: Martin Rex <[email-masked]>
Date: Thu, 21 Jan 2010 00:12:02 +0100 (MET)

> "client authenticated" data received on the session after renegotiation.

I should clarify this:  Prohibiting app data exchange _during_ a
renegotiation handshake is something that I advocated for myself
(and would likely implement myself if I would implement TLS), see

http://www.ietf.org/mail-archive/web/tls/current/msg04091.html

But given the full-duplex nature of the TLS exchanges before
and after renegotiation, I would cut the "renegotiation handshake"
differently, and _not_ consider a HelloRequest message to be part
of that handshake.  Because of the full-duplex nature, the handshake
is not guaranteed to be started synchronously on both directions
of the communication.  The TLS handshake itself is half-duplex
by nature (which might be the reason why the SSL spec defined the
interleaving of renegotiation handshake and application data
in the first place).

The implementation challenge is to get back in sync for the
TLS handshake.  Implementations like OpenSSL seem to use a half-duplex
protocol state engine for the TLS handshake (which is perfectly OK
for the initial handshake!), but that makes it little trickier to
implement the semantics that I outlined in my above message.

> depends on the application layer to interpret this information as well).

Singling out the HelloRequest message from the TLS handshake protocol
engine is likely simpler than allowing the handshake to begin on
a per-direction basis, i.e. the client sending side starts the handshake
with sending the ClientHello handshake message, the client receiving
part starts the handshake when it receives the ServerHello.

For the server side this might be easier to implement, because the
ServerHello or a no-renegotiation alert can normally be created
in a fairly synchronous fashion, but the difficulties may depend
much on the API between TLS and app (and whether TLS is transport-less
or in direct control of the communication channel so that it can
reply without the help of the application).

> implement the rest, which as I mentioned is not trivial.

I don't have any real experience with HTTPS-Servers that perform
on-demand TLS authentication, but HTTP pipelining might already
break an assumption about most communication being half-duplex.

(In which case a HTTP client app might have to drop to not-pipeline
over HTTPS)

-Martin

---

From: Nikos Mavrogiannopoulos <[email-masked]>
Date: Thu, 21 Jan 2010 08:52:30 +0100

> (and would likely implement myself if I would implement TLS), see

Ah ok I got the point. Applications that use gnutls can in the time
frame between renegotiation request and handshake start to check and
read pending application data. However this is not done implicitly by
the handshake procedure, that will error if it encounters application data.

> interleaving of renegotiation handshake and application data

Indeed, but there is always the issue of how many record packets to
accept before starting the handshake. Is the client allowed to start the
handshake 2 minutes later or after 2mb of transferred data? Currently I
left this to the application developer.

regards,
Nikos