OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ | |
6 #define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <queue> | |
11 #include <string> | |
12 | |
13 #include "base/cancelable_callback.h" | |
14 #include "base/gtest_prod_util.h" | |
15 #include "base/macros.h" | |
16 #include "base/memory/ref_counted.h" | |
17 #include "base/threading/thread_checker.h" | |
18 #include "base/timer/timer.h" | |
19 #include "components/cast_channel/cast_channel_enum.h" | |
20 #include "extensions/browser/api/api_resource.h" | |
21 #include "extensions/browser/api/api_resource_manager.h" | |
22 #include "extensions/browser/api/cast_channel/cast_auth_util.h" | |
23 #include "extensions/browser/api/cast_channel/cast_socket.h" | |
24 #include "extensions/browser/api/cast_channel/cast_transport.h" | |
25 #include "extensions/common/api/cast_channel/logging.pb.h" | |
26 #include "net/base/completion_callback.h" | |
27 #include "net/base/io_buffer.h" | |
28 #include "net/base/ip_endpoint.h" | |
29 #include "net/log/net_log_source.h" | |
30 | |
31 namespace net { | |
32 class CertVerifier; | |
33 class CTPolicyEnforcer; | |
34 class CTVerifier; | |
35 class NetLog; | |
36 class SSLClientSocket; | |
37 class StreamSocket; | |
38 class TCPClientSocket; | |
39 class TransportSecurityState; | |
40 class X509Certificate; | |
41 } | |
42 | |
43 namespace extensions { | |
44 namespace api { | |
45 namespace cast_channel { | |
46 class CastMessage; | |
47 class Logger; | |
48 struct LastErrors; | |
49 | |
50 // Cast device capabilities. | |
51 enum CastDeviceCapability { | |
52 NONE = 0, | |
53 VIDEO_OUT = 1 << 0, | |
54 VIDEO_IN = 1 << 1, | |
55 AUDIO_OUT = 1 << 2, | |
56 AUDIO_IN = 1 << 3, | |
57 DEV_MODE = 1 << 4 | |
58 }; | |
59 | |
60 // Public interface of the CastSocket class. | |
61 class CastSocket { | |
62 public: | |
63 using ChannelError = ::cast_channel::ChannelError; | |
64 using ChannelAuthType = ::cast_channel::ChannelAuthType; | |
65 using ReadyState = ::cast_channel::ReadyState; | |
66 | |
67 virtual ~CastSocket() {} | |
68 | |
69 // Used by BrowserContextKeyedAPIFactory. | |
70 static const char* service_name() { return "CastSocketImplManager"; } | |
71 | |
72 // Connects the channel to the peer. If successful, the channel will be in | |
73 // READY_STATE_OPEN. DO NOT delete the CastSocket object in |callback|. | |
74 // Instead use Close(). | |
75 // |callback| will be invoked with any ChannelError that occurred, or | |
76 // CHANNEL_ERROR_NONE if successful. | |
77 // If the CastSocket is destroyed while the connection is pending, |callback| | |
78 // will be invoked with CHANNEL_ERROR_UNKNOWN. In this case, invoking | |
79 // |callback| must not result in any re-entrancy behavior. | |
80 // |delegate| receives message receipt and error events. | |
81 // Ownership of |delegate| is transferred to this CastSocket. | |
82 virtual void Connect(std::unique_ptr<CastTransport::Delegate> delegate, | |
83 base::Callback<void(ChannelError)> callback) = 0; | |
84 | |
85 // Closes the channel if not already closed. On completion, the channel will | |
86 // be in READY_STATE_CLOSED. | |
87 // | |
88 // It is fine to delete this object in |callback|. | |
89 virtual void Close(const net::CompletionCallback& callback) = 0; | |
90 | |
91 // The IP endpoint for the destination of the channel. | |
92 virtual const net::IPEndPoint& ip_endpoint() const = 0; | |
93 | |
94 // Channel id generated by the CastChannelService. | |
95 virtual int id() const = 0; | |
96 | |
97 // Sets the channel id generated by CastChannelService. | |
98 virtual void set_id(int id) = 0; | |
99 | |
100 // The authentication level requested for the channel. | |
101 virtual ChannelAuthType channel_auth() const = 0; | |
102 | |
103 // The ready state of the channel. | |
104 virtual ReadyState ready_state() const = 0; | |
105 | |
106 // Returns the last error that occurred on this channel, or | |
107 // CHANNEL_ERROR_NONE if no error has occurred. | |
108 virtual ChannelError error_state() const = 0; | |
109 | |
110 // True when keep-alive signaling is handled for this socket. | |
111 virtual bool keep_alive() const = 0; | |
112 | |
113 // Whether the channel is audio only as identified by the device | |
114 // certificate during channel authentication. | |
115 virtual bool audio_only() const = 0; | |
116 | |
117 // Marks a socket as invalid due to an error, and sends an OnError | |
118 // event to |delegate_|. | |
119 // The OnError event receipient is responsible for closing the socket in the | |
120 // event of an error. | |
121 // Setting the error state does not close the socket if it is open. | |
122 virtual void SetErrorState(ChannelError error_state) = 0; | |
123 | |
124 // Returns a pointer to the socket's message transport layer. Can be used to | |
125 // send and receive CastMessages over the socket. | |
126 virtual CastTransport* transport() const = 0; | |
127 }; | |
128 | |
129 // This class implements a channel between Chrome and a Cast device using a TCP | |
130 // socket with SSL. The channel may authenticate that the receiver is a genuine | |
131 // Cast device. All CastSocketImpl objects must be used only on the IO thread. | |
132 // | |
133 // NOTE: Not called "CastChannel" to reduce confusion with the generated API | |
134 // code. | |
135 class CastSocketImpl : public CastSocket { | |
136 public: | |
137 // Creates a new CastSocket that connects to |ip_endpoint| with | |
138 // |channel_auth|. |owner_extension_id| is the id of the extension that opened | |
139 // the socket. |channel_auth| must not be CHANNEL_AUTH_NONE. | |
140 // Parameters: | |
141 // |owner_extension_id|: ID of the extension calling the API. | |
142 // |ip_endpoint|: IP address of the remote host. | |
143 // |channel_auth|: Authentication method used for connecting to a Cast | |
144 // receiver. | |
145 // |net_log|: Log of socket events. | |
146 // |connect_timeout|: Connection timeout interval. | |
147 // |logger|: Log of cast channel events. | |
148 CastSocketImpl(const std::string& owner_extension_id, | |
149 const net::IPEndPoint& ip_endpoint, | |
150 ChannelAuthType channel_auth, | |
151 net::NetLog* net_log, | |
152 const base::TimeDelta& connect_timeout, | |
153 bool keep_alive, | |
154 const scoped_refptr<Logger>& logger, | |
155 uint64_t device_capabilities); | |
156 | |
157 // For test-only. | |
158 // This constructor allows for setting a custom AuthContext. | |
159 CastSocketImpl(const std::string& owner_extension_id, | |
160 const net::IPEndPoint& ip_endpoint, | |
161 ChannelAuthType channel_auth, | |
162 net::NetLog* net_log, | |
163 const base::TimeDelta& connect_timeout, | |
164 bool keep_alive, | |
165 const scoped_refptr<Logger>& logger, | |
166 uint64_t device_capabilities, | |
167 const AuthContext& auth_context); | |
168 | |
169 // Ensures that the socket is closed. | |
170 ~CastSocketImpl() override; | |
171 | |
172 // CastSocket interface. | |
173 void Connect(std::unique_ptr<CastTransport::Delegate> delegate, | |
174 base::Callback<void(ChannelError)> callback) override; | |
175 CastTransport* transport() const override; | |
176 void Close(const net::CompletionCallback& callback) override; | |
177 const net::IPEndPoint& ip_endpoint() const override; | |
178 int id() const override; | |
179 void set_id(int channel_id) override; | |
180 ChannelAuthType channel_auth() const override; | |
181 ReadyState ready_state() const override; | |
182 ChannelError error_state() const override; | |
183 bool keep_alive() const override; | |
184 bool audio_only() const override; | |
185 | |
186 protected: | |
187 // CastTransport::Delegate methods for receiving handshake messages. | |
188 class AuthTransportDelegate : public CastTransport::Delegate { | |
189 public: | |
190 explicit AuthTransportDelegate(CastSocketImpl* socket); | |
191 | |
192 // Gets the error state of the channel. | |
193 // Returns CHANNEL_ERROR_NONE if no errors are present. | |
194 ChannelError error_state() const; | |
195 | |
196 // Gets recorded error details. | |
197 LastErrors last_errors() const; | |
198 | |
199 // CastTransport::Delegate interface. | |
200 void OnError(ChannelError error_state) override; | |
201 void OnMessage(const CastMessage& message) override; | |
202 void Start() override; | |
203 | |
204 private: | |
205 CastSocketImpl* socket_; | |
206 ChannelError error_state_; | |
207 LastErrors last_errors_; | |
208 }; | |
209 | |
210 // Replaces the internally-constructed transport object with one provided | |
211 // by the caller (e.g. a mock). | |
212 void SetTransportForTesting(std::unique_ptr<CastTransport> transport); | |
213 | |
214 // Verifies whether the socket complies with cast channel policy. | |
215 // Audio only channel policy mandates that a device declaring a video out | |
216 // capability must not have a certificate with audio only policy. | |
217 bool VerifyChannelPolicy(const AuthResult& result); | |
218 | |
219 private: | |
220 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestConnectAuthMessageCorrupted); | |
221 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, | |
222 TestConnectChallengeReplyReceiveError); | |
223 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, | |
224 TestConnectChallengeVerificationFails); | |
225 friend class AuthTransportDelegate; | |
226 friend class CastSocketTest; | |
227 friend class TestCastSocket; | |
228 | |
229 void SetErrorState(ChannelError error_state) override; | |
230 | |
231 // Frees resources and cancels pending callbacks. |ready_state_| will be set | |
232 // READY_STATE_CLOSED on completion. A no-op if |ready_state_| is already | |
233 // READY_STATE_CLOSED. | |
234 void CloseInternal(); | |
235 | |
236 // Creates an instance of TCPClientSocket. | |
237 virtual std::unique_ptr<net::TCPClientSocket> CreateTcpSocket(); | |
238 // Creates an instance of SSLClientSocket with the given underlying |socket|. | |
239 virtual std::unique_ptr<net::SSLClientSocket> CreateSslSocket( | |
240 std::unique_ptr<net::StreamSocket> socket); | |
241 // Extracts peer certificate from SSLClientSocket instance when the socket | |
242 // is in cert error state. | |
243 // Returns null if the certificate could not be extracted. | |
244 // TODO(kmarshall): Use MockSSLClientSocket for tests instead of overriding | |
245 // this function. | |
246 virtual scoped_refptr<net::X509Certificate> ExtractPeerCert(); | |
247 // Verifies whether the challenge reply received from the peer is valid: | |
248 // 1. Signature in the reply is valid. | |
249 // 2. Certificate is rooted to a trusted CA. | |
250 virtual bool VerifyChallengeReply(); | |
251 | |
252 // Invoked by a cancelable closure when connection setup time | |
253 // exceeds the interval specified at |connect_timeout|. | |
254 void OnConnectTimeout(); | |
255 | |
256 ///////////////////////////////////////////////////////////////////////////// | |
257 // Following methods work together to implement the following flow: | |
258 // 1. Create a new TCP socket and connect to it | |
259 // 2. Create a new SSL socket and try connecting to it | |
260 // 3. If connection fails due to invalid cert authority, then extract the | |
261 // peer certificate from the error. | |
262 // 4. Whitelist the peer certificate and try #1 and #2 again. | |
263 // 5. If SSL socket is connected successfully, and if protocol is casts:// | |
264 // then issue an auth challenge request. | |
265 // 6. Validate the auth challenge response. | |
266 // | |
267 // Main method that performs connection state transitions. | |
268 void DoConnectLoop(int result); | |
269 // Each of the below Do* method is executed in the corresponding | |
270 // connection state. For example when connection state is TCP_CONNECT | |
271 // DoTcpConnect is called, and so on. | |
272 int DoTcpConnect(); | |
273 int DoTcpConnectComplete(int result); | |
274 int DoSslConnect(); | |
275 int DoSslConnectComplete(int result); | |
276 int DoAuthChallengeSend(); | |
277 int DoAuthChallengeSendComplete(int result); | |
278 int DoAuthChallengeReplyComplete(int result); | |
279 ///////////////////////////////////////////////////////////////////////////// | |
280 | |
281 // Resets the cancellable callback used for async invocations of | |
282 // DoConnectLoop. | |
283 void ResetConnectLoopCallback(); | |
284 | |
285 // Posts a task to invoke |connect_loop_callback_| with |result| on the | |
286 // current message loop. | |
287 void PostTaskToStartConnectLoop(int result); | |
288 | |
289 // Runs the external connection callback and resets it. | |
290 void DoConnectCallback(); | |
291 | |
292 virtual bool CalledOnValidThread() const; | |
293 | |
294 virtual base::Timer* GetTimer(); | |
295 | |
296 void SetConnectState(proto::ConnectionState connect_state); | |
297 void SetReadyState(ReadyState ready_state); | |
298 | |
299 base::ThreadChecker thread_checker_; | |
300 | |
301 // The id of the channel. | |
302 int channel_id_; | |
303 // The IP endpoint that the the channel is connected to. | |
304 net::IPEndPoint ip_endpoint_; | |
305 // Receiver authentication requested for the channel. | |
306 ChannelAuthType channel_auth_; | |
307 // The NetLog for this service. | |
308 net::NetLog* net_log_; | |
309 // The NetLog source for this service. | |
310 net::NetLogSource net_log_source_; | |
311 // True when keep-alive signaling should be handled for this socket. | |
312 bool keep_alive_; | |
313 | |
314 // Shared logging object, used to log CastSocket events for diagnostics. | |
315 scoped_refptr<Logger> logger_; | |
316 | |
317 // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket | |
318 // since in some cases the destructor of SSLClientSocket may call a method | |
319 // to cancel a cert verification request. | |
320 std::unique_ptr<net::CertVerifier> cert_verifier_; | |
321 std::unique_ptr<net::TransportSecurityState> transport_security_state_; | |
322 std::unique_ptr<net::CTVerifier> cert_transparency_verifier_; | |
323 std::unique_ptr<net::CTPolicyEnforcer> ct_policy_enforcer_; | |
324 | |
325 // Owned ptr to the underlying TCP socket. | |
326 std::unique_ptr<net::TCPClientSocket> tcp_socket_; | |
327 | |
328 // Owned ptr to the underlying SSL socket. | |
329 std::unique_ptr<net::SSLClientSocket> socket_; | |
330 | |
331 // Certificate of the peer. This field may be empty if the peer | |
332 // certificate is not yet fetched. | |
333 scoped_refptr<net::X509Certificate> peer_cert_; | |
334 | |
335 // The challenge context for the current connection. | |
336 const AuthContext auth_context_; | |
337 | |
338 // Reply received from the receiver to a challenge request. | |
339 std::unique_ptr<CastMessage> challenge_reply_; | |
340 | |
341 // Callback invoked when the socket is connected or fails to connect. | |
342 base::Callback<void(ChannelError)> connect_callback_; | |
343 | |
344 // Callback invoked by |connect_timeout_timer_| to cancel the connection. | |
345 base::CancelableClosure connect_timeout_callback_; | |
346 | |
347 // Duration to wait before timing out. | |
348 base::TimeDelta connect_timeout_; | |
349 | |
350 // Timer invoked when the connection has timed out. | |
351 std::unique_ptr<base::Timer> connect_timeout_timer_; | |
352 | |
353 // Set when a timeout is triggered and the connection process has | |
354 // canceled. | |
355 bool is_canceled_; | |
356 | |
357 // Capabilities declared by the cast device. | |
358 uint64_t device_capabilities_; | |
359 | |
360 // Whether the channel is audio only as identified by the device | |
361 // certificate during channel authentication. | |
362 bool audio_only_; | |
363 | |
364 // Connection flow state machine state. | |
365 proto::ConnectionState connect_state_; | |
366 | |
367 // Write flow state machine state. | |
368 proto::WriteState write_state_; | |
369 | |
370 // Read flow state machine state. | |
371 proto::ReadState read_state_; | |
372 | |
373 // The last error encountered by the channel. | |
374 ChannelError error_state_; | |
375 | |
376 // The current status of the channel. | |
377 ReadyState ready_state_; | |
378 | |
379 // Callback which, when invoked, will re-enter the connection state machine. | |
380 // Oustanding callbacks will be cancelled when |this| is destroyed. | |
381 // The callback signature is based on net::CompletionCallback, which passes | |
382 // operation result codes as byte counts in the success case, or as | |
383 // net::Error enum values for error cases. | |
384 base::CancelableCallback<void(int)> connect_loop_callback_; | |
385 | |
386 // Cast message formatting and parsing layer. | |
387 std::unique_ptr<CastTransport> transport_; | |
388 | |
389 // Caller's message read and error handling delegate. | |
390 std::unique_ptr<CastTransport::Delegate> delegate_; | |
391 | |
392 // Raw pointer to the auth handshake delegate. Used to get detailed error | |
393 // information. | |
394 AuthTransportDelegate* auth_delegate_; | |
395 | |
396 DISALLOW_COPY_AND_ASSIGN(CastSocketImpl); | |
397 }; | |
398 } // namespace cast_channel | |
399 } // namespace api | |
400 } // namespace extensions | |
401 | |
402 #endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ | |
OLD | NEW |