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// This StreamSocket implementation is to be used with servers that
6// accept connections on port 443 but don't really use SSL.  For
7// example, the Google Talk servers do this to bypass proxies.  (The
8// connection is upgraded to TLS as part of the XMPP negotiation, so
9// security is preserved.)  A "fake" SSL handshake is done immediately
10// after connection to fool proxies into thinking that this is a real
11// SSL connection.
12//
13// NOTE: This StreamSocket implementation does *not* do a real SSL
14// handshake nor does it do any encryption!
15
16#ifndef JINGLE_GLUE_FAKE_SSL_CLIENT_SOCKET_H_
17#define JINGLE_GLUE_FAKE_SSL_CLIENT_SOCKET_H_
18
19#include <cstddef>
20
21#include "base/basictypes.h"
22#include "base/compiler_specific.h"
23#include "base/memory/ref_counted.h"
24#include "base/memory/scoped_ptr.h"
25#include "base/strings/string_piece.h"
26#include "net/base/completion_callback.h"
27#include "net/base/net_errors.h"
28#include "net/socket/stream_socket.h"
29
30namespace net {
31class DrainableIOBuffer;
32class SSLInfo;
33}  // namespace net
34
35namespace jingle_glue {
36
37class FakeSSLClientSocket : public net::StreamSocket {
38 public:
39  explicit FakeSSLClientSocket(scoped_ptr<net::StreamSocket> transport_socket);
40
41  virtual ~FakeSSLClientSocket();
42
43  // Exposed for testing.
44  static base::StringPiece GetSslClientHello();
45  static base::StringPiece GetSslServerHello();
46
47  // net::StreamSocket implementation.
48  virtual int Read(net::IOBuffer* buf, int buf_len,
49                   const net::CompletionCallback& callback) OVERRIDE;
50  virtual int Write(net::IOBuffer* buf, int buf_len,
51                    const net::CompletionCallback& callback) OVERRIDE;
52  virtual int SetReceiveBufferSize(int32 size) OVERRIDE;
53  virtual int SetSendBufferSize(int32 size) OVERRIDE;
54  virtual int Connect(const net::CompletionCallback& callback) OVERRIDE;
55  virtual void Disconnect() OVERRIDE;
56  virtual bool IsConnected() const OVERRIDE;
57  virtual bool IsConnectedAndIdle() const OVERRIDE;
58  virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE;
59  virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE;
60  virtual const net::BoundNetLog& NetLog() const OVERRIDE;
61  virtual void SetSubresourceSpeculation() OVERRIDE;
62  virtual void SetOmniboxSpeculation() OVERRIDE;
63  virtual bool WasEverUsed() const OVERRIDE;
64  virtual bool UsingTCPFastOpen() const OVERRIDE;
65  virtual bool WasNpnNegotiated() const OVERRIDE;
66  virtual net::NextProto GetNegotiatedProtocol() const OVERRIDE;
67  virtual bool GetSSLInfo(net::SSLInfo* ssl_info) OVERRIDE;
68
69 private:
70  enum HandshakeState {
71    STATE_NONE,
72    STATE_CONNECT,
73    STATE_SEND_CLIENT_HELLO,
74    STATE_VERIFY_SERVER_HELLO,
75  };
76
77  int DoHandshakeLoop();
78  void RunUserConnectCallback(int status);
79  void DoHandshakeLoopWithUserConnectCallback();
80
81  int DoConnect();
82  void OnConnectDone(int status);
83  void ProcessConnectDone();
84
85  int DoSendClientHello();
86  void OnSendClientHelloDone(int status);
87  void ProcessSendClientHelloDone(size_t written);
88
89  int DoVerifyServerHello();
90  void OnVerifyServerHelloDone(int status);
91  net::Error ProcessVerifyServerHelloDone(size_t read);
92
93  scoped_ptr<net::StreamSocket> transport_socket_;
94
95  // During the handshake process, holds a value from HandshakeState.
96  // STATE_NONE otherwise.
97  HandshakeState next_handshake_state_;
98
99  // True iff we're connected and we've finished the handshake.
100  bool handshake_completed_;
101
102  // The callback passed to Connect().
103  net::CompletionCallback user_connect_callback_;
104
105  scoped_refptr<net::DrainableIOBuffer> write_buf_;
106  scoped_refptr<net::DrainableIOBuffer> read_buf_;
107};
108
109}  // namespace jingle_glue
110
111#endif  // JINGLE_GLUE_FAKE_SSL_CLIENT_SOCKET_H_
112