| 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 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 packet_size_(0), | 55 packet_size_(0), |
| 56 use_dtls_srtp_(false), | 56 use_dtls_srtp_(false), |
| 57 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10), | 57 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10), |
| 58 negotiated_dtls_(false), | 58 negotiated_dtls_(false), |
| 59 received_dtls_client_hello_(false), | 59 received_dtls_client_hello_(false), |
| 60 received_dtls_server_hello_(false) { | 60 received_dtls_server_hello_(false) { |
| 61 } | 61 } |
| 62 void SetIceProtocol(cricket::TransportProtocol proto) { | 62 void SetIceProtocol(cricket::TransportProtocol proto) { |
| 63 protocol_ = proto; | 63 protocol_ = proto; |
| 64 } | 64 } |
| 65 void CreateIdentity(rtc::KeyType key_type) { | 65 void CreateCertificate(rtc::KeyType key_type) { |
| 66 identity_.reset(rtc::SSLIdentity::Generate(name_, key_type)); | 66 certificate_ = webrtc::DtlsCertificate::Create( |
| 67 rtc::scoped_ptr<rtc::SSLIdentity>( |
| 68 rtc::SSLIdentity::Generate(name_, key_type)).Pass()); |
| 67 } | 69 } |
| 68 rtc::SSLIdentity* identity() { return identity_.get(); } | 70 const rtc::scoped_refptr<webrtc::DtlsCertificate>& certificate() { |
| 71 return certificate_; |
| 72 } |
| 69 void SetupSrtp() { | 73 void SetupSrtp() { |
| 70 ASSERT(identity_.get() != NULL); | 74 ASSERT(certificate_); |
| 71 use_dtls_srtp_ = true; | 75 use_dtls_srtp_ = true; |
| 72 } | 76 } |
| 73 void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) { | 77 void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) { |
| 74 ASSERT(transport_.get() == NULL); | 78 ASSERT(transport_.get() == NULL); |
| 75 ssl_max_version_ = version; | 79 ssl_max_version_ = version; |
| 76 } | 80 } |
| 77 void SetupChannels(int count, cricket::IceRole role) { | 81 void SetupChannels(int count, cricket::IceRole role) { |
| 78 transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>( | 82 transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>( |
| 79 signaling_thread_, worker_thread_, "dtls content name", NULL, | 83 signaling_thread_, worker_thread_, "dtls content name", NULL, |
| 80 identity_.get())); | 84 certificate_)); |
| 81 transport_->SetAsync(true); | 85 transport_->SetAsync(true); |
| 82 transport_->SetIceRole(role); | 86 transport_->SetIceRole(role); |
| 83 transport_->SetIceTiebreaker( | 87 transport_->SetIceTiebreaker( |
| 84 (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); | 88 (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); |
| 85 transport_->SignalWritableState.connect(this, | 89 transport_->SignalWritableState.connect(this, |
| 86 &DtlsTestClient::OnTransportWritableState); | 90 &DtlsTestClient::OnTransportWritableState); |
| 87 | 91 |
| 88 for (int i = 0; i < count; ++i) { | 92 for (int i = 0; i < count; ++i) { |
| 89 cricket::DtlsTransportChannelWrapper* channel = | 93 cricket::DtlsTransportChannelWrapper* channel = |
| 90 static_cast<cricket::DtlsTransportChannelWrapper*>( | 94 static_cast<cricket::DtlsTransportChannelWrapper*>( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 111 static_cast<cricket::DtlsTransportChannelWrapper*>(ch); | 115 static_cast<cricket::DtlsTransportChannelWrapper*>(ch); |
| 112 return (wrapper) ? | 116 return (wrapper) ? |
| 113 static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL; | 117 static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL; |
| 114 } | 118 } |
| 115 | 119 |
| 116 // Offer DTLS if we have an identity; pass in a remote fingerprint only if | 120 // Offer DTLS if we have an identity; pass in a remote fingerprint only if |
| 117 // both sides support DTLS. | 121 // both sides support DTLS. |
| 118 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, | 122 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, |
| 119 ConnectionRole local_role, ConnectionRole remote_role, | 123 ConnectionRole local_role, ConnectionRole remote_role, |
| 120 int flags) { | 124 int flags) { |
| 121 Negotiate(identity_.get(), (identity_) ? peer->identity_.get() : NULL, | 125 if (certificate_) { |
| 122 action, local_role, remote_role, flags); | 126 Negotiate(certificate_->identity(), |
| 127 peer->certificate_ ? peer->certificate_->identity() : nullptr, |
| 128 action, local_role, remote_role, flags); |
| 129 } else { |
| 130 Negotiate(nullptr, nullptr, |
| 131 action, local_role, remote_role, flags); |
| 132 } |
| 123 } | 133 } |
| 124 | 134 |
| 125 // Allow any DTLS configuration to be specified (including invalid ones). | 135 // Allow any DTLS configuration to be specified (including invalid ones). |
| 126 void Negotiate(rtc::SSLIdentity* local_identity, | 136 void Negotiate(rtc::SSLIdentity* local_identity, |
| 127 rtc::SSLIdentity* remote_identity, | 137 rtc::SSLIdentity* remote_identity, |
| 128 cricket::ContentAction action, | 138 cricket::ContentAction action, |
| 129 ConnectionRole local_role, | 139 ConnectionRole local_role, |
| 130 ConnectionRole remote_role, | 140 ConnectionRole remote_role, |
| 131 int flags) { | 141 int flags) { |
| 132 rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint; | 142 rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 size_t sent = 0; | 261 size_t sent = 0; |
| 252 do { | 262 do { |
| 253 // Fill the packet with a known value and a sequence number to check | 263 // Fill the packet with a known value and a sequence number to check |
| 254 // against, and make sure that it doesn't look like DTLS. | 264 // against, and make sure that it doesn't look like DTLS. |
| 255 memset(packet.get(), sent & 0xff, size); | 265 memset(packet.get(), sent & 0xff, size); |
| 256 packet[0] = (srtp) ? 0x80 : 0x00; | 266 packet[0] = (srtp) ? 0x80 : 0x00; |
| 257 rtc::SetBE32(packet.get() + kPacketNumOffset, | 267 rtc::SetBE32(packet.get() + kPacketNumOffset, |
| 258 static_cast<uint32>(sent)); | 268 static_cast<uint32>(sent)); |
| 259 | 269 |
| 260 // Only set the bypass flag if we've activated DTLS. | 270 // Only set the bypass flag if we've activated DTLS. |
| 261 int flags = (identity_.get() && srtp) ? cricket::PF_SRTP_BYPASS : 0; | 271 int flags = (certificate_ && srtp) ? cricket::PF_SRTP_BYPASS : 0; |
| 262 rtc::PacketOptions packet_options; | 272 rtc::PacketOptions packet_options; |
| 263 int rv = channels_[channel]->SendPacket( | 273 int rv = channels_[channel]->SendPacket( |
| 264 packet.get(), size, packet_options, flags); | 274 packet.get(), size, packet_options, flags); |
| 265 ASSERT_GT(rv, 0); | 275 ASSERT_GT(rv, 0); |
| 266 ASSERT_EQ(size, static_cast<size_t>(rv)); | 276 ASSERT_EQ(size, static_cast<size_t>(rv)); |
| 267 ++sent; | 277 ++sent; |
| 268 } while (sent < count); | 278 } while (sent < count); |
| 269 } | 279 } |
| 270 | 280 |
| 271 int SendInvalidSrtpPacket(size_t channel, size_t size) { | 281 int SendInvalidSrtpPacket(size_t channel, size_t size) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 } | 342 } |
| 333 | 343 |
| 334 void OnTransportChannelReadPacket(cricket::TransportChannel* channel, | 344 void OnTransportChannelReadPacket(cricket::TransportChannel* channel, |
| 335 const char* data, size_t size, | 345 const char* data, size_t size, |
| 336 const rtc::PacketTime& packet_time, | 346 const rtc::PacketTime& packet_time, |
| 337 int flags) { | 347 int flags) { |
| 338 uint32 packet_num = 0; | 348 uint32 packet_num = 0; |
| 339 ASSERT_TRUE(VerifyPacket(data, size, &packet_num)); | 349 ASSERT_TRUE(VerifyPacket(data, size, &packet_num)); |
| 340 received_.insert(packet_num); | 350 received_.insert(packet_num); |
| 341 // Only DTLS-SRTP packets should have the bypass flag set. | 351 // Only DTLS-SRTP packets should have the bypass flag set. |
| 342 int expected_flags = (identity_.get() && IsRtpLeadByte(data[0])) ? | 352 int expected_flags = (certificate_ && IsRtpLeadByte(data[0])) ? |
| 343 cricket::PF_SRTP_BYPASS : 0; | 353 cricket::PF_SRTP_BYPASS : 0; |
| 344 ASSERT_EQ(expected_flags, flags); | 354 ASSERT_EQ(expected_flags, flags); |
| 345 } | 355 } |
| 346 | 356 |
| 347 // Hook into the raw packet stream to make sure DTLS packets are encrypted. | 357 // Hook into the raw packet stream to make sure DTLS packets are encrypted. |
| 348 void OnFakeTransportChannelReadPacket(cricket::TransportChannel* channel, | 358 void OnFakeTransportChannelReadPacket(cricket::TransportChannel* channel, |
| 349 const char* data, size_t size, | 359 const char* data, size_t size, |
| 350 const rtc::PacketTime& time, | 360 const rtc::PacketTime& time, |
| 351 int flags) { | 361 int flags) { |
| 352 // Flags shouldn't be set on the underlying TransportChannel packets. | 362 // Flags shouldn't be set on the underlying TransportChannel packets. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 370 } | 380 } |
| 371 } | 381 } |
| 372 } | 382 } |
| 373 } | 383 } |
| 374 | 384 |
| 375 private: | 385 private: |
| 376 std::string name_; | 386 std::string name_; |
| 377 rtc::Thread* signaling_thread_; | 387 rtc::Thread* signaling_thread_; |
| 378 rtc::Thread* worker_thread_; | 388 rtc::Thread* worker_thread_; |
| 379 cricket::TransportProtocol protocol_; | 389 cricket::TransportProtocol protocol_; |
| 380 rtc::scoped_ptr<rtc::SSLIdentity> identity_; | 390 rtc::scoped_refptr<webrtc::DtlsCertificate> certificate_; |
| 381 rtc::scoped_ptr<cricket::FakeTransport> transport_; | 391 rtc::scoped_ptr<cricket::FakeTransport> transport_; |
| 382 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; | 392 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; |
| 383 size_t packet_size_; | 393 size_t packet_size_; |
| 384 std::set<int> received_; | 394 std::set<int> received_; |
| 385 bool use_dtls_srtp_; | 395 bool use_dtls_srtp_; |
| 386 rtc::SSLProtocolVersion ssl_max_version_; | 396 rtc::SSLProtocolVersion ssl_max_version_; |
| 387 bool negotiated_dtls_; | 397 bool negotiated_dtls_; |
| 388 bool received_dtls_client_hello_; | 398 bool received_dtls_client_hello_; |
| 389 bool received_dtls_server_hello_; | 399 bool received_dtls_server_hello_; |
| 390 }; | 400 }; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 407 channel_ct_ = static_cast<int>(channel_ct); | 417 channel_ct_ = static_cast<int>(channel_ct); |
| 408 } | 418 } |
| 409 void SetMaxProtocolVersions(rtc::SSLProtocolVersion c1, | 419 void SetMaxProtocolVersions(rtc::SSLProtocolVersion c1, |
| 410 rtc::SSLProtocolVersion c2) { | 420 rtc::SSLProtocolVersion c2) { |
| 411 client1_.SetupMaxProtocolVersion(c1); | 421 client1_.SetupMaxProtocolVersion(c1); |
| 412 client2_.SetupMaxProtocolVersion(c2); | 422 client2_.SetupMaxProtocolVersion(c2); |
| 413 ssl_expected_version_ = std::min(c1, c2); | 423 ssl_expected_version_ = std::min(c1, c2); |
| 414 } | 424 } |
| 415 void PrepareDtls(bool c1, bool c2, rtc::KeyType key_type) { | 425 void PrepareDtls(bool c1, bool c2, rtc::KeyType key_type) { |
| 416 if (c1) { | 426 if (c1) { |
| 417 client1_.CreateIdentity(key_type); | 427 client1_.CreateCertificate(key_type); |
| 418 } | 428 } |
| 419 if (c2) { | 429 if (c2) { |
| 420 client2_.CreateIdentity(key_type); | 430 client2_.CreateCertificate(key_type); |
| 421 } | 431 } |
| 422 if (c1 && c2) | 432 if (c1 && c2) |
| 423 use_dtls_ = true; | 433 use_dtls_ = true; |
| 424 } | 434 } |
| 425 void PrepareDtlsSrtp(bool c1, bool c2) { | 435 void PrepareDtlsSrtp(bool c1, bool c2) { |
| 426 if (!use_dtls_) | 436 if (!use_dtls_) |
| 427 return; | 437 return; |
| 428 | 438 |
| 429 if (c1) | 439 if (c1) |
| 430 client1_.SetupSrtp(); | 440 client1_.SetupSrtp(); |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 TestTransfer(0, 1000, 100, true); | 859 TestTransfer(0, 1000, 100, true); |
| 850 TestTransfer(1, 1000, 100, true); | 860 TestTransfer(1, 1000, 100, true); |
| 851 } | 861 } |
| 852 | 862 |
| 853 // Test Certificates state after negotiation but before connection. | 863 // Test Certificates state after negotiation but before connection. |
| 854 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { | 864 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { |
| 855 MAYBE_SKIP_TEST(HaveDtls); | 865 MAYBE_SKIP_TEST(HaveDtls); |
| 856 PrepareDtls(true, true, rtc::KT_DEFAULT); | 866 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 857 Negotiate(); | 867 Negotiate(); |
| 858 | 868 |
| 859 rtc::scoped_ptr<rtc::SSLIdentity> identity1; | 869 rtc::scoped_refptr<webrtc::DtlsCertificate> dtlscert1; |
| 860 rtc::scoped_ptr<rtc::SSLIdentity> identity2; | 870 rtc::scoped_refptr<webrtc::DtlsCertificate> dtlscert2; |
| 861 rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1; | 871 rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1; |
| 862 rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2; | 872 rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2; |
| 863 | 873 |
| 864 // After negotiation, each side has a distinct local certificate, but still no | 874 // After negotiation, each side has a distinct local certificate, but still no |
| 865 // remote certificate, because connection has not yet occurred. | 875 // remote certificate, because connection has not yet occurred. |
| 866 ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept())); | 876 ASSERT_TRUE(client1_.transport()->GetCertificate(&dtlscert1)); |
| 867 ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept())); | 877 ASSERT_TRUE(client2_.transport()->GetCertificate(&dtlscert2)); |
| 868 ASSERT_NE(identity1->certificate().ToPEMString(), | 878 ASSERT_NE(dtlscert1->identity()->certificate().ToPEMString(), |
| 869 identity2->certificate().ToPEMString()); | 879 dtlscert2->identity()->certificate().ToPEMString()); |
| 870 ASSERT_FALSE( | 880 ASSERT_FALSE( |
| 871 client1_.transport()->GetRemoteCertificate(remote_cert1.accept())); | 881 client1_.transport()->GetRemoteCertificate(remote_cert1.accept())); |
| 872 ASSERT_FALSE(remote_cert1 != NULL); | 882 ASSERT_FALSE(remote_cert1 != NULL); |
| 873 ASSERT_FALSE( | 883 ASSERT_FALSE( |
| 874 client2_.transport()->GetRemoteCertificate(remote_cert2.accept())); | 884 client2_.transport()->GetRemoteCertificate(remote_cert2.accept())); |
| 875 ASSERT_FALSE(remote_cert2 != NULL); | 885 ASSERT_FALSE(remote_cert2 != NULL); |
| 876 } | 886 } |
| 877 | 887 |
| 878 // Test Certificates state after connection. | 888 // Test Certificates state after connection. |
| 879 TEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) { | 889 TEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) { |
| 880 MAYBE_SKIP_TEST(HaveDtls); | 890 MAYBE_SKIP_TEST(HaveDtls); |
| 881 PrepareDtls(true, true, rtc::KT_DEFAULT); | 891 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 882 ASSERT_TRUE(Connect()); | 892 ASSERT_TRUE(Connect()); |
| 883 | 893 |
| 884 rtc::scoped_ptr<rtc::SSLIdentity> identity1; | 894 rtc::scoped_refptr<webrtc::DtlsCertificate> dtlscert1; |
| 885 rtc::scoped_ptr<rtc::SSLIdentity> identity2; | 895 rtc::scoped_refptr<webrtc::DtlsCertificate> dtlscert2; |
| 886 rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1; | 896 rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1; |
| 887 rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2; | 897 rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2; |
| 888 | 898 |
| 889 // After connection, each side has a distinct local certificate. | 899 // After connection, each side has a distinct local certificate. |
| 890 ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept())); | 900 ASSERT_TRUE(client1_.transport()->GetCertificate(&dtlscert1)); |
| 891 ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept())); | 901 ASSERT_TRUE(client2_.transport()->GetCertificate(&dtlscert2)); |
| 892 ASSERT_NE(identity1->certificate().ToPEMString(), | 902 ASSERT_NE(dtlscert1->identity()->certificate().ToPEMString(), |
| 893 identity2->certificate().ToPEMString()); | 903 dtlscert2->identity()->certificate().ToPEMString()); |
| 894 | 904 |
| 895 // Each side's remote certificate is the other side's local certificate. | 905 // Each side's remote certificate is the other side's local certificate. |
| 896 ASSERT_TRUE( | 906 ASSERT_TRUE( |
| 897 client1_.transport()->GetRemoteCertificate(remote_cert1.accept())); | 907 client1_.transport()->GetRemoteCertificate(remote_cert1.accept())); |
| 898 ASSERT_EQ(remote_cert1->ToPEMString(), | 908 ASSERT_EQ(remote_cert1->ToPEMString(), |
| 899 identity2->certificate().ToPEMString()); | 909 dtlscert2->identity()->certificate().ToPEMString()); |
| 900 ASSERT_TRUE( | 910 ASSERT_TRUE( |
| 901 client2_.transport()->GetRemoteCertificate(remote_cert2.accept())); | 911 client2_.transport()->GetRemoteCertificate(remote_cert2.accept())); |
| 902 ASSERT_EQ(remote_cert2->ToPEMString(), | 912 ASSERT_EQ(remote_cert2->ToPEMString(), |
| 903 identity1->certificate().ToPEMString()); | 913 dtlscert1->identity()->certificate().ToPEMString()); |
| 904 } | 914 } |
| OLD | NEW |