Subject: [TLS] Alerts after early_data

From: Matt Caswell <[email-masked]>
Date: Tue, 7 Aug 2018 09:35:40 +0100

If a client has sent early_data and later encounters an error before it
has sent the end of early data message, should the alert be sent in
plaintext, or encrypted using the client_early_traffic secret? The error
could occur before or after the client knows whether the server has
accepted its early_data.

Thanks

Matt

---

From: Hubert Kario <[email-masked]>
Date: Wed, 08 Aug 2018 13:13:32 +0200

> could occur before or after the client knows whether the server has

I'd say that if the alert is in relation to early_data, it should be encrypted 
with client_early_traffic keys (internal_error, user_canceled), if it is in 
relation to ServerHello, it should be in plaintext, and when it is in relation 
to EncryptedExtensions, Certificate, ..., or Finished message, it may be 
either in plaintext or encrypted with client_handshake_traffic_secret

(of course, plaintext alerts are allowed only until the first record encrypted 
with handshake_traffic_secret keys)

logic being, that the purpose of the alert is to tell the other side why the 
connection is being broken, no use of doing that if the other side (or even an 
admin using the server's SSLKEYLOGFILE) won't be able to read that message

that being said, very strict reading of the draft-28 would indicate that 
alerts shouldn't be encrypted at all with the client_early_traffic keys:

   0-RTT messages sent in the first flight have the same (encrypted)
   content types as messages of the same type sent in other flights
   (handshake and application_data) but are protected under different
   keys.

(the "alert" type is not listed)
https://tools.ietf.org/html/draft-ietf-tls-tls13-28#page-58
-- 
Regards,
Hubert Kario
Senior Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 115, 612 00  Brno, Czech Republic

---

From: Matt Caswell <[email-masked]>
Date: Wed, 8 Aug 2018 12:26:29 +0100

> with client_early_traffic keys (internal_error, user_canceled), if it is in 

The problem with this is that if the server does not accept the early
data then it won't be able to read the alert. From the server's
perspective the client will just abort with no alert sent.

> https://tools.ietf.org/html/draft-ietf-tls-tls13-28#page-58

This was my interpretation too (thanks). What I've (now) implemented in
OpenSSL is that all alerts from the client are in plaintext until the
client_handshake_traffic_secret is in place, and then encrypted from
then on.

On the server side we tolerate encrypted (with client_early_traffic key
or client_handshake_traffic_secret key as appropriate for the context)
or unencrypted alerts until we've actually seen a handshake message from
the client encrypted with the client_handshake_traffic_secret. From then
on, only encrypted alerts are accepted.

Matt

---

From: Hubert Kario <[email-masked]>
Date: Wed, 08 Aug 2018 13:35:51 +0200

On Wednesday, 8 August 2018 13:26:29 CEST Matt Caswell wrote:
> > I'd say that if the alert is in relation to early_data, it should be
> > encrypted with client_early_traffic keys (internal_error, user_canceled),
> > if it is in

upside is that it makes the ciphertext unusable for replay, as if server is 
able to decrypt it, it will automatically abort

whether that plays better with EndOfEarlyData handling on server side or not 
depends on implementation – if implementation wants the application layer to 
be able to send data as soon as possible to the client, it may result in code 
returning from handshake before lack of EndOfEarlyData is noted (and still 
providing early_data to application)
 
> on, only encrypted alerts are accepted.

sounds like what I had in mind