Enforce that pre_shared_key must come with psk_key_exchange_modes.

Omitting the extension means we'll never issue tickets, but if the
client were to offer a ticket anyway, RFC8446 4.2.9 says we MUST reject
the ClientHello. It's not clear on what alert to use, but
missing_extension is probably appropriate.

Thanks to Ben Kaduk for pointing this out.

Change-Id: Ie5c720eac9dd2e1a27ba8a13c59b707c109eaa4e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46464
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
grpc-202302
David Benjamin 4 years ago committed by CQ bot account: commit-bot@chromium.org
parent 4aef687fcf
commit 3af62269df
  1. 4
      ssl/test/runner/common.go
  2. 2
      ssl/test/runner/handshake_client.go
  3. 20
      ssl/test/runner/runner.go
  4. 10
      ssl/tls13_server.cc

@ -1240,8 +1240,8 @@ type ProtocolBugs struct {
// session ticket.
SendEmptySessionTicket bool
// SendPSKKeyExchangeModes, if present, determines the PSK key exchange modes
// to send.
// SendPSKKeyExchangeModes, if not nil, determines the PSK key exchange
// modes to send. If a non-nil empty slice, no extension will be sent.
SendPSKKeyExchangeModes []byte
// ExpectNoNewSessionTicket, if present, means that the client will fail upon

@ -186,7 +186,7 @@ func (c *Conn) clientHandshake() error {
hello.supportedCurves = nil
}
if len(c.config.Bugs.SendPSKKeyExchangeModes) != 0 {
if c.config.Bugs.SendPSKKeyExchangeModes != nil {
hello.pskKEModes = c.config.Bugs.SendPSKKeyExchangeModes
}

@ -12169,6 +12169,26 @@ func addSessionTicketTests() {
expectResumeRejected: true,
})
// Test that the server rejects ClientHellos with pre_shared_key but without
// psk_key_exchange_modes.
testCases = append(testCases, testCase{
testType: serverTest,
name: "TLS13-SendNoKEMModesWithPSK-Server",
config: Config{
MaxVersion: VersionTLS13,
},
resumeConfig: &Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendPSKKeyExchangeModes: []byte{},
},
},
resumeSession: true,
shouldFail: true,
expectedLocalError: "remote error: missing extension",
expectedError: ":MISSING_EXTENSION:",
})
// Test that the client ticket age is sent correctly.
testCases = append(testCases, testCase{
testType: clientTest,

@ -252,6 +252,16 @@ static enum ssl_ticket_aead_result_t select_session(
return ssl_ticket_aead_ignore_ticket;
}
// Per RFC8446, section 4.2.9, servers MUST abort the handshake if the client
// sends pre_shared_key without psk_key_exchange_modes.
CBS unused;
if (!ssl_client_hello_get_extension(client_hello, &unused,
TLSEXT_TYPE_psk_key_exchange_modes)) {
*out_alert = SSL_AD_MISSING_EXTENSION;
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
return ssl_ticket_aead_error;
}
CBS ticket, binders;
uint32_t client_ticket_age;
if (!ssl_ext_pre_shared_key_parse_clienthello(

Loading…
Cancel
Save