1 // Copyright 2013 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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
11 #include "base/basictypes.h"
12 #include "base/callback.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/threading/thread_checker.h"
17 #include "chrome/common/extensions/api/cast_channel.h"
18 #include "extensions/browser/api/api_resource.h"
19 #include "extensions/browser/api/api_resource_manager.h"
20 #include "net/base/completion_callback.h"
21 #include "net/base/io_buffer.h"
22 #include "net/base/ip_endpoint.h"
23 #include "net/base/net_log.h"
28 class SSLClientSocket;
30 class TCPClientSocket;
31 class TransportSecurityState;
34 namespace extensions {
36 namespace cast_channel {
40 // This class implements a channel between Chrome and a Cast device using a TCP
41 // socket with SSL. The channel may authenticate that the receiver is a genuine
42 // Cast device. All CastSocket objects must be used only on the IO thread.
44 // NOTE: Not called "CastChannel" to reduce confusion with the generated API
46 class CastSocket : public ApiResource,
47 public base::SupportsWeakPtr<CastSocket> {
49 // Object to be informed of incoming messages and errors.
52 // An error occurred on the channel.
53 // It is fine to delete the socket in this callback.
54 virtual void OnError(const CastSocket* socket, ChannelError error) = 0;
55 // A message was received on the channel.
56 // Do NOT delete the socket in this callback.
57 virtual void OnMessage(const CastSocket* socket,
58 const MessageInfo& message) = 0;
61 virtual ~Delegate() {}
64 // Creates a new CastSocket that connects to |ip_endpoint| with
65 // |channel_auth|. |owner_extension_id| is the id of the extension that opened
66 // the socket. |channel_auth| must not be CHANNEL_AUTH_NONE.
67 CastSocket(const std::string& owner_extension_id,
68 const net::IPEndPoint& ip_endpoint,
69 ChannelAuthType channel_auth,
70 CastSocket::Delegate* delegate,
71 net::NetLog* net_log);
72 virtual ~CastSocket();
74 // The IP endpoint for the destination of the channel.
75 const net::IPEndPoint& ip_endpoint() const { return ip_endpoint_; }
77 // The authentication level requested for the channel.
78 ChannelAuthType channel_auth() const { return channel_auth_; }
80 // Returns a cast:// or casts:// URL for the channel endpoint.
81 // For backwards compatibility.
82 std::string CastUrl() const;
84 // Channel id for the ApiResourceManager.
85 int id() const { return channel_id_; }
87 // Sets the channel id.
88 void set_id(int channel_id) { channel_id_ = channel_id; }
90 // Returns the state of the channel. Virtual for testing.
91 virtual ReadyState ready_state() const;
93 // Returns the last error that occurred on this channel, or
94 // CHANNEL_ERROR_NONE if no error has occurred. Virtual for testing.
95 virtual ChannelError error_state() const;
97 // Connects the channel to the peer. If successful, the channel will be in
99 // It is fine to delete the CastSocket object in |callback|.
100 virtual void Connect(const net::CompletionCallback& callback);
102 // Sends a message over a connected channel. The channel must be in
105 // Note that if an error occurs the following happens:
106 // 1. Completion callbacks for all pending writes are invoked with error.
107 // 2. Delegate::OnError is called once.
108 // 3. Castsocket is closed.
110 // DO NOT delete the CastSocket object in write completion callback.
111 // But it is fine to delete the socket in Delegate::OnError
112 virtual void SendMessage(const MessageInfo& message,
113 const net::CompletionCallback& callback);
115 // Closes the channel. On completion, the channel will be in
116 // READY_STATE_CLOSED.
117 // It is fine to delete the CastSocket object in |callback|.
118 virtual void Close(const net::CompletionCallback& callback);
121 // Message header struct. If fields are added, be sure to update
122 // header_size(). Protected to allow use of *_size() methods in unit tests.
123 struct MessageHeader {
125 // Sets the message size.
126 void SetMessageSize(size_t message_size);
127 // Prepends this header to |str|.
128 void PrependToString(std::string* str);
129 // Reads |header| from the beginning of |buffer|.
130 static void ReadFromIOBuffer(net::GrowableIOBuffer* buffer,
131 MessageHeader* header);
132 // Size (in bytes) of the message header.
133 static uint32 header_size() { return sizeof(uint32); }
135 // Maximum size (in bytes) of a message payload on the wire (does not
137 static uint32 max_message_size() { return 65536; }
139 std::string ToString();
140 // The size of the following protocol message in bytes, in host byte order.
145 friend class ApiResourceManager<CastSocket>;
146 friend class CastSocketTest;
148 static const char* service_name() { return "CastSocketManager"; }
150 // Internal connection states.
151 enum ConnectionState {
153 CONN_STATE_TCP_CONNECT,
154 CONN_STATE_TCP_CONNECT_COMPLETE,
155 CONN_STATE_SSL_CONNECT,
156 CONN_STATE_SSL_CONNECT_COMPLETE,
157 CONN_STATE_AUTH_CHALLENGE_SEND,
158 CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE,
159 CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE,
162 // Internal write states.
166 WRITE_STATE_WRITE_COMPLETE,
167 WRITE_STATE_DO_CALLBACK,
171 // Internal read states.
175 READ_STATE_READ_COMPLETE,
176 READ_STATE_DO_CALLBACK,
180 // Creates an instance of TCPClientSocket.
181 virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket();
182 // Creates an instance of SSLClientSocket with the given underlying |socket|.
183 virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket(
184 scoped_ptr<net::StreamSocket> socket);
185 // Extracts peer certificate from SSLClientSocket instance when the socket
186 // is in cert error state.
187 // Returns whether certificate is successfully extracted.
188 virtual bool ExtractPeerCert(std::string* cert);
189 // Verifies whether the challenge reply received from the peer is valid:
190 // 1. Signature in the reply is valid.
191 // 2. Certificate is rooted to a trusted CA.
192 virtual bool VerifyChallengeReply();
194 /////////////////////////////////////////////////////////////////////////////
195 // Following methods work together to implement the following flow:
196 // 1. Create a new TCP socket and connect to it
197 // 2. Create a new SSL socket and try connecting to it
198 // 3. If connection fails due to invalid cert authority, then extract the
199 // peer certificate from the error.
200 // 4. Whitelist the peer certificate and try #1 and #2 again.
201 // 5. If SSL socket is connected successfully, and if protocol is casts://
202 // then issue an auth challenge request.
203 // 6. Validate the auth challenge response.
205 // Main method that performs connection state transitions.
206 void DoConnectLoop(int result);
207 // Each of the below Do* method is executed in the corresponding
208 // connection state. For example when connection state is TCP_CONNECT
209 // DoTcpConnect is called, and so on.
211 int DoTcpConnectComplete(int result);
213 int DoSslConnectComplete(int result);
214 int DoAuthChallengeSend();
215 int DoAuthChallengeSendComplete(int result);
216 int DoAuthChallengeReplyComplete(int result);
217 /////////////////////////////////////////////////////////////////////////////
219 /////////////////////////////////////////////////////////////////////////////
220 // Following methods work together to implement write flow.
222 // Main method that performs write flow state transitions.
223 void DoWriteLoop(int result);
224 // Each of the below Do* method is executed in the corresponding
225 // write state. For example when write state is WRITE_STATE_WRITE_COMPLETE
226 // DowriteComplete is called, and so on.
228 int DoWriteComplete(int result);
229 int DoWriteCallback();
230 int DoWriteError(int result);
231 /////////////////////////////////////////////////////////////////////////////
233 /////////////////////////////////////////////////////////////////////////////
234 // Following methods work together to implement read flow.
236 // Main method that performs write flow state transitions.
237 void DoReadLoop(int result);
238 // Each of the below Do* method is executed in the corresponding
239 // write state. For example when write state is READ_STATE_READ_COMPLETE
240 // DoReadComplete is called, and so on.
242 int DoReadComplete(int result);
243 int DoReadCallback();
244 int DoReadError(int result);
245 /////////////////////////////////////////////////////////////////////////////
247 // Runs the external connection callback and resets it.
248 void DoConnectCallback(int result);
249 // Adds |message| to the write queue and starts the write loop if needed.
250 void SendCastMessageInternal(const CastMessage& message,
251 const net::CompletionCallback& callback);
252 void PostTaskToStartConnectLoop(int result);
253 void PostTaskToStartReadLoop();
254 void StartReadLoop();
255 // Parses the contents of header_read_buffer_ and sets current_message_size_
256 // to the size of the body of the message.
257 bool ProcessHeader();
258 // Parses the contents of body_read_buffer_ and sets current_message_ to
259 // the message received.
261 // Closes socket, updating the error state and signaling the delegate that
262 // |error| has occurred.
263 void CloseWithError(ChannelError error);
264 // Serializes the content of message_proto (with a header) to |message_data|.
265 static bool Serialize(const CastMessage& message_proto,
266 std::string* message_data);
268 virtual bool CalledOnValidThread() const;
270 base::ThreadChecker thread_checker_;
272 // The id of the channel.
275 // The IP endpoint that the the channel is connected to.
276 net::IPEndPoint ip_endpoint_;
277 // Receiver authentication requested for the channel.
278 ChannelAuthType channel_auth_;
279 // Delegate to inform of incoming messages and errors.
282 // IOBuffer for reading the message header.
283 scoped_refptr<net::GrowableIOBuffer> header_read_buffer_;
284 // IOBuffer for reading the message body.
285 scoped_refptr<net::GrowableIOBuffer> body_read_buffer_;
286 // IOBuffer to currently read into.
287 scoped_refptr<net::GrowableIOBuffer> current_read_buffer_;
288 // The number of bytes in the current message body.
289 uint32 current_message_size_;
290 // Last message received on the socket.
291 scoped_ptr<CastMessage> current_message_;
293 // The NetLog for this service.
294 net::NetLog* net_log_;
295 // The NetLog source for this service.
296 net::NetLog::Source net_log_source_;
298 // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket
299 // since in some cases the destructor of SSLClientSocket may call a method
300 // to cancel a cert verification request.
301 scoped_ptr<net::CertVerifier> cert_verifier_;
302 scoped_ptr<net::TransportSecurityState> transport_security_state_;
304 // Owned ptr to the underlying TCP socket.
305 scoped_ptr<net::TCPClientSocket> tcp_socket_;
306 // Owned ptr to the underlying SSL socket.
307 scoped_ptr<net::SSLClientSocket> socket_;
308 // Certificate of the peer. This field may be empty if the peer
309 // certificate is not yet fetched.
310 std::string peer_cert_;
311 // Reply received from the receiver to a challenge request.
312 scoped_ptr<CastMessage> challenge_reply_;
314 // Callback invoked when the socket is connected.
315 net::CompletionCallback connect_callback_;
317 // Connection flow state machine state.
318 ConnectionState connect_state_;
319 // Write flow state machine state.
320 WriteState write_state_;
321 // Read flow state machine state.
322 ReadState read_state_;
323 // The last error encountered by the channel.
324 ChannelError error_state_;
325 // The current status of the channel.
326 ReadyState ready_state_;
328 // Holds a message to be written to the socket. |callback| is invoked when the
329 // message is fully written or an error occurrs.
330 struct WriteRequest {
331 explicit WriteRequest(const net::CompletionCallback& callback);
333 // Sets the content of the request by serializing |message| into |io_buffer|
334 // and prepending the header. Must only be called once.
335 bool SetContent(const CastMessage& message_proto);
337 net::CompletionCallback callback;
338 scoped_refptr<net::DrainableIOBuffer> io_buffer;
340 // Queue of pending writes. The message at the front of the queue is the one
342 std::queue<WriteRequest> write_queue_;
344 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestFullSecureConnectionFlowAsync);
345 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestRead);
346 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadHeaderParseError);
347 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadMany);
348 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestWriteErrorLargeMessage);
349 DISALLOW_COPY_AND_ASSIGN(CastSocket);
352 } // namespace cast_channel
354 } // namespace extensions
356 #endif // CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_