Fix False Start without session tickets.
One of the state transitions wasn't rewritten to CR_CHANGE. Add a test to
exercise this codepath. Also SSL_cutthrough_complete references the state.
Change-Id: Ib2f7ac5ac3f0348864efa93cf13cfd87454572f0
Reviewed-on: https://boringssl-review.googlesource.com/1337
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 72966c7..13e3ae5 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -554,7 +554,7 @@
if (s->tlsext_ticket_expected)
s->state=SSL3_ST_CR_SESSION_TICKET_A;
else
- s->state=SSL3_ST_CR_FINISHED_A;
+ s->state=SSL3_ST_CR_CHANGE;
ssl_free_wbio_buffer(s);
ret = 1;
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index a360070..c26fca9 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3237,6 +3237,7 @@
ssl3_can_cutthrough(s) && /* cutthrough allowed */
s->s3->previous_server_finished_len == 0 && /* not a renegotiation handshake */
(s->state == SSL3_ST_CR_SESSION_TICKET_A || /* ready to write app-data*/
+ s->state == SSL3_ST_CR_CHANGE ||
s->state == SSL3_ST_CR_FINISHED_A));
}
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index f06ccd3..1cfe080 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -77,9 +77,9 @@
static const char *advertise_npn = NULL;
static int next_protos_advertised_callback(SSL *ssl,
- const uint8_t **out,
- unsigned int *out_len,
- void *arg) {
+ const uint8_t **out,
+ unsigned int *out_len,
+ void *arg) {
if (!advertise_npn)
return SSL_TLSEXT_ERR_NOACK;
@@ -90,6 +90,22 @@
return SSL_TLSEXT_ERR_OK;
}
+static const char *select_next_proto = NULL;
+
+static int next_proto_select_callback(SSL* ssl,
+ uint8_t** out,
+ uint8_t* outlen,
+ const uint8_t* in,
+ unsigned inlen,
+ void* arg) {
+ if (!select_next_proto)
+ return SSL_TLSEXT_ERR_NOACK;
+
+ *out = (uint8_t*)select_next_proto;
+ *outlen = strlen(select_next_proto);
+ return SSL_TLSEXT_ERR_OK;
+}
+
static SSL_CTX *setup_ctx(int is_server) {
if (!SSL_library_init()) {
return NULL;
@@ -117,6 +133,8 @@
SSL_CTX_set_next_protos_advertised_cb(
ssl_ctx, next_protos_advertised_callback, NULL);
+ SSL_CTX_set_next_proto_select_cb(
+ ssl_ctx, next_proto_select_callback, NULL);
return ssl_ctx;
@@ -234,6 +252,15 @@
return 1;
}
expected_next_proto = argv[i];
+ } else if (strcmp(argv[i], "-false-start") == 0) {
+ SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
+ } else if (strcmp(argv[i], "-select-next-proto") == 0) {
+ i++;
+ if (i >= argc) {
+ fprintf(stderr, "Missing parameter\n");
+ return 1;
+ }
+ select_next_proto = argv[i];
} else {
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
return 1;
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 1ed733c..eedb2f1 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -343,6 +343,30 @@
shouldFail: true,
expectedError: ":CCS_RECEIVED_EARLY:",
},
+ {
+ name: "FalseStart",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ },
+ flags: []string{
+ "-false-start",
+ "-select-next-proto", "foo",
+ },
+ resumeSession: true,
+ },
+ {
+ name: "FalseStart-SessionTicketsDisabled",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ SessionTicketsDisabled: true,
+ },
+ flags: []string{
+ "-false-start",
+ "-select-next-proto", "foo",
+ },
+ },
}
func doExchange(testType testType, config *Config, conn net.Conn, messageLen int) error {