runner: Remove split handshake test machinery from the handshaker This dramatically simplifies the handshaker binary, as it's now just responsible for a single request/response operation. Bug: 376969215 Change-Id: I2748f23d41bfbb8caf4e004d90e1b086f0239193 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/100188 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Lily Chen <chlily@google.com> Auto-Submit: David Benjamin <davidben@google.com>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index 2eefbde..36bec75 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc
@@ -502,9 +502,7 @@ } } - // early_callback_called is updated in the handshaker, so we don't see it - // here. - if (!config->handoff && config->is_server && !state->early_callback_called) { + if (config->is_server && !state->early_callback_called) { fprintf(stderr, "early callback not called\n"); return false; } @@ -781,8 +779,7 @@ return true; } -static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session, - bssl::UniquePtr<SSL> *ssl_uniqueptr, +static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session, SSL *ssl, const TestConfig *config, bool is_resume, bool is_retry, SettingsWriter *writer); @@ -869,7 +866,8 @@ bio.release(); // SSL_set_bio takes ownership. } - bool ret = DoExchange(out_session, &ssl, config, is_resume, false, writer); + bool ret = + DoExchange(out_session, ssl.get(), config, is_resume, false, writer); if (!config->is_server && is_resume && config->expect_reject_early_data) { // We must have failed due to an early data rejection. if (ret) { @@ -914,9 +912,9 @@ return false; } - assert(!config->handoff); config = retry_config; - ret = DoExchange(out_session, &ssl, retry_config, is_resume, true, writer); + ret = DoExchange(out_session, ssl.get(), retry_config, is_resume, true, + writer); } // An ECH rejection appears as a failed connection. Note `ssl` may use a @@ -978,29 +976,14 @@ return true; } -static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session, - bssl::UniquePtr<SSL> *ssl_uniqueptr, +static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session, SSL *ssl, const TestConfig *config, bool is_resume, bool is_retry, SettingsWriter *writer) { int ret; - SSL *ssl = ssl_uniqueptr->get(); SSL_CTX *session_ctx = SSL_get_SSL_CTX(ssl); TestState *test_state = GetTestState(ssl); if (!config->implicit_handshake) { - if (config->handoff) { -#if defined(HANDSHAKER_SUPPORTED) - if (!DoSplitHandshake(ssl_uniqueptr, writer, is_resume)) { - return false; - } - ssl = ssl_uniqueptr->get(); - test_state = GetTestState(ssl); -#else - fprintf(stderr, "The external handshaker can only be used on Linux\n"); - return false; -#endif - } - do { ret = CheckIdempotentError("SSL_do_handshake", ssl, [&]() -> int { return SSL_do_handshake(ssl);
diff --git a/ssl/test/fuzzer.h b/ssl/test/fuzzer.h index 668442a..c3a37bf 100644 --- a/ssl/test/fuzzer.h +++ b/ssl/test/fuzzer.h
@@ -335,60 +335,19 @@ SSL_set_tlsext_host_name(ssl.get(), "hostname"); } - // ssl_handoff may or may not be used. - bssl::UniquePtr<SSL> ssl_handoff(SSL_new(ctx_.get())); - bssl::UniquePtr<SSL> ssl_handback(SSL_new(ctx_.get())); - SSL_set_accept_state(ssl_handoff.get()); - SSL_set0_rbio(ssl.get(), MakeBIO(CBS_data(&cbs), CBS_len(&cbs)).release()); SSL_set0_wbio(ssl.get(), BIO_new(BIO_s_mem())); - SSL *ssl_handshake = ssl.get(); - bool handshake_successful = false; - bool handback_successful = false; - for (;;) { - int ret = SSL_do_handshake(ssl_handshake); - if (ret < 0 && SSL_get_error(ssl_handshake, ret) == SSL_ERROR_HANDOFF) { - MoveBIOs(ssl_handoff.get(), ssl.get()); - // Ordinarily we would call SSL_serialize_handoff(ssl.get(). But for - // fuzzing, use the serialized handoff that's getting fuzzed. - if (!bssl::SSL_apply_handoff(ssl_handoff.get(), handoff_)) { - if (debug_) { - fprintf(stderr, "Handoff failed.\n"); - } - break; - } - ssl_handshake = ssl_handoff.get(); - } else if (ret < 0 && - SSL_get_error(ssl_handshake, ret) == SSL_ERROR_HANDBACK) { - MoveBIOs(ssl_handback.get(), ssl_handoff.get()); - if (!bssl::SSL_apply_handback(ssl_handback.get(), handback_)) { - if (debug_) { - fprintf(stderr, "Handback failed.\n"); - } - break; - } - handback_successful = true; - ssl_handshake = ssl_handback.get(); - } else { - handshake_successful = ret == 1; - break; - } - } - - if (debug_) { - if (!handshake_successful) { - fprintf(stderr, "Handshake failed.\n"); - } else if (handback_successful) { - fprintf(stderr, "Handback successful.\n"); - } + bool handshake_successful = SSL_do_handshake(ssl.get()) == 1; + if (debug_ && !handshake_successful) { + fprintf(stderr, "Handshake failed.\n"); } if (handshake_successful) { // Keep reading application data until error or EOF. uint8_t tmp[1024]; for (;;) { - if (SSL_read(ssl_handshake, tmp, sizeof(tmp)) <= 0) { + if (SSL_read(ssl.get(), tmp, sizeof(tmp)) <= 0) { break; } } @@ -506,8 +465,6 @@ // `ctx` is shared between runs, so we must clear any modifications to it // made later on in this function. SSL_CTX_flush_sessions(ctx_.get(), 0); - handoff_ = {}; - handback_ = {}; bssl::UniquePtr<SSL> ssl(SSL_new(ctx_.get())); if (role_ == kServer) { @@ -551,28 +508,6 @@ SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, nullptr); break; - case kHandoffTag: { - CBS handoff; - if (!CBS_get_u24_length_prefixed(cbs, &handoff)) { - return nullptr; - } - handoff_.assign(CBS_data(&handoff), - CBS_data(&handoff) + CBS_len(&handoff)); - bssl::SSL_set_handoff_mode(ssl.get(), 1); - break; - } - - case kHandbackTag: { - CBS handback; - if (!CBS_get_u24_length_prefixed(cbs, &handback)) { - return nullptr; - } - handback_.assign(CBS_data(&handback), - CBS_data(&handback) + CBS_len(&handback)); - bssl::SSL_set_handoff_mode(ssl.get(), 1); - break; - } - case kHintsTag: { CBS hints; if (!CBS_get_u24_length_prefixed(cbs, &hints)) { @@ -644,7 +579,6 @@ Protocol protocol_; Role role_; bssl::UniquePtr<SSL_CTX> ctx_; - std::vector<uint8_t> handoff_, handback_; }; } // namespace
diff --git a/ssl/test/fuzzer_tags.h b/ssl/test/fuzzer_tags.h index 26f8b1f..acc3489 100644 --- a/ssl/test/fuzzer_tags.h +++ b/ssl/test/fuzzer_tags.h
@@ -39,11 +39,7 @@ // certificates. static const uint16_t kRequestClientCert = 2; -// kHandoffTag is followed by the output of `SSL_serialize_handoff`. -static const uint16_t kHandoffTag = 3; - -// kHandbackTag is followed by the output of `SSL_serialize_handback`. -static const uint16_t kHandbackTag = 4; +// 3 and 4 used to be kHandoffTag and kHandbackTag. // kHintsTag is followed by the output of `SSL_serialize_handshake_hints`. static const uint16_t kHintsTag = 5;
diff --git a/ssl/test/handshake_util.cc b/ssl/test/handshake_util.cc index 6a5502e..441f15c 100644 --- a/ssl/test/handshake_util.cc +++ b/ssl/test/handshake_util.cc
@@ -138,24 +138,6 @@ #if defined(HANDSHAKER_SUPPORTED) -// MoveBIOs moves the `BIO`s of `src` to `dst`. It is used for handoff. -static void MoveBIOs(SSL *dest, SSL *src) { - BIO *rbio = SSL_get_rbio(src); - BIO_up_ref(rbio); - SSL_set0_rbio(dest, rbio); - - BIO *wbio = SSL_get_wbio(src); - BIO_up_ref(wbio); - SSL_set0_wbio(dest, wbio); - - SSL_set0_rbio(src, nullptr); - SSL_set0_wbio(src, nullptr); -} - -static bool HandoffReady(SSL *ssl, int ret) { - return ret < 0 && SSL_get_error(ssl, ret) == SSL_ERROR_HANDOFF; -} - static ssize_t read_eintr(int fd, void *out, size_t len) { ssize_t ret; do { @@ -180,130 +162,6 @@ return ret; } -// Proxy relays data between `socket`, which is connected to the client, and the -// handshaker, which is connected to the numerically specified file descriptors, -// until the handshaker returns control. -static bool Proxy(BIO *socket, bool async, int control, int rfd, int wfd) { - for (;;) { - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(wfd, &rfds); - FD_SET(control, &rfds); - int fd_max = wfd > control ? wfd : control; - if (select(fd_max + 1, &rfds, nullptr, nullptr, nullptr) == -1) { - perror("select"); - return false; - } - - char buf[64]; - ssize_t bytes; - if (FD_ISSET(wfd, &rfds) && - (bytes = read_eintr(wfd, buf, sizeof(buf))) > 0) { - char *b = buf; - while (bytes) { - int written = BIO_write(socket, b, bytes); - if (!written) { - fprintf(stderr, "BIO_write wrote nothing\n"); - return false; - } - if (written < 0) { - if (async) { - AsyncBioAllowWrite(socket, 1); - continue; - } - fprintf(stderr, "BIO_write failed\n"); - return false; - } - b += written; - bytes -= written; - } - // Flush all pending data from the handshaker to the client before - // considering control messages. - continue; - } - - if (!FD_ISSET(control, &rfds)) { - continue; - } - - char msg; - if (read_eintr(control, &msg, 1) != 1) { - perror("read"); - return false; - } - switch (msg) { - case kControlMsgDone: - return true; - case kControlMsgError: - return false; - case kControlMsgUnimplemented: - exit(kExitCodeUnimplemented); - case kControlMsgWantRead: - break; - default: - fprintf(stderr, "Unknown control message from handshaker: %c\n", msg); - return false; - } - - auto proxy_data = [&](uint8_t *out, size_t len) -> bool { - if (async) { - AsyncBioAllowRead(socket, len); - } - - while (len > 0) { - int bytes_read = BIO_read(socket, out, len); - if (bytes_read < 1) { - fprintf(stderr, "BIO_read failed\n"); - return false; - } - - ssize_t bytes_written = write_eintr(rfd, out, bytes_read); - if (bytes_written == -1) { - perror("write"); - return false; - } - if (bytes_written != bytes_read) { - fprintf(stderr, "short write (%zd of %d bytes)\n", bytes_written, - bytes_read); - return false; - } - - len -= bytes_read; - out += bytes_read; - } - return true; - }; - - // Process one SSL record at a time. That way, we don't send the handshaker - // anything it doesn't want to process, e.g. early data. - uint8_t header[SSL3_RT_HEADER_LENGTH]; - if (!proxy_data(header, sizeof(header))) { - return false; - } - if (header[1] != 3) { - fprintf(stderr, "bad header\n"); - return false; - } - size_t remaining = (header[3] << 8) + header[4]; - while (remaining > 0) { - uint8_t readbuf[64]; - size_t len = remaining > sizeof(readbuf) ? sizeof(readbuf) : remaining; - if (!proxy_data(readbuf, len)) { - return false; - } - remaining -= len; - } - - // The handshaker blocks on the control channel, so we have to signal - // it that the data have been written. - msg = kControlMsgWriteCompleted; - if (write_eintr(control, &msg, 1) != 1) { - perror("write"); - return false; - } - } -} - class ScopedFD { public: ScopedFD() : fd_(-1) {} @@ -486,76 +344,6 @@ return true; } -// RunHandshaker forks and execs the handshaker binary, handing off `input`, -// and, after proxying some amount of handshake traffic, handing back `out`. -static bool RunHandshaker(BIO *bio, const TestConfig *config, bool is_resume, - Span<const uint8_t> input, - std::vector<uint8_t> *out) { - int rfd[2], wfd[2]; - // We use pipes, rather than some other mechanism, for their buffers. During - // the handshake, this process acts as a dumb proxy until receiving the - // handback signal, which arrives asynchronously. The race condition means - // that this process could incorrectly proxy post-handshake data from the - // client to the handshaker. - // - // To avoid this, this process never proxies data to the handshaker that the - // handshaker has not explicitly requested as a result of hitting - // `SSL_ERROR_WANT_READ`. Pipes allow the data to sit in a buffer while the - // two processes synchronize over the `control` channel. - if (pipe(rfd) != 0) { - perror("pipe"); - return false; - } - ScopedFD rfd0_closer(rfd[0]), rfd1_closer(rfd[1]); - - if (pipe(wfd) != 0) { - perror("pipe"); - return false; - } - ScopedFD wfd0_closer(wfd[0]), wfd1_closer(wfd[1]); - - ScopedProcess handshaker; - ScopedFD control; - if (!StartHandshaker( - &handshaker, &control, config, is_resume, - {{kFdProxyToHandshaker, rfd[0]}, {kFdHandshakerToProxy, wfd[1]}}, - {rfd[1], wfd[0]})) { - return false; - } - - rfd0_closer.Reset(); - wfd1_closer.Reset(); - - if (write_eintr(control.fd(), input.data(), input.size()) == -1) { - perror("write"); - return false; - } - bool ok = Proxy(bio, config->async, control.fd(), rfd[1], wfd[0]); - int wstatus; - if (!handshaker.Wait(&wstatus)) { - perror("waitpid"); - return false; - } - if (ok && wstatus) { - fprintf(stderr, "handshaker exited irregularly\n"); - return false; - } - if (!ok) { - return false; // This is a "good", i.e. expected, error. - } - - constexpr size_t kBufSize = 1024 * 1024; - std::vector<uint8_t> buf(kBufSize); - ssize_t len = read_eintr(control.fd(), buf.data(), buf.size()); - if (len == -1) { - perror("read"); - return false; - } - buf.resize(len); - *out = std::move(buf); - return true; -} - static bool RequestHandshakeHint(const TestConfig *config, bool is_resume, Span<const uint8_t> input, bool *out_has_hints, std::vector<uint8_t> *out_hints) { @@ -613,86 +401,6 @@ return true; } -// PrepareHandoff accepts the `ClientHello` from `ssl` and serializes state to -// be passed to the handshaker. The serialized state includes both the SSL -// handoff, as well test-related state. -static bool PrepareHandoff(SSL *ssl, SettingsWriter *writer, - std::vector<uint8_t> *out_handoff) { - SSL_set_handoff_mode(ssl, 1); - - const TestConfig *config = GetTestConfig(ssl); - int ret = -1; - do { - ret = CheckIdempotentError( - "SSL_do_handshake", ssl, - [&]() -> int { return SSL_do_handshake(ssl); }); - } while (!HandoffReady(ssl, ret) && - config->async && - RetryAsync(ssl, ret)); - if (!HandoffReady(ssl, ret)) { - fprintf(stderr, "Handshake failed while waiting for handoff.\n"); - return false; - } - - ScopedCBB cbb; - SSL_CLIENT_HELLO hello; - if (!CBB_init(cbb.get(), 512) || - !SSL_serialize_handoff(ssl, cbb.get(), &hello) || - !writer->WriteHandoff({CBB_data(cbb.get()), CBB_len(cbb.get())}) || - !SerializeContextState(SSL_get_SSL_CTX(ssl), cbb.get()) || - !GetTestState(ssl)->Serialize(cbb.get())) { - fprintf(stderr, "Handoff serialisation failed.\n"); - return false; - } - out_handoff->assign(CBB_data(cbb.get()), - CBB_data(cbb.get()) + CBB_len(cbb.get())); - return true; -} - -// DoSplitHandshake delegates the SSL handshake to a separate process, called -// the handshaker. This process proxies I/O between the handshaker and the -// client, using the `BIO` from `ssl`. After a successful handshake, `ssl` is -// replaced with a new `SSL` object, in a way that is intended to be invisible -// to the caller. -bool DoSplitHandshake(UniquePtr<SSL> *ssl, SettingsWriter *writer, - bool is_resume) { - assert(SSL_get_rbio(ssl->get()) == SSL_get_wbio(ssl->get())); - std::vector<uint8_t> handshaker_input; - const TestConfig *config = GetTestConfig(ssl->get()); - // out is the response from the handshaker, which includes a serialized - // handback message, but also serialized updates to the `TestState`. - std::vector<uint8_t> out; - if (!PrepareHandoff(ssl->get(), writer, &handshaker_input) || - !RunHandshaker(SSL_get_rbio(ssl->get()), config, is_resume, - handshaker_input, &out)) { - fprintf(stderr, "Handoff failed.\n"); - return false; - } - - SSL_CTX *ctx = SSL_get_SSL_CTX(ssl->get()); - UniquePtr<SSL> ssl_handback = config->NewSSL(ctx, nullptr, nullptr); - if (!ssl_handback) { - return false; - } - CBS output, handback; - CBS_init(&output, out.data(), out.size()); - if (!CBS_get_u24_length_prefixed(&output, &handback) || - !DeserializeContextState(&output, ctx) || - !SetTestState(ssl_handback.get(), TestState::Deserialize(&output, ctx)) || - !GetTestState(ssl_handback.get()) || !writer->WriteHandback(handback) || - !SSL_apply_handback(ssl_handback.get(), handback)) { - fprintf(stderr, "Handback failed.\n"); - return false; - } - MoveBIOs(ssl_handback.get(), ssl->get()); - GetTestState(ssl_handback.get())->async_bio = - GetTestState(ssl->get())->async_bio; - GetTestState(ssl->get())->async_bio = nullptr; - - *ssl = std::move(ssl_handback); - return true; -} - bool GetHandshakeHint(SSL *ssl, SettingsWriter *writer, bool is_resume, const SSL_CLIENT_HELLO *client_hello) { ScopedCBB input;
diff --git a/ssl/test/handshake_util.h b/ssl/test/handshake_util.h index b1c0ea5..ffacff2 100644 --- a/ssl/test/handshake_util.h +++ b/ssl/test/handshake_util.h
@@ -39,14 +39,6 @@ inline constexpr int kExitCodeMustFail = 90; #if defined(HANDSHAKER_SUPPORTED) -// DoSplitHandshake delegates the SSL handshake to a separate process, called -// the handshaker. This process proxies I/O between the handshaker and the -// client, using the `BIO` from `ssl`. After a successful handshake, `ssl` is -// replaced with a new `SSL` object, in a way that is intended to be invisible -// to the caller. -bool DoSplitHandshake(bssl::UniquePtr<SSL> *ssl, SettingsWriter *writer, - bool is_resume); - // GetHandshakeHint requests a handshake hint from the handshaker process and // configures the result on `ssl`. It returns true on success and false on // error.
diff --git a/ssl/test/handshaker.cc b/ssl/test/handshaker.cc index 0104de6..67d1abd 100644 --- a/ssl/test/handshaker.cc +++ b/ssl/test/handshaker.cc
@@ -18,6 +18,7 @@ #include <signal.h> #include <unistd.h> +#include <cstdio> #include <memory> #include <openssl/bytestring.h> @@ -48,94 +49,6 @@ return ret; } -bool HandbackReady(SSL *ssl, int ret) { - return ret < 0 && SSL_get_error(ssl, ret) == SSL_ERROR_HANDBACK; -} - -bool Handshaker(const TestConfig *config, int rfd, int wfd, - Span<const uint8_t> input, int control) { - UniquePtr<SSL_CTX> ctx = config->SetupCtx(/*old_ctx=*/nullptr); - if (!ctx) { - return false; - } - UniquePtr<SSL> ssl = - config->NewSSL(ctx.get(), /*session=*/nullptr, /*test_state=*/nullptr); - if (!ssl) { - fprintf(stderr, "Error creating SSL object in handshaker.\n"); - ERR_print_errors_fp(stderr); - return false; - } - - // Set `O_NONBLOCK` in order to break out of the loop when we hit - // `SSL_ERROR_WANT_READ`, so that we can send `kControlMsgWantRead` to the - // proxy. - if (fcntl(rfd, F_SETFL, O_NONBLOCK) != 0) { - perror("fcntl"); - return false; - } - SSL_set_rfd(ssl.get(), rfd); - SSL_set_wfd(ssl.get(), wfd); - - CBS cbs, handoff; - CBS_init(&cbs, input.data(), input.size()); - if (!CBS_get_asn1_element(&cbs, &handoff, CBS_ASN1_SEQUENCE) || - !DeserializeContextState(&cbs, ctx.get()) || - !SetTestState(ssl.get(), TestState::Deserialize(&cbs, ctx.get())) || - !GetTestState(ssl.get()) || - !SSL_apply_handoff(ssl.get(), handoff)) { - fprintf(stderr, "Handoff application failed.\n"); - return false; - } - - int ret = 0; - for (;;) { - ret = CheckIdempotentError( - "SSL_do_handshake", ssl.get(), - [&]() -> int { return SSL_do_handshake(ssl.get()); }); - if (SSL_get_error(ssl.get(), ret) == SSL_ERROR_WANT_READ) { - // Synchronize with the proxy, i.e. don't let the handshake continue until - // the proxy has sent more data. - char msg = kControlMsgWantRead; - if (write_eintr(control, &msg, 1) != 1 || - read_eintr(control, &msg, 1) != 1 || - msg != kControlMsgWriteCompleted) { - fprintf(stderr, "read via proxy failed\n"); - return false; - } - continue; - } - if (!RetryAsync(ssl.get(), ret)) { - break; - } - } - if (!HandbackReady(ssl.get(), ret)) { - fprintf(stderr, "Handshaker: %s\n", - SSL_error_description(SSL_get_error(ssl.get(), ret))); - ERR_print_errors_fp(stderr); - return false; - } - - ScopedCBB output; - CBB handback; - if (!CBB_init(output.get(), 1024) || - !CBB_add_u24_length_prefixed(output.get(), &handback) || - !SSL_serialize_handback(ssl.get(), &handback) || - !SerializeContextState(ctx.get(), output.get()) || - !GetTestState(ssl.get())->Serialize(output.get())) { - fprintf(stderr, "Handback serialisation failed.\n"); - return false; - } - - char msg = kControlMsgDone; - if (write_eintr(control, &msg, 1) == -1 || - write_eintr(control, CBB_data(output.get()), CBB_len(output.get())) == - -1) { - perror("write"); - return false; - } - return true; -} - bool GenerateHandshakeHint(const TestConfig *config, bssl::Span<const uint8_t> request, int control) { // The handshake hint contains the ClientHello and the capabilities string. @@ -267,15 +180,13 @@ } #endif // FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if (config->handshake_hints) { - if (!GenerateHandshakeHint(config, request, kFdControl)) { - return SignalError(); - } - } else { - if (!Handshaker(config, kFdProxyToHandshaker, kFdHandshakerToProxy, - request, kFdControl)) { - return SignalError(); - } + if (!config->handshake_hints) { + // Historically omitting -handshake-hints ran the split handshakes mode. + fprintf(stderr, "Handshaker missing -handshake-hints flag."); + return SignalError(); + } + if (!GenerateHandshakeHint(config, request, kFdControl)) { + return SignalError(); } return 0; }
diff --git a/ssl/test/settings_writer.cc b/ssl/test/settings_writer.cc index 293702f..234928c 100644 --- a/ssl/test/settings_writer.cc +++ b/ssl/test/settings_writer.cc
@@ -87,14 +87,6 @@ return fwrite(settings, settings_len, 1, file.get()) == 1; } -bool SettingsWriter::WriteHandoff(bssl::Span<const uint8_t> handoff) { - return WriteData(kHandoffTag, handoff); -} - -bool SettingsWriter::WriteHandback(bssl::Span<const uint8_t> handback) { - return WriteData(kHandbackTag, handback); -} - bool SettingsWriter::WriteHints(bssl::Span<const uint8_t> hints) { return WriteData(kHintsTag, hints); }
diff --git a/ssl/test/settings_writer.h b/ssl/test/settings_writer.h index 306d095..36a35d3 100644 --- a/ssl/test/settings_writer.h +++ b/ssl/test/settings_writer.h
@@ -33,8 +33,6 @@ // Commit writes the buffered data to disk. bool Commit(); - bool WriteHandoff(bssl::Span<const uint8_t> handoff); - bool WriteHandback(bssl::Span<const uint8_t> handback); bool WriteHints(bssl::Span<const uint8_t> hints); private:
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc index 9e09491..a86b7b2 100644 --- a/ssl/test/test_config.cc +++ b/ssl/test/test_config.cc
@@ -528,7 +528,6 @@ StringFlag("-expect-msg-callback", &TestConfig::expect_msg_callback), BoolFlag("-allow-false-start-without-alpn", &TestConfig::allow_false_start_without_alpn), - BoolFlag("-handoff", &TestConfig::handoff), BoolFlag("-handshake-hints", &TestConfig::handshake_hints), BoolFlag("-allow-hint-mismatch", &TestConfig::allow_hint_mismatch), BoolFlag("-use-ocsp-callback", &TestConfig::use_ocsp_callback),
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h index 56d347c..e0642c4 100644 --- a/ssl/test/test_config.h +++ b/ssl/test/test_config.h
@@ -217,7 +217,6 @@ bool use_custom_verify_callback = false; std::string expect_msg_callback; bool allow_false_start_without_alpn = false; - bool handoff = false; bool handshake_hints = false; bool allow_hint_mismatch = false; bool use_ocsp_callback = false;
diff --git a/ssl/test/test_state.cc b/ssl/test/test_state.cc index fc33d58..d439c62 100644 --- a/ssl/test/test_state.cc +++ b/ssl/test/test_state.cc
@@ -79,103 +79,3 @@ void CopySessions(SSL_CTX *dst, const SSL_CTX *src) { lh_SSL_SESSION_doall_arg(FromOpaque(src)->sessions, ssl_ctx_add_session, dst); } - -static void push_session(SSL_SESSION *session, void *arg) { - auto s = reinterpret_cast<std::vector<SSL_SESSION *> *>(arg); - s->push_back(session); -} - -bool SerializeContextState(SSL_CTX *ctx, CBB *cbb) { - CBB out, ctx_sessions, ticket_keys; - uint8_t keys[48]; - if (!CBB_add_u24_length_prefixed(cbb, &out) || - !CBB_add_u16(&out, 0 /* version */) || - !SSL_CTX_get_tlsext_ticket_keys(ctx, &keys, sizeof(keys)) || - !CBB_add_u8_length_prefixed(&out, &ticket_keys) || - !CBB_add_bytes(&ticket_keys, keys, sizeof(keys)) || - !CBB_add_asn1(&out, &ctx_sessions, CBS_ASN1_SEQUENCE)) { - return false; - } - std::vector<SSL_SESSION *> sessions; - lh_SSL_SESSION_doall_arg(FromOpaque(ctx)->sessions, push_session, &sessions); - for (const auto &sess : sessions) { - if (!ssl_session_serialize(sess, &ctx_sessions)) { - return false; - } - } - return CBB_flush(cbb); -} - -bool DeserializeContextState(CBS *cbs, SSL_CTX *ctx) { - CBS in, sessions, ticket_keys; - uint16_t version; - constexpr uint16_t kVersion = 0; - if (!CBS_get_u24_length_prefixed(cbs, &in) || - !CBS_get_u16(&in, &version) || - version > kVersion || - !CBS_get_u8_length_prefixed(&in, &ticket_keys) || - !SSL_CTX_set_tlsext_ticket_keys(ctx, CBS_data(&ticket_keys), - CBS_len(&ticket_keys)) || - !CBS_get_asn1(&in, &sessions, CBS_ASN1_SEQUENCE)) { - return false; - } - while (CBS_len(&sessions)) { - UniquePtr<SSL_SESSION> session = SSL_SESSION_parse( - &sessions, FromOpaque(ctx)->x509_method, FromOpaque(ctx)->pool.get()); - if (!session) { - return false; - } - SSL_CTX_add_session(ctx, session.get()); - } - return true; -} - -bool TestState::Serialize(CBB *cbb) const { - CBB out, pending, text; - if (!CBB_add_u24_length_prefixed(cbb, &out) || - !CBB_add_u16(&out, 0 /* version */) || - !CBB_add_u24_length_prefixed(&out, &pending) || - (pending_session && - !ssl_session_serialize(pending_session.get(), &pending)) || - !CBB_add_u16_length_prefixed(&out, &text) || - !CBB_add_bytes( - &text, reinterpret_cast<const uint8_t *>(msg_callback_text.data()), - msg_callback_text.length()) || - !CBB_add_asn1_uint64(&out, g_clock.tv_sec) || - !CBB_add_asn1_uint64(&out, g_clock.tv_usec) || - !CBB_flush(cbb)) { - return false; - } - return true; -} - -std::unique_ptr<TestState> TestState::Deserialize(CBS *cbs, SSL_CTX *ctx) { - CBS in, pending_session, text; - auto state = std::make_unique<TestState>(); - uint16_t version; - constexpr uint16_t kVersion = 0; - uint64_t sec, usec; - if (!CBS_get_u24_length_prefixed(cbs, &in) || // - !CBS_get_u16(&in, &version) || // - version > kVersion || - !CBS_get_u24_length_prefixed(&in, &pending_session) || - !CBS_get_u16_length_prefixed(&in, &text) || - !CBS_get_asn1_uint64(&in, &sec) || // - !CBS_get_asn1_uint64(&in, &usec) || // - usec >= 1000000) { - return nullptr; - } - if (CBS_len(&pending_session)) { - state->pending_session = - SSL_SESSION_parse(&pending_session, FromOpaque(ctx)->x509_method, - FromOpaque(ctx)->pool.get()); - if (!state->pending_session) { - return nullptr; - } - } - state->msg_callback_text = std::string( - reinterpret_cast<const char *>(CBS_data(&text)), CBS_len(&text)); - g_clock.tv_sec = sec; - g_clock.tv_usec = usec; - return state; -}
diff --git a/ssl/test/test_state.h b/ssl/test/test_state.h index 8856a78..150e47e 100644 --- a/ssl/test/test_state.h +++ b/ssl/test/test_state.h
@@ -25,17 +25,6 @@ #include "mock_quic_transport.h" struct TestState { - // Serialize writes `pending_session` and `msg_callback_text` to `out`, for - // use in split-handshake tests. We don't try to serialize every bit of test - // state, but serializing `pending_session` is necessary to exercise session - // resumption, and `msg_callback_text` is especially useful. In the general - // case, checks of state updated during the handshake can be skipped when - // `config->handoff`. - bool Serialize(CBB *out) const; - - // Deserialize returns a new `TestState` from data written by `Serialize`. - static std::unique_ptr<TestState> Deserialize(CBS *cbs, SSL_CTX *ctx); - // async_bio is async BIO which pauses reads and writes. BIO *async_bio = nullptr; // packeted_bio is the packeted BIO which simulates read timeouts. @@ -82,12 +71,4 @@ void CopySessions(SSL_CTX *dest, const SSL_CTX *src); -// SerializeContextState writes session material (sessions and ticket keys) from -// `ctx` into `cbb`. -bool SerializeContextState(SSL_CTX *ctx, CBB *cbb); - -// DeserializeContextState updates `out` with material previously serialized by -// SerializeContextState. -bool DeserializeContextState(CBS *in, SSL_CTX *out); - #endif // HEADER_TEST_STATE