From 7e3305eebd7fb06d57e7f25b3bbf9c10d526f7d5 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 28 Jul 2014 14:52:32 -0400 Subject: [PATCH] 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 --- ssl/s3_clnt.c | 2 +- ssl/ssl_lib.c | 1 + ssl/test/bssl_shim.cc | 33 ++++++++++++++++++++++++++++++--- ssl/test/runner/runner.go | 24 ++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 72966c769..13e3ae5d4 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -554,7 +554,7 @@ int ssl3_connect(SSL *s) 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 a36007022..c26fca985 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -3237,6 +3237,7 @@ int SSL_cutthrough_complete(const SSL *s) 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 f06ccd30e..1cfe080f9 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc @@ -77,9 +77,9 @@ static int skip_verify(int preverify_ok, X509_STORE_CTX *store_ctx) { 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 @@ static int next_protos_advertised_callback(SSL *ssl, 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 @@ static SSL_CTX *setup_ctx(int is_server) { 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 @@ static int do_exchange(SSL_SESSION **out_session, 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 1ed733c9e..eedb2f1da 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -343,6 +343,30 @@ var testCases = []testCase{ 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 {