|
|
|
/* Copyright (c) 2018, Google Inc.
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
|
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
|
|
|
|
|
|
#ifndef HEADER_TEST_STATE
|
|
|
|
#define HEADER_TEST_STATE
|
|
|
|
|
|
|
|
#include <openssl/base.h>
|
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#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.
|
|
|
|
BIO *packeted_bio = nullptr;
|
|
|
|
std::unique_ptr<MockQuicTransport> quic_transport;
|
|
|
|
bool cert_ready = false;
|
|
|
|
bssl::UniquePtr<SSL_SESSION> session;
|
|
|
|
bssl::UniquePtr<SSL_SESSION> pending_session;
|
|
|
|
bool early_callback_called = false;
|
|
|
|
bool handshake_done = false;
|
|
|
|
// private_key is the underlying private key used when testing custom keys.
|
|
|
|
bssl::UniquePtr<EVP_PKEY> private_key;
|
|
|
|
// When private key methods are used, whether the private key was used.
|
|
|
|
bool used_private_key = false;
|
|
|
|
std::vector<uint8_t> private_key_result;
|
|
|
|
// private_key_retries is the number of times an asynchronous private key
|
|
|
|
// operation has been retried.
|
|
|
|
unsigned private_key_retries = 0;
|
|
|
|
bool got_new_session = false;
|
|
|
|
bssl::UniquePtr<SSL_SESSION> new_session;
|
|
|
|
bool ticket_decrypt_done = false;
|
|
|
|
bool alpn_select_done = false;
|
|
|
|
bool early_callback_ready = false;
|
|
|
|
bool custom_verify_ready = false;
|
|
|
|
std::string msg_callback_text;
|
|
|
|
bool msg_callback_ok = true;
|
|
|
|
// cert_verified is true if certificate verification has been driven to
|
|
|
|
// completion. This tests that the callback is not called again after this.
|
|
|
|
bool cert_verified = false;
|
|
|
|
int explicit_renegotiates = 0;
|
|
|
|
std::function<bool(const SSL_CLIENT_HELLO*)> get_handshake_hints_cb;
|
Check hs->early_session, not ssl->session, for the early data limit.
ServerHello/EncryptedExtensions/Finished is logically one atomic flight
that exits the early data state, we have process each message
sequentially. Until we've processed Finished, we are still in the early
data state and must support writing data. Individual messages *are*
processed atomically, so the interesting points are before ServerHello
(already tested), after ServerHello, and after EncryptedExtensions.
The TLS 1.3 handshake internally clears ssl->session when processing
ServerHello, so getting the early data information from ssl->session
does not work. Instead, use hs->early_session, which is what other
codepaths use.
I've tested this with runner rather than ssl_test, so we can test both
post-SH and post-EE states. ssl_test would be more self-contained, since
we can directly control the API calls, but it cannot test the post-EE
state. To reduce record overhead, our production implementation packs EE
and Finished into the same record, which means the handshake will
process the two atomically. Instead, I've tested this in runner, with a
flag to partially drive the handshake before reading early data.
I've also tweaked the logic to hopefully be a little clearer.
Bug: chromium:1208784
Change-Id: Ia4901042419c5324054f97743bd1aac59ebf8f24
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/47485
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
4 years ago
|
|
|
int last_message_received = -1;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool SetTestState(SSL *ssl, std::unique_ptr<TestState> state);
|
|
|
|
|
|
|
|
TestState *GetTestState(const SSL *ssl);
|
|
|
|
|
|
|
|
struct timeval *GetClock();
|
|
|
|
|
|
|
|
void AdvanceClock(unsigned seconds);
|
|
|
|
|
|
|
|
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
|