OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2011 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 <set> | 11 #include <set> |
12 | 12 |
13 #include "webrtc/p2p/base/dtlstransport.h" | 13 #include "webrtc/p2p/base/dtlstransport.h" |
14 #include "webrtc/p2p/base/fakesession.h" | 14 #include "webrtc/p2p/base/faketransportcontroller.h" |
15 #include "webrtc/base/common.h" | 15 #include "webrtc/base/common.h" |
16 #include "webrtc/base/dscp.h" | 16 #include "webrtc/base/dscp.h" |
17 #include "webrtc/base/gunit.h" | 17 #include "webrtc/base/gunit.h" |
18 #include "webrtc/base/helpers.h" | 18 #include "webrtc/base/helpers.h" |
19 #include "webrtc/base/scoped_ptr.h" | 19 #include "webrtc/base/scoped_ptr.h" |
20 #include "webrtc/base/ssladapter.h" | 20 #include "webrtc/base/ssladapter.h" |
21 #include "webrtc/base/sslidentity.h" | 21 #include "webrtc/base/sslidentity.h" |
22 #include "webrtc/base/sslstreamadapter.h" | 22 #include "webrtc/base/sslstreamadapter.h" |
23 #include "webrtc/base/stringutils.h" | 23 #include "webrtc/base/stringutils.h" |
24 #include "webrtc/base/thread.h" | |
25 | 24 |
26 #define MAYBE_SKIP_TEST(feature) \ | 25 #define MAYBE_SKIP_TEST(feature) \ |
27 if (!(rtc::SSLStreamAdapter::feature())) { \ | 26 if (!(rtc::SSLStreamAdapter::feature())) { \ |
28 LOG(LS_INFO) << "Feature disabled... skipping"; \ | 27 LOG(LS_INFO) << "Feature disabled... skipping"; \ |
29 return; \ | 28 return; \ |
30 } | 29 } |
31 | 30 |
32 static const char AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80"; | 31 static const char AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80"; |
33 static const char kIceUfrag1[] = "TESTICEUFRAG0001"; | 32 static const char kIceUfrag1[] = "TESTICEUFRAG0001"; |
34 static const char kIcePwd1[] = "TESTICEPWD00000000000001"; | 33 static const char kIcePwd1[] = "TESTICEPWD00000000000001"; |
35 static const size_t kPacketNumOffset = 8; | 34 static const size_t kPacketNumOffset = 8; |
36 static const size_t kPacketHeaderLen = 12; | 35 static const size_t kPacketHeaderLen = 12; |
37 | 36 |
38 static bool IsRtpLeadByte(uint8 b) { | 37 static bool IsRtpLeadByte(uint8 b) { |
39 return ((b & 0xC0) == 0x80); | 38 return ((b & 0xC0) == 0x80); |
40 } | 39 } |
41 | 40 |
42 using cricket::ConnectionRole; | 41 using cricket::ConnectionRole; |
43 | 42 |
44 enum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 }; | 43 enum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 }; |
45 | 44 |
46 class DtlsTestClient : public sigslot::has_slots<> { | 45 class DtlsTestClient : public sigslot::has_slots<> { |
47 public: | 46 public: |
48 DtlsTestClient(const std::string& name, | 47 DtlsTestClient(const std::string& name) : |
49 rtc::Thread* signaling_thread, | |
50 rtc::Thread* worker_thread) : | |
51 name_(name), | 48 name_(name), |
52 signaling_thread_(signaling_thread), | |
53 worker_thread_(worker_thread), | |
54 protocol_(cricket::ICEPROTO_GOOGLE), | 49 protocol_(cricket::ICEPROTO_GOOGLE), |
55 packet_size_(0), | 50 packet_size_(0), |
56 use_dtls_srtp_(false), | 51 use_dtls_srtp_(false), |
57 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10), | 52 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10), |
58 negotiated_dtls_(false), | 53 negotiated_dtls_(false), |
59 received_dtls_client_hello_(false), | 54 received_dtls_client_hello_(false), |
60 received_dtls_server_hello_(false) { | 55 received_dtls_server_hello_(false) { |
61 } | 56 } |
62 void SetIceProtocol(cricket::TransportProtocol proto) { | 57 void SetIceProtocol(cricket::TransportProtocol proto) { |
63 protocol_ = proto; | 58 protocol_ = proto; |
64 } | 59 } |
65 void CreateIdentity() { | 60 void CreateIdentity() { |
66 identity_.reset(rtc::SSLIdentity::Generate(name_)); | 61 identity_.reset(rtc::SSLIdentity::Generate(name_)); |
67 } | 62 } |
68 rtc::SSLIdentity* identity() { return identity_.get(); } | 63 rtc::SSLIdentity* identity() { return identity_.get(); } |
69 void SetupSrtp() { | 64 void SetupSrtp() { |
70 ASSERT(identity_.get() != NULL); | 65 ASSERT(identity_.get() != NULL); |
71 use_dtls_srtp_ = true; | 66 use_dtls_srtp_ = true; |
72 } | 67 } |
73 void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) { | 68 void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) { |
74 ASSERT(transport_.get() == NULL); | 69 ASSERT(transport_.get() == NULL); |
75 ssl_max_version_ = version; | 70 ssl_max_version_ = version; |
76 } | 71 } |
77 void SetupChannels(int count, cricket::IceRole role) { | 72 void SetupChannels(int count, cricket::IceRole role) { |
78 transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>( | 73 transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>( |
79 signaling_thread_, worker_thread_, "dtls content name", NULL, | 74 "dtls content name", NULL, identity_.get())); |
80 identity_.get())); | |
81 transport_->SetAsync(true); | 75 transport_->SetAsync(true); |
82 transport_->SetIceRole(role); | 76 transport_->SetIceRole(role); |
83 transport_->SetIceTiebreaker( | 77 transport_->SetIceTiebreaker( |
84 (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); | 78 (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); |
85 transport_->SignalWritableState.connect(this, | 79 transport_->SignalWritableState.connect(this, |
86 &DtlsTestClient::OnTransportWritableState); | 80 &DtlsTestClient::OnTransportWritableState); |
87 | 81 |
88 for (int i = 0; i < count; ++i) { | 82 for (int i = 0; i < count; ++i) { |
89 cricket::DtlsTransportChannelWrapper* channel = | 83 cricket::DtlsTransportChannelWrapper* channel = |
90 static_cast<cricket::DtlsTransportChannelWrapper*>( | 84 static_cast<cricket::DtlsTransportChannelWrapper*>( |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 } | 188 } |
195 negotiated_dtls_ = (local_identity && remote_identity); | 189 negotiated_dtls_ = (local_identity && remote_identity); |
196 } | 190 } |
197 | 191 |
198 bool Connect(DtlsTestClient* peer) { | 192 bool Connect(DtlsTestClient* peer) { |
199 transport_->ConnectChannels(); | 193 transport_->ConnectChannels(); |
200 transport_->SetDestination(peer->transport_.get()); | 194 transport_->SetDestination(peer->transport_.get()); |
201 return true; | 195 return true; |
202 } | 196 } |
203 | 197 |
204 bool writable() const { return transport_->writable(); } | 198 bool all_channels_writable() const { |
| 199 return transport_->all_channels_writable(); |
| 200 } |
205 | 201 |
206 void CheckRole(rtc::SSLRole role) { | 202 void CheckRole(rtc::SSLRole role) { |
207 if (role == rtc::SSL_CLIENT) { | 203 if (role == rtc::SSL_CLIENT) { |
208 ASSERT_FALSE(received_dtls_client_hello_); | 204 ASSERT_FALSE(received_dtls_client_hello_); |
209 ASSERT_TRUE(received_dtls_server_hello_); | 205 ASSERT_TRUE(received_dtls_server_hello_); |
210 } else { | 206 } else { |
211 ASSERT_TRUE(received_dtls_client_hello_); | 207 ASSERT_TRUE(received_dtls_client_hello_); |
212 ASSERT_FALSE(received_dtls_server_hello_); | 208 ASSERT_FALSE(received_dtls_server_hello_); |
213 } | 209 } |
214 } | 210 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); | 363 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); |
368 } else if (IsRtpLeadByte(data[0])) { | 364 } else if (IsRtpLeadByte(data[0])) { |
369 ASSERT_TRUE(VerifyPacket(data, size, NULL)); | 365 ASSERT_TRUE(VerifyPacket(data, size, NULL)); |
370 } | 366 } |
371 } | 367 } |
372 } | 368 } |
373 } | 369 } |
374 | 370 |
375 private: | 371 private: |
376 std::string name_; | 372 std::string name_; |
377 rtc::Thread* signaling_thread_; | |
378 rtc::Thread* worker_thread_; | |
379 cricket::TransportProtocol protocol_; | 373 cricket::TransportProtocol protocol_; |
380 rtc::scoped_ptr<rtc::SSLIdentity> identity_; | 374 rtc::scoped_ptr<rtc::SSLIdentity> identity_; |
381 rtc::scoped_ptr<cricket::FakeTransport> transport_; | 375 rtc::scoped_ptr<cricket::FakeTransport> transport_; |
382 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; | 376 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; |
383 size_t packet_size_; | 377 size_t packet_size_; |
384 std::set<int> received_; | 378 std::set<int> received_; |
385 bool use_dtls_srtp_; | 379 bool use_dtls_srtp_; |
386 rtc::SSLProtocolVersion ssl_max_version_; | 380 rtc::SSLProtocolVersion ssl_max_version_; |
387 bool negotiated_dtls_; | 381 bool negotiated_dtls_; |
388 bool received_dtls_client_hello_; | 382 bool received_dtls_client_hello_; |
389 bool received_dtls_server_hello_; | 383 bool received_dtls_server_hello_; |
390 }; | 384 }; |
391 | 385 |
392 | 386 |
393 class DtlsTransportChannelTest : public testing::Test { | 387 class DtlsTransportChannelTest : public testing::Test { |
394 public: | 388 public: |
395 DtlsTransportChannelTest() : | 389 DtlsTransportChannelTest() : |
396 client1_("P1", rtc::Thread::Current(), | 390 client1_("P1"), |
397 rtc::Thread::Current()), | 391 client2_("P2"), |
398 client2_("P2", rtc::Thread::Current(), | |
399 rtc::Thread::Current()), | |
400 channel_ct_(1), | 392 channel_ct_(1), |
401 use_dtls_(false), | 393 use_dtls_(false), |
402 use_dtls_srtp_(false), | 394 use_dtls_srtp_(false), |
403 ssl_expected_version_(rtc::SSL_PROTOCOL_DTLS_10) { | 395 ssl_expected_version_(rtc::SSL_PROTOCOL_DTLS_10) { |
404 } | 396 } |
405 | 397 |
406 void SetChannelCount(size_t channel_ct) { | 398 void SetChannelCount(size_t channel_ct) { |
407 channel_ct_ = static_cast<int>(channel_ct); | 399 channel_ct_ = static_cast<int>(channel_ct); |
408 } | 400 } |
409 void SetMaxProtocolVersions(rtc::SSLProtocolVersion c1, | 401 void SetMaxProtocolVersions(rtc::SSLProtocolVersion c1, |
(...skipping 26 matching lines...) Expand all Loading... |
436 } | 428 } |
437 | 429 |
438 bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) { | 430 bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) { |
439 Negotiate(client1_role, client2_role); | 431 Negotiate(client1_role, client2_role); |
440 | 432 |
441 bool rv = client1_.Connect(&client2_); | 433 bool rv = client1_.Connect(&client2_); |
442 EXPECT_TRUE(rv); | 434 EXPECT_TRUE(rv); |
443 if (!rv) | 435 if (!rv) |
444 return false; | 436 return false; |
445 | 437 |
446 EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000); | 438 EXPECT_TRUE_WAIT(client1_.all_channels_writable() && |
447 if (!client1_.writable() || !client2_.writable()) | 439 client2_.all_channels_writable(), 10000); |
| 440 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) |
448 return false; | 441 return false; |
449 | 442 |
450 // Check that we used the right roles. | 443 // Check that we used the right roles. |
451 if (use_dtls_) { | 444 if (use_dtls_) { |
452 rtc::SSLRole client1_ssl_role = | 445 rtc::SSLRole client1_ssl_role = |
453 (client1_role == cricket::CONNECTIONROLE_ACTIVE || | 446 (client1_role == cricket::CONNECTIONROLE_ACTIVE || |
454 (client2_role == cricket::CONNECTIONROLE_PASSIVE && | 447 (client2_role == cricket::CONNECTIONROLE_PASSIVE && |
455 client1_role == cricket::CONNECTIONROLE_ACTPASS)) ? | 448 client1_role == cricket::CONNECTIONROLE_ACTPASS)) ? |
456 rtc::SSL_CLIENT : rtc::SSL_SERVER; | 449 rtc::SSL_CLIENT : rtc::SSL_SERVER; |
457 | 450 |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 MAYBE_SKIP_TEST(HaveDtlsSrtp); | 830 MAYBE_SKIP_TEST(HaveDtlsSrtp); |
838 SetChannelCount(2); | 831 SetChannelCount(2); |
839 PrepareDtls(true, true); | 832 PrepareDtls(true, true); |
840 PrepareDtlsSrtp(true, true); | 833 PrepareDtlsSrtp(true, true); |
841 Negotiate(); | 834 Negotiate(); |
842 | 835 |
843 Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, | 836 Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, |
844 cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); | 837 cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); |
845 bool rv = client1_.Connect(&client2_); | 838 bool rv = client1_.Connect(&client2_); |
846 EXPECT_TRUE(rv); | 839 EXPECT_TRUE(rv); |
847 EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000); | 840 EXPECT_TRUE_WAIT(client1_.all_channels_writable() && |
| 841 client2_.all_channels_writable(), 10000); |
848 | 842 |
849 TestTransfer(0, 1000, 100, true); | 843 TestTransfer(0, 1000, 100, true); |
850 TestTransfer(1, 1000, 100, true); | 844 TestTransfer(1, 1000, 100, true); |
851 } | 845 } |
852 | 846 |
853 // Test Certificates state after negotiation but before connection. | 847 // Test Certificates state after negotiation but before connection. |
854 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { | 848 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { |
855 MAYBE_SKIP_TEST(HaveDtls); | 849 MAYBE_SKIP_TEST(HaveDtls); |
856 PrepareDtls(true, true); | 850 PrepareDtls(true, true); |
857 Negotiate(); | 851 Negotiate(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 // Each side's remote certificate is the other side's local certificate. | 889 // Each side's remote certificate is the other side's local certificate. |
896 ASSERT_TRUE( | 890 ASSERT_TRUE( |
897 client1_.transport()->GetRemoteCertificate(remote_cert1.accept())); | 891 client1_.transport()->GetRemoteCertificate(remote_cert1.accept())); |
898 ASSERT_EQ(remote_cert1->ToPEMString(), | 892 ASSERT_EQ(remote_cert1->ToPEMString(), |
899 identity2->certificate().ToPEMString()); | 893 identity2->certificate().ToPEMString()); |
900 ASSERT_TRUE( | 894 ASSERT_TRUE( |
901 client2_.transport()->GetRemoteCertificate(remote_cert2.accept())); | 895 client2_.transport()->GetRemoteCertificate(remote_cert2.accept())); |
902 ASSERT_EQ(remote_cert2->ToPEMString(), | 896 ASSERT_EQ(remote_cert2->ToPEMString(), |
903 identity1->certificate().ToPEMString()); | 897 identity1->certificate().ToPEMString()); |
904 } | 898 } |
OLD | NEW |