1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <stdint.h>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/check_op.h"
- #include "base/run_loop.h"
- #include "base/test/bind.h"
- #include "base/test/task_environment.h"
- #include "base/threading/thread.h"
- #include "mojo/public/cpp/bindings/pending_receiver.h"
- #include "mojo/public/cpp/bindings/remote.h"
- #include "net/base/completion_once_callback.h"
- #include "net/base/net_errors.h"
- #include "net/base/network_isolation_key.h"
- #include "net/base/test_completion_callback.h"
- #include "net/proxy_resolution/configured_proxy_resolution_service.h"
- #include "net/socket/server_socket.h"
- #include "net/socket/socket_test_util.h"
- #include "net/test/embedded_test_server/embedded_test_server.h"
- #include "net/test/embedded_test_server/http_request.h"
- #include "net/test/embedded_test_server/http_response.h"
- #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
- #include "net/url_request/url_request_context.h"
- #include "net/url_request/url_request_context_builder.h"
- #include "net/url_request/url_request_test_util.h"
- #include "services/network/mojo_socket_test_util.h"
- #include "services/network/proxy_resolving_socket_factory_mojo.h"
- #include "services/network/public/mojom/network_service.mojom.h"
- #include "services/network/public/mojom/tls_socket.mojom.h"
- #include "services/network/socket_factory.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace network {
- namespace {
- // Message sent over the tcp connection.
- const char kMsg[] = "please start tls!";
- const size_t kMsgSize = strlen(kMsg);
- // Message sent over the tls connection.
- const char kSecretMsg[] = "here is secret.";
- const size_t kSecretMsgSize = strlen(kSecretMsg);
- class TLSClientSocketTestBase {
- public:
- enum Mode { kDirect, kProxyResolving };
- explicit TLSClientSocketTestBase(Mode mode)
- : mode_(mode),
- task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
- TLSClientSocketTestBase(const TLSClientSocketTestBase&) = delete;
- TLSClientSocketTestBase& operator=(const TLSClientSocketTestBase&) = delete;
- virtual ~TLSClientSocketTestBase() {}
- Mode mode() { return mode_; }
- protected:
- // One of the two fields will be set, depending on the mode.
- struct SocketHandle {
- mojo::Remote<mojom::TCPConnectedSocket> tcp_socket;
- mojo::Remote<mojom::ProxyResolvingSocket> proxy_socket;
- };
- struct SocketRequest {
- mojo::PendingReceiver<mojom::TCPConnectedSocket> tcp_socket_receiver;
- mojo::PendingReceiver<mojom::ProxyResolvingSocket> proxy_socket_receiver;
- };
- // Initializes the test fixture. If |use_mock_sockets|, mock client socket
- // factory will be used.
- void Init(bool use_mock_sockets, bool configure_proxy) {
- auto context_builder = net::CreateTestURLRequestContextBuilder();
- if (use_mock_sockets) {
- mock_client_socket_factory_.set_enable_read_if_ready(true);
- context_builder->set_client_socket_factory_for_testing(
- &mock_client_socket_factory_);
- }
- if (configure_proxy) {
- context_builder->set_proxy_resolution_service(
- net::ConfiguredProxyResolutionService::CreateFixedForTest(
- "http://proxy:8080", TRAFFIC_ANNOTATION_FOR_TESTS));
- }
- url_request_context_ = context_builder->Build();
- factory_ = std::make_unique<SocketFactory>(/*net_log=*/nullptr,
- url_request_context_.get());
- proxy_resolving_factory_ =
- std::make_unique<ProxyResolvingSocketFactoryMojo>(
- url_request_context_.get());
- }
- // Reads |num_bytes| from |handle| or reads until an error occurs. Returns the
- // bytes read as a string.
- std::string Read(mojo::ScopedDataPipeConsumerHandle* handle,
- size_t num_bytes) {
- std::string received_contents;
- while (received_contents.size() < num_bytes) {
- base::RunLoop().RunUntilIdle();
- std::vector<char> buffer(num_bytes);
- uint32_t read_size = static_cast<uint32_t>(num_bytes);
- MojoResult result = handle->get().ReadData(buffer.data(), &read_size,
- MOJO_READ_DATA_FLAG_NONE);
- if (result == MOJO_RESULT_SHOULD_WAIT)
- continue;
- if (result != MOJO_RESULT_OK)
- return received_contents;
- received_contents.append(buffer.data(), read_size);
- }
- return received_contents;
- }
- SocketRequest MakeRequest(SocketHandle* handle) {
- SocketRequest result;
- if (mode_ == kDirect)
- result.tcp_socket_receiver =
- handle->tcp_socket.BindNewPipeAndPassReceiver();
- else
- result.proxy_socket_receiver =
- handle->proxy_socket.BindNewPipeAndPassReceiver();
- return result;
- }
- void ResetSocket(SocketHandle* handle) {
- if (mode_ == kDirect)
- handle->tcp_socket.reset();
- else
- handle->proxy_socket.reset();
- }
- int CreateSocketSync(SocketRequest request,
- const net::IPEndPoint& remote_addr) {
- if (mode_ == kDirect) {
- return CreateTCPConnectedSocketSync(
- std::move(request.tcp_socket_receiver), remote_addr);
- } else {
- return CreateProxyResolvingSocketSync(
- std::move(request.proxy_socket_receiver), remote_addr);
- }
- }
- int CreateTCPConnectedSocketSync(
- mojo::PendingReceiver<mojom::TCPConnectedSocket> receiver,
- const net::IPEndPoint& remote_addr) {
- net::AddressList remote_addr_list(remote_addr);
- base::RunLoop run_loop;
- int net_error = net::ERR_FAILED;
- factory_->CreateTCPConnectedSocket(
- absl::nullopt /* local_addr */, remote_addr_list,
- nullptr /* tcp_connected_socket_options */,
- TRAFFIC_ANNOTATION_FOR_TESTS, std::move(receiver),
- pre_tls_observer()->GetObserverRemote(),
- base::BindLambdaForTesting(
- [&](int result,
- const absl::optional<net::IPEndPoint>& actual_local_addr,
- const absl::optional<net::IPEndPoint>& peer_addr,
- mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
- mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
- net_error = result;
- pre_tls_recv_handle_ = std::move(receive_pipe_handle);
- pre_tls_send_handle_ = std::move(send_pipe_handle);
- run_loop.Quit();
- }));
- run_loop.Run();
- return net_error;
- }
- int CreateProxyResolvingSocketSync(
- mojo::PendingReceiver<mojom::ProxyResolvingSocket> receiver,
- const net::IPEndPoint& remote_addr) {
- GURL url("https://" + remote_addr.ToString());
- base::RunLoop run_loop;
- int net_error = net::ERR_FAILED;
- proxy_resolving_factory_->CreateProxyResolvingSocket(
- url, net::NetworkIsolationKey(), nullptr /* options */,
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
- std::move(receiver), mojo::NullRemote() /* observer */,
- base::BindLambdaForTesting(
- [&](int result,
- const absl::optional<net::IPEndPoint>& actual_local_addr,
- const absl::optional<net::IPEndPoint>& peer_addr,
- mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
- mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
- net_error = result;
- pre_tls_recv_handle_ = std::move(receive_pipe_handle);
- pre_tls_send_handle_ = std::move(send_pipe_handle);
- run_loop.Quit();
- }));
- run_loop.Run();
- return net_error;
- }
- void UpgradeToTLS(SocketHandle* handle,
- const net::HostPortPair& host_port_pair,
- mojo::PendingReceiver<mojom::TLSClientSocket> receiver,
- net::CompletionOnceCallback callback) {
- if (mode_ == kDirect) {
- UpgradeTCPConnectedSocketToTLS(handle->tcp_socket.get(), host_port_pair,
- nullptr /* options */, std::move(receiver),
- std::move(callback));
- } else {
- UpgradeProxyResolvingSocketToTLS(handle->proxy_socket.get(),
- host_port_pair, std::move(receiver),
- std::move(callback));
- }
- }
- void UpgradeTCPConnectedSocketToTLS(
- mojom::TCPConnectedSocket* client_socket,
- const net::HostPortPair& host_port_pair,
- mojom::TLSClientSocketOptionsPtr options,
- mojo::PendingReceiver<mojom::TLSClientSocket> receiver,
- net::CompletionOnceCallback callback) {
- client_socket->UpgradeToTLS(
- host_port_pair, std::move(options),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
- std::move(receiver), post_tls_observer()->GetObserverRemote(),
- base::BindOnce(
- [](net::CompletionOnceCallback cb,
- mojo::ScopedDataPipeConsumerHandle* consumer_handle_out,
- mojo::ScopedDataPipeProducerHandle* producer_handle_out,
- absl::optional<net::SSLInfo>* ssl_info_out, int result,
- mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
- mojo::ScopedDataPipeProducerHandle send_pipe_handle,
- const absl::optional<net::SSLInfo>& ssl_info) {
- *consumer_handle_out = std::move(receive_pipe_handle);
- *producer_handle_out = std::move(send_pipe_handle);
- *ssl_info_out = ssl_info;
- std::move(cb).Run(result);
- },
- std::move(callback), &post_tls_recv_handle_, &post_tls_send_handle_,
- &ssl_info_));
- }
- void UpgradeProxyResolvingSocketToTLS(
- mojom::ProxyResolvingSocket* client_socket,
- const net::HostPortPair& host_port_pair,
- mojo::PendingReceiver<mojom::TLSClientSocket> receiver,
- net::CompletionOnceCallback callback) {
- client_socket->UpgradeToTLS(
- host_port_pair,
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
- std::move(receiver), post_tls_observer()->GetObserverRemote(),
- base::BindOnce(
- [](net::CompletionOnceCallback cb,
- mojo::ScopedDataPipeConsumerHandle* consumer_handle,
- mojo::ScopedDataPipeProducerHandle* producer_handle, int result,
- mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
- mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
- *consumer_handle = std::move(receive_pipe_handle);
- *producer_handle = std::move(send_pipe_handle);
- std::move(cb).Run(result);
- },
- std::move(callback), &post_tls_recv_handle_,
- &post_tls_send_handle_));
- }
- TestSocketObserver* pre_tls_observer() { return &pre_tls_observer_; }
- TestSocketObserver* post_tls_observer() { return &post_tls_observer_; }
- mojo::ScopedDataPipeConsumerHandle* pre_tls_recv_handle() {
- return &pre_tls_recv_handle_;
- }
- mojo::ScopedDataPipeProducerHandle* pre_tls_send_handle() {
- return &pre_tls_send_handle_;
- }
- mojo::ScopedDataPipeConsumerHandle* post_tls_recv_handle() {
- return &post_tls_recv_handle_;
- }
- mojo::ScopedDataPipeProducerHandle* post_tls_send_handle() {
- return &post_tls_send_handle_;
- }
- const absl::optional<net::SSLInfo>& ssl_info() { return ssl_info_; }
- net::MockClientSocketFactory* mock_client_socket_factory() {
- return &mock_client_socket_factory_;
- }
- Mode mode() const { return mode_; }
- private:
- Mode mode_;
- base::test::TaskEnvironment task_environment_;
- // Mojo data handles obtained from CreateTCPConnectedSocket.
- mojo::ScopedDataPipeConsumerHandle pre_tls_recv_handle_;
- mojo::ScopedDataPipeProducerHandle pre_tls_send_handle_;
- // Mojo data handles obtained from UpgradeToTLS.
- mojo::ScopedDataPipeConsumerHandle post_tls_recv_handle_;
- mojo::ScopedDataPipeProducerHandle post_tls_send_handle_;
- // SSLInfo obtained from UpgradeToTLS.
- absl::optional<net::SSLInfo> ssl_info_;
- net::MockClientSocketFactory mock_client_socket_factory_;
- std::unique_ptr<net::URLRequestContext> url_request_context_;
- std::unique_ptr<SocketFactory> factory_;
- std::unique_ptr<ProxyResolvingSocketFactoryMojo> proxy_resolving_factory_;
- TestSocketObserver pre_tls_observer_;
- TestSocketObserver post_tls_observer_;
- };
- class TLSClientSocketTest
- : public ::testing::TestWithParam<TLSClientSocketTestBase::Mode>,
- public TLSClientSocketTestBase {
- public:
- TLSClientSocketTest() : TLSClientSocketTestBase(GetParam()) {
- Init(true /* use_mock_sockets */, false /* configure_proxy */);
- }
- TLSClientSocketTest(const TLSClientSocketTest&) = delete;
- TLSClientSocketTest& operator=(const TLSClientSocketTest&) = delete;
- ~TLSClientSocketTest() override {}
- };
- // Basic test to call UpgradeToTLS, and then read/write after UpgradeToTLS is
- // successful.
- TEST_P(TLSClientSocketTest, UpgradeToTLS) {
- const net::MockRead kReads[] = {net::MockRead(net::ASYNC, kMsg, kMsgSize, 1),
- net::MockRead(net::SYNCHRONOUS, net::OK, 2)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 0)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- uint32_t num_bytes = strlen(kMsg);
- EXPECT_EQ(MOJO_RESULT_OK, post_tls_send_handle()->get().WriteData(
- &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kMsg, Read(post_tls_recv_handle(), kMsgSize));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Same as the UpgradeToTLS test above, except this test calls
- // base::RunLoop().RunUntilIdle() after destroying the pre-tls data pipes.
- TEST_P(TLSClientSocketTest, ClosePipesRunUntilIdleAndUpgradeToTLS) {
- const net::MockRead kReads[] = {net::MockRead(net::ASYNC, kMsg, kMsgSize, 1),
- net::MockRead(net::SYNCHRONOUS, net::OK, 2)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 0)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- // Call RunUntilIdle() to test the case that pipes are closed before
- // UpgradeToTLS.
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- base::RunLoop().RunUntilIdle();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- uint32_t num_bytes = strlen(kMsg);
- EXPECT_EQ(MOJO_RESULT_OK, post_tls_send_handle()->get().WriteData(
- &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kMsg, Read(post_tls_recv_handle(), kMsgSize));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Calling UpgradeToTLS on the same mojo::Remote<TCPConnectedSocket> is illegal
- // and should receive an error.
- TEST_P(TLSClientSocketTest, UpgradeToTLSTwice) {
- const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 0)};
- net::SequencedSocketData data_provider(kReads, base::span<net::MockWrite>());
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- // First UpgradeToTLS should complete successfully.
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- // Second time UpgradeToTLS is called, it should fail.
- mojo::Remote<mojom::TLSClientSocket> tls_socket2;
- base::RunLoop run_loop;
- int net_error = net::ERR_FAILED;
- if (mode() == kDirect) {
- auto upgrade2_callback = base::BindLambdaForTesting(
- [&](int result, mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
- mojo::ScopedDataPipeProducerHandle send_pipe_handle,
- const absl::optional<net::SSLInfo>& ssl_info) {
- net_error = result;
- run_loop.Quit();
- });
- client_socket.tcp_socket->UpgradeToTLS(
- host_port_pair, nullptr /* ssl_config_ptr */,
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
- tls_socket2.BindNewPipeAndPassReceiver(),
- mojo::NullRemote() /*observer */, std::move(upgrade2_callback));
- } else {
- auto upgrade2_callback = base::BindLambdaForTesting(
- [&](int result, mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
- mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
- net_error = result;
- run_loop.Quit();
- });
- client_socket.proxy_socket->UpgradeToTLS(
- host_port_pair,
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
- tls_socket2.BindNewPipeAndPassReceiver(),
- mojo::NullRemote() /*observer */, std::move(upgrade2_callback));
- }
- run_loop.Run();
- ASSERT_EQ(net::ERR_SOCKET_NOT_CONNECTED, net_error);
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- TEST_P(TLSClientSocketTest, UpgradeToTLSWithCustomSSLConfig) {
- // No custom options in the proxy-resolving case.
- if (mode() != kDirect)
- return;
- const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 0)};
- net::SequencedSocketData data_provider(kReads, base::span<net::MockWrite>());
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- ssl_socket.expected_ssl_version_min = net::SSL_PROTOCOL_VERSION_TLS1_2;
- ssl_socket.expected_ssl_version_max = net::SSL_PROTOCOL_VERSION_TLS1_3;
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- base::RunLoop run_loop;
- mojom::TLSClientSocketOptionsPtr options =
- mojom::TLSClientSocketOptions::New();
- options->version_min = mojom::SSLVersion::kTLS12;
- options->version_max = mojom::SSLVersion::kTLS13;
- int net_error = net::ERR_FAILED;
- auto upgrade_callback = base::BindLambdaForTesting(
- [&](int result, mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
- mojo::ScopedDataPipeProducerHandle send_pipe_handle,
- const absl::optional<net::SSLInfo>& ssl_info) {
- net_error = result;
- run_loop.Quit();
- });
- client_socket.tcp_socket->UpgradeToTLS(
- host_port_pair, std::move(options),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
- tls_socket.BindNewPipeAndPassReceiver(), mojo::NullRemote() /*observer */,
- std::move(upgrade_callback));
- run_loop.Run();
- ASSERT_EQ(net::OK, net_error);
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Same as the UpgradeToTLS test, except this also reads and writes to the tcp
- // connection before UpgradeToTLS is called.
- TEST_P(TLSClientSocketTest, ReadWriteBeforeUpgradeToTLS) {
- const net::MockRead kReads[] = {
- net::MockRead(net::SYNCHRONOUS, kMsg, kMsgSize, 0),
- net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 3),
- net::MockRead(net::SYNCHRONOUS, net::OK, 4)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 1),
- net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 2),
- };
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- EXPECT_EQ(kMsg, Read(pre_tls_recv_handle(), kMsgSize));
- uint32_t num_bytes = kMsgSize;
- EXPECT_EQ(MOJO_RESULT_OK, pre_tls_send_handle()->get().WriteData(
- &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- num_bytes = strlen(kSecretMsg);
- EXPECT_EQ(MOJO_RESULT_OK,
- post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
- MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Tests that a read error is encountered after UpgradeToTLS completes
- // successfully.
- TEST_P(TLSClientSocketTest, ReadErrorAfterUpgradeToTLS) {
- const net::MockRead kReads[] = {
- net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 1),
- net::MockRead(net::SYNCHRONOUS, net::ERR_CONNECTION_CLOSED, 2)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 0)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- uint32_t num_bytes = strlen(kSecretMsg);
- EXPECT_EQ(MOJO_RESULT_OK,
- post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
- MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
- EXPECT_EQ(net::ERR_CONNECTION_CLOSED,
- post_tls_observer()->WaitForReadError());
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Tests that a read error is encountered after UpgradeToTLS completes
- // successfully.
- TEST_P(TLSClientSocketTest, WriteErrorAfterUpgradeToTLS) {
- const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 0)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, net::ERR_CONNECTION_CLOSED, 1)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- uint32_t num_bytes = strlen(kSecretMsg);
- EXPECT_EQ(MOJO_RESULT_OK,
- post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
- MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(net::ERR_CONNECTION_CLOSED,
- post_tls_observer()->WaitForWriteError());
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Tests that reading from the pre-tls data pipe is okay even after UpgradeToTLS
- // is called.
- TEST_P(TLSClientSocketTest, ReadFromPreTlsDataPipeAfterUpgradeToTLS) {
- const net::MockRead kReads[] = {
- net::MockRead(net::ASYNC, kMsg, kMsgSize, 0),
- net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 2),
- net::MockRead(net::SYNCHRONOUS, net::OK, 3)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 1)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(kMsg, Read(pre_tls_recv_handle(), kMsgSize));
- // Reset pre-tls receive pipe now and UpgradeToTLS should complete.
- pre_tls_recv_handle()->reset();
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- uint32_t num_bytes = strlen(kSecretMsg);
- EXPECT_EQ(MOJO_RESULT_OK,
- post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
- MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Tests that writing to the pre-tls data pipe is okay even after UpgradeToTLS
- // is called.
- TEST_P(TLSClientSocketTest, WriteToPreTlsDataPipeAfterUpgradeToTLS) {
- const net::MockRead kReads[] = {
- net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 2),
- net::MockRead(net::SYNCHRONOUS, net::OK, 3)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 0),
- net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 1)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- base::RunLoop().RunUntilIdle();
- uint32_t num_bytes = strlen(kMsg);
- EXPECT_EQ(MOJO_RESULT_OK, pre_tls_send_handle()->get().WriteData(
- &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- // Reset pre-tls send pipe now and UpgradeToTLS should complete.
- pre_tls_send_handle()->reset();
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- num_bytes = strlen(kSecretMsg);
- EXPECT_EQ(MOJO_RESULT_OK,
- post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
- MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Tests that reading from and writing to pre-tls data pipe is okay even after
- // UpgradeToTLS is called.
- TEST_P(TLSClientSocketTest, ReadAndWritePreTlsDataPipeAfterUpgradeToTLS) {
- const net::MockRead kReads[] = {
- net::MockRead(net::ASYNC, kMsg, kMsgSize, 0),
- net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 3),
- net::MockRead(net::SYNCHRONOUS, net::OK, 4)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 1),
- net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 2)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- base::RunLoop run_loop;
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- EXPECT_EQ(kMsg, Read(pre_tls_recv_handle(), kMsgSize));
- uint32_t num_bytes = strlen(kMsg);
- EXPECT_EQ(MOJO_RESULT_OK, pre_tls_send_handle()->get().WriteData(
- &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- // Reset pre-tls pipes now and UpgradeToTLS should complete.
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- num_bytes = strlen(kSecretMsg);
- EXPECT_EQ(MOJO_RESULT_OK,
- post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
- MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Tests that a read error is encountered before UpgradeToTLS completes.
- TEST_P(TLSClientSocketTest, ReadErrorBeforeUpgradeToTLS) {
- // This requires pre_tls_observer(), which is not provided by proxy resolving
- // sockets.
- if (mode() != kDirect)
- return;
- const net::MockRead kReads[] = {
- net::MockRead(net::ASYNC, kMsg, kMsgSize, 0),
- net::MockRead(net::SYNCHRONOUS, net::ERR_CONNECTION_CLOSED, 1)};
- net::SequencedSocketData data_provider(kReads, base::span<net::MockWrite>());
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- EXPECT_EQ(kMsg, Read(pre_tls_recv_handle(), kMsgSize));
- EXPECT_EQ(net::ERR_CONNECTION_CLOSED, pre_tls_observer()->WaitForReadError());
- // Reset pre-tls receive pipe now and UpgradeToTLS should complete.
- pre_tls_recv_handle()->reset();
- ASSERT_EQ(net::ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
- ResetSocket(&client_socket);
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Tests that a write error is encountered before UpgradeToTLS completes.
- TEST_P(TLSClientSocketTest, WriteErrorBeforeUpgradeToTLS) {
- // This requires pre_tls_observer(), which is not provided by proxy resolving
- // sockets.
- if (mode() != kDirect)
- return;
- const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 1)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::SYNCHRONOUS, net::ERR_CONNECTION_CLOSED, 0)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- uint32_t num_bytes = strlen(kMsg);
- EXPECT_EQ(MOJO_RESULT_OK, pre_tls_send_handle()->get().WriteData(
- &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(net::ERR_CONNECTION_CLOSED,
- pre_tls_observer()->WaitForWriteError());
- // Reset pre-tls send pipe now and UpgradeToTLS should complete.
- pre_tls_send_handle()->reset();
- ASSERT_EQ(net::ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
- ResetSocket(&client_socket);
- base::RunLoop().RunUntilIdle();
- // Write failed before the mock read can be consumed.
- EXPECT_FALSE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- INSTANTIATE_TEST_SUITE_P(
- All,
- TLSClientSocketTest,
- ::testing::Values(TLSClientSocketTestBase::kDirect,
- TLSClientSocketTestBase::kProxyResolving));
- // Tests with proxy resolving socket and a proxy actually configured.
- class TLSCLientSocketProxyTest : public ::testing::Test,
- public TLSClientSocketTestBase {
- public:
- TLSCLientSocketProxyTest()
- : TLSClientSocketTestBase(TLSClientSocketTestBase::kProxyResolving) {
- Init(true /* use_mock_sockets*/, true /* configure_proxy */);
- }
- TLSCLientSocketProxyTest(const TLSCLientSocketProxyTest&) = delete;
- TLSCLientSocketProxyTest& operator=(const TLSCLientSocketProxyTest&) = delete;
- ~TLSCLientSocketProxyTest() override {}
- };
- TEST_F(TLSCLientSocketProxyTest, UpgradeToTLS) {
- const char kConnectRequest[] =
- "CONNECT 192.168.1.1:1234 HTTP/1.1\r\n"
- "Host: 192.168.1.1:1234\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n";
- const char kConnectResponse[] = "HTTP/1.1 200 OK\r\n\r\n";
- const net::MockRead kReads[] = {
- net::MockRead(net::ASYNC, kConnectResponse, strlen(kConnectResponse), 1),
- net::MockRead(net::ASYNC, kMsg, kMsgSize, 3),
- net::MockRead(net::SYNCHRONOUS, net::OK, 4)};
- const net::MockWrite kWrites[] = {
- net::MockWrite(net::ASYNC, kConnectRequest, strlen(kConnectRequest), 0),
- net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 2)};
- net::SequencedSocketData data_provider(kReads, kWrites);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress(192, 168, 1, 1), 1234);
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeToTLS(&client_socket, host_port_pair,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ResetSocket(&client_socket);
- uint32_t num_bytes = strlen(kMsg);
- EXPECT_EQ(MOJO_RESULT_OK, post_tls_send_handle()->get().WriteData(
- &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kMsg, Read(post_tls_recv_handle(), kMsgSize));
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- class TLSClientSocketIoModeTest : public TLSClientSocketTestBase,
- public testing::TestWithParam<net::IoMode> {
- public:
- TLSClientSocketIoModeTest()
- : TLSClientSocketTestBase(TLSClientSocketTestBase::kDirect) {
- Init(true /* use_mock_sockets*/, false /* configure_proxy */);
- }
- TLSClientSocketIoModeTest(const TLSClientSocketIoModeTest&) = delete;
- TLSClientSocketIoModeTest& operator=(const TLSClientSocketIoModeTest&) =
- delete;
- ~TLSClientSocketIoModeTest() override {}
- };
- INSTANTIATE_TEST_SUITE_P(All,
- TLSClientSocketIoModeTest,
- testing::Values(net::SYNCHRONOUS, net::ASYNC));
- TEST_P(TLSClientSocketIoModeTest, MultipleWriteToTLSSocket) {
- const int kNumIterations = 3;
- std::vector<net::MockRead> reads;
- std::vector<net::MockWrite> writes;
- int sequence_number = 0;
- net::IoMode mode = GetParam();
- for (int j = 0; j < kNumIterations; ++j) {
- for (size_t i = 0; i < kSecretMsgSize; ++i) {
- writes.push_back(
- net::MockWrite(mode, &kSecretMsg[i], 1, sequence_number++));
- }
- for (size_t i = 0; i < kSecretMsgSize; ++i) {
- reads.push_back(
- net::MockRead(net::ASYNC, &kSecretMsg[i], 1, sequence_number++));
- }
- if (j == kNumIterations - 1) {
- reads.push_back(net::MockRead(mode, net::OK, sequence_number++));
- }
- }
- net::SequencedSocketData data_provider(reads, writes);
- data_provider.set_connect_data(net::MockConnect(GetParam(), net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- mojo::Remote<mojom::TCPConnectedSocket> client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateTCPConnectedSocketSync(
- client_socket.BindNewPipeAndPassReceiver(), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- UpgradeTCPConnectedSocketToTLS(
- client_socket.get(), host_port_pair, nullptr /* options */,
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- client_socket.reset();
- EXPECT_FALSE(ssl_info());
- // Loop kNumIterations times to test that writes can follow reads, and reads
- // can follow writes.
- for (int j = 0; j < kNumIterations; ++j) {
- // Write multiple times.
- for (size_t i = 0; i < kSecretMsgSize; ++i) {
- uint32_t num_bytes = 1;
- EXPECT_EQ(MOJO_RESULT_OK,
- post_tls_send_handle()->get().WriteData(
- &kSecretMsg[i], &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- // Flush the 1 byte write.
- base::RunLoop().RunUntilIdle();
- }
- // Reading kSecretMsgSize should coalesce the 1-byte mock reads.
- EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
- }
- EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
- EXPECT_TRUE(data_provider.AllReadDataConsumed());
- EXPECT_TRUE(data_provider.AllWriteDataConsumed());
- }
- // Check SSLInfo is provided in both sync and async cases.
- TEST_P(TLSClientSocketIoModeTest, SSLInfo) {
- // End of file. Reads don't matter, only the handshake does.
- std::vector<net::MockRead> reads = {net::MockRead(net::SYNCHRONOUS, net::OK)};
- std::vector<net::MockWrite> writes;
- net::SequencedSocketData data_provider(reads, writes);
- data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
- mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
- net::SSLSocketDataProvider ssl_socket(GetParam(), net::OK);
- // Set a value on SSLInfo to make sure it's correctly received.
- ssl_socket.ssl_info.is_issued_by_known_root = true;
- mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);
- mojo::Remote<mojom::TCPConnectedSocket> client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
- EXPECT_EQ(net::OK,
- CreateTCPConnectedSocketSync(
- client_socket.BindNewPipeAndPassReceiver(), server_addr));
- net::HostPortPair host_port_pair("example.org", 443);
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- mojo::Remote<mojom::TLSClientSocket> tls_socket;
- mojom::TLSClientSocketOptionsPtr options =
- mojom::TLSClientSocketOptions::New();
- options->send_ssl_info = true;
- UpgradeTCPConnectedSocketToTLS(
- client_socket.get(), host_port_pair, std::move(options),
- tls_socket.BindNewPipeAndPassReceiver(), callback.callback());
- ASSERT_EQ(net::OK, callback.WaitForResult());
- ASSERT_TRUE(ssl_info());
- EXPECT_TRUE(ssl_socket.ssl_info.is_issued_by_known_root);
- EXPECT_FALSE(ssl_socket.ssl_info.is_fatal_cert_error);
- }
- class TLSClientSocketTestWithEmbeddedTestServerBase
- : public TLSClientSocketTestBase {
- public:
- explicit TLSClientSocketTestWithEmbeddedTestServerBase(Mode mode)
- : TLSClientSocketTestBase(mode),
- server_(net::EmbeddedTestServer::TYPE_HTTPS) {
- Init(false /* use_mock_sockets */, false /* configure_proxy */);
- }
- TLSClientSocketTestWithEmbeddedTestServerBase(
- const TLSClientSocketTestWithEmbeddedTestServerBase&) = delete;
- TLSClientSocketTestWithEmbeddedTestServerBase& operator=(
- const TLSClientSocketTestWithEmbeddedTestServerBase&) = delete;
- ~TLSClientSocketTestWithEmbeddedTestServerBase() override {}
- // Starts the test server using the specified certificate.
- [[nodiscard]] bool StartTestServer(
- net::EmbeddedTestServer::ServerCertificate certificate) {
- server_.RegisterRequestHandler(
- base::BindRepeating([](const net::test_server::HttpRequest& request) {
- if (base::StartsWith(request.relative_url, "/secret",
- base::CompareCase::INSENSITIVE_ASCII)) {
- return std::unique_ptr<net::test_server::HttpResponse>(
- new net::test_server::RawHttpResponse("HTTP/1.1 200 OK",
- "Hello There!"));
- }
- return std::unique_ptr<net::test_server::HttpResponse>();
- }));
- server_.SetSSLConfig(certificate);
- return server_.Start();
- }
- // Attempts to eastablish a TLS connection to the test server by first
- // establishing a TCP connection, and then upgrading it. Returns the
- // resulting network error code.
- [[nodiscard]] int CreateTLSSocket() {
- SocketHandle client_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(),
- server_.port());
- EXPECT_EQ(net::OK,
- CreateSocketSync(MakeRequest(&client_socket), server_addr));
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- UpgradeToTLS(&client_socket, server_.host_port_pair(),
- tls_socket_.BindNewPipeAndPassReceiver(), callback.callback());
- int result = callback.WaitForResult();
- ResetSocket(&client_socket);
- return result;
- }
- [[nodiscard]] int CreateTLSSocketWithOptions(
- mojom::TLSClientSocketOptionsPtr options) {
- // Proxy connections don't support TLSClientSocketOptions.
- DCHECK_EQ(kDirect, mode());
- mojo::Remote<mojom::TCPConnectedSocket> tcp_socket;
- net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(),
- server_.port());
- EXPECT_EQ(net::OK,
- CreateTCPConnectedSocketSync(
- tcp_socket.BindNewPipeAndPassReceiver(), server_addr));
- pre_tls_recv_handle()->reset();
- pre_tls_send_handle()->reset();
- net::TestCompletionCallback callback;
- UpgradeTCPConnectedSocketToTLS(
- tcp_socket.get(), server_.host_port_pair(), std::move(options),
- tls_socket_.BindNewPipeAndPassReceiver(), callback.callback());
- int result = callback.WaitForResult();
- tcp_socket.reset();
- return result;
- }
- void TestTlsSocket() {
- ASSERT_TRUE(tls_socket_.is_bound());
- const char kTestMsg[] = "GET /secret HTTP/1.1\r\n\r\n";
- uint32_t num_bytes = strlen(kTestMsg);
- const char kResponse[] = "HTTP/1.1 200 OK\n\n";
- EXPECT_EQ(MOJO_RESULT_OK,
- post_tls_send_handle()->get().WriteData(
- &kTestMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
- EXPECT_EQ(kResponse, Read(post_tls_recv_handle(), strlen(kResponse)));
- }
- net::EmbeddedTestServer* server() { return &server_; }
- private:
- net::EmbeddedTestServer server_;
- mojo::Remote<mojom::TLSClientSocket> tls_socket_;
- };
- class TLSClientSocketTestWithEmbeddedTestServer
- : public TLSClientSocketTestWithEmbeddedTestServerBase,
- public ::testing::TestWithParam<TLSClientSocketTestBase::Mode> {
- public:
- TLSClientSocketTestWithEmbeddedTestServer()
- : TLSClientSocketTestWithEmbeddedTestServerBase(GetParam()) {}
- TLSClientSocketTestWithEmbeddedTestServer(
- const TLSClientSocketTestWithEmbeddedTestServer&) = delete;
- TLSClientSocketTestWithEmbeddedTestServer& operator=(
- const TLSClientSocketTestWithEmbeddedTestServer&) = delete;
- ~TLSClientSocketTestWithEmbeddedTestServer() override {}
- };
- TEST_P(TLSClientSocketTestWithEmbeddedTestServer, Basic) {
- ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_OK));
- ASSERT_EQ(net::OK, CreateTLSSocket());
- // No SSLInfo should be received by default. SSLInfo is only supported in the
- // kDirect case, but it doesn't hurt to check it's null it in the
- // kProxyResolving case.
- EXPECT_FALSE(ssl_info());
- TestTlsSocket();
- }
- TEST_P(TLSClientSocketTestWithEmbeddedTestServer, ServerCertError) {
- ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_MISMATCHED_NAME));
- ASSERT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, CreateTLSSocket());
- // No SSLInfo should be received by default. SSLInfo is only supported in the
- // kDirect case, but it doesn't hurt to check it's null in the kProxyResolving
- // case.
- EXPECT_FALSE(ssl_info());
- // Handles should be invalid.
- EXPECT_FALSE(post_tls_recv_handle()->is_valid());
- EXPECT_FALSE(post_tls_send_handle()->is_valid());
- }
- INSTANTIATE_TEST_SUITE_P(
- All,
- TLSClientSocketTestWithEmbeddedTestServer,
- ::testing::Values(TLSClientSocketTestBase::kDirect,
- TLSClientSocketTestBase::kProxyResolving));
- class TLSClientSocketDirectTestWithEmbeddedTestServer
- : public TLSClientSocketTestWithEmbeddedTestServerBase,
- public testing::Test {
- public:
- TLSClientSocketDirectTestWithEmbeddedTestServer()
- : TLSClientSocketTestWithEmbeddedTestServerBase(kDirect) {}
- TLSClientSocketDirectTestWithEmbeddedTestServer(
- const TLSClientSocketDirectTestWithEmbeddedTestServer&) = delete;
- TLSClientSocketDirectTestWithEmbeddedTestServer& operator=(
- const TLSClientSocketDirectTestWithEmbeddedTestServer&) = delete;
- ~TLSClientSocketDirectTestWithEmbeddedTestServer() override {}
- };
- TEST_F(TLSClientSocketDirectTestWithEmbeddedTestServer, SSLInfo) {
- ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_OK));
- mojom::TLSClientSocketOptionsPtr options =
- mojom::TLSClientSocketOptions::New();
- options->send_ssl_info = true;
- ASSERT_EQ(net::OK, CreateTLSSocketWithOptions(std::move(options)));
- ASSERT_TRUE(ssl_info());
- EXPECT_TRUE(ssl_info()->is_valid());
- EXPECT_FALSE(ssl_info()->is_fatal_cert_error);
- TestTlsSocket();
- }
- TEST_F(TLSClientSocketDirectTestWithEmbeddedTestServer,
- SSLInfoServerCertError) {
- ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_MISMATCHED_NAME));
- mojom::TLSClientSocketOptionsPtr options =
- mojom::TLSClientSocketOptions::New();
- options->send_ssl_info = true;
- // Requesting SSLInfo should not bypass cert verification.
- ASSERT_EQ(net::ERR_CERT_COMMON_NAME_INVALID,
- CreateTLSSocketWithOptions(std::move(options)));
- // No SSLInfo should be provided on error.
- EXPECT_FALSE(ssl_info());
- // Handles should be invalid.
- EXPECT_FALSE(post_tls_recv_handle()->is_valid());
- EXPECT_FALSE(post_tls_send_handle()->is_valid());
- }
- // Check skipping cert verification always received SSLInfo, even with valid
- // certs.
- TEST_F(TLSClientSocketDirectTestWithEmbeddedTestServer,
- UnsafelySkipCertVerification) {
- ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_OK));
- mojom::TLSClientSocketOptionsPtr options =
- mojom::TLSClientSocketOptions::New();
- options->unsafely_skip_cert_verification = true;
- ASSERT_EQ(net::OK, CreateTLSSocketWithOptions(std::move(options)));
- ASSERT_TRUE(ssl_info());
- EXPECT_TRUE(ssl_info()->is_valid());
- EXPECT_FALSE(ssl_info()->is_fatal_cert_error);
- TestTlsSocket();
- }
- TEST_F(TLSClientSocketDirectTestWithEmbeddedTestServer,
- UnsafelySkipCertVerificationServerCertError) {
- ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_MISMATCHED_NAME));
- mojom::TLSClientSocketOptionsPtr options =
- mojom::TLSClientSocketOptions::New();
- options->unsafely_skip_cert_verification = true;
- ASSERT_EQ(net::OK, CreateTLSSocketWithOptions(std::move(options)));
- ASSERT_TRUE(ssl_info());
- EXPECT_TRUE(ssl_info()->is_valid());
- EXPECT_FALSE(ssl_info()->is_fatal_cert_error);
- TestTlsSocket();
- }
- } // namespace
- } // namespace network
|