Enabling 0-RTT on new Session Tickets.
This adds support for setting 0-RTT mode on tickets minted by
BoringSSL, allowing for testing of the initial handshake knowledge.
BUG=76
Change-Id: Ic199842c03b5401ef122a537fdb7ed9e9a5c635a
Reviewed-on: https://boringssl-review.googlesource.com/12740
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index d46a027..a98ff43 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -1045,6 +1045,10 @@
SSL_CTX_set_short_header_enabled(ssl_ctx.get(), 1);
}
+ if (config->enable_early_data) {
+ SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
+ }
+
return ssl_ctx;
}
@@ -1844,6 +1848,19 @@
GetTestState(ssl.get())->got_new_session ? "" : " not");
return false;
}
+
+ if (expect_new_session) {
+ bool got_early_data_info =
+ GetTestState(ssl.get())->new_session->ticket_max_early_data != 0;
+ if (config->expect_early_data_info != got_early_data_info) {
+ fprintf(
+ stderr,
+ "new session did%s include ticket_early_data_info, but we expected "
+ "the opposite\n",
+ got_early_data_info ? "" : " not");
+ return false;
+ }
+ }
}
if (out_session) {
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index e527185..029fd4a 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -95,6 +95,7 @@
extensionSupportedVersions uint16 = 43 // draft-ietf-tls-tls13-16
extensionCookie uint16 = 44 // draft-ietf-tls-tls13-16
extensionPSKKeyExchangeModes uint16 = 45 // draft-ietf-tls-tls13-18
+ extensionTicketEarlyDataInfo uint16 = 46 // draft-ietf-tls-tls13-18
extensionCustom uint16 = 1234 // not IANA assigned
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
extensionRenegotiationInfo uint16 = 0xff01
@@ -102,11 +103,6 @@
extensionShortHeader uint16 = 27463 // not IANA assigned
)
-// TLS ticket extension numbers
-const (
- ticketExtensionCustom uint16 = 1234 // not IANA assigned
-)
-
// TLS signaling cipher suite values
const (
scsvRenegotiation uint16 = 0x00ff
@@ -959,6 +955,15 @@
// receipt of a NewSessionTicket message.
ExpectNoNewSessionTicket bool
+ // SendTicketEarlyDataInfo, if non-zero, is the maximum amount of data that we
+ // will accept as early data, and gets sent in the ticket_early_data_info
+ // extension of the NewSessionTicket message.
+ SendTicketEarlyDataInfo uint32
+
+ // ExpectTicketEarlyDataInfo, if true, means that the client will fail upon
+ // absence of the ticket_early_data_info extension.
+ ExpectTicketEarlyDataInfo bool
+
// ExpectTicketAge, if non-zero, is the expected age of the ticket that the
// server receives from the client.
ExpectTicketAge time.Duration
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
index 3e22465..62a46bf 100644
--- a/ssl/test/runner/conn.go
+++ b/ssl/test/runner/conn.go
@@ -1451,6 +1451,10 @@
return errors.New("tls: no GREASE ticket extension found")
}
+ if c.config.Bugs.ExpectTicketEarlyDataInfo && newSessionTicket.earlyDataInfo == 0 {
+ return errors.New("tls: no ticket_early_data_info extension found")
+ }
+
if c.config.Bugs.ExpectNoNewSessionTicket {
return errors.New("tls: received unexpected NewSessionTicket")
}
@@ -1765,6 +1769,7 @@
m := &newSessionTicketMsg{
version: c.vers,
ticketLifetime: uint32(24 * time.Hour / time.Second),
+ earlyDataInfo: c.config.Bugs.SendTicketEarlyDataInfo,
customExtension: c.config.Bugs.CustomTicketExtension,
ticketAgeAdd: ticketAgeAdd,
}
diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go
index 01f673b..a431cb5 100644
--- a/ssl/test/runner/handshake_messages.go
+++ b/ssl/test/runner/handshake_messages.go
@@ -2008,6 +2008,7 @@
ticketLifetime uint32
ticketAgeAdd uint32
ticket []byte
+ earlyDataInfo uint32
customExtension string
hasGREASEExtension bool
}
@@ -2031,8 +2032,12 @@
if m.version >= VersionTLS13 {
extensions := body.addU16LengthPrefixed()
+ if m.earlyDataInfo > 0 {
+ extensions.addU16(extensionTicketEarlyDataInfo)
+ extensions.addU16LengthPrefixed().addU32(m.earlyDataInfo)
+ }
if len(m.customExtension) > 0 {
- extensions.addU16(ticketExtensionCustom)
+ extensions.addU16(extensionCustom)
extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
}
}
@@ -2078,28 +2083,37 @@
if len(data) < 2 {
return false
}
- extsLength := int(data[0])<<8 + int(data[1])
+
+ extensionsLength := int(data[0])<<8 | int(data[1])
data = data[2:]
- if len(data) < extsLength {
+ if extensionsLength != len(data) {
return false
}
- extensions := data[:extsLength]
- data = data[extsLength:]
- for len(extensions) > 0 {
- if len(extensions) < 4 {
+ for len(data) != 0 {
+ if len(data) < 4 {
return false
}
- extValue := uint16(extensions[0])<<8 | uint16(extensions[1])
- extLength := int(extensions[2])<<8 | int(extensions[3])
- if len(extensions) < 4+extLength {
+ extension := uint16(data[0])<<8 | uint16(data[1])
+ length := int(data[2])<<8 | int(data[3])
+ data = data[4:]
+ if len(data) < length {
return false
}
- extensions = extensions[4+extLength:]
- if isGREASEValue(extValue) {
- m.hasGREASEExtension = true
+ switch extension {
+ case extensionTicketEarlyDataInfo:
+ if length != 4 {
+ return false
+ }
+ m.earlyDataInfo = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+ default:
+ if isGREASEValue(extension) {
+ m.hasGREASEExtension = true
+ }
}
+
+ data = data[length:]
}
}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 56026b2..5c3d914 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -8379,6 +8379,33 @@
expectedLocalError: "tls: invalid ticket age",
})
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "TLS13-SendTicketEarlyDataInfo",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendTicketEarlyDataInfo: 16384,
+ },
+ },
+ flags: []string{
+ "-expect-early-data-info",
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TLS13-ExpectTicketEarlyDataInfo",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ ExpectTicketEarlyDataInfo: true,
+ },
+ },
+ flags: []string{
+ "-enable-early-data",
+ },
+ })
}
func addChangeCipherSpecTests() {
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 22e4c9c..a06b5e5 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -81,8 +81,10 @@
{ "-tls-unique", &TestConfig::tls_unique },
{ "-expect-ticket-renewal", &TestConfig::expect_ticket_renewal },
{ "-expect-no-session", &TestConfig::expect_no_session },
+ { "-expect-early-data-info", &TestConfig::expect_early_data_info },
{ "-use-ticket-callback", &TestConfig::use_ticket_callback },
{ "-renew-ticket", &TestConfig::renew_ticket },
+ { "-enable-early-data", &TestConfig::enable_early_data },
{ "-enable-client-custom-extension",
&TestConfig::enable_client_custom_extension },
{ "-enable-server-custom-extension",
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 882cddc..1307d56 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -83,8 +83,10 @@
bool tls_unique = false;
bool expect_ticket_renewal = false;
bool expect_no_session = false;
+ bool expect_early_data_info = false;
bool use_ticket_callback = false;
bool renew_ticket = false;
+ bool enable_early_data = false;
bool enable_client_custom_extension = false;
bool enable_server_custom_extension = false;
bool custom_extension_skip = false;