1 // Copyright (c) 2012 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 #include "jingle/glue/fake_ssl_client_socket.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <cstdlib>
10 #include <cstring>
11 #include <utility>
12
13 #include "base/bind.h"
14 #include "base/compiler_specific.h"
15 #include "base/logging.h"
16 #include "base/stl_util.h"
17 #include "net/base/io_buffer.h"
18 #include "net/base/net_errors.h"
19 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
20
21 namespace jingle_glue {
22
23 namespace {
24
25 // The constants below were taken from libjingle's socketadapters.cc.
26 // Basically, we do a "fake" SSL handshake to fool proxies into
27 // thinking this is a real SSL connection.
28
29 // This is a SSL v2 CLIENT_HELLO message.
30 // TODO(juberti): Should this have a session id? The response doesn't have a
31 // certificate, so the hello should have a session id.
32 static const uint8_t kSslClientHello[] = {
33 0x80, 0x46, // msg len
34 0x01, // CLIENT_HELLO
35 0x03, 0x01, // SSL 3.1
36 0x00, 0x2d, // ciphersuite len
37 0x00, 0x00, // session id len
38 0x00, 0x10, // challenge len
39 0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0, // ciphersuites
40 0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80, //
41 0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a, //
42 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, //
43 0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, //
44 0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc, // challenge
45 0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea //
46 };
47
48 // This is a TLSv1 SERVER_HELLO message.
49 static const uint8_t kSslServerHello[] = {
50 0x16, // handshake message
51 0x03, 0x01, // SSL 3.1
52 0x00, 0x4a, // message len
53 0x02, // SERVER_HELLO
54 0x00, 0x00, 0x46, // handshake len
55 0x03, 0x01, // SSL 3.1
56 0x42, 0x85, 0x45, 0xa7, 0x27, 0xa9, 0x5d, 0xa0, // server random
57 0xb3, 0xc5, 0xe7, 0x53, 0xda, 0x48, 0x2b, 0x3f, //
58 0xc6, 0x5a, 0xca, 0x89, 0xc1, 0x58, 0x52, 0xa1, //
59 0x78, 0x3c, 0x5b, 0x17, 0x46, 0x00, 0x85, 0x3f, //
60 0x20, // session id len
61 0x0e, 0xd3, 0x06, 0x72, 0x5b, 0x5b, 0x1b, 0x5f, // session id
62 0x15, 0xac, 0x13, 0xf9, 0x88, 0x53, 0x9d, 0x9b, //
63 0xe8, 0x3d, 0x7b, 0x0c, 0x30, 0x32, 0x6e, 0x38, //
64 0x4d, 0xa2, 0x75, 0x57, 0x41, 0x6c, 0x34, 0x5c, //
65 0x00, 0x04, // RSA/RC4-128/MD5
66 0x00 // null compression
67 };
68
NewDrainableIOBufferWithSize(int size)69 scoped_refptr<net::DrainableIOBuffer> NewDrainableIOBufferWithSize(int size) {
70 return base::MakeRefCounted<net::DrainableIOBuffer>(
71 base::MakeRefCounted<net::IOBuffer>(size), size);
72 }
73
74 } // namespace
75
GetSslClientHello()76 base::StringPiece FakeSSLClientSocket::GetSslClientHello() {
77 return base::StringPiece(reinterpret_cast<const char*>(kSslClientHello),
78 base::size(kSslClientHello));
79 }
80
GetSslServerHello()81 base::StringPiece FakeSSLClientSocket::GetSslServerHello() {
82 return base::StringPiece(reinterpret_cast<const char*>(kSslServerHello),
83 base::size(kSslServerHello));
84 }
85
FakeSSLClientSocket(std::unique_ptr<net::StreamSocket> transport_socket)86 FakeSSLClientSocket::FakeSSLClientSocket(
87 std::unique_ptr<net::StreamSocket> transport_socket)
88 : transport_socket_(std::move(transport_socket)),
89 next_handshake_state_(STATE_NONE),
90 handshake_completed_(false),
91 write_buf_(NewDrainableIOBufferWithSize(base::size(kSslClientHello))),
92 read_buf_(NewDrainableIOBufferWithSize(base::size(kSslServerHello))) {
93 CHECK(transport_socket_.get());
94 std::memcpy(write_buf_->data(), kSslClientHello, base::size(kSslClientHello));
95 }
96
~FakeSSLClientSocket()97 FakeSSLClientSocket::~FakeSSLClientSocket() {}
98
Read(net::IOBuffer * buf,int buf_len,net::CompletionOnceCallback callback)99 int FakeSSLClientSocket::Read(net::IOBuffer* buf,
100 int buf_len,
101 net::CompletionOnceCallback callback) {
102 DCHECK_EQ(next_handshake_state_, STATE_NONE);
103 DCHECK(handshake_completed_);
104 return transport_socket_->Read(buf, buf_len, std::move(callback));
105 }
106
ReadIfReady(net::IOBuffer * buf,int buf_len,net::CompletionOnceCallback callback)107 int FakeSSLClientSocket::ReadIfReady(net::IOBuffer* buf,
108 int buf_len,
109 net::CompletionOnceCallback callback) {
110 DCHECK_EQ(next_handshake_state_, STATE_NONE);
111 DCHECK(handshake_completed_);
112 return transport_socket_->ReadIfReady(buf, buf_len, std::move(callback));
113 }
114
CancelReadIfReady()115 int FakeSSLClientSocket::CancelReadIfReady() {
116 DCHECK_EQ(next_handshake_state_, STATE_NONE);
117 DCHECK(handshake_completed_);
118 return transport_socket_->CancelReadIfReady();
119 }
120
Write(net::IOBuffer * buf,int buf_len,net::CompletionOnceCallback callback,const net::NetworkTrafficAnnotationTag & traffic_annotation)121 int FakeSSLClientSocket::Write(
122 net::IOBuffer* buf,
123 int buf_len,
124 net::CompletionOnceCallback callback,
125 const net::NetworkTrafficAnnotationTag& traffic_annotation) {
126 DCHECK_EQ(next_handshake_state_, STATE_NONE);
127 DCHECK(handshake_completed_);
128 return transport_socket_->Write(buf, buf_len, std::move(callback),
129 traffic_annotation);
130 }
131
SetReceiveBufferSize(int32_t size)132 int FakeSSLClientSocket::SetReceiveBufferSize(int32_t size) {
133 return transport_socket_->SetReceiveBufferSize(size);
134 }
135
SetSendBufferSize(int32_t size)136 int FakeSSLClientSocket::SetSendBufferSize(int32_t size) {
137 return transport_socket_->SetSendBufferSize(size);
138 }
139
Connect(net::CompletionOnceCallback callback)140 int FakeSSLClientSocket::Connect(net::CompletionOnceCallback callback) {
141 // We don't support synchronous operation, even if
142 // |transport_socket_| does.
143 DCHECK(!callback.is_null());
144 DCHECK_EQ(next_handshake_state_, STATE_NONE);
145 DCHECK(!handshake_completed_);
146 DCHECK(user_connect_callback_.is_null());
147 DCHECK_EQ(write_buf_->BytesConsumed(), 0);
148 DCHECK_EQ(read_buf_->BytesConsumed(), 0);
149
150 next_handshake_state_ = STATE_CONNECT;
151 int status = DoHandshakeLoop();
152 if (status == net::ERR_IO_PENDING)
153 user_connect_callback_ = std::move(callback);
154
155 return status;
156 }
157
DoHandshakeLoop()158 int FakeSSLClientSocket::DoHandshakeLoop() {
159 DCHECK_NE(next_handshake_state_, STATE_NONE);
160 int status = net::OK;
161 do {
162 HandshakeState state = next_handshake_state_;
163 next_handshake_state_ = STATE_NONE;
164 switch (state) {
165 case STATE_CONNECT:
166 status = DoConnect();
167 break;
168 case STATE_SEND_CLIENT_HELLO:
169 status = DoSendClientHello();
170 break;
171 case STATE_VERIFY_SERVER_HELLO:
172 status = DoVerifyServerHello();
173 break;
174 default:
175 status = net::ERR_UNEXPECTED;
176 LOG(DFATAL) << "unexpected state: " << state;
177 break;
178 }
179 } while ((status != net::ERR_IO_PENDING) &&
180 (next_handshake_state_ != STATE_NONE));
181 return status;
182 }
183
RunUserConnectCallback(int status)184 void FakeSSLClientSocket::RunUserConnectCallback(int status) {
185 DCHECK_LE(status, net::OK);
186 next_handshake_state_ = STATE_NONE;
187 std::move(user_connect_callback_).Run(status);
188 }
189
DoHandshakeLoopWithUserConnectCallback()190 void FakeSSLClientSocket::DoHandshakeLoopWithUserConnectCallback() {
191 int status = DoHandshakeLoop();
192 if (status != net::ERR_IO_PENDING) {
193 RunUserConnectCallback(status);
194 }
195 }
196
DoConnect()197 int FakeSSLClientSocket::DoConnect() {
198 int status = transport_socket_->Connect(base::BindOnce(
199 &FakeSSLClientSocket::OnConnectDone, base::Unretained(this)));
200 if (status != net::OK) {
201 return status;
202 }
203 ProcessConnectDone();
204 return net::OK;
205 }
206
OnConnectDone(int status)207 void FakeSSLClientSocket::OnConnectDone(int status) {
208 DCHECK_NE(status, net::ERR_IO_PENDING);
209 DCHECK_LE(status, net::OK);
210 DCHECK(!user_connect_callback_.is_null());
211 if (status != net::OK) {
212 RunUserConnectCallback(status);
213 return;
214 }
215 ProcessConnectDone();
216 DoHandshakeLoopWithUserConnectCallback();
217 }
218
ProcessConnectDone()219 void FakeSSLClientSocket::ProcessConnectDone() {
220 DCHECK_EQ(write_buf_->BytesConsumed(), 0);
221 DCHECK_EQ(read_buf_->BytesConsumed(), 0);
222 next_handshake_state_ = STATE_SEND_CLIENT_HELLO;
223 }
224
DoSendClientHello()225 int FakeSSLClientSocket::DoSendClientHello() {
226 int status = transport_socket_->Write(
227 write_buf_.get(), write_buf_->BytesRemaining(),
228 base::BindOnce(&FakeSSLClientSocket::OnSendClientHelloDone,
229 base::Unretained(this)),
230 TRAFFIC_ANNOTATION_FOR_TESTS);
231 if (status < net::OK) {
232 return status;
233 }
234 ProcessSendClientHelloDone(static_cast<size_t>(status));
235 return net::OK;
236 }
237
OnSendClientHelloDone(int status)238 void FakeSSLClientSocket::OnSendClientHelloDone(int status) {
239 DCHECK_NE(status, net::ERR_IO_PENDING);
240 DCHECK(!user_connect_callback_.is_null());
241 if (status < net::OK) {
242 RunUserConnectCallback(status);
243 return;
244 }
245 ProcessSendClientHelloDone(static_cast<size_t>(status));
246 DoHandshakeLoopWithUserConnectCallback();
247 }
248
ProcessSendClientHelloDone(size_t written)249 void FakeSSLClientSocket::ProcessSendClientHelloDone(size_t written) {
250 DCHECK_LE(written, static_cast<size_t>(write_buf_->BytesRemaining()));
251 DCHECK_EQ(read_buf_->BytesConsumed(), 0);
252 if (written < static_cast<size_t>(write_buf_->BytesRemaining())) {
253 next_handshake_state_ = STATE_SEND_CLIENT_HELLO;
254 write_buf_->DidConsume(written);
255 } else {
256 next_handshake_state_ = STATE_VERIFY_SERVER_HELLO;
257 }
258 }
259
DoVerifyServerHello()260 int FakeSSLClientSocket::DoVerifyServerHello() {
261 int status = transport_socket_->Read(
262 read_buf_.get(), read_buf_->BytesRemaining(),
263 base::BindOnce(&FakeSSLClientSocket::OnVerifyServerHelloDone,
264 base::Unretained(this)));
265 if (status < net::OK) {
266 return status;
267 }
268 size_t read = static_cast<size_t>(status);
269 return ProcessVerifyServerHelloDone(read);
270 }
271
OnVerifyServerHelloDone(int status)272 void FakeSSLClientSocket::OnVerifyServerHelloDone(int status) {
273 DCHECK_NE(status, net::ERR_IO_PENDING);
274 DCHECK(!user_connect_callback_.is_null());
275 if (status < net::OK) {
276 RunUserConnectCallback(status);
277 return;
278 }
279 size_t read = static_cast<size_t>(status);
280 status = ProcessVerifyServerHelloDone(read);
281 if (status < net::OK) {
282 RunUserConnectCallback(status);
283 return;
284 }
285 if (handshake_completed_) {
286 RunUserConnectCallback(net::OK);
287 } else {
288 DoHandshakeLoopWithUserConnectCallback();
289 }
290 }
291
ProcessVerifyServerHelloDone(size_t read)292 net::Error FakeSSLClientSocket::ProcessVerifyServerHelloDone(size_t read) {
293 DCHECK_LE(read, static_cast<size_t>(read_buf_->BytesRemaining()));
294 if (read == 0U) {
295 return net::ERR_UNEXPECTED;
296 }
297 const uint8_t* expected_data_start =
298 &kSslServerHello[base::size(kSslServerHello) -
299 read_buf_->BytesRemaining()];
300 if (std::memcmp(expected_data_start, read_buf_->data(), read) != 0) {
301 return net::ERR_UNEXPECTED;
302 }
303 if (read < static_cast<size_t>(read_buf_->BytesRemaining())) {
304 next_handshake_state_ = STATE_VERIFY_SERVER_HELLO;
305 read_buf_->DidConsume(read);
306 } else {
307 next_handshake_state_ = STATE_NONE;
308 handshake_completed_ = true;
309 }
310 return net::OK;
311 }
312
Disconnect()313 void FakeSSLClientSocket::Disconnect() {
314 transport_socket_->Disconnect();
315 next_handshake_state_ = STATE_NONE;
316 handshake_completed_ = false;
317 user_connect_callback_.Reset();
318 write_buf_->SetOffset(0);
319 read_buf_->SetOffset(0);
320 }
321
IsConnected() const322 bool FakeSSLClientSocket::IsConnected() const {
323 return handshake_completed_ && transport_socket_->IsConnected();
324 }
325
IsConnectedAndIdle() const326 bool FakeSSLClientSocket::IsConnectedAndIdle() const {
327 return handshake_completed_ && transport_socket_->IsConnectedAndIdle();
328 }
329
GetPeerAddress(net::IPEndPoint * address) const330 int FakeSSLClientSocket::GetPeerAddress(net::IPEndPoint* address) const {
331 return transport_socket_->GetPeerAddress(address);
332 }
333
GetLocalAddress(net::IPEndPoint * address) const334 int FakeSSLClientSocket::GetLocalAddress(net::IPEndPoint* address) const {
335 return transport_socket_->GetLocalAddress(address);
336 }
337
NetLog() const338 const net::NetLogWithSource& FakeSSLClientSocket::NetLog() const {
339 return transport_socket_->NetLog();
340 }
341
WasEverUsed() const342 bool FakeSSLClientSocket::WasEverUsed() const {
343 return transport_socket_->WasEverUsed();
344 }
345
WasAlpnNegotiated() const346 bool FakeSSLClientSocket::WasAlpnNegotiated() const {
347 return transport_socket_->WasAlpnNegotiated();
348 }
349
GetNegotiatedProtocol() const350 net::NextProto FakeSSLClientSocket::GetNegotiatedProtocol() const {
351 return transport_socket_->GetNegotiatedProtocol();
352 }
353
GetSSLInfo(net::SSLInfo * ssl_info)354 bool FakeSSLClientSocket::GetSSLInfo(net::SSLInfo* ssl_info) {
355 return transport_socket_->GetSSLInfo(ssl_info);
356 }
357
GetConnectionAttempts(net::ConnectionAttempts * out) const358 void FakeSSLClientSocket::GetConnectionAttempts(
359 net::ConnectionAttempts* out) const {
360 out->clear();
361 }
362
GetTotalReceivedBytes() const363 int64_t FakeSSLClientSocket::GetTotalReceivedBytes() const {
364 NOTIMPLEMENTED();
365 return 0;
366 }
367
ApplySocketTag(const net::SocketTag & tag)368 void FakeSSLClientSocket::ApplySocketTag(const net::SocketTag& tag) {
369 NOTIMPLEMENTED();
370 }
371
372 } // namespace jingle_glue
373