Skip to content

TLS 1.3 server: don't send NewSessionTicket (session resumption is not implemented)#403

Open
EdouardMALOT wants to merge 1 commit into
eclipse-threadx:masterfrom
EdouardMALOT:fix/tls13-no-stub-newsessionticket
Open

TLS 1.3 server: don't send NewSessionTicket (session resumption is not implemented)#403
EdouardMALOT wants to merge 1 commit into
eclipse-threadx:masterfrom
EdouardMALOT:fix/tls13-no-stub-newsessionticket

Conversation

@EdouardMALOT

Copy link
Copy Markdown
Contributor

Summary

The TLS 1.3 server sends a NewSessionTicket after every completed handshake, but session resumption is not implemented: the server can never honor the ticket it just issued.

What _nx_secure_tls_send_newsessionticket() actually sends: ticket_lifetime = 604800 (the RFC maximum, 7 days), a random ticket_age_add, and the hardcoded string "NewSessionTicket" as ticket identity. No server-side state is created. The ticket is a stub.

What happens when a client caches that ticket and offers it on its next connection depends on the build:

  • With NX_SECURE_ENABLE_PSK_CIPHERSUITES: _nx_secure_tls_process_clienthello_psk_extension() rejects any PSK identity with a non-zero obfuscated age (/* Only support external PSKs (no session resumption). */) with NX_SECURE_TLS_BAD_CLIENTHELLO_PSK_EXTENSION and a fatal alert. Since ticket_age_add is random, a replayed ticket's obfuscated age is never zero in practice. Observed in the field with Java (JSSE) clients: every other connection fails. Connection N succeeds and caches the ticket, connection N+1 replays it and is aborted, JSSE drops the cached ticket, connection N+2 succeeds, and so on.
  • Without it: the pre_shared_key extension is ignored and the handshake completes as a full handshake. No failure, but every TLS 1.3 client is handed a 7-day stub ticket it will cache and uselessly replay on every connection.

Changes

  • nx_secure/src/nx_secure_tls_1_3_server_handshake.c — do not send NewSessionTicket after the client Finished. The message is optional per RFC 8446 §4.6.1 ("the server MAY send"); not advertising resumption is the correct behavior as long as it is not implemented.

_nx_secure_tls_send_newsessionticket() has no state side effects (it only writes the packet), so nothing downstream is affected; the function is kept for the day resumption support lands. The PSK extension handler is untouched, so external PSKs (age == 0) keep working. Incidentally, the removed block also contained an unchecked status (_nx_secure_tls_send_newsessionticket()'s return value was overwritten by the next call).

Possible follow-up, out of scope here: per RFC 8446 §4.2.11, a server that does not accept an offered PSK identity should skip it and fall back to a full handshake rather than abort. That would harden the handler against resumption offers from any peer.

Test plan

  • TLS 1.3 server with NX_SECURE_ENABLE_PSK_CIPHERSUITES, Java (JSSE) client making repeated connections: previously every other handshake failed with a fatal alert, now all connections succeed
  • TLS 1.3 client ↔ NetX server full handshake: unchanged apart from the absent (optional) NewSessionTicket record
  • External PSK ciphersuites: unchanged (PSK extension handler untouched)

…orted)

_nx_secure_tls_1_3_server_handshake.c sent a NewSessionTicket after every
Client Finished, advertising session resumption to the client. But
_nx_secure_tls_process_clienthello_psk_extension explicitly rejects any
PSK with age != 0 (i.e. every real resumption attempt) with
NX_SECURE_TLS_BAD_CLIENTHELLO_PSK_EXTENSION — the existing implementation
only supports external PSKs.
Net effect on clients that act on the advertised ticket (Java JSSE in
particular): every other handshake fails. Conn N succeeds + caches the
ticket; conn N+1 replays the ticket → server sends Alert(internal_error)
→ JSSE invalidates the cache; conn N+2 succeeds; loop.
Fix: skip the NewSessionTicket send. The PSK consumer code stays as-is
so any future external-PSK use case is unaffected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant