Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Side by Side Diff: chrome/browser/extensions/api/cast_channel/cast_socket.cc

Issue 35443002: Update CastSocket connection flow to check for receiver credentials. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/extensions/api/cast_channel/cast_socket.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h" 5 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h"
6 6
7 #include <cert.h>
8 #include <cryptohi.h>
9 #include <pk11pub.h>
10 #include <seccomon.h>
7 #include <string.h> 11 #include <string.h>
8 12
9 #include "base/bind.h" 13 #include "base/bind.h"
10 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
11 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
12 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
13 #include "base/sys_byteorder.h" 17 #include "base/sys_byteorder.h"
14 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h" 18 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h"
15 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h" 19 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h"
20 #include "crypto/scoped_nss_types.h"
Ryan Sleevi 2013/10/22 20:23:22 DESIGN: Strictly speaking, while I realize extensi
Munjal (Google) 2013/10/22 23:42:43 Trying to understand this: - You are saying that I
Ryan Sleevi 2013/10/23 19:14:04 That's because the NetworkingPrivate code is/was o
Munjal (Google) 2013/10/23 20:08:56 Done.
16 #include "net/base/address_list.h" 21 #include "net/base/address_list.h"
17 #include "net/base/host_port_pair.h" 22 #include "net/base/host_port_pair.h"
18 #include "net/base/net_errors.h" 23 #include "net/base/net_errors.h"
19 #include "net/base/net_util.h" 24 #include "net/base/net_util.h"
20 #include "net/cert/cert_verifier.h" 25 #include "net/cert/cert_verifier.h"
21 #include "net/cert/x509_certificate.h" 26 #include "net/cert/x509_certificate.h"
22 #include "net/http/transport_security_state.h" 27 #include "net/http/transport_security_state.h"
23 #include "net/socket/client_socket_factory.h" 28 #include "net/socket/client_socket_factory.h"
24 #include "net/socket/client_socket_handle.h" 29 #include "net/socket/client_socket_handle.h"
25 #include "net/socket/ssl_client_socket.h" 30 #include "net/socket/ssl_client_socket.h"
(...skipping 11 matching lines...) Expand all
37 // Size of the message header, in bytes. Don't use sizeof(MessageHeader) 42 // Size of the message header, in bytes. Don't use sizeof(MessageHeader)
38 // because of alignment; instead, sum the sizeof() for the fields. 43 // because of alignment; instead, sum the sizeof() for the fields.
39 const uint32 kMessageHeaderSize = sizeof(uint32); 44 const uint32 kMessageHeaderSize = sizeof(uint32);
40 45
41 // The default keepalive delay. On Linux, keepalives probes will be sent after 46 // The default keepalive delay. On Linux, keepalives probes will be sent after
42 // the socket is idle for this length of time, and the socket will be closed 47 // the socket is idle for this length of time, and the socket will be closed
43 // after 9 failed probes. So the total idle time before close is 10 * 48 // after 9 failed probes. So the total idle time before close is 10 *
44 // kTcpKeepAliveDelaySecs. 49 // kTcpKeepAliveDelaySecs.
45 const int kTcpKeepAliveDelaySecs = 10; 50 const int kTcpKeepAliveDelaySecs = 10;
46 51
52 // Public key of the certificate with which the peer cert should be signed.
53 static const unsigned char kCAPublicKeyDER[] = {
54 0x30, 0x82, 0x03, 0x87, 0x30, 0x82, 0x02, 0x6f, 0xa0, 0x03, 0x02, 0x01,
55 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
56 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x7c, 0x31, 0x0b, 0x30,
57 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
58 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c,
59 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06,
60 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x61,
61 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x13, 0x30, 0x11, 0x06,
62 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
63 0x20, 0x49, 0x6e, 0x63, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
64 0x0b, 0x0c, 0x09, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x54, 0x56,
65 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x45,
66 0x75, 0x72, 0x65, 0x6b, 0x61, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
67 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x31, 0x32, 0x31, 0x39, 0x30,
68 0x30, 0x34, 0x37, 0x31, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x32, 0x31, 0x32,
69 0x31, 0x34, 0x30, 0x30, 0x34, 0x37, 0x31, 0x32, 0x5a, 0x30, 0x7d, 0x31,
70 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
71 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
72 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30,
73 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, 0x6e,
74 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x13, 0x30,
75 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x47, 0x6f, 0x6f, 0x67,
76 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
77 0x55, 0x04, 0x0b, 0x0c, 0x09, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20,
78 0x54, 0x56, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
79 0x0f, 0x45, 0x75, 0x72, 0x65, 0x6b, 0x61, 0x20, 0x47, 0x65, 0x6e, 0x31,
80 0x20, 0x49, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
81 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
82 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
83 0x00, 0xbc, 0x22, 0x80, 0xbd, 0x80, 0xf6, 0x3a, 0x21, 0x00, 0x3b, 0xae,
84 0x76, 0x5e, 0x35, 0x7f, 0x3d, 0xc3, 0x64, 0x5c, 0x55, 0x94, 0x86, 0x34,
85 0x2f, 0x05, 0x87, 0x28, 0xcd, 0xf7, 0x69, 0x8c, 0x17, 0xb3, 0x50, 0xa7,
86 0xb8, 0x82, 0xfa, 0xdf, 0xc7, 0x43, 0x2d, 0xd6, 0x7e, 0xab, 0xa0, 0x6f,
87 0xb7, 0x13, 0x72, 0x80, 0xa4, 0x47, 0x15, 0xc1, 0x20, 0x99, 0x50, 0xcd,
88 0xec, 0x14, 0x62, 0x09, 0x5b, 0xa4, 0x98, 0xcd, 0xd2, 0x41, 0xb6, 0x36,
89 0x4e, 0xff, 0xe8, 0x2e, 0x32, 0x30, 0x4a, 0x81, 0xa8, 0x42, 0xa3, 0x6c,
90 0x9b, 0x33, 0x6e, 0xca, 0xb2, 0xf5, 0x53, 0x66, 0xe0, 0x27, 0x53, 0x86,
91 0x1a, 0x85, 0x1e, 0xa7, 0x39, 0x3f, 0x4a, 0x77, 0x8e, 0xfb, 0x54, 0x66,
92 0x66, 0xfb, 0x58, 0x54, 0xc0, 0x5e, 0x39, 0xc7, 0xf5, 0x50, 0x06, 0x0b,
93 0xe0, 0x8a, 0xd4, 0xce, 0xe1, 0x6a, 0x55, 0x1f, 0x8b, 0x17, 0x00, 0xe6,
94 0x69, 0xa3, 0x27, 0xe6, 0x08, 0x25, 0x69, 0x3c, 0x12, 0x9d, 0x8d, 0x05,
95 0x2c, 0xd6, 0x2e, 0xa2, 0x31, 0xde, 0xb4, 0x52, 0x50, 0xd6, 0x20, 0x49,
96 0xde, 0x71, 0xa0, 0xf9, 0xad, 0x20, 0x40, 0x12, 0xf1, 0xdd, 0x25, 0xeb,
97 0xd5, 0xe6, 0xb8, 0x36, 0xf4, 0xd6, 0x8f, 0x7f, 0xca, 0x43, 0xdc, 0xd7,
98 0x10, 0x5b, 0xe6, 0x3f, 0x51, 0x8a, 0x85, 0xb3, 0xf3, 0xff, 0xf6, 0x03,
99 0x2d, 0xcb, 0x23, 0x4f, 0x9c, 0xad, 0x18, 0xe7, 0x93, 0x05, 0x8c, 0xac,
100 0x52, 0x9a, 0xf7, 0x4c, 0xe9, 0x99, 0x7a, 0xbe, 0x6e, 0x7e, 0x4d, 0x0a,
101 0xe3, 0xc6, 0x1c, 0xa9, 0x93, 0xfa, 0x3a, 0xa5, 0x91, 0x5d, 0x1c, 0xbd,
102 0x66, 0xeb, 0xcc, 0x60, 0xdc, 0x86, 0x74, 0xca, 0xcf, 0xf8, 0x92, 0x1c,
103 0x98, 0x7d, 0x57, 0xfa, 0x61, 0x47, 0x9e, 0xab, 0x80, 0xb7, 0xe4, 0x48,
104 0x80, 0x2a, 0x92, 0xc5, 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x13,
105 0x30, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30,
106 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a,
107 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
108 0x01, 0x01, 0x00, 0x8b, 0xd4, 0xa1, 0xb1, 0xcf, 0x5d, 0xcd, 0x7b, 0x6c,
109 0x48, 0x4a, 0x41, 0x1f, 0x53, 0x2f, 0x18, 0x2d, 0x32, 0x45, 0xff, 0x9e,
110 0xab, 0xd3, 0x73, 0x3e, 0x1f, 0x22, 0xd7, 0xea, 0xfa, 0x01, 0xe6, 0x73,
111 0x03, 0x0f, 0x2b, 0xc6, 0x25, 0xbb, 0xa5, 0xee, 0xc5, 0xf5, 0x45, 0xcb,
112 0x24, 0x12, 0x2a, 0xad, 0xc2, 0x5d, 0x05, 0xf4, 0x7a, 0xf5, 0xc2, 0x9b,
113 0x10, 0x16, 0x5a, 0xd1, 0x0a, 0x73, 0xc5, 0x16, 0x39, 0xa0, 0x10, 0xca,
114 0xd1, 0x68, 0x85, 0x9e, 0xfb, 0x9e, 0x26, 0x83, 0x8e, 0x58, 0xf3, 0x77,
115 0xa0, 0x4e, 0xe5, 0xdb, 0x97, 0xbe, 0x2d, 0x00, 0x5f, 0xf5, 0x94, 0xdb,
116 0xb1, 0x9d, 0x65, 0x6b, 0xfd, 0xf0, 0xd1, 0x04, 0x51, 0xdf, 0xcc, 0x92,
117 0xa6, 0x99, 0x2d, 0x71, 0xf5, 0x4d, 0xd5, 0x23, 0xfe, 0x33, 0x1c, 0xa9,
118 0xb4, 0xab, 0xc5, 0xbf, 0x1a, 0xb8, 0xd1, 0x80, 0xef, 0x89, 0xc9, 0xe2,
119 0x1f, 0x9c, 0x4c, 0x48, 0x3b, 0xa2, 0xfa, 0x02, 0x0a, 0xdc, 0x84, 0x01,
120 0x8a, 0x87, 0x02, 0xfb, 0x59, 0xee, 0xa7, 0x4c, 0x04, 0x7d, 0x74, 0x99,
121 0x87, 0x6a, 0x25, 0x44, 0xad, 0x16, 0xaa, 0xec, 0x4e, 0x35, 0x1b, 0x7c,
122 0x7b, 0x84, 0xc9, 0xb1, 0x3f, 0xe1, 0x82, 0x70, 0xe5, 0x0d, 0xe7, 0xd9,
123 0x6d, 0xfa, 0x95, 0xb6, 0xc5, 0xe4, 0x1e, 0xe8, 0x11, 0x9b, 0xd8, 0xb2,
124 0xf3, 0xa4, 0xfd, 0x13, 0xf3, 0x83, 0x4f, 0xf7, 0x07, 0x14, 0x20, 0xbb,
125 0x22, 0xa5, 0xa6, 0x8f, 0xd6, 0xb5, 0xdb, 0xa9, 0x74, 0x78, 0xe2, 0x93,
126 0x0d, 0xe5, 0x23, 0x2f, 0x05, 0x17, 0xe0, 0xb2, 0x97, 0x67, 0x34, 0x4d,
127 0x0f, 0x9c, 0x76, 0x43, 0x7b, 0xa6, 0x21, 0x4a, 0x56, 0x05, 0xf6, 0x2a,
128 0x7c, 0xf2, 0x7f, 0x12, 0x94, 0x82, 0x26, 0x29, 0x07, 0xf0, 0x0b, 0x6c,
129 0x6c, 0x79, 0x14, 0xb0, 0x74, 0xd5, 0x6c };
130
47 } // namespace 131 } // namespace
48 132
133 typedef scoped_ptr_malloc<
134 CERTCertificate,
135 crypto::NSSDestroyer<CERTCertificate, CERT_DestroyCertificate> >
136 ScopedCERTCertificate;
137
49 namespace extensions { 138 namespace extensions {
50 139
51 static base::LazyInstance< 140 static base::LazyInstance<
52 ProfileKeyedAPIFactory<ApiResourceManager<api::cast_channel::CastSocket> > > 141 ProfileKeyedAPIFactory<ApiResourceManager<api::cast_channel::CastSocket> > >
53 g_factory = LAZY_INSTANCE_INITIALIZER; 142 g_factory = LAZY_INSTANCE_INITIALIZER;
54 143
55 // static 144 // static
56 template <> 145 template <>
57 ProfileKeyedAPIFactory<ApiResourceManager<api::cast_channel::CastSocket> >* 146 ProfileKeyedAPIFactory<ApiResourceManager<api::cast_channel::CastSocket> >*
58 ApiResourceManager<api::cast_channel::CastSocket>::GetFactoryInstance() { 147 ApiResourceManager<api::cast_channel::CastSocket>::GetFactoryInstance() {
59 return &g_factory.Get(); 148 return &g_factory.Get();
60 } 149 }
61 150
62 namespace api { 151 namespace api {
63 namespace cast_channel { 152 namespace cast_channel {
64 153
65 const uint32 kMaxMessageSize = 65536; 154 const uint32 kMaxMessageSize = 65536;
66 155
67 CastSocket::CastSocket(const std::string& owner_extension_id, 156 CastSocket::CastSocket(const std::string& owner_extension_id,
68 const GURL& url, CastSocket::Delegate* delegate, 157 const GURL& url,
158 CastSocket::Delegate* delegate,
69 net::NetLog* net_log) : 159 net::NetLog* net_log) :
70 ApiResource(owner_extension_id), 160 ApiResource(owner_extension_id),
71 channel_id_(0), 161 channel_id_(0),
72 url_(url), 162 url_(url),
73 delegate_(delegate), 163 delegate_(delegate),
74 is_secure_(false), 164 is_secure_(false),
75 error_state_(CHANNEL_ERROR_NONE), 165 error_state_(CHANNEL_ERROR_NONE),
76 ready_state_(READY_STATE_NONE), 166 ready_state_(READY_STATE_NONE),
77 write_callback_pending_(false), 167 write_callback_pending_(false),
78 read_callback_pending_(false), 168 read_callback_pending_(false),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 229
140 scoped_ptr<net::ClientSocketHandle> connection(new net::ClientSocketHandle); 230 scoped_ptr<net::ClientSocketHandle> connection(new net::ClientSocketHandle);
141 connection->SetSocket(tcp_socket_.PassAs<net::StreamSocket>()); 231 connection->SetSocket(tcp_socket_.PassAs<net::StreamSocket>());
142 net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint( 232 net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint(
143 ip_endpoint_); 233 ip_endpoint_);
144 234
145 return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket( 235 return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket(
146 connection.Pass(), host_and_port, ssl_config, context); 236 connection.Pass(), host_and_port, ssl_config, context);
147 } 237 }
148 238
239 bool CastSocket::ExtractPeerCert(std::string* cert) {
240 CHECK(peer_cert_.empty());
241 net::SSLInfo ssl_info;
242 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get())
243 return false;
244 bool result = net::X509Certificate::GetDEREncoded(
245 ssl_info.cert->os_cert_handle(), cert);
246 if (result)
247 DVLOG(1) << "Successfully extracted peer certificate: " << *cert;
248 return result;
249 }
250
251 void CastSocket::SendAuthChallenge() {
252 CastMessage challenge_message;
253 CreateAuthChallengeMessage(&challenge_message);
254 SendMessageInternal(challenge_message,
255 base::Bind(&CastSocket::OnChallengeEvent, AsWeakPtr()));
Ryan Sleevi 2013/10/22 20:23:22 It's unfortunate that you have to use WeakPtr here
Munjal (Google) 2013/10/22 23:42:43 Right now, all code in this file uses WeakPtr. I w
256 }
257
149 void CastSocket::OnConnectComplete(int result) { 258 void CastSocket::OnConnectComplete(int result) {
150 int rv = DoConnectLoop(result); 259 int rv = DoConnectLoop(result);
151 if (rv != net::ERR_IO_PENDING) 260 if (rv != net::ERR_IO_PENDING)
152 DoConnectCallback(rv); 261 DoConnectCallback(rv);
153 } 262 }
154 263
264 void CastSocket::OnChallengeEvent(int result) {
265 int rv = DoConnectLoop(result);
266 if (rv != net::ERR_IO_PENDING)
267 DoConnectCallback(rv);
268 }
269
155 void CastSocket::Connect(const net::CompletionCallback& callback) { 270 void CastSocket::Connect(const net::CompletionCallback& callback) {
156 DCHECK(CalledOnValidThread()); 271 DCHECK(CalledOnValidThread());
157 int result = net::ERR_CONNECTION_FAILED; 272 int result = net::ERR_CONNECTION_FAILED;
158 DVLOG(1) << "Connect readyState = " << ready_state_; 273 DVLOG(1) << "Connect readyState = " << ready_state_;
159 if (ready_state_ != READY_STATE_NONE) { 274 if (ready_state_ != READY_STATE_NONE) {
160 callback.Run(result); 275 callback.Run(result);
161 return; 276 return;
162 } 277 }
163 if (!ParseChannelUrl(url_)) { 278 if (!ParseChannelUrl(url_)) {
164 CloseWithError(cast_channel::CHANNEL_ERROR_CONNECT_ERROR); 279 CloseWithError(cast_channel::CHANNEL_ERROR_CONNECT_ERROR);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 case CONN_STATE_TCP_CONNECT_COMPLETE: 313 case CONN_STATE_TCP_CONNECT_COMPLETE:
199 rv = DoTcpConnectComplete(rv); 314 rv = DoTcpConnectComplete(rv);
200 break; 315 break;
201 case CONN_STATE_SSL_CONNECT: 316 case CONN_STATE_SSL_CONNECT:
202 DCHECK_EQ(net::OK, rv); 317 DCHECK_EQ(net::OK, rv);
203 rv = DoSslConnect(); 318 rv = DoSslConnect();
204 break; 319 break;
205 case CONN_STATE_SSL_CONNECT_COMPLETE: 320 case CONN_STATE_SSL_CONNECT_COMPLETE:
206 rv = DoSslConnectComplete(rv); 321 rv = DoSslConnectComplete(rv);
207 break; 322 break;
323 case CONN_STATE_AUTH_CHALLENGE_SEND:
324 rv = DoAuthChallengeSend();
325 break;
326 case CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE:
327 rv = DoAuthChallengeSendComplete(rv);
328 break;
329 case CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE:
330 rv = DoAuthChallengeReplyComplete(rv);
331 break;
332
208 default: 333 default:
209 NOTREACHED() << "BUG in CastSocket state machine code"; 334 NOTREACHED() << "BUG in CastSocket state machine code";
210 break; 335 break;
211 } 336 }
212 } while (rv != net::ERR_IO_PENDING && next_state_ != CONN_STATE_NONE); 337 } while (rv != net::ERR_IO_PENDING && next_state_ != CONN_STATE_NONE);
213 // Get out of the loop either when: 338 // Get out of the loop either when:
214 // a. A network operation is pending, OR 339 // a. A network operation is pending, OR
215 // b. The Do* method called did not change state 340 // b. The Do* method called did not change state
216 341
217 return rv; 342 return rv;
(...skipping 18 matching lines...) Expand all
236 return socket_->Connect( 361 return socket_->Connect(
237 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr())); 362 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr()));
238 } 363 }
239 364
240 int CastSocket::DoSslConnectComplete(int result) { 365 int CastSocket::DoSslConnectComplete(int result) {
241 // TODO(mfoltz,munjal): Authenticate the channel if is_secure_ == true. 366 // TODO(mfoltz,munjal): Authenticate the channel if is_secure_ == true.
242 if (result == net::ERR_CERT_AUTHORITY_INVALID && 367 if (result == net::ERR_CERT_AUTHORITY_INVALID &&
243 peer_cert_.empty() && 368 peer_cert_.empty() &&
244 ExtractPeerCert(&peer_cert_)) { 369 ExtractPeerCert(&peer_cert_)) {
245 next_state_ = CONN_STATE_TCP_CONNECT; 370 next_state_ = CONN_STATE_TCP_CONNECT;
371 } else if (result == net::OK && is_secure_) {
372 next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND;
246 } 373 }
247 return result; 374 return result;
248 } 375 }
249 376
377 int CastSocket::DoAuthChallengeSend() {
378 next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE;
379 SendAuthChallenge();
380 return net::ERR_IO_PENDING;
381 }
382
383 int CastSocket::DoAuthChallengeSendComplete(int result) {
384 next_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE;
Ryan Sleevi 2013/10/22 20:23:22 Shouldn't you update this only after the error che
Munjal (Google) 2013/10/22 23:42:43 Done.
385 if (result != net::OK)
386 return result;
387
388 ReadData();
Ryan Sleevi 2013/10/22 20:23:22 BUG: This may synchronously complete (line 635), w
Munjal (Google) 2013/10/22 23:42:43 Done.
389 return net::ERR_IO_PENDING;
390 }
391
392 int CastSocket::DoAuthChallengeReplyComplete(int result) {
393 if (result != net::OK)
394 return result;
395 if (VerifyChallengeReply())
396 return net::OK;
397 else
398 return net::ERR_FAILED;
399 }
400
401 bool CastSocket::VerifyChallengeReply() {
402 CHECK(!peer_cert_.empty());
403 CHECK(challenge_reply_.get());
Ryan Sleevi 2013/10/22 20:23:22 SECURITY BUG: Seems like an attacker could induce
Munjal (Google) 2013/10/22 23:42:43 Done.
404
405 DVLOG(1) << "Challenge reply: " << MessageProtoToString(*challenge_reply_);
406
407 if (challenge_reply_->payload_type() != CastMessage_PayloadType_BINARY) {
408 LOG(ERROR) << "Wrong payload type in challenge reply";
Ryan Sleevi 2013/10/22 20:23:22 DVLOG? There's fairly extensive use of LOG() here
Munjal (Google) 2013/10/22 23:42:43 Done.
409 return false;
410 }
411 if (!challenge_reply_->has_payload_binary()) {
412 LOG(ERROR) << "Payload type is binary but payload_binary field not set";
413 return false;
414 }
415 DeviceAuthMessage auth_message;
416 if (!auth_message.ParseFromString(challenge_reply_->payload_binary())) {
417 LOG(ERROR) << "Cannot parse binary payload into DeviceAuthMessage";
418 return false;
419 }
420 DVLOG(1) << "Auth message: " << AuthMessageToString(auth_message);
421 if (auth_message.has_error()) {
422 LOG(ERROR) << "Auth message has error: " <<
423 auth_message.error().error_type();
424 return false;
425 }
426 if (!auth_message.has_response()) {
427 LOG(ERROR) << "Auth message has no response field";
428 return false;
429 }
430
431 const AuthResponse& response = auth_message.response();
432 return VerifyCredentials(response.client_auth_certificate(),
433 response.signature(),
434 peer_cert_);
435 }
436
437 bool CastSocket::VerifyCredentials(const std::string& certificate,
438 const std::string& signature,
439 const std::string& data) {
440 // Make a copy of the incoming cert string since we are going to
441 // directly use the underlying char array.
442 std::string cert_data(certificate);
443 SECItem der_cert;
444 der_cert.type = siDERCertBuffer;
445 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
446 cert_data.c_str()));
447 der_cert.len = cert_data.length();
448
449 // Parse into a certificate structure.
450 ScopedCERTCertificate cert(CERT_NewTempCertificate(
451 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE));
Ryan Sleevi 2013/10/22 20:23:22 You should make sure that crypto::EnsureNSSInit()
Munjal (Google) 2013/10/22 23:42:43 Done.
452 if (!cert.get()) {
453 LOG(ERROR) << "Failed to parse certificate.";
454 return false;
455 }
456
457 // Check that the certificate is signed by trusted CA.
458 SECItem trusted_ca_key_der_item;
459 trusted_ca_key_der_item.type = siDERCertBuffer;
460 trusted_ca_key_der_item.data = const_cast<unsigned char*>(kCAPublicKeyDER);
461 trusted_ca_key_der_item.len = sizeof(kCAPublicKeyDER);
462 crypto::ScopedSECKEYPublicKey ca_public_key(
463 SECKEY_ImportDERPublicKey(&trusted_ca_key_der_item, CKK_RSA));
464 SECStatus verified = CERT_VerifySignedDataWithPublicKey(
465 &cert->signatureWrap, ca_public_key.get(), NULL);
466 if (verified != SECSuccess) {
467 LOG(ERROR)<< "Cert not signed by trusted CA";
468 return false;
469 }
470
471 // Verify that the |signature| matches |data|.
472 crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert.get()));
473 if (!public_key.get()) {
474 LOG(ERROR) << "Unable to extract public key from certificate.";
475 return false;
476 }
477 SECItem signature_item;
478 signature_item.type = siBuffer;
479 signature_item.data = reinterpret_cast<unsigned char*>(
480 const_cast<char*>(signature.c_str()));
481 signature_item.len = static_cast<unsigned int>(signature.size());
482 verified = VFY_VerifyDataDirect(
483 reinterpret_cast<unsigned char*>(const_cast<char*>(data.c_str())),
484 data.size(),
485 public_key.get(),
486 &signature_item,
487 SEC_OID_PKCS1_RSA_ENCRYPTION,
488 SEC_OID_SHA1, NULL, NULL);
489
490 if (verified != SECSuccess) {
491 LOG(ERROR) << "Signed blobs did not match.";
492 return false;
493 }
494 return true;
495 }
496
250 void CastSocket::DoConnectCallback(int result) { 497 void CastSocket::DoConnectCallback(int result) {
251 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED; 498 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED;
252 error_state_ = (result == net::OK) ? 499 error_state_ = (result == net::OK) ?
253 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR; 500 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR;
254 base::ResetAndReturn(&connect_callback_).Run(result); 501 base::ResetAndReturn(&connect_callback_).Run(result);
255 if (result == net::OK) 502 if (result == net::OK)
256 ReadData(); 503 ReadData();
257 } 504 }
258 505
259 void CastSocket::Close(const net::CompletionCallback& callback) { 506 void CastSocket::Close(const net::CompletionCallback& callback) {
260 DCHECK(CalledOnValidThread()); 507 DCHECK(CalledOnValidThread());
261 DVLOG(1) << "Close ReadyState = " << ready_state_; 508 DVLOG(1) << "Close ReadyState = " << ready_state_;
262 tcp_socket_.reset(NULL); 509 tcp_socket_.reset(NULL);
263 socket_.reset(NULL); 510 socket_.reset(NULL);
264 cert_verifier_.reset(NULL); 511 cert_verifier_.reset(NULL);
265 transport_security_state_.reset(NULL); 512 transport_security_state_.reset(NULL);
266 ready_state_ = READY_STATE_CLOSED; 513 ready_state_ = READY_STATE_CLOSED;
267 callback.Run(net::OK); 514 callback.Run(net::OK);
268 } 515 }
269 516
270 void CastSocket::SendMessage(const MessageInfo& message, 517 void CastSocket::SendMessage(const MessageInfo& message,
271 const net::CompletionCallback& callback) { 518 const net::CompletionCallback& callback) {
272 DCHECK(CalledOnValidThread()); 519 DCHECK(CalledOnValidThread());
273 DVLOG(1) << "Send ReadyState " << ready_state_; 520 DVLOG(1) << "Send ReadyState " << ready_state_;
274 int result = net::ERR_FAILED; 521 int result = net::ERR_FAILED;
275 if (ready_state_ != READY_STATE_OPEN) { 522 if (ready_state_ != READY_STATE_OPEN) {
276 callback.Run(result); 523 callback.Run(result);
277 return; 524 return;
278 } 525 }
279 WriteRequest write_request(callback);
280 CastMessage message_proto; 526 CastMessage message_proto;
281 if (!MessageInfoToCastMessage(message, &message_proto) || 527 if (!MessageInfoToCastMessage(message, &message_proto)) {
282 !write_request.SetContent(message_proto)) {
283 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE); 528 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
284 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the 529 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the
285 // caller. 530 // caller.
286 callback.Run(net::OK); 531 callback.Run(net::OK);
287 return; 532 return;
288 } 533 }
534 SendMessageInternal(message_proto, callback);
535 }
536
537 void CastSocket::SendMessageInternal(const CastMessage& message_proto,
538 const net::CompletionCallback& callback) {
539 WriteRequest write_request(callback);
540 if (!write_request.SetContent(message_proto)) {
541 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
542 callback.Run(net::OK);
Ryan Sleevi 2013/10/22 20:23:22 BUG: You run a callback but then continue executin
Munjal (Google) 2013/10/22 23:42:43 Done.
543 }
289 write_queue_.push(write_request); 544 write_queue_.push(write_request);
290 WriteData(); 545 WriteData();
291 } 546 }
292 547
293 void CastSocket::WriteData() { 548 void CastSocket::WriteData() {
294 DCHECK(CalledOnValidThread()); 549 DCHECK(CalledOnValidThread());
295 DVLOG(1) << "WriteData q = " << write_queue_.size(); 550 DVLOG(1) << "WriteData q = " << write_queue_.size();
296 if (write_queue_.empty() || write_callback_pending_) 551 if (write_queue_.empty() || write_callback_pending_)
297 return; 552 return;
298 553
299 WriteRequest& request = write_queue_.front(); 554 WriteRequest& request = write_queue_.front();
300 if (ready_state_ != READY_STATE_OPEN) {
301 request.callback.Run(net::ERR_FAILED);
302 return;
303 }
304 555
305 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() << 556 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() <<
306 " bytes_written " << request.io_buffer->BytesConsumed(); 557 " bytes_written " << request.io_buffer->BytesConsumed();
307 558
308 write_callback_pending_ = true; 559 write_callback_pending_ = true;
309 int result = socket_->Write( 560 int result = socket_->Write(
310 request.io_buffer.get(), 561 request.io_buffer.get(),
311 request.io_buffer->BytesRemaining(), 562 request.io_buffer->BytesRemaining(),
312 base::Bind(&CastSocket::OnWriteData, AsWeakPtr())); 563 base::Bind(&CastSocket::OnWriteData, AsWeakPtr()));
313 564
314 DVLOG(1) << "WriteData result = " << result;
315
316 if (result != net::ERR_IO_PENDING) 565 if (result != net::ERR_IO_PENDING)
317 OnWriteData(result); 566 OnWriteData(result);
318 } 567 }
319 568
320 void CastSocket::OnWriteData(int result) { 569 void CastSocket::OnWriteData(int result) {
321 DCHECK(CalledOnValidThread()); 570 DCHECK(CalledOnValidThread());
322 DVLOG(1) << "OnWriteComplete result = " << result; 571 DVLOG(1) << "OnWriteComplete result = " << result;
323 DCHECK(write_callback_pending_); 572 DCHECK(write_callback_pending_);
324 DCHECK(!write_queue_.empty()); 573 DCHECK(!write_queue_.empty());
325 write_callback_pending_ = false; 574 write_callback_pending_ = false;
(...skipping 27 matching lines...) Expand all
353 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 602 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
354 return; 603 return;
355 } 604 }
356 605
357 if (!write_queue_.empty()) 606 if (!write_queue_.empty())
358 WriteData(); 607 WriteData();
359 } 608 }
360 609
361 void CastSocket::ReadData() { 610 void CastSocket::ReadData() {
362 DCHECK(CalledOnValidThread()); 611 DCHECK(CalledOnValidThread());
363 if (!socket_.get() || ready_state_ != READY_STATE_OPEN) { 612 if (!socket_.get())
364 return; 613 return;
365 }
366 DCHECK(!read_callback_pending_); 614 DCHECK(!read_callback_pending_);
367 read_callback_pending_ = true; 615 read_callback_pending_ = true;
368 // Figure out if we are reading the header or body, and the remaining bytes. 616 // Figure out if we are reading the header or body, and the remaining bytes.
369 uint32 num_bytes_to_read = 0; 617 uint32 num_bytes_to_read = 0;
370 if (header_read_buffer_->RemainingCapacity() > 0) { 618 if (header_read_buffer_->RemainingCapacity() > 0) {
371 current_read_buffer_ = header_read_buffer_; 619 current_read_buffer_ = header_read_buffer_;
372 num_bytes_to_read = header_read_buffer_->RemainingCapacity(); 620 num_bytes_to_read = header_read_buffer_->RemainingCapacity();
373 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize); 621 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize);
374 } else { 622 } else {
375 DCHECK_GT(current_message_size_, 0U); 623 DCHECK_GT(current_message_size_, 0U);
(...skipping 10 matching lines...) Expand all
386 DVLOG(1) << "ReadData result = " << result; 634 DVLOG(1) << "ReadData result = " << result;
387 if (result > 0) { 635 if (result > 0) {
388 OnReadData(result); 636 OnReadData(result);
389 } else if (result != net::ERR_IO_PENDING) { 637 } else if (result != net::ERR_IO_PENDING) {
390 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 638 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
391 } 639 }
392 } 640 }
393 641
394 void CastSocket::OnReadData(int result) { 642 void CastSocket::OnReadData(int result) {
395 DCHECK(CalledOnValidThread()); 643 DCHECK(CalledOnValidThread());
396 DVLOG(1) << "OnReadData result = " << result << 644 DVLOG(1) << "OnReadData result = " << result
397 " header offset = " << header_read_buffer_->offset() << 645 << " header offset = " << header_read_buffer_->offset()
398 " body offset = " << body_read_buffer_->offset(); 646 << " body offset = " << body_read_buffer_->offset();
399 read_callback_pending_ = false; 647 read_callback_pending_ = false;
400 if (result <= 0) { 648 if (result <= 0) {
401 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 649 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
402 return; 650 return;
403 } 651 }
404 // We read some data. Move the offset in the current buffer forward. 652 // We read some data. Move the offset in the current buffer forward.
405 DCHECK_LE(current_read_buffer_->offset() + result, 653 DCHECK_LE(current_read_buffer_->offset() + result,
406 current_read_buffer_->capacity()); 654 current_read_buffer_->capacity());
407 current_read_buffer_->set_offset(current_read_buffer_->offset() + result); 655 current_read_buffer_->set_offset(current_read_buffer_->offset() + result);
408 656
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 bool CastSocket::ParseMessageFromBody() { 700 bool CastSocket::ParseMessageFromBody() {
453 DCHECK(CalledOnValidThread()); 701 DCHECK(CalledOnValidThread());
454 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()), 702 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()),
455 current_message_size_); 703 current_message_size_);
456 CastMessage message_proto; 704 CastMessage message_proto;
457 if (!message_proto.ParseFromArray( 705 if (!message_proto.ParseFromArray(
458 body_read_buffer_->StartOfBuffer(), 706 body_read_buffer_->StartOfBuffer(),
459 current_message_size_)) 707 current_message_size_))
460 return false; 708 return false;
461 DVLOG(1) << "Parsed message " << MessageProtoToString(message_proto); 709 DVLOG(1) << "Parsed message " << MessageProtoToString(message_proto);
462 if (delegate_) { 710 // If the message is an auth message then we handle it internally.
711 if (IsAuthMessage(message_proto)) {
712 challenge_reply_.reset(new CastMessage(message_proto));
713 OnChallengeEvent(net::OK);
714 } else if (delegate_) {
463 MessageInfo message; 715 MessageInfo message;
464 if (!CastMessageToMessageInfo(message_proto, &message)) 716 if (!CastMessageToMessageInfo(message_proto, &message))
465 return false; 717 return false;
466 delegate_->OnMessage(this, message); 718 delegate_->OnMessage(this, message);
467 } 719 }
468 return true; 720 return true;
469 } 721 }
470 722
471 // static 723 // static
472 bool CastSocket::Serialize(const CastMessage& message_proto, 724 bool CastSocket::Serialize(const CastMessage& message_proto,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data), 829 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data),
578 message_data.size()); 830 message_data.size());
579 return true; 831 return true;
580 } 832 }
581 833
582 CastSocket::WriteRequest::~WriteRequest() { } 834 CastSocket::WriteRequest::~WriteRequest() { }
583 835
584 } // namespace cast_channel 836 } // namespace cast_channel
585 } // namespace api 837 } // namespace api
586 } // namespace extensions 838 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/cast_channel/cast_socket.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698