Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / base / ssladapter_unittest.cc
1 /*
2  *  Copyright 2014 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include <string>
12
13 #include "webrtc/base/gunit.h"
14 #include "webrtc/base/ipaddress.h"
15 #include "webrtc/base/socketstream.h"
16 #include "webrtc/base/ssladapter.h"
17 #include "webrtc/base/sslstreamadapter.h"
18 #include "webrtc/base/stream.h"
19 #include "webrtc/base/virtualsocketserver.h"
20
21 static const int kTimeout = 5000;
22
23 static rtc::AsyncSocket* CreateSocket(const rtc::SSLMode& ssl_mode) {
24   rtc::SocketAddress address(rtc::IPAddress(INADDR_ANY), 0);
25
26   rtc::AsyncSocket* socket = rtc::Thread::Current()->
27       socketserver()->CreateAsyncSocket(
28       address.family(), (ssl_mode == rtc::SSL_MODE_DTLS) ?
29       SOCK_DGRAM : SOCK_STREAM);
30   socket->Bind(address);
31
32   return socket;
33 }
34
35 static std::string GetSSLProtocolName(const rtc::SSLMode& ssl_mode) {
36   return (ssl_mode == rtc::SSL_MODE_DTLS) ? "DTLS" : "TLS";
37 }
38
39 class SSLAdapterTestDummyClient : public sigslot::has_slots<> {
40  public:
41   explicit SSLAdapterTestDummyClient(const rtc::SSLMode& ssl_mode)
42       : ssl_mode_(ssl_mode) {
43     rtc::AsyncSocket* socket = CreateSocket(ssl_mode_);
44
45     ssl_adapter_.reset(rtc::SSLAdapter::Create(socket));
46
47     // Ignore any certificate errors for the purpose of testing.
48     // Note: We do this only because we don't have a real certificate.
49     // NEVER USE THIS IN PRODUCTION CODE!
50     ssl_adapter_->set_ignore_bad_cert(true);
51
52     ssl_adapter_->SignalReadEvent.connect(this,
53         &SSLAdapterTestDummyClient::OnSSLAdapterReadEvent);
54     ssl_adapter_->SignalCloseEvent.connect(this,
55         &SSLAdapterTestDummyClient::OnSSLAdapterCloseEvent);
56   }
57
58   rtc::AsyncSocket::ConnState GetState() const {
59     return ssl_adapter_->GetState();
60   }
61
62   const std::string& GetReceivedData() const {
63     return data_;
64   }
65
66   int Connect(const std::string& hostname, const rtc::SocketAddress& address) {
67     LOG(LS_INFO) << "Starting " << GetSSLProtocolName(ssl_mode_)
68         << " handshake with " << hostname;
69
70     if (ssl_adapter_->StartSSL(hostname.c_str(), false) != 0) {
71       return -1;
72     }
73
74     LOG(LS_INFO) << "Initiating connection with " << address;
75
76     return ssl_adapter_->Connect(address);
77   }
78
79   int Close() {
80     return ssl_adapter_->Close();
81   }
82
83   int Send(const std::string& message) {
84     LOG(LS_INFO) << "Client sending '" << message << "'";
85
86     return ssl_adapter_->Send(message.data(), message.length());
87   }
88
89   void OnSSLAdapterReadEvent(rtc::AsyncSocket* socket) {
90     char buffer[4096] = "";
91
92     // Read data received from the server and store it in our internal buffer.
93     int read = socket->Recv(buffer, sizeof(buffer) - 1);
94     if (read != -1) {
95       buffer[read] = '\0';
96
97       LOG(LS_INFO) << "Client received '" << buffer << "'";
98
99       data_ += buffer;
100     }
101   }
102
103   void OnSSLAdapterCloseEvent(rtc::AsyncSocket* socket, int error) {
104     // OpenSSLAdapter signals handshake failure with a close event, but without
105     // closing the socket! Let's close the socket here. This way GetState() can
106     // return CS_CLOSED after failure.
107     if (socket->GetState() != rtc::AsyncSocket::CS_CLOSED) {
108       socket->Close();
109     }
110   }
111
112  private:
113   const rtc::SSLMode ssl_mode_;
114
115   rtc::scoped_ptr<rtc::SSLAdapter> ssl_adapter_;
116
117   std::string data_;
118 };
119
120 class SSLAdapterTestDummyServer : public sigslot::has_slots<> {
121  public:
122   explicit SSLAdapterTestDummyServer(const rtc::SSLMode& ssl_mode)
123       : ssl_mode_(ssl_mode) {
124     // Generate a key pair and a certificate for this host.
125     ssl_identity_.reset(rtc::SSLIdentity::Generate(GetHostname()));
126
127     server_socket_.reset(CreateSocket(ssl_mode_));
128
129     server_socket_->SignalReadEvent.connect(this,
130         &SSLAdapterTestDummyServer::OnServerSocketReadEvent);
131
132     server_socket_->Listen(1);
133
134     LOG(LS_INFO) << ((ssl_mode_ == rtc::SSL_MODE_DTLS) ? "UDP" : "TCP")
135         << " server listening on " << server_socket_->GetLocalAddress();
136   }
137
138   rtc::SocketAddress GetAddress() const {
139     return server_socket_->GetLocalAddress();
140   }
141
142   std::string GetHostname() const {
143     // Since we don't have a real certificate anyway, the value here doesn't
144     // really matter.
145     return "example.com";
146   }
147
148   const std::string& GetReceivedData() const {
149     return data_;
150   }
151
152   int Send(const std::string& message) {
153     if (ssl_stream_adapter_ == NULL
154         || ssl_stream_adapter_->GetState() != rtc::SS_OPEN) {
155       // No connection yet.
156       return -1;
157     }
158
159     LOG(LS_INFO) << "Server sending '" << message << "'";
160
161     size_t written;
162     int error;
163
164     rtc::StreamResult r = ssl_stream_adapter_->Write(message.data(),
165         message.length(), &written, &error);
166     if (r == rtc::SR_SUCCESS) {
167       return written;
168     } else {
169       return -1;
170     }
171   }
172
173   void OnServerSocketReadEvent(rtc::AsyncSocket* socket) {
174     if (ssl_stream_adapter_ != NULL) {
175       // Only a single connection is supported.
176       return;
177     }
178
179     rtc::SocketAddress address;
180     rtc::AsyncSocket* new_socket = socket->Accept(&address);
181     rtc::SocketStream* stream = new rtc::SocketStream(new_socket);
182
183     ssl_stream_adapter_.reset(rtc::SSLStreamAdapter::Create(stream));
184     ssl_stream_adapter_->SetServerRole();
185
186     // SSLStreamAdapter is normally used for peer-to-peer communication, but
187     // here we're testing communication between a client and a server
188     // (e.g. a WebRTC-based application and an RFC 5766 TURN server), where
189     // clients are not required to provide a certificate during handshake.
190     // Accordingly, we must disable client authentication here.
191     ssl_stream_adapter_->set_client_auth_enabled(false);
192
193     ssl_stream_adapter_->SetIdentity(ssl_identity_->GetReference());
194
195     // Set a bogus peer certificate digest.
196     unsigned char digest[20];
197     size_t digest_len = sizeof(digest);
198     ssl_stream_adapter_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
199         digest_len);
200
201     ssl_stream_adapter_->StartSSLWithPeer();
202
203     ssl_stream_adapter_->SignalEvent.connect(this,
204         &SSLAdapterTestDummyServer::OnSSLStreamAdapterEvent);
205   }
206
207   void OnSSLStreamAdapterEvent(rtc::StreamInterface* stream, int sig, int err) {
208     if (sig & rtc::SE_READ) {
209       char buffer[4096] = "";
210
211       size_t read;
212       int error;
213
214       // Read data received from the client and store it in our internal
215       // buffer.
216       rtc::StreamResult r = stream->Read(buffer,
217           sizeof(buffer) - 1, &read, &error);
218       if (r == rtc::SR_SUCCESS) {
219         buffer[read] = '\0';
220
221         LOG(LS_INFO) << "Server received '" << buffer << "'";
222
223         data_ += buffer;
224       }
225     }
226   }
227
228  private:
229   const rtc::SSLMode ssl_mode_;
230
231   rtc::scoped_ptr<rtc::AsyncSocket> server_socket_;
232   rtc::scoped_ptr<rtc::SSLStreamAdapter> ssl_stream_adapter_;
233
234   rtc::scoped_ptr<rtc::SSLIdentity> ssl_identity_;
235
236   std::string data_;
237 };
238
239 class SSLAdapterTestBase : public testing::Test,
240                            public sigslot::has_slots<> {
241  public:
242   explicit SSLAdapterTestBase(const rtc::SSLMode& ssl_mode)
243       : ssl_mode_(ssl_mode),
244         ss_scope_(new rtc::VirtualSocketServer(NULL)),
245         server_(new SSLAdapterTestDummyServer(ssl_mode_)),
246         client_(new SSLAdapterTestDummyClient(ssl_mode_)),
247         handshake_wait_(kTimeout) {
248   }
249
250   void SetHandshakeWait(int wait) {
251     handshake_wait_ = wait;
252   }
253
254   void TestHandshake(bool expect_success) {
255     int rv;
256
257     // The initial state is CS_CLOSED
258     ASSERT_EQ(rtc::AsyncSocket::CS_CLOSED, client_->GetState());
259
260     rv = client_->Connect(server_->GetHostname(), server_->GetAddress());
261     ASSERT_EQ(0, rv);
262
263     // Now the state should be CS_CONNECTING
264     ASSERT_EQ(rtc::AsyncSocket::CS_CONNECTING, client_->GetState());
265
266     if (expect_success) {
267       // If expecting success, the client should end up in the CS_CONNECTED
268       // state after handshake.
269       EXPECT_EQ_WAIT(rtc::AsyncSocket::CS_CONNECTED, client_->GetState(),
270           handshake_wait_);
271
272       LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_) << " handshake complete.";
273
274     } else {
275       // On handshake failure the client should end up in the CS_CLOSED state.
276       EXPECT_EQ_WAIT(rtc::AsyncSocket::CS_CLOSED, client_->GetState(),
277           handshake_wait_);
278
279       LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_) << " handshake failed.";
280     }
281   }
282
283   void TestTransfer(const std::string& message) {
284     int rv;
285
286     rv = client_->Send(message);
287     ASSERT_EQ(static_cast<int>(message.length()), rv);
288
289     // The server should have received the client's message.
290     EXPECT_EQ_WAIT(message, server_->GetReceivedData(), kTimeout);
291
292     rv = server_->Send(message);
293     ASSERT_EQ(static_cast<int>(message.length()), rv);
294
295     // The client should have received the server's message.
296     EXPECT_EQ_WAIT(message, client_->GetReceivedData(), kTimeout);
297
298     LOG(LS_INFO) << "Transfer complete.";
299   }
300
301  private:
302   const rtc::SSLMode ssl_mode_;
303
304   const rtc::SocketServerScope ss_scope_;
305
306   rtc::scoped_ptr<SSLAdapterTestDummyServer> server_;
307   rtc::scoped_ptr<SSLAdapterTestDummyClient> client_;
308
309   int handshake_wait_;
310 };
311
312 class SSLAdapterTestTLS : public SSLAdapterTestBase {
313  public:
314   SSLAdapterTestTLS() : SSLAdapterTestBase(rtc::SSL_MODE_TLS) {}
315 };
316
317
318 #if SSL_USE_OPENSSL
319
320 // Basic tests: TLS
321
322 // Test that handshake works
323 TEST_F(SSLAdapterTestTLS, TestTLSConnect) {
324   TestHandshake(true);
325 }
326
327 // Test transfer between client and server
328 TEST_F(SSLAdapterTestTLS, TestTLSTransfer) {
329   TestHandshake(true);
330   TestTransfer("Hello, world!");
331 }
332
333 #endif  // SSL_USE_OPENSSL
334