Index: webrtc/pc/channel_unittest.cc |
diff --git a/webrtc/pc/channel_unittest.cc b/webrtc/pc/channel_unittest.cc |
index 492c7d548c6166d26ccb2fd15b423009a5e4cf6e..9a7d4643f8f2ade9f9d5fcee757d5aaf9d5b0706 100644 |
--- a/webrtc/pc/channel_unittest.cc |
+++ b/webrtc/pc/channel_unittest.cc |
@@ -14,6 +14,7 @@ |
#include "webrtc/base/buffer.h" |
#include "webrtc/base/gunit.h" |
#include "webrtc/base/logging.h" |
+#include "webrtc/base/sslstreamadapter.h" |
#include "webrtc/media/base/fakemediaengine.h" |
#include "webrtc/media/base/fakertp.h" |
#include "webrtc/media/base/mediachannel.h" |
@@ -93,7 +94,7 @@ template<class T> |
class ChannelTest : public testing::Test, public sigslot::has_slots<> { |
public: |
enum Flags { RTCP = 0x1, RTCP_MUX = 0x2, SECURE = 0x4, SSRC_MUX = 0x8, |
- DTLS = 0x10 }; |
+ DTLS = 0x10, GCM_CIPHER = 0x20 }; |
ChannelTest(bool verify_playout, |
rtc::ArrayView<const uint8_t> rtp_data, |
@@ -134,10 +135,10 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { |
media_channel2_ = ch2; |
channel1_.reset( |
CreateChannel(worker_thread, network_thread_, &media_engine_, ch1, |
- transport_controller1_.get(), (flags1 & RTCP) != 0)); |
+ transport_controller1_.get(), flags1)); |
channel2_.reset( |
CreateChannel(worker_thread, network_thread_, &media_engine_, ch2, |
- transport_controller2_.get(), (flags2 & RTCP) != 0)); |
+ transport_controller2_.get(), flags2)); |
channel1_->SignalMediaMonitor.connect(this, |
&ChannelTest<T>::OnMediaMonitor1); |
channel2_->SignalMediaMonitor.connect(this, |
@@ -186,10 +187,14 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { |
cricket::MediaEngineInterface* engine, |
typename T::MediaChannel* ch, |
cricket::TransportController* transport_controller, |
- bool rtcp) { |
+ int flags) { |
typename T::Channel* channel = |
new typename T::Channel(worker_thread, network_thread, engine, ch, |
- transport_controller, cricket::CN_AUDIO, rtcp); |
+ transport_controller, cricket::CN_AUDIO, |
+ (flags & RTCP) != 0); |
+ rtc::CryptoOptions crypto_options; |
+ crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0; |
+ channel->SetCryptoOptions(crypto_options); |
if (!channel->Init_w(nullptr)) { |
delete channel; |
channel = NULL; |
@@ -368,6 +373,21 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { |
bool CheckNoRtcp2() { |
return media_channel2_->CheckNoRtcp(); |
} |
+ // Checks that the channel is using GCM iff GCM_CIPHER is set in flags. |
+ // Returns true if so. |
+ bool CheckGcmCipher(typename T::Channel* channel, int flags) { |
+ int suite; |
+ if (!channel->transport_channel()->GetSrtpCryptoSuite(&suite)) { |
+ return false; |
+ } |
+ |
+ if (flags & GCM_CIPHER) { |
+ return rtc::IsGcmCryptoSuite(suite); |
+ } else { |
+ return (suite != rtc::SRTP_INVALID_CRYPTO_SUITE && |
+ !rtc::IsGcmCryptoSuite(suite)); |
+ } |
+ } |
void CreateContent(int flags, |
const cricket::AudioCodec& audio_codec, |
@@ -1288,8 +1308,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { |
// Test that we properly send SRTP with RTCP in both directions. |
// You can pass in DTLS and/or RTCP_MUX as flags. |
void SendSrtpToSrtp(int flags1_in = 0, int flags2_in = 0) { |
- ASSERT((flags1_in & ~(RTCP_MUX | DTLS)) == 0); |
- ASSERT((flags2_in & ~(RTCP_MUX | DTLS)) == 0); |
+ ASSERT((flags1_in & ~(RTCP_MUX | DTLS | GCM_CIPHER)) == 0); |
+ ASSERT((flags2_in & ~(RTCP_MUX | DTLS | GCM_CIPHER)) == 0); |
int flags1 = RTCP | SECURE | flags1_in; |
int flags2 = RTCP | SECURE | flags2_in; |
@@ -1307,6 +1327,14 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { |
EXPECT_TRUE(channel2_->secure()); |
EXPECT_EQ(dtls1 && dtls2, channel1_->secure_dtls()); |
EXPECT_EQ(dtls1 && dtls2, channel2_->secure_dtls()); |
+ // We can only query the negotiated cipher suite for DTLS-SRTP transport |
+ // channels. |
+ if (dtls1 && dtls2) { |
+ // A GCM cipher is only used if both channels support GCM ciphers. |
+ int common_gcm_flags = flags1 & flags2 & GCM_CIPHER; |
+ EXPECT_TRUE(CheckGcmCipher(channel1_.get(), common_gcm_flags)); |
+ EXPECT_TRUE(CheckGcmCipher(channel2_.get(), common_gcm_flags)); |
+ } |
SendRtp1(); |
SendRtp2(); |
SendRtcp1(); |
@@ -2022,10 +2050,14 @@ cricket::VideoChannel* ChannelTest<VideoTraits>::CreateChannel( |
cricket::MediaEngineInterface* engine, |
cricket::FakeVideoMediaChannel* ch, |
cricket::TransportController* transport_controller, |
- bool rtcp) { |
+ int flags) { |
cricket::VideoChannel* channel = |
new cricket::VideoChannel(worker_thread, network_thread, ch, |
- transport_controller, cricket::CN_VIDEO, rtcp); |
+ transport_controller, cricket::CN_VIDEO, |
+ (flags & RTCP) != 0); |
+ rtc::CryptoOptions crypto_options; |
+ crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0; |
+ channel->SetCryptoOptions(crypto_options); |
if (!channel->Init_w(nullptr)) { |
delete channel; |
channel = NULL; |
@@ -2253,6 +2285,21 @@ TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtp) { |
Base::SendSrtpToSrtp(DTLS, DTLS); |
} |
+TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpGcmBoth) { |
+ MAYBE_SKIP_TEST(HaveDtlsSrtp); |
+ Base::SendSrtpToSrtp(DTLS | GCM_CIPHER, DTLS | GCM_CIPHER); |
+} |
+ |
+TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpGcmOne) { |
+ MAYBE_SKIP_TEST(HaveDtlsSrtp); |
+ Base::SendSrtpToSrtp(DTLS | GCM_CIPHER, DTLS); |
+} |
+ |
+TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpGcmTwo) { |
+ MAYBE_SKIP_TEST(HaveDtlsSrtp); |
+ Base::SendSrtpToSrtp(DTLS, DTLS | GCM_CIPHER); |
+} |
+ |
TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) { |
MAYBE_SKIP_TEST(HaveDtlsSrtp); |
Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX); |
@@ -2583,6 +2630,21 @@ TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtp) { |
Base::SendSrtpToSrtp(DTLS, DTLS); |
} |
+TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpGcmBoth) { |
+ MAYBE_SKIP_TEST(HaveDtlsSrtp); |
+ Base::SendSrtpToSrtp(DTLS | GCM_CIPHER, DTLS | GCM_CIPHER); |
+} |
+ |
+TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpGcmOne) { |
+ MAYBE_SKIP_TEST(HaveDtlsSrtp); |
+ Base::SendSrtpToSrtp(DTLS | GCM_CIPHER, DTLS); |
+} |
+ |
+TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpGcmTwo) { |
+ MAYBE_SKIP_TEST(HaveDtlsSrtp); |
+ Base::SendSrtpToSrtp(DTLS, DTLS | GCM_CIPHER); |
+} |
+ |
TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) { |
MAYBE_SKIP_TEST(HaveDtlsSrtp); |
Base::SendSrtpToSrtp(DTLS | RTCP_MUX, DTLS | RTCP_MUX); |
@@ -3262,10 +3324,14 @@ cricket::DataChannel* ChannelTest<DataTraits>::CreateChannel( |
cricket::MediaEngineInterface* engine, |
cricket::FakeDataMediaChannel* ch, |
cricket::TransportController* transport_controller, |
- bool rtcp) { |
+ int flags) { |
cricket::DataChannel* channel = |
new cricket::DataChannel(worker_thread, network_thread, ch, |
- transport_controller, cricket::CN_DATA, rtcp); |
+ transport_controller, cricket::CN_DATA, |
+ (flags & RTCP) != 0); |
+ rtc::CryptoOptions crypto_options; |
+ crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0; |
+ channel->SetCryptoOptions(crypto_options); |
if (!channel->Init_w(nullptr)) { |
delete channel; |
channel = NULL; |