OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2011 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 <memory> | |
12 | |
13 #include "webrtc/base/fakesslidentity.h" | |
14 #include "webrtc/base/gunit.h" | |
15 #include "webrtc/base/network.h" | |
16 #include "webrtc/p2p/base/faketransportcontroller.h" | |
17 | |
18 using cricket::JsepTransport; | |
19 using cricket::TransportChannel; | |
20 using cricket::FakeTransportChannel; | |
21 using cricket::IceRole; | |
22 using cricket::TransportDescription; | |
23 using rtc::SocketAddress; | |
24 | |
25 static const char kIceUfrag1[] = "TESTICEUFRAG0001"; | |
26 static const char kIcePwd1[] = "TESTICEPWD00000000000001"; | |
27 | |
28 static const char kIceUfrag2[] = "TESTICEUFRAG0002"; | |
29 static const char kIcePwd2[] = "TESTICEPWD00000000000002"; | |
30 | |
31 class JsepTransportTest : public testing::Test, public sigslot::has_slots<> { | |
32 public: | |
33 JsepTransportTest() | |
34 : transport_(new JsepTransport("test content name", nullptr)) {} | |
35 bool SetupChannel() { | |
36 fake_ice_channel_.reset(new FakeTransportChannel(transport_->mid(), 1)); | |
37 fake_dtls_channel_.reset(new FakeTransportChannel(transport_->mid(), 1)); | |
38 return transport_->AddChannel(fake_dtls_channel_.get(), 1); | |
39 } | |
40 void DestroyChannel() { transport_->RemoveChannel(1); } | |
41 | |
42 protected: | |
43 std::unique_ptr<FakeTransportChannel> fake_dtls_channel_; | |
44 std::unique_ptr<FakeTransportChannel> fake_ice_channel_; | |
45 std::unique_ptr<JsepTransport> transport_; | |
46 }; | |
47 | |
48 // This test verifies channels are created with proper ICE | |
49 // ufrag/password after a transport description is applied. | |
50 TEST_F(JsepTransportTest, TestChannelIceParameters) { | |
51 cricket::TransportDescription local_desc(kIceUfrag1, kIcePwd1); | |
52 ASSERT_TRUE(transport_->SetLocalTransportDescription( | |
53 local_desc, cricket::CA_OFFER, NULL)); | |
54 EXPECT_TRUE(SetupChannel()); | |
55 EXPECT_EQ(cricket::ICEMODE_FULL, fake_dtls_channel_->remote_ice_mode()); | |
56 EXPECT_EQ(kIceUfrag1, fake_dtls_channel_->ice_ufrag()); | |
57 EXPECT_EQ(kIcePwd1, fake_dtls_channel_->ice_pwd()); | |
58 | |
59 cricket::TransportDescription remote_desc(kIceUfrag1, kIcePwd1); | |
60 ASSERT_TRUE(transport_->SetRemoteTransportDescription( | |
61 remote_desc, cricket::CA_ANSWER, NULL)); | |
62 EXPECT_EQ(cricket::ICEMODE_FULL, fake_dtls_channel_->remote_ice_mode()); | |
63 EXPECT_EQ(kIceUfrag1, fake_dtls_channel_->remote_ice_ufrag()); | |
64 EXPECT_EQ(kIcePwd1, fake_dtls_channel_->remote_ice_pwd()); | |
65 } | |
66 | |
67 // Verifies that IceCredentialsChanged returns true when either ufrag or pwd | |
68 // changed, and false in other cases. | |
69 TEST_F(JsepTransportTest, TestIceCredentialsChanged) { | |
70 EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u2", "p2")); | |
71 EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u2", "p1")); | |
72 EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u1", "p2")); | |
73 EXPECT_FALSE(cricket::IceCredentialsChanged("u1", "p1", "u1", "p1")); | |
74 } | |
75 | |
76 TEST_F(JsepTransportTest, TestGetStats) { | |
77 EXPECT_TRUE(SetupChannel()); | |
78 cricket::TransportStats stats; | |
79 EXPECT_TRUE(transport_->GetStats(&stats)); | |
80 // Note that this tests the behavior of a FakeTransportChannel. | |
81 ASSERT_EQ(1U, stats.channel_stats.size()); | |
82 EXPECT_EQ(1, stats.channel_stats[0].component); | |
83 // Set local transport description for FakeTransport before connecting. | |
84 TransportDescription faketransport_desc( | |
85 std::vector<std::string>(), | |
86 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), | |
87 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), cricket::ICEMODE_FULL, | |
88 cricket::CONNECTIONROLE_NONE, nullptr); | |
89 transport_->SetLocalTransportDescription(faketransport_desc, | |
90 cricket::CA_OFFER, nullptr); | |
91 EXPECT_TRUE(transport_->GetStats(&stats)); | |
92 ASSERT_EQ(1U, stats.channel_stats.size()); | |
93 EXPECT_EQ(1, stats.channel_stats[0].component); | |
94 } | |
95 | |
96 // Tests that VerifyCertificateFingerprint only returns true when the | |
97 // certificate matches the fingerprint. | |
98 TEST_F(JsepTransportTest, TestVerifyCertificateFingerprint) { | |
99 std::string error_desc; | |
100 EXPECT_FALSE( | |
101 transport_->VerifyCertificateFingerprint(nullptr, nullptr, &error_desc)); | |
102 rtc::KeyType key_types[] = {rtc::KT_RSA, rtc::KT_ECDSA}; | |
103 | |
104 for (auto& key_type : key_types) { | |
105 rtc::scoped_refptr<rtc::RTCCertificate> certificate = | |
106 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>( | |
107 rtc::SSLIdentity::Generate("testing", key_type))); | |
108 ASSERT_NE(nullptr, certificate); | |
109 | |
110 std::string digest_algorithm; | |
111 ASSERT_TRUE(certificate->ssl_certificate().GetSignatureDigestAlgorithm( | |
112 &digest_algorithm)); | |
113 ASSERT_FALSE(digest_algorithm.empty()); | |
114 std::unique_ptr<rtc::SSLFingerprint> good_fingerprint( | |
115 rtc::SSLFingerprint::Create(digest_algorithm, certificate->identity())); | |
116 ASSERT_NE(nullptr, good_fingerprint); | |
117 | |
118 EXPECT_TRUE(transport_->VerifyCertificateFingerprint( | |
119 certificate.get(), good_fingerprint.get(), &error_desc)); | |
120 EXPECT_FALSE(transport_->VerifyCertificateFingerprint( | |
121 certificate.get(), nullptr, &error_desc)); | |
122 EXPECT_FALSE(transport_->VerifyCertificateFingerprint( | |
123 nullptr, good_fingerprint.get(), &error_desc)); | |
124 | |
125 rtc::SSLFingerprint bad_fingerprint = *good_fingerprint; | |
126 bad_fingerprint.digest.AppendData("0", 1); | |
127 EXPECT_FALSE(transport_->VerifyCertificateFingerprint( | |
128 certificate.get(), &bad_fingerprint, &error_desc)); | |
129 } | |
130 } | |
131 | |
132 // Tests that NegotiateRole sets the SSL role correctly. | |
133 TEST_F(JsepTransportTest, TestNegotiateRole) { | |
134 TransportDescription local_desc(kIceUfrag1, kIcePwd1); | |
135 TransportDescription remote_desc(kIceUfrag2, kIcePwd2); | |
136 | |
137 struct NegotiateRoleParams { | |
138 cricket::ConnectionRole local_role; | |
139 cricket::ConnectionRole remote_role; | |
140 cricket::ContentAction local_action; | |
141 cricket::ContentAction remote_action; | |
142 }; | |
143 | |
144 rtc::SSLRole ssl_role; | |
145 std::string error_desc; | |
146 | |
147 // Parameters which set the SSL role to SSL_CLIENT. | |
148 NegotiateRoleParams valid_client_params[] = { | |
149 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_ACTPASS, | |
150 cricket::CA_ANSWER, cricket::CA_OFFER}, | |
151 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_ACTPASS, | |
152 cricket::CA_PRANSWER, cricket::CA_OFFER}, | |
153 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_PASSIVE, | |
154 cricket::CA_OFFER, cricket::CA_ANSWER}, | |
155 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_PASSIVE, | |
156 cricket::CA_OFFER, cricket::CA_PRANSWER}}; | |
157 | |
158 for (auto& param : valid_client_params) { | |
159 local_desc.connection_role = param.local_role; | |
160 remote_desc.connection_role = param.remote_role; | |
161 | |
162 ASSERT_TRUE(transport_->SetRemoteTransportDescription( | |
163 remote_desc, param.remote_action, nullptr)); | |
164 ASSERT_TRUE(transport_->SetLocalTransportDescription( | |
165 local_desc, param.local_action, nullptr)); | |
166 EXPECT_TRUE( | |
167 transport_->NegotiateRole(param.local_action, &ssl_role, &error_desc)); | |
168 EXPECT_EQ(rtc::SSL_CLIENT, ssl_role); | |
169 } | |
170 | |
171 // Parameters which set the SSL role to SSL_SERVER. | |
172 NegotiateRoleParams valid_server_params[] = { | |
173 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_ACTPASS, | |
174 cricket::CA_ANSWER, cricket::CA_OFFER}, | |
175 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_ACTPASS, | |
176 cricket::CA_PRANSWER, cricket::CA_OFFER}, | |
177 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE, | |
178 cricket::CA_OFFER, cricket::CA_ANSWER}, | |
179 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE, | |
180 cricket::CA_OFFER, cricket::CA_PRANSWER}}; | |
181 | |
182 for (auto& param : valid_server_params) { | |
183 local_desc.connection_role = param.local_role; | |
184 remote_desc.connection_role = param.remote_role; | |
185 | |
186 ASSERT_TRUE(transport_->SetRemoteTransportDescription( | |
187 remote_desc, param.remote_action, nullptr)); | |
188 ASSERT_TRUE(transport_->SetLocalTransportDescription( | |
189 local_desc, param.local_action, nullptr)); | |
190 EXPECT_TRUE( | |
191 transport_->NegotiateRole(param.local_action, &ssl_role, &error_desc)); | |
192 EXPECT_EQ(rtc::SSL_SERVER, ssl_role); | |
193 } | |
194 | |
195 // Invalid parameters due to both peers having a duplicate role. | |
196 NegotiateRoleParams duplicate_params[] = { | |
197 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_ACTIVE, | |
198 cricket::CA_ANSWER, cricket::CA_OFFER}, | |
199 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTPASS, | |
200 cricket::CA_ANSWER, cricket::CA_OFFER}, | |
201 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_PASSIVE, | |
202 cricket::CA_ANSWER, cricket::CA_OFFER}, | |
203 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_ACTIVE, | |
204 cricket::CA_PRANSWER, cricket::CA_OFFER}, | |
205 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTPASS, | |
206 cricket::CA_PRANSWER, cricket::CA_OFFER}, | |
207 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_PASSIVE, | |
208 cricket::CA_PRANSWER, cricket::CA_OFFER}, | |
209 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_ACTIVE, | |
210 cricket::CA_OFFER, cricket::CA_ANSWER}, | |
211 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTPASS, | |
212 cricket::CA_OFFER, cricket::CA_ANSWER}, | |
213 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_PASSIVE, | |
214 cricket::CA_OFFER, cricket::CA_ANSWER}, | |
215 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_ACTIVE, | |
216 cricket::CA_OFFER, cricket::CA_PRANSWER}, | |
217 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTPASS, | |
218 cricket::CA_OFFER, cricket::CA_PRANSWER}, | |
219 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_PASSIVE, | |
220 cricket::CA_OFFER, cricket::CA_PRANSWER}}; | |
221 | |
222 for (auto& param : duplicate_params) { | |
223 local_desc.connection_role = param.local_role; | |
224 remote_desc.connection_role = param.remote_role; | |
225 | |
226 ASSERT_TRUE(transport_->SetRemoteTransportDescription( | |
227 remote_desc, param.remote_action, nullptr)); | |
228 ASSERT_TRUE(transport_->SetLocalTransportDescription( | |
229 local_desc, param.local_action, nullptr)); | |
230 EXPECT_FALSE( | |
231 transport_->NegotiateRole(param.local_action, &ssl_role, &error_desc)); | |
232 } | |
233 | |
234 // Invalid parameters due to the offerer not using ACTPASS. | |
235 NegotiateRoleParams offerer_without_actpass_params[] = { | |
236 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_PASSIVE, | |
237 cricket::CA_ANSWER, cricket::CA_OFFER}, | |
238 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_ACTIVE, | |
239 cricket::CA_ANSWER, cricket::CA_OFFER}, | |
240 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_PASSIVE, | |
241 cricket::CA_ANSWER, cricket::CA_OFFER}, | |
242 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_PASSIVE, | |
243 cricket::CA_PRANSWER, cricket::CA_OFFER}, | |
244 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_ACTIVE, | |
245 cricket::CA_PRANSWER, cricket::CA_OFFER}, | |
246 {cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_PASSIVE, | |
247 cricket::CA_PRANSWER, cricket::CA_OFFER}, | |
248 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_PASSIVE, | |
249 cricket::CA_OFFER, cricket::CA_ANSWER}, | |
250 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_ACTIVE, | |
251 cricket::CA_OFFER, cricket::CA_ANSWER}, | |
252 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_ACTPASS, | |
253 cricket::CA_OFFER, cricket::CA_ANSWER}, | |
254 {cricket::CONNECTIONROLE_ACTIVE, cricket::CONNECTIONROLE_PASSIVE, | |
255 cricket::CA_OFFER, cricket::CA_PRANSWER}, | |
256 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_ACTIVE, | |
257 cricket::CA_OFFER, cricket::CA_PRANSWER}, | |
258 {cricket::CONNECTIONROLE_PASSIVE, cricket::CONNECTIONROLE_ACTPASS, | |
259 cricket::CA_OFFER, cricket::CA_PRANSWER}}; | |
260 | |
261 for (auto& param : offerer_without_actpass_params) { | |
262 local_desc.connection_role = param.local_role; | |
263 remote_desc.connection_role = param.remote_role; | |
264 | |
265 ASSERT_TRUE(transport_->SetRemoteTransportDescription( | |
266 remote_desc, param.remote_action, nullptr)); | |
267 ASSERT_TRUE(transport_->SetLocalTransportDescription( | |
268 local_desc, param.local_action, nullptr)); | |
269 EXPECT_FALSE( | |
270 transport_->NegotiateRole(param.local_action, &ssl_role, &error_desc)); | |
271 } | |
272 } | |
OLD | NEW |