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 |