| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2004 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 <algorithm> |
| 12 |
| 11 #include "webrtc/pc/srtpfilter.h" | 13 #include "webrtc/pc/srtpfilter.h" |
| 12 | 14 |
| 13 #include "third_party/libsrtp/include/srtp.h" | 15 #include "third_party/libsrtp/include/srtp.h" |
| 14 #include "webrtc/base/buffer.h" | 16 #include "webrtc/base/buffer.h" |
| 15 #include "webrtc/base/byteorder.h" | 17 #include "webrtc/base/byteorder.h" |
| 16 #include "webrtc/base/constructormagic.h" | 18 #include "webrtc/base/constructormagic.h" |
| 17 #include "webrtc/base/gunit.h" | 19 #include "webrtc/base/gunit.h" |
| 18 #include "webrtc/base/thread.h" | 20 #include "webrtc/base/thread.h" |
| 19 #include "webrtc/media/base/cryptoparams.h" | 21 #include "webrtc/media/base/cryptoparams.h" |
| 20 #include "webrtc/media/base/fakertp.h" | 22 #include "webrtc/media/base/fakertp.h" |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 | 188 |
| 187 EXPECT_TRUE(f2_.ProtectRtcp(rtcp_packet, rtcp_len, | 189 EXPECT_TRUE(f2_.ProtectRtcp(rtcp_packet, rtcp_len, |
| 188 static_cast<int>(rtcp_buffer.size()), | 190 static_cast<int>(rtcp_buffer.size()), |
| 189 &out_len)); | 191 &out_len)); |
| 190 EXPECT_EQ(out_len, rtcp_len + 4 + rtcp_auth_tag_len(cs2)); // NOLINT | 192 EXPECT_EQ(out_len, rtcp_len + 4 + rtcp_auth_tag_len(cs2)); // NOLINT |
| 191 EXPECT_NE(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len)); | 193 EXPECT_NE(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len)); |
| 192 EXPECT_TRUE(f1_.UnprotectRtcp(rtcp_packet, out_len, &out_len)); | 194 EXPECT_TRUE(f1_.UnprotectRtcp(rtcp_packet, out_len, &out_len)); |
| 193 EXPECT_EQ(rtcp_len, out_len); | 195 EXPECT_EQ(rtcp_len, out_len); |
| 194 EXPECT_EQ(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len)); | 196 EXPECT_EQ(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len)); |
| 195 } | 197 } |
| 198 void TestProtectUnprotectHeaderEncryption(const std::string& cs1, |
| 199 const std::string& cs2, |
| 200 const std::vector<int>& encrypted_header_ids) { |
| 201 rtc::Buffer rtp_buffer(sizeof(kPcmuFrameWithExtensions) + |
| 202 rtp_auth_tag_len(cs1)); |
| 203 char* rtp_packet = rtp_buffer.data<char>(); |
| 204 char original_rtp_packet[sizeof(kPcmuFrameWithExtensions)]; |
| 205 int rtp_len = sizeof(kPcmuFrameWithExtensions), out_len; |
| 206 memcpy(rtp_packet, kPcmuFrameWithExtensions, rtp_len); |
| 207 // In order to be able to run this test function multiple times we can not |
| 208 // use the same sequence number twice. Increase the sequence number by one. |
| 209 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet) + 2, |
| 210 ++sequence_number_); |
| 211 memcpy(original_rtp_packet, rtp_packet, rtp_len); |
| 212 |
| 213 EXPECT_TRUE(f1_.ProtectRtp(rtp_packet, rtp_len, |
| 214 static_cast<int>(rtp_buffer.size()), |
| 215 &out_len)); |
| 216 EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs1)); |
| 217 EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len)); |
| 218 CompareHeaderExtensions(rtp_packet, original_rtp_packet, |
| 219 encrypted_header_ids, false); |
| 220 EXPECT_TRUE(f2_.UnprotectRtp(rtp_packet, out_len, &out_len)); |
| 221 EXPECT_EQ(rtp_len, out_len); |
| 222 EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len)); |
| 223 CompareHeaderExtensions(rtp_packet, original_rtp_packet, |
| 224 encrypted_header_ids, true); |
| 225 |
| 226 EXPECT_TRUE(f2_.ProtectRtp(rtp_packet, rtp_len, |
| 227 static_cast<int>(rtp_buffer.size()), |
| 228 &out_len)); |
| 229 EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs2)); |
| 230 EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len)); |
| 231 CompareHeaderExtensions(rtp_packet, original_rtp_packet, |
| 232 encrypted_header_ids, false); |
| 233 EXPECT_TRUE(f1_.UnprotectRtp(rtp_packet, out_len, &out_len)); |
| 234 EXPECT_EQ(rtp_len, out_len); |
| 235 EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len)); |
| 236 CompareHeaderExtensions(rtp_packet, original_rtp_packet, |
| 237 encrypted_header_ids, true); |
| 238 } |
| 196 void TestProtectSetParamsDirect(bool enable_external_auth, int cs, | 239 void TestProtectSetParamsDirect(bool enable_external_auth, int cs, |
| 197 const uint8_t* key1, int key1_len, const uint8_t* key2, int key2_len, | 240 const uint8_t* key1, int key1_len, const uint8_t* key2, int key2_len, |
| 198 const std::string& cs_name) { | 241 const std::string& cs_name) { |
| 199 EXPECT_EQ(key1_len, key2_len); | 242 EXPECT_EQ(key1_len, key2_len); |
| 200 EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs)); | 243 EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs)); |
| 201 if (enable_external_auth) { | 244 if (enable_external_auth) { |
| 202 f1_.EnableExternalAuth(); | 245 f1_.EnableExternalAuth(); |
| 203 f2_.EnableExternalAuth(); | 246 f2_.EnableExternalAuth(); |
| 204 } | 247 } |
| 205 EXPECT_TRUE(f1_.SetRtpParams(cs, key1, key1_len, cs, key2, key2_len)); | 248 EXPECT_TRUE(f1_.SetRtpParams(cs, key1, key1_len, cs, key2, key2_len)); |
| 206 EXPECT_TRUE(f2_.SetRtpParams(cs, key2, key2_len, cs, key1, key1_len)); | 249 EXPECT_TRUE(f2_.SetRtpParams(cs, key2, key2_len, cs, key1, key1_len)); |
| 207 EXPECT_TRUE(f1_.SetRtcpParams(cs, key1, key1_len, cs, key2, key2_len)); | 250 EXPECT_TRUE(f1_.SetRtcpParams(cs, key1, key1_len, cs, key2, key2_len)); |
| 208 EXPECT_TRUE(f2_.SetRtcpParams(cs, key2, key2_len, cs, key1, key1_len)); | 251 EXPECT_TRUE(f2_.SetRtcpParams(cs, key2, key2_len, cs, key1, key1_len)); |
| 209 EXPECT_TRUE(f1_.IsActive()); | 252 EXPECT_TRUE(f1_.IsActive()); |
| 210 EXPECT_TRUE(f2_.IsActive()); | 253 EXPECT_TRUE(f2_.IsActive()); |
| 211 if (rtc::IsGcmCryptoSuite(cs)) { | 254 if (rtc::IsGcmCryptoSuite(cs)) { |
| 212 EXPECT_FALSE(f1_.IsExternalAuthActive()); | 255 EXPECT_FALSE(f1_.IsExternalAuthActive()); |
| 213 EXPECT_FALSE(f2_.IsExternalAuthActive()); | 256 EXPECT_FALSE(f2_.IsExternalAuthActive()); |
| 214 } else if (enable_external_auth) { | 257 } else if (enable_external_auth) { |
| 215 EXPECT_TRUE(f1_.IsExternalAuthActive()); | 258 EXPECT_TRUE(f1_.IsExternalAuthActive()); |
| 216 EXPECT_TRUE(f2_.IsExternalAuthActive()); | 259 EXPECT_TRUE(f2_.IsExternalAuthActive()); |
| 217 } | 260 } |
| 218 TestProtectUnprotect(cs_name, cs_name); | 261 TestProtectUnprotect(cs_name, cs_name); |
| 219 } | 262 } |
| 263 void TestProtectSetParamsDirectHeaderEncryption(int cs, |
| 264 const uint8_t* key1, int key1_len, const uint8_t* key2, int key2_len, |
| 265 const std::string& cs_name) { |
| 266 std::vector<int> encrypted_headers; |
| 267 encrypted_headers.push_back(1); |
| 268 // Don't encrypt header ids 2 and 3. |
| 269 encrypted_headers.push_back(4); |
| 270 EXPECT_EQ(key1_len, key2_len); |
| 271 EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs)); |
| 272 f1_.SetEncryptedHeaderExtensionIds(CS_LOCAL, encrypted_headers); |
| 273 f1_.SetEncryptedHeaderExtensionIds(CS_REMOTE, encrypted_headers); |
| 274 f2_.SetEncryptedHeaderExtensionIds(CS_LOCAL, encrypted_headers); |
| 275 f2_.SetEncryptedHeaderExtensionIds(CS_REMOTE, encrypted_headers); |
| 276 EXPECT_TRUE(f1_.SetRtpParams(cs, key1, key1_len, cs, key2, key2_len)); |
| 277 EXPECT_TRUE(f2_.SetRtpParams(cs, key2, key2_len, cs, key1, key1_len)); |
| 278 EXPECT_TRUE(f1_.IsActive()); |
| 279 EXPECT_TRUE(f2_.IsActive()); |
| 280 EXPECT_FALSE(f1_.IsExternalAuthActive()); |
| 281 EXPECT_FALSE(f2_.IsExternalAuthActive()); |
| 282 TestProtectUnprotectHeaderEncryption(cs_name, cs_name, encrypted_headers); |
| 283 } |
| 220 cricket::SrtpFilter f1_; | 284 cricket::SrtpFilter f1_; |
| 221 cricket::SrtpFilter f2_; | 285 cricket::SrtpFilter f2_; |
| 222 int sequence_number_; | 286 int sequence_number_; |
| 223 }; | 287 }; |
| 224 | 288 |
| 225 // Test that we can set up the session and keys properly. | 289 // Test that we can set up the session and keys properly. |
| 226 TEST_F(SrtpFilterTest, TestGoodSetupOneCipherSuite) { | 290 TEST_F(SrtpFilterTest, TestGoodSetupOneCipherSuite) { |
| 227 EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); | 291 EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); |
| 228 EXPECT_FALSE(f1_.IsActive()); | 292 EXPECT_FALSE(f1_.IsActive()); |
| 229 EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); | 293 EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 }; | 676 }; |
| 613 | 677 |
| 614 // Test directly setting the params with AES_CM_128_HMAC_SHA1_80. | 678 // Test directly setting the params with AES_CM_128_HMAC_SHA1_80. |
| 615 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_80) { | 679 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_80) { |
| 616 bool enable_external_auth = GetParam(); | 680 bool enable_external_auth = GetParam(); |
| 617 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_80, | 681 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_80, |
| 618 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, | 682 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, |
| 619 CS_AES_CM_128_HMAC_SHA1_80); | 683 CS_AES_CM_128_HMAC_SHA1_80); |
| 620 } | 684 } |
| 621 | 685 |
| 686 TEST_F(SrtpFilterTest, |
| 687 TestProtectSetParamsDirectHeaderEncryption_AES_CM_128_HMAC_SHA1_80) { |
| 688 TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AES128_CM_SHA1_80, |
| 689 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, |
| 690 CS_AES_CM_128_HMAC_SHA1_80); |
| 691 } |
| 692 |
| 622 // Test directly setting the params with AES_CM_128_HMAC_SHA1_32. | 693 // Test directly setting the params with AES_CM_128_HMAC_SHA1_32. |
| 623 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_32) { | 694 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_32) { |
| 624 bool enable_external_auth = GetParam(); | 695 bool enable_external_auth = GetParam(); |
| 625 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_32, | 696 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_32, |
| 626 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, | 697 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, |
| 627 CS_AES_CM_128_HMAC_SHA1_32); | 698 CS_AES_CM_128_HMAC_SHA1_32); |
| 628 } | 699 } |
| 629 | 700 |
| 701 TEST_F(SrtpFilterTest, |
| 702 TestProtectSetParamsDirectHeaderEncryption_AES_CM_128_HMAC_SHA1_32) { |
| 703 TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AES128_CM_SHA1_32, |
| 704 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, |
| 705 CS_AES_CM_128_HMAC_SHA1_32); |
| 706 } |
| 707 |
| 630 // Test directly setting the params with SRTP_AEAD_AES_128_GCM. | 708 // Test directly setting the params with SRTP_AEAD_AES_128_GCM. |
| 631 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_128_GCM) { | 709 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_128_GCM) { |
| 632 bool enable_external_auth = GetParam(); | 710 bool enable_external_auth = GetParam(); |
| 633 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AEAD_AES_128_GCM, | 711 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AEAD_AES_128_GCM, |
| 634 kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2, kTestKeyGcm128Len, | 712 kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2, kTestKeyGcm128Len, |
| 635 CS_AEAD_AES_128_GCM); | 713 CS_AEAD_AES_128_GCM); |
| 636 } | 714 } |
| 637 | 715 |
| 716 TEST_F(SrtpFilterTest, |
| 717 TestProtectSetParamsDirectHeaderEncryption_SRTP_AEAD_AES_128_GCM) { |
| 718 TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AEAD_AES_128_GCM, |
| 719 kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2, kTestKeyGcm128Len, |
| 720 CS_AEAD_AES_128_GCM); |
| 721 } |
| 722 |
| 638 // Test directly setting the params with SRTP_AEAD_AES_256_GCM. | 723 // Test directly setting the params with SRTP_AEAD_AES_256_GCM. |
| 639 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_256_GCM) { | 724 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_256_GCM) { |
| 640 bool enable_external_auth = GetParam(); | 725 bool enable_external_auth = GetParam(); |
| 641 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AEAD_AES_256_GCM, | 726 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AEAD_AES_256_GCM, |
| 642 kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2, kTestKeyGcm256Len, | 727 kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2, kTestKeyGcm256Len, |
| 643 CS_AEAD_AES_256_GCM); | 728 CS_AEAD_AES_256_GCM); |
| 644 } | 729 } |
| 645 | 730 |
| 731 TEST_F(SrtpFilterTest, |
| 732 TestProtectSetParamsDirectHeaderEncryption_SRTP_AEAD_AES_256_GCM) { |
| 733 TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AEAD_AES_256_GCM, |
| 734 kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2, kTestKeyGcm256Len, |
| 735 CS_AEAD_AES_256_GCM); |
| 736 } |
| 737 |
| 646 // Run all tests both with and without external auth enabled. | 738 // Run all tests both with and without external auth enabled. |
| 647 INSTANTIATE_TEST_CASE_P(ExternalAuth, | 739 INSTANTIATE_TEST_CASE_P(ExternalAuth, |
| 648 SrtpFilterProtectSetParamsDirectTest, | 740 SrtpFilterProtectSetParamsDirectTest, |
| 649 ::testing::Values(true, false)); | 741 ::testing::Values(true, false)); |
| 650 | 742 |
| 651 // Test directly setting the params with bogus keys. | 743 // Test directly setting the params with bogus keys. |
| 652 TEST_F(SrtpFilterTest, TestSetParamsKeyTooShort) { | 744 TEST_F(SrtpFilterTest, TestSetParamsKeyTooShort) { |
| 653 EXPECT_FALSE(f1_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, | 745 EXPECT_FALSE(f1_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, |
| 654 kTestKeyLen - 1, rtc::SRTP_AES128_CM_SHA1_80, | 746 kTestKeyLen - 1, rtc::SRTP_AES128_CM_SHA1_80, |
| 655 kTestKey1, kTestKeyLen - 1)); | 747 kTestKey1, kTestKeyLen - 1)); |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_fail); | 1095 srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_fail); |
| 1004 EXPECT_EQ(-1, mode_); | 1096 EXPECT_EQ(-1, mode_); |
| 1005 EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); | 1097 EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_); |
| 1006 // Now the error will be triggered again. | 1098 // Now the error will be triggered again. |
| 1007 Reset(); | 1099 Reset(); |
| 1008 rtc::Thread::Current()->SleepMs(210); | 1100 rtc::Thread::Current()->SleepMs(210); |
| 1009 srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_fail); | 1101 srtp_stat_.AddUnprotectRtcpResult(srtp_err_status_fail); |
| 1010 EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); | 1102 EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_); |
| 1011 EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); | 1103 EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_); |
| 1012 } | 1104 } |
| OLD | NEW |