Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: webrtc/p2p/base/dtlstransportchannel_unittest.cc

Issue 2140283002: Fixing issue with DTLS channel when using "presume writable" flag. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 117
118 // Offer DTLS if we have an identity; pass in a remote fingerprint only if 118 // Offer DTLS if we have an identity; pass in a remote fingerprint only if
119 // both sides support DTLS. 119 // both sides support DTLS.
120 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, 120 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action,
121 ConnectionRole local_role, ConnectionRole remote_role, 121 ConnectionRole local_role, ConnectionRole remote_role,
122 int flags) { 122 int flags) {
123 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, 123 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action,
124 local_role, remote_role, flags); 124 local_role, remote_role, flags);
125 } 125 }
126 126
127 std::unique_ptr<rtc::SSLFingerprint> MakeFingerprintFromCertificate(
128 const rtc::scoped_refptr<rtc::RTCCertificate>& cert) {
129 std::unique_ptr<rtc::SSLFingerprint> fingerprint;
130 if (cert) {
pthatcher1 2016/07/13 00:04:19 Maybe have it be early return? if (!cert) { ret
Taylor Brandstetter 2016/07/13 16:17:41 Done.
131 std::string digest_algorithm;
132 EXPECT_TRUE(cert->ssl_certificate().GetSignatureDigestAlgorithm(
133 &digest_algorithm));
134 EXPECT_FALSE(digest_algorithm.empty());
135 fingerprint.reset(
136 rtc::SSLFingerprint::Create(digest_algorithm, cert->identity()));
137 EXPECT_TRUE(fingerprint.get() != NULL);
138 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm);
139 }
140 return fingerprint;
141 }
142
143 void SetLocalTransportDescription(
144 const rtc::scoped_refptr<rtc::RTCCertificate>& cert,
145 cricket::ContentAction action,
146 ConnectionRole role,
147 int flags) {
148 auto fingerprint = MakeFingerprintFromCertificate(cert);
149 cricket::TransportDescription local_desc(
150 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
151 role, fingerprint.get());
152
153 if (action == cricket::CA_OFFER) {
154 if (use_dtls_srtp_ && !(flags & NF_REOFFER)) {
155 // SRTP ciphers will be set only in the beginning.
156 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
157 channels_.begin();
158 it != channels_.end(); ++it) {
pthatcher1 2016/07/13 00:04:19 c++11 style for loop?
Taylor Brandstetter 2016/07/13 16:17:41 Done.
159 std::vector<int> ciphers;
160 ciphers.push_back(rtc::SRTP_AES128_CM_SHA1_80);
161 EXPECT_TRUE((*it)->SetSrtpCryptoSuites(ciphers));
162 }
163 }
164
165 EXPECT_TRUE(transport_->SetLocalTransportDescription(local_desc, action,
166 nullptr));
167 } else {
168 // If |expect_success| is false, expect SRTD or SLTD to fail when
169 // content action is CA_ANSWER.
170 bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true;
171 EXPECT_EQ(expect_success, transport_->SetLocalTransportDescription(
172 local_desc, action, nullptr));
173 }
174 set_local_cert_ = (cert != nullptr);
pthatcher1 2016/07/13 00:04:20 Would has_local_cert_ be a better name?
Taylor Brandstetter 2016/07/13 16:17:41 The method is called SetLocalTransportDescription
Taylor Brandstetter 2016/07/13 16:20:16 Oh I misread your comment. I thought you were aski
175 }
176
177 void SetRemoteTransportDescription(
178 const rtc::scoped_refptr<rtc::RTCCertificate>& cert,
179 cricket::ContentAction action,
180 ConnectionRole role,
181 int flags) {
182 auto fingerprint = MakeFingerprintFromCertificate(cert);
183 cricket::TransportDescription remote_desc(
184 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
185 role, fingerprint.get());
186
187 if (action == cricket::CA_OFFER) {
188 if (use_dtls_srtp_ && !(flags & NF_REOFFER)) {
189 // SRTP ciphers will be set only in the beginning.
190 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
191 channels_.begin();
192 it != channels_.end(); ++it) {
193 std::vector<int> ciphers;
194 ciphers.push_back(rtc::SRTP_AES128_CM_SHA1_80);
195 EXPECT_TRUE((*it)->SetSrtpCryptoSuites(ciphers));
196 }
197 }
pthatcher1 2016/07/13 00:04:19 It seems like a MakeTransportDescription(action, c
Taylor Brandstetter 2016/07/13 16:17:41 Setting the ciphers you mean? I'll make a separate
198
199 EXPECT_TRUE(transport_->SetRemoteTransportDescription(remote_desc, action,
200 nullptr));
201 } else {
202 // If |expect_success| is false, expect SRTD or SLTD to fail when
203 // content action is CA_ANSWER.
204 bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true;
205 EXPECT_EQ(expect_success, transport_->SetRemoteTransportDescription(
206 remote_desc, action, nullptr));
207 }
208 set_remote_cert_ = (cert != nullptr);
209 }
210
127 // Allow any DTLS configuration to be specified (including invalid ones). 211 // Allow any DTLS configuration to be specified (including invalid ones).
128 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, 212 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert,
129 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, 213 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert,
130 cricket::ContentAction action, 214 cricket::ContentAction action,
131 ConnectionRole local_role, 215 ConnectionRole local_role,
132 ConnectionRole remote_role, 216 ConnectionRole remote_role,
133 int flags) { 217 int flags) {
134 std::unique_ptr<rtc::SSLFingerprint> local_fingerprint; 218 if (action == cricket::CA_OFFER) {
135 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint; 219 SetLocalTransportDescription(local_cert, cricket::CA_OFFER, local_role,
136 if (local_cert) { 220 flags);
137 std::string digest_algorithm; 221 SetRemoteTransportDescription(remote_cert, cricket::CA_ANSWER,
138 ASSERT_TRUE(local_cert->ssl_certificate().GetSignatureDigestAlgorithm( 222 remote_role, flags);
139 &digest_algorithm)); 223 } else {
140 ASSERT_FALSE(digest_algorithm.empty()); 224 SetRemoteTransportDescription(remote_cert, cricket::CA_OFFER, remote_role,
141 local_fingerprint.reset(rtc::SSLFingerprint::Create( 225 flags);
142 digest_algorithm, local_cert->identity())); 226 // If remote if the offerer and has no DTLS support, answer will be
143 ASSERT_TRUE(local_fingerprint.get() != NULL); 227 // without any fingerprint.
144 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); 228 SetLocalTransportDescription(remote_cert ? local_cert : nullptr,
229 cricket::CA_ANSWER, local_role, flags);
145 } 230 }
146 if (remote_cert) {
147 std::string digest_algorithm;
148 ASSERT_TRUE(remote_cert->ssl_certificate().GetSignatureDigestAlgorithm(
149 &digest_algorithm));
150 ASSERT_FALSE(digest_algorithm.empty());
151 remote_fingerprint.reset(rtc::SSLFingerprint::Create(
152 digest_algorithm, remote_cert->identity()));
153 ASSERT_TRUE(remote_fingerprint.get() != NULL);
154 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm);
155 }
156
157 if (use_dtls_srtp_ && !(flags & NF_REOFFER)) {
158 // SRTP ciphers will be set only in the beginning.
159 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
160 channels_.begin(); it != channels_.end(); ++it) {
161 std::vector<int> ciphers;
162 ciphers.push_back(rtc::SRTP_AES128_CM_SHA1_80);
163 ASSERT_TRUE((*it)->SetSrtpCryptoSuites(ciphers));
164 }
165 }
166
167 cricket::TransportDescription local_desc(
168 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
169 local_role,
170 // If remote if the offerer and has no DTLS support, answer will be
171 // without any fingerprint.
172 (action == cricket::CA_ANSWER && !remote_cert)
173 ? nullptr
174 : local_fingerprint.get());
175
176 cricket::TransportDescription remote_desc(
177 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL,
178 remote_role, remote_fingerprint.get());
179
180 bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true;
181 // If |expect_success| is false, expect SRTD or SLTD to fail when
182 // content action is CA_ANSWER.
183 if (action == cricket::CA_OFFER) {
184 ASSERT_TRUE(transport_->SetLocalTransportDescription(
185 local_desc, cricket::CA_OFFER, NULL));
186 ASSERT_EQ(expect_success, transport_->SetRemoteTransportDescription(
187 remote_desc, cricket::CA_ANSWER, NULL));
188 } else {
189 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
190 remote_desc, cricket::CA_OFFER, NULL));
191 ASSERT_EQ(expect_success, transport_->SetLocalTransportDescription(
192 local_desc, cricket::CA_ANSWER, NULL));
193 }
194 negotiated_dtls_ = (local_cert && remote_cert);
195 } 231 }
196 232
197 bool Connect(DtlsTestClient* peer, bool asymmetric) { 233 bool Connect(DtlsTestClient* peer, bool asymmetric) {
198 transport_->SetDestination(peer->transport_.get(), asymmetric); 234 transport_->SetDestination(peer->transport_.get(), asymmetric);
199 return true; 235 return true;
200 } 236 }
201 237
202 bool all_channels_writable() const { 238 bool all_channels_writable() const {
203 if (channels_.empty()) { 239 if (channels_.empty()) {
204 return false; 240 return false;
(...skipping 15 matching lines...) Expand all
220 return false; 256 return false;
221 } 257 }
222 } 258 }
223 return true; 259 return true;
224 } 260 }
225 261
226 int received_dtls_client_hellos() const { 262 int received_dtls_client_hellos() const {
227 return received_dtls_client_hellos_; 263 return received_dtls_client_hellos_;
228 } 264 }
229 265
266 bool negotiated_dtls() const { return set_local_cert_ && set_remote_cert_; }
267
230 void CheckRole(rtc::SSLRole role) { 268 void CheckRole(rtc::SSLRole role) {
231 if (role == rtc::SSL_CLIENT) { 269 if (role == rtc::SSL_CLIENT) {
232 ASSERT_EQ(0, received_dtls_client_hellos_); 270 ASSERT_EQ(0, received_dtls_client_hellos_);
233 ASSERT_GT(received_dtls_server_hellos_, 0); 271 ASSERT_GT(received_dtls_server_hellos_, 0);
234 } else { 272 } else {
235 ASSERT_GT(received_dtls_client_hellos_, 0); 273 ASSERT_GT(received_dtls_client_hellos_, 0);
236 ASSERT_EQ(0, received_dtls_server_hellos_); 274 ASSERT_EQ(0, received_dtls_server_hellos_);
237 } 275 }
238 } 276 }
239 277
240 void CheckSrtp(int expected_crypto_suite) { 278 void CheckSrtp(int expected_crypto_suite) {
241 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = 279 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
242 channels_.begin(); it != channels_.end(); ++it) { 280 channels_.begin(); it != channels_.end(); ++it) {
243 int crypto_suite; 281 int crypto_suite;
244 282
245 bool rv = (*it)->GetSrtpCryptoSuite(&crypto_suite); 283 bool rv = (*it)->GetSrtpCryptoSuite(&crypto_suite);
246 if (negotiated_dtls_ && expected_crypto_suite) { 284 if (negotiated_dtls() && expected_crypto_suite) {
247 ASSERT_TRUE(rv); 285 ASSERT_TRUE(rv);
248 286
249 ASSERT_EQ(crypto_suite, expected_crypto_suite); 287 ASSERT_EQ(crypto_suite, expected_crypto_suite);
250 } else { 288 } else {
251 ASSERT_FALSE(rv); 289 ASSERT_FALSE(rv);
252 } 290 }
253 } 291 }
254 } 292 }
255 293
256 void CheckSsl() { 294 void CheckSsl() {
257 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = 295 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
258 channels_.begin(); it != channels_.end(); ++it) { 296 channels_.begin(); it != channels_.end(); ++it) {
259 int cipher; 297 int cipher;
260 298
261 bool rv = (*it)->GetSslCipherSuite(&cipher); 299 bool rv = (*it)->GetSslCipherSuite(&cipher);
262 if (negotiated_dtls_) { 300 if (negotiated_dtls()) {
263 ASSERT_TRUE(rv); 301 ASSERT_TRUE(rv);
264 302
265 EXPECT_TRUE( 303 EXPECT_TRUE(
266 rtc::SSLStreamAdapter::IsAcceptableCipher(cipher, rtc::KT_DEFAULT)); 304 rtc::SSLStreamAdapter::IsAcceptableCipher(cipher, rtc::KT_DEFAULT));
267 } else { 305 } else {
268 ASSERT_FALSE(rv); 306 ASSERT_FALSE(rv);
269 } 307 }
270 } 308 }
271 } 309 }
272 310
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 ASSERT_EQ(0, flags); 419 ASSERT_EQ(0, flags);
382 420
383 // Look at the handshake packets to see what role we played. 421 // Look at the handshake packets to see what role we played.
384 // Check that non-handshake packets are DTLS data or SRTP bypass. 422 // Check that non-handshake packets are DTLS data or SRTP bypass.
385 if (data[0] == 22 && size > 17) { 423 if (data[0] == 22 && size > 17) {
386 if (data[13] == 1) { 424 if (data[13] == 1) {
387 ++received_dtls_client_hellos_; 425 ++received_dtls_client_hellos_;
388 } else if (data[13] == 2) { 426 } else if (data[13] == 2) {
389 ++received_dtls_server_hellos_; 427 ++received_dtls_server_hellos_;
390 } 428 }
391 } else if (negotiated_dtls_ && !(data[0] >= 20 && data[0] <= 22)) { 429 } else if (negotiated_dtls() && !(data[0] >= 20 && data[0] <= 22)) {
392 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0])); 430 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0]));
393 if (data[0] == 23) { 431 if (data[0] == 23) {
394 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); 432 ASSERT_TRUE(VerifyEncryptedPacket(data, size));
395 } else if (IsRtpLeadByte(data[0])) { 433 } else if (IsRtpLeadByte(data[0])) {
396 ASSERT_TRUE(VerifyPacket(data, size, NULL)); 434 ASSERT_TRUE(VerifyPacket(data, size, NULL));
397 } 435 }
398 } 436 }
399 } 437 }
400 438
401 private: 439 private:
402 std::string name_; 440 std::string name_;
403 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; 441 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
404 std::unique_ptr<cricket::FakeTransport> transport_; 442 std::unique_ptr<cricket::FakeTransport> transport_;
405 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; 443 std::vector<cricket::DtlsTransportChannelWrapper*> channels_;
406 size_t packet_size_ = 0u; 444 size_t packet_size_ = 0u;
407 std::set<int> received_; 445 std::set<int> received_;
408 bool use_dtls_srtp_ = false; 446 bool use_dtls_srtp_ = false;
409 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; 447 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
410 bool negotiated_dtls_ = false; 448 bool set_local_cert_ = false;
449 bool set_remote_cert_ = false;
411 int received_dtls_client_hellos_ = 0; 450 int received_dtls_client_hellos_ = 0;
412 int received_dtls_server_hellos_ = 0; 451 int received_dtls_server_hellos_ = 0;
413 rtc::SentPacket sent_packet_; 452 rtc::SentPacket sent_packet_;
414 }; 453 };
415 454
416 // Note that this test always uses a FakeClock, due to the |fake_clock_| member 455 // Note that this test always uses a FakeClock, due to the |fake_clock_| member
417 // variable. 456 // variable.
418 class DtlsTransportChannelTest : public testing::Test { 457 class DtlsTransportChannelTest : public testing::Test {
419 public: 458 public:
420 DtlsTransportChannelTest() 459 DtlsTransportChannelTest()
(...skipping 29 matching lines...) Expand all
450 489
451 if (c1) 490 if (c1)
452 client1_.SetupSrtp(); 491 client1_.SetupSrtp();
453 if (c2) 492 if (c2)
454 client2_.SetupSrtp(); 493 client2_.SetupSrtp();
455 494
456 if (c1 && c2) 495 if (c1 && c2)
457 use_dtls_srtp_ = true; 496 use_dtls_srtp_ = true;
458 } 497 }
459 498
460 bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) { 499 // Negotiate local/remote fingerprint before or after the underlying
461 Negotiate(client1_role, client2_role); 500 // tranpsort is connected?
501 enum NegotiateOrdering { NEGOTIATE_BEFORE_CONNECT, CONNECT_BEFORE_NEGOTIATE };
502 bool Connect(ConnectionRole client1_role,
503 ConnectionRole client2_role,
504 NegotiateOrdering ordering = NEGOTIATE_BEFORE_CONNECT) {
505 bool rv;
506 if (ordering == NEGOTIATE_BEFORE_CONNECT) {
507 Negotiate(client1_role, client2_role);
508 rv = client1_.Connect(&client2_, false);
509 } else {
510 client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING);
511 client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED);
512 // This is equivalent to an offer being processed on both sides, but an
513 // answer not yet being received on the initiating side. So the
514 // connection will be made before negotiation has finished on both sides.
515 client1_.SetLocalTransportDescription(client1_.certificate(),
516 cricket::CA_OFFER, client1_role, 0);
517 client2_.SetRemoteTransportDescription(
518 client1_.certificate(), cricket::CA_OFFER, client1_role, 0);
519 client2_.SetLocalTransportDescription(
520 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0);
521 rv = client1_.Connect(&client2_, false);
522 client1_.SetRemoteTransportDescription(
523 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0);
524 }
462 525
463 bool rv = client1_.Connect(&client2_, false);
464 EXPECT_TRUE(rv); 526 EXPECT_TRUE(rv);
465 if (!rv) 527 if (!rv)
466 return false; 528 return false;
467 529
468 EXPECT_TRUE_WAIT( 530 EXPECT_TRUE_WAIT(
469 client1_.all_channels_writable() && client2_.all_channels_writable(), 531 client1_.all_channels_writable() && client2_.all_channels_writable(),
470 kTimeout); 532 kTimeout);
471 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) 533 if (!client1_.all_channels_writable() || !client2_.all_channels_writable())
472 return false; 534 return false;
473 535
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 // millisecond before the expected time and verify that no unexpected 1073 // millisecond before the expected time and verify that no unexpected
1012 // retransmissions were sent. Then advance it the final millisecond and 1074 // retransmissions were sent. Then advance it the final millisecond and
1013 // verify that the expected retransmission was sent. 1075 // verify that the expected retransmission was sent.
1014 fake_clock_.AdvanceTime( 1076 fake_clock_.AdvanceTime(
1015 rtc::TimeDelta::FromMilliseconds(timeout_schedule_ms[i] - 1)); 1077 rtc::TimeDelta::FromMilliseconds(timeout_schedule_ms[i] - 1));
1016 EXPECT_EQ(expected_hellos, client1_.received_dtls_client_hellos()); 1078 EXPECT_EQ(expected_hellos, client1_.received_dtls_client_hellos());
1017 fake_clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); 1079 fake_clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1));
1018 EXPECT_EQ(++expected_hellos, client1_.received_dtls_client_hellos()); 1080 EXPECT_EQ(++expected_hellos, client1_.received_dtls_client_hellos());
1019 } 1081 }
1020 } 1082 }
1083
1084 // Test that a DTLS connection can be made even if the underlying transport
1085 // is connected before DTLS fingerprints/roles have been negotiated.
1086 TEST_F(DtlsTransportChannelTest, TestConnectBeforeNegotiate) {
1087 MAYBE_SKIP_TEST(HaveDtls);
1088 PrepareDtls(true, true, rtc::KT_DEFAULT);
1089 ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
1090 cricket::CONNECTIONROLE_ACTIVE,
1091 CONNECT_BEFORE_NEGOTIATE));
1092 TestTransfer(0, 1000, 100, false);
1093 }
OLDNEW
« webrtc/p2p/base/dtlstransportchannel.cc ('K') | « webrtc/p2p/base/dtlstransportchannel.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698