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 |