blob: ecb231553ab4b11ce58523742434aaf4eec3db96 [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2019 The Chromium Authors
Jordan Bayles95bb73e2019-11-20 22:09:362// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Arthur Sonzognib948e672024-07-31 08:29:045#ifdef UNSAFE_BUFFERS_BUILD
6// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
7#pragma allow_unsafe_buffers
8#endif
9
btolsch496b728df2020-02-21 06:01:1810#include "components/openscreen_platform/tls_connection_factory.h"
Jordan Bayles95bb73e2019-11-20 22:09:3611
btolsch496b728df2020-02-21 06:01:1812#include <openssl/pool.h>
Jordan Bayles95bb73e2019-11-20 22:09:3613#include <utility>
14
Hans Wennborgdf87046c2020-04-28 11:06:2415#include "base/notreached.h"
btolsch4bdffd92020-04-08 07:27:2516#include "components/openscreen_platform/network_context.h"
Fabrice de Gans-Riberie17abf54b2020-01-28 00:29:5417#include "components/openscreen_platform/network_util.h"
btolsch496b728df2020-02-21 06:01:1818#include "components/openscreen_platform/tls_client_connection.h"
Jordan Bayles95bb73e2019-11-20 22:09:3619#include "net/base/host_port_pair.h"
20#include "net/base/net_errors.h"
21#include "net/ssl/ssl_info.h"
22#include "net/traffic_annotation/network_traffic_annotation.h"
btolsch4bdffd92020-04-08 07:27:2523#include "services/network/public/mojom/network_context.mojom.h"
Jordan Bayles95bb73e2019-11-20 22:09:3624#include "third_party/openscreen/src/platform/api/tls_connection.h"
25#include "third_party/openscreen/src/platform/base/tls_connect_options.h"
26#include "third_party/openscreen/src/platform/base/tls_credentials.h"
27#include "third_party/openscreen/src/platform/base/tls_listen_options.h"
28
29namespace openscreen {
Yuri Wiitala9fca519b32019-12-06 02:03:5230
mark a. foltz10444752023-06-17 00:11:5931class TaskRunner;
32
Jordan Bayles95bb73e2019-11-20 22:09:3633std::unique_ptr<TlsConnectionFactory> TlsConnectionFactory::CreateFactory(
mark a. foltz19c2ea332024-04-03 18:55:0434 Client& client,
mark a. foltz10444752023-06-17 00:11:5935 TaskRunner& task_runner) {
36 return std::make_unique<openscreen_platform::TlsConnectionFactory>(client);
Jordan Bayles95bb73e2019-11-20 22:09:3637}
Yuri Wiitala9fca519b32019-12-06 02:03:5238
Jordan Bayles95bb73e2019-11-20 22:09:3639} // namespace openscreen
40
btolsch496b728df2020-02-21 06:01:1841namespace openscreen_platform {
Jordan Bayles95bb73e2019-11-20 22:09:3642
43namespace {
44
45using openscreen::IPEndpoint;
Yuri Wiitala9fca519b32019-12-06 02:03:5246using openscreen::TlsConnectOptions;
47using openscreen::TlsCredentials;
48using openscreen::TlsListenOptions;
Jordan Bayles95bb73e2019-11-20 22:09:3649
50constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
btolsch496b728df2020-02-21 06:01:1851 net::DefineNetworkTrafficAnnotation("openscreen_tls_message", R"(
Jordan Bayles95bb73e2019-11-20 22:09:3652 semantics {
53 sender: "Open Screen"
54 description:
55 "Open Screen TLS messages are used by the third_party Open Screen "
btolsch496b728df2020-02-21 06:01:1856 "library, primarily for the libcast CastSocket implementation."
Jordan Bayles95bb73e2019-11-20 22:09:3657 trigger:
58 "Any TLS encrypted message that needs to be sent or received by "
59 "the Open Screen library."
60 data:
61 "Messages defined by the Open Screen Protocol specification."
62 destination: OTHER
63 destination_other:
64 "The connection is made to an Open Screen endpoint on the LAN "
65 "selected by the user, i.e. via a dialog."
66 }
67 policy {
68 cookies_allowed: NO
69 setting:
70 "This request cannot be disabled, but it would not be sent if user "
71 "does not connect to a Open Screen endpoint on the local network."
72 policy_exception_justification: "Not implemented."
73 })");
74
75} // namespace
76
btolsch496b728df2020-02-21 06:01:1877TlsConnectionFactory::~TlsConnectionFactory() = default;
Jordan Bayles95bb73e2019-11-20 22:09:3678
btolsch496b728df2020-02-21 06:01:1879void TlsConnectionFactory::Connect(const IPEndpoint& remote_address,
80 const TlsConnectOptions& options) {
btolsch4bdffd92020-04-08 07:27:2581 network::mojom::NetworkContext* network_context =
82 openscreen_platform::GetNetworkContext();
Jordan Bayles95bb73e2019-11-20 22:09:3683 if (!network_context) {
84 client_->OnError(this, openscreen::Error::Code::kItemNotFound);
85 return;
86 }
87
88 TcpConnectRequest request(options, remote_address,
89 mojo::Remote<network::mojom::TCPConnectedSocket>{});
90
91 const net::AddressList address_list(
Fabrice de Gans-Riberie17abf54b2020-01-28 00:29:5492 openscreen_platform::ToNetEndPoint(remote_address));
Jordan Bayles95bb73e2019-11-20 22:09:3693
btolsch496b728df2020-02-21 06:01:1894 mojo::PendingReceiver<network::mojom::TCPConnectedSocket> receiver =
95 request.tcp_socket.BindNewPipeAndPassReceiver();
96
Jordan Bayles95bb73e2019-11-20 22:09:3697 network_context->CreateTCPConnectedSocket(
Arthur Sonzognic571efb2024-01-26 20:26:1898 std::nullopt /* local_addr */, address_list,
Jordan Bayles95bb73e2019-11-20 22:09:3699 nullptr /* tcp_connected_socket_options */,
100 net::MutableNetworkTrafficAnnotationTag(kTrafficAnnotation),
btolsch496b728df2020-02-21 06:01:18101 std::move(receiver), mojo::NullRemote(), /* observer */
102 base::BindOnce(&TlsConnectionFactory::OnTcpConnect,
Jordan Bayles95bb73e2019-11-20 22:09:36103 weak_factory_.GetWeakPtr(), std::move(request)));
104}
105
btolsch496b728df2020-02-21 06:01:18106void TlsConnectionFactory::SetListenCredentials(
Jordan Bayles95bb73e2019-11-20 22:09:36107 const TlsCredentials& credentials) {
108 NOTIMPLEMENTED();
109}
110
btolsch496b728df2020-02-21 06:01:18111void TlsConnectionFactory::Listen(const IPEndpoint& local_address,
112 const TlsListenOptions& options) {
Jordan Bayles95bb73e2019-11-20 22:09:36113 NOTIMPLEMENTED();
114}
115
btolsch496b728df2020-02-21 06:01:18116TlsConnectionFactory::TlsConnectionFactory(
mark a. foltz19c2ea332024-04-03 18:55:04117 openscreen::TlsConnectionFactory::Client& client)
mark a. foltz10444752023-06-17 00:11:59118 : client_(client) {}
Jordan Bayles95bb73e2019-11-20 22:09:36119
btolsch496b728df2020-02-21 06:01:18120TlsConnectionFactory::TcpConnectRequest::TcpConnectRequest(
Yuri Wiitala9fca519b32019-12-06 02:03:52121 openscreen::TlsConnectOptions options_in,
Jordan Bayles95bb73e2019-11-20 22:09:36122 openscreen::IPEndpoint remote_address_in,
123 mojo::Remote<network::mojom::TCPConnectedSocket> tcp_socket_in)
124 : options(std::move(options_in)),
125 remote_address(std::move(remote_address_in)),
126 tcp_socket(std::move(tcp_socket_in)) {}
btolsch496b728df2020-02-21 06:01:18127TlsConnectionFactory::TcpConnectRequest::TcpConnectRequest(
Jordan Bayles95bb73e2019-11-20 22:09:36128 TcpConnectRequest&&) = default;
btolsch496b728df2020-02-21 06:01:18129TlsConnectionFactory::TcpConnectRequest&
130TlsConnectionFactory::TcpConnectRequest::operator=(TcpConnectRequest&&) =
Jordan Bayles95bb73e2019-11-20 22:09:36131 default;
132
btolsch496b728df2020-02-21 06:01:18133TlsConnectionFactory::TcpConnectRequest::~TcpConnectRequest() = default;
Jordan Bayles95bb73e2019-11-20 22:09:36134
btolsch496b728df2020-02-21 06:01:18135TlsConnectionFactory::TlsUpgradeRequest::TlsUpgradeRequest(
Jordan Bayles95bb73e2019-11-20 22:09:36136 openscreen::IPEndpoint local_address_in,
137 openscreen::IPEndpoint remote_address_in,
138 mojo::Remote<network::mojom::TCPConnectedSocket> tcp_socket_in,
139 mojo::Remote<network::mojom::TLSClientSocket> tls_socket_in)
140 : local_address(std::move(local_address_in)),
141 remote_address(std::move(remote_address_in)),
142 tcp_socket(std::move(tcp_socket_in)),
143 tls_socket(std::move(tls_socket_in)) {}
btolsch496b728df2020-02-21 06:01:18144TlsConnectionFactory::TlsUpgradeRequest::TlsUpgradeRequest(
Jordan Bayles95bb73e2019-11-20 22:09:36145 TlsUpgradeRequest&&) = default;
btolsch496b728df2020-02-21 06:01:18146TlsConnectionFactory::TlsUpgradeRequest&
147TlsConnectionFactory::TlsUpgradeRequest::operator=(TlsUpgradeRequest&&) =
Jordan Bayles95bb73e2019-11-20 22:09:36148 default;
btolsch496b728df2020-02-21 06:01:18149TlsConnectionFactory::TlsUpgradeRequest::~TlsUpgradeRequest() = default;
Jordan Bayles95bb73e2019-11-20 22:09:36150
btolsch496b728df2020-02-21 06:01:18151void TlsConnectionFactory::OnTcpConnect(
Jordan Bayles95bb73e2019-11-20 22:09:36152 TcpConnectRequest request,
153 int32_t net_result,
Arthur Sonzognic571efb2024-01-26 20:26:18154 const std::optional<net::IPEndPoint>& local_address,
155 const std::optional<net::IPEndPoint>& remote_address,
Jordan Bayles95bb73e2019-11-20 22:09:36156 mojo::ScopedDataPipeConsumerHandle receive_stream,
157 mojo::ScopedDataPipeProducerHandle send_stream) {
158 // We only care about net_result, since local_address doesn't matter,
159 // remote_address should be 1 out of 1 addresses provided in the connect
160 // call, and the streams must be closed before upgrading is allowed.
161 if (net_result != net::OK) {
162 client_->OnConnectionFailed(this, request.remote_address);
163 return;
164 }
165
166 net::HostPortPair host_port_pair = net::HostPortPair::FromIPEndPoint(
Fabrice de Gans-Riberie17abf54b2020-01-28 00:29:54167 openscreen_platform::ToNetEndPoint(request.remote_address));
Jordan Bayles95bb73e2019-11-20 22:09:36168 network::mojom::TLSClientSocketOptionsPtr options =
169 network::mojom::TLSClientSocketOptions::New();
170 options->unsafely_skip_cert_verification =
171 request.options.unsafely_skip_certificate_validation;
172
173 openscreen::IPEndpoint local_endpoint{};
174 if (local_address) {
Fabrice de Gans-Riberie17abf54b2020-01-28 00:29:54175 local_endpoint =
176 openscreen_platform::ToOpenScreenEndPoint(local_address.value());
Jordan Bayles95bb73e2019-11-20 22:09:36177 }
178
179 TlsUpgradeRequest upgrade_request(
btolsch496b728df2020-02-21 06:01:18180 std::move(local_endpoint), std::move(request.remote_address),
Jordan Bayles95bb73e2019-11-20 22:09:36181 std::move(request.tcp_socket),
182 mojo::Remote<network::mojom::TLSClientSocket>{});
183
btolsch496b728df2020-02-21 06:01:18184 network::mojom::TCPConnectedSocket* tcp_socket =
185 upgrade_request.tcp_socket.get();
186 mojo::PendingReceiver<network::mojom::TLSClientSocket> tls_receiver =
187 upgrade_request.tls_socket.BindNewPipeAndPassReceiver();
188
189 tcp_socket->UpgradeToTLS(
Jordan Bayles95bb73e2019-11-20 22:09:36190 host_port_pair, std::move(options),
191 net::MutableNetworkTrafficAnnotationTag(kTrafficAnnotation),
btolsch496b728df2020-02-21 06:01:18192 std::move(tls_receiver), mojo::NullRemote() /* observer */,
193 base::BindOnce(&TlsConnectionFactory::OnTlsUpgrade,
Jordan Bayles95bb73e2019-11-20 22:09:36194 weak_factory_.GetWeakPtr(), std::move(upgrade_request)));
195}
196
btolsch496b728df2020-02-21 06:01:18197void TlsConnectionFactory::OnTlsUpgrade(
Jordan Bayles95bb73e2019-11-20 22:09:36198 TlsUpgradeRequest request,
199 int32_t net_result,
200 mojo::ScopedDataPipeConsumerHandle receive_stream,
201 mojo::ScopedDataPipeProducerHandle send_stream,
Arthur Sonzognic571efb2024-01-26 20:26:18202 const std::optional<net::SSLInfo>& ssl_info) {
Jordan Bayles95bb73e2019-11-20 22:09:36203 if (net_result != net::OK) {
204 client_->OnConnectionFailed(this, request.remote_address);
205 return;
206 }
207
btolsch496b728df2020-02-21 06:01:18208 auto tls_connection = std::make_unique<TlsClientConnection>(
mark a. foltz10444752023-06-17 00:11:59209 request.local_address, request.remote_address, std::move(receive_stream),
210 std::move(send_stream), std::move(request.tcp_socket),
211 std::move(request.tls_socket));
Jordan Bayles95bb73e2019-11-20 22:09:36212
btolsch496b728df2020-02-21 06:01:18213 CRYPTO_BUFFER* der_buffer = ssl_info.value().unverified_cert->cert_buffer();
214 const uint8_t* data = CRYPTO_BUFFER_data(der_buffer);
215 std::vector<uint8_t> der_x509_certificate(
216 data, data + CRYPTO_BUFFER_len(der_buffer));
217 client_->OnConnected(this, std::move(der_x509_certificate),
218 std::move(tls_connection));
Jordan Bayles95bb73e2019-11-20 22:09:36219}
220
btolsch496b728df2020-02-21 06:01:18221} // namespace openscreen_platform