Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <string> | 12 #include <string> |
| 13 | 13 |
| 14 #include "webrtc/base/gunit.h" | 14 #include "webrtc/base/gunit.h" |
| 15 #include "webrtc/base/ipaddress.h" | 15 #include "webrtc/base/ipaddress.h" |
| 16 #include "webrtc/base/socketstream.h" | 16 #include "webrtc/base/socketstream.h" |
| 17 #include "webrtc/base/ssladapter.h" | 17 #include "webrtc/base/ssladapter.h" |
| 18 #include "webrtc/base/sslidentity.h" | |
| 18 #include "webrtc/base/sslstreamadapter.h" | 19 #include "webrtc/base/sslstreamadapter.h" |
| 19 #include "webrtc/base/sslidentity.h" | |
| 20 #include "webrtc/base/stream.h" | 20 #include "webrtc/base/stream.h" |
| 21 #include "webrtc/base/stringencode.h" | |
| 21 #include "webrtc/base/virtualsocketserver.h" | 22 #include "webrtc/base/virtualsocketserver.h" |
| 22 | 23 |
| 23 static const int kTimeout = 5000; | 24 static const int kTimeout = 5000; |
| 24 | 25 |
| 25 static rtc::AsyncSocket* CreateSocket(const rtc::SSLMode& ssl_mode) { | 26 static rtc::AsyncSocket* CreateSocket(const rtc::SSLMode& ssl_mode) { |
| 26 rtc::SocketAddress address(rtc::IPAddress(INADDR_ANY), 0); | 27 rtc::SocketAddress address(rtc::IPAddress(INADDR_ANY), 0); |
| 27 | 28 |
| 28 rtc::AsyncSocket* socket = rtc::Thread::Current()-> | 29 rtc::AsyncSocket* socket = rtc::Thread::Current()-> |
| 29 socketserver()->CreateAsyncSocket( | 30 socketserver()->CreateAsyncSocket( |
| 30 address.family(), (ssl_mode == rtc::SSL_MODE_DTLS) ? | 31 address.family(), (ssl_mode == rtc::SSL_MODE_DTLS) ? |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 | 203 |
| 203 void OnServerSocketReadEvent(rtc::AsyncSocket* socket) { | 204 void OnServerSocketReadEvent(rtc::AsyncSocket* socket) { |
| 204 // Only a single connection is supported. | 205 // Only a single connection is supported. |
| 205 ASSERT_TRUE(ssl_stream_adapter_ == nullptr); | 206 ASSERT_TRUE(ssl_stream_adapter_ == nullptr); |
| 206 | 207 |
| 207 DoHandshake(server_socket_->Accept(nullptr)); | 208 DoHandshake(server_socket_->Accept(nullptr)); |
| 208 } | 209 } |
| 209 | 210 |
| 210 void OnSSLStreamAdapterEvent(rtc::StreamInterface* stream, int sig, int err) { | 211 void OnSSLStreamAdapterEvent(rtc::StreamInterface* stream, int sig, int err) { |
| 211 if (sig & rtc::SE_READ) { | 212 if (sig & rtc::SE_READ) { |
| 212 char buffer[4096] = ""; | 213 do { |
| 214 char buffer[4096] = ""; | |
| 215 size_t read; | |
| 216 int error; | |
| 213 | 217 |
| 214 size_t read; | 218 // Read data received from the client and store it in our internal |
|
juberti1
2017/06/02 05:35:44
This shouldn't be necessary - we should trigger a
Taylor Brandstetter
2017/06/02 06:49:14
Hmm. So is this an issue with VirtualSocketServer?
| |
| 215 int error; | 219 // buffer. Keep reading until Read returns something other than |
| 220 // SR_SUCCESS, since multiple SSL records could be received in a single | |
| 221 // TCP packet. | |
| 222 rtc::StreamResult r = | |
| 223 stream->Read(buffer, sizeof(buffer) - 1, &read, &error); | |
| 224 if (r != rtc::SR_SUCCESS) { | |
| 225 break; | |
| 226 } | |
| 216 | 227 |
| 217 // Read data received from the client and store it in our internal | |
| 218 // buffer. | |
| 219 rtc::StreamResult r = stream->Read(buffer, | |
| 220 sizeof(buffer) - 1, &read, &error); | |
| 221 if (r == rtc::SR_SUCCESS) { | |
| 222 buffer[read] = '\0'; | 228 buffer[read] = '\0'; |
| 223 | |
| 224 LOG(LS_INFO) << "Server received '" << buffer << "'"; | 229 LOG(LS_INFO) << "Server received '" << buffer << "'"; |
| 225 | |
| 226 data_ += buffer; | 230 data_ += buffer; |
| 227 } | 231 } while (true); |
| 228 } | 232 } |
| 229 } | 233 } |
| 230 | 234 |
| 231 private: | 235 private: |
| 232 void DoHandshake(rtc::AsyncSocket* socket) { | 236 void DoHandshake(rtc::AsyncSocket* socket) { |
| 233 rtc::SocketStream* stream = new rtc::SocketStream(socket); | 237 rtc::SocketStream* stream = new rtc::SocketStream(socket); |
| 234 | 238 |
| 235 ssl_stream_adapter_.reset(rtc::SSLStreamAdapter::Create(stream)); | 239 ssl_stream_adapter_.reset(rtc::SSLStreamAdapter::Create(stream)); |
| 236 | 240 |
| 237 ssl_stream_adapter_->SetMode(ssl_mode_); | 241 ssl_stream_adapter_->SetMode(ssl_mode_); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 | 333 |
| 330 rv = server_->Send(message); | 334 rv = server_->Send(message); |
| 331 ASSERT_EQ(static_cast<int>(message.length()), rv); | 335 ASSERT_EQ(static_cast<int>(message.length()), rv); |
| 332 | 336 |
| 333 // The client should have received the server's message. | 337 // The client should have received the server's message. |
| 334 EXPECT_EQ_WAIT(message, client_->GetReceivedData(), kTimeout); | 338 EXPECT_EQ_WAIT(message, client_->GetReceivedData(), kTimeout); |
| 335 | 339 |
| 336 LOG(LS_INFO) << "Transfer complete."; | 340 LOG(LS_INFO) << "Transfer complete."; |
| 337 } | 341 } |
| 338 | 342 |
| 339 private: | 343 protected: |
| 340 const rtc::SSLMode ssl_mode_; | 344 const rtc::SSLMode ssl_mode_; |
| 341 | 345 |
| 342 std::unique_ptr<rtc::VirtualSocketServer> vss_; | 346 std::unique_ptr<rtc::VirtualSocketServer> vss_; |
| 343 rtc::AutoSocketServerThread thread_; | 347 rtc::AutoSocketServerThread thread_; |
| 344 std::unique_ptr<SSLAdapterTestDummyServer> server_; | 348 std::unique_ptr<SSLAdapterTestDummyServer> server_; |
| 345 std::unique_ptr<SSLAdapterTestDummyClient> client_; | 349 std::unique_ptr<SSLAdapterTestDummyClient> client_; |
| 346 | 350 |
| 347 int handshake_wait_; | 351 int handshake_wait_; |
| 348 }; | 352 }; |
| 349 | 353 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnect) { | 386 TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnect) { |
| 383 TestHandshake(true); | 387 TestHandshake(true); |
| 384 } | 388 } |
| 385 | 389 |
| 386 // Test transfer between client and server, using RSA | 390 // Test transfer between client and server, using RSA |
| 387 TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransfer) { | 391 TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransfer) { |
| 388 TestHandshake(true); | 392 TestHandshake(true); |
| 389 TestTransfer("Hello, world!"); | 393 TestTransfer("Hello, world!"); |
| 390 } | 394 } |
| 391 | 395 |
| 396 TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferWithBlockedSocket) { | |
|
juberti1
2017/06/02 05:35:44
Put this into a TestTransferWithBlockedSocket func
Taylor Brandstetter
2017/06/02 06:49:14
I don't think that helps, since I only want to run
juberti1
2017/06/02 17:47:22
Sure, but I was thinking it would be easiest for f
| |
| 397 TestHandshake(true); | |
| 398 | |
| 399 // Tell the underlying socket to simulate being blocked. | |
| 400 vss_->SetSendingBlocked(true); | |
| 401 | |
| 402 std::string expected; | |
| 403 int rv; | |
| 404 // Send messages until the SSL socket adapter starts applying backpressure. | |
| 405 // Note that this may not occur immediately since there may be some amount of | |
| 406 // intermediate buffering (either in our code or in BoringSSL). | |
| 407 for (int i = 0; i < 1024; ++i) { | |
| 408 std::string message = "Hello, world: " + rtc::ToString(i); | |
| 409 rv = client_->Send(message); | |
| 410 if (rv != static_cast<int>(message.size())) { | |
| 411 // This test assumes either the whole message or none of it is sent. | |
| 412 ASSERT_EQ(-1, rv); | |
| 413 break; | |
| 414 } | |
| 415 expected += message; | |
| 416 } | |
| 417 // Assert that the loop above exited due to Send returning -1. | |
| 418 ASSERT_EQ(-1, rv); | |
|
pthatcher1
2017/06/02 04:58:22
Should we verify that sending the same thing while
Taylor Brandstetter
2017/06/02 06:49:14
Done.
pthatcher1
2017/06/02 13:24:24
I meant doing something like
EXPECT_EQ(-1, clie
Taylor Brandstetter
2017/06/02 17:10:53
This already tests that the last message (for whic
| |
| 419 | |
| 420 // Unblock the underlying socket. All of the buffered messages should be sent | |
| 421 // without any further action. | |
| 422 vss_->SetSendingBlocked(false); | |
| 423 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout); | |
| 424 | |
| 425 // Send another message. This previously wasn't working | |
| 426 std::string final_message = "Fin."; | |
| 427 expected += final_message; | |
| 428 EXPECT_EQ(static_cast<int>(final_message.size()), | |
| 429 client_->Send(final_message)); | |
| 430 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout); | |
| 431 } | |
| 432 | |
| 392 // Test transfer between client and server, using ECDSA | 433 // Test transfer between client and server, using ECDSA |
| 393 TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransfer) { | 434 TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransfer) { |
| 394 TestHandshake(true); | 435 TestHandshake(true); |
| 395 TestTransfer("Hello, world!"); | 436 TestTransfer("Hello, world!"); |
| 396 } | 437 } |
| 397 | 438 |
| 398 // Basic tests: DTLS | 439 // Basic tests: DTLS |
| 399 | 440 |
| 400 // Test that handshake works, using RSA | 441 // Test that handshake works, using RSA |
| 401 TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnect) { | 442 TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnect) { |
| 402 TestHandshake(true); | 443 TestHandshake(true); |
| 403 } | 444 } |
| 404 | 445 |
| 405 // Test that handshake works, using ECDSA | 446 // Test that handshake works, using ECDSA |
| 406 TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnect) { | 447 TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnect) { |
| 407 TestHandshake(true); | 448 TestHandshake(true); |
| 408 } | 449 } |
| 409 | 450 |
| 410 // Test transfer between client and server, using RSA | 451 // Test transfer between client and server, using RSA |
| 411 TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransfer) { | 452 TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransfer) { |
| 412 TestHandshake(true); | 453 TestHandshake(true); |
| 413 TestTransfer("Hello, world!"); | 454 TestTransfer("Hello, world!"); |
| 414 } | 455 } |
| 415 | 456 |
| 416 // Test transfer between client and server, using ECDSA | 457 // Test transfer between client and server, using ECDSA |
| 417 TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransfer) { | 458 TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransfer) { |
| 418 TestHandshake(true); | 459 TestHandshake(true); |
| 419 TestTransfer("Hello, world!"); | 460 TestTransfer("Hello, world!"); |
| 420 } | 461 } |
| OLD | NEW |