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