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 size_t rtp_packet_size = rtp_buffer.size(); |
| 205 char original_rtp_packet[sizeof(kPcmuFrameWithExtensions)]; |
| 206 size_t original_rtp_packet_size = sizeof(original_rtp_packet); |
| 207 int rtp_len = sizeof(kPcmuFrameWithExtensions), out_len; |
| 208 memcpy(rtp_packet, kPcmuFrameWithExtensions, rtp_len); |
| 209 // In order to be able to run this test function multiple times we can not |
| 210 // use the same sequence number twice. Increase the sequence number by one. |
| 211 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet) + 2, |
| 212 ++sequence_number_); |
| 213 memcpy(original_rtp_packet, rtp_packet, rtp_len); |
| 214 |
| 215 EXPECT_TRUE(f1_.ProtectRtp(rtp_packet, rtp_len, |
| 216 static_cast<int>(rtp_buffer.size()), |
| 217 &out_len)); |
| 218 EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs1)); |
| 219 EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len)); |
| 220 CompareHeaderExtensions(rtp_packet, rtp_packet_size, |
| 221 original_rtp_packet, original_rtp_packet_size, |
| 222 encrypted_header_ids, false); |
| 223 EXPECT_TRUE(f2_.UnprotectRtp(rtp_packet, out_len, &out_len)); |
| 224 EXPECT_EQ(rtp_len, out_len); |
| 225 EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len)); |
| 226 CompareHeaderExtensions(rtp_packet, rtp_packet_size, |
| 227 original_rtp_packet, original_rtp_packet_size, |
| 228 encrypted_header_ids, true); |
| 229 |
| 230 EXPECT_TRUE(f2_.ProtectRtp(rtp_packet, rtp_len, |
| 231 static_cast<int>(rtp_buffer.size()), |
| 232 &out_len)); |
| 233 EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs2)); |
| 234 EXPECT_NE(0, memcmp(rtp_packet, original_rtp_packet, rtp_len)); |
| 235 CompareHeaderExtensions(rtp_packet, rtp_packet_size, |
| 236 original_rtp_packet, original_rtp_packet_size, |
| 237 encrypted_header_ids, false); |
| 238 EXPECT_TRUE(f1_.UnprotectRtp(rtp_packet, out_len, &out_len)); |
| 239 EXPECT_EQ(rtp_len, out_len); |
| 240 EXPECT_EQ(0, memcmp(rtp_packet, original_rtp_packet, rtp_len)); |
| 241 CompareHeaderExtensions(rtp_packet, rtp_packet_size, |
| 242 original_rtp_packet, original_rtp_packet_size, |
| 243 encrypted_header_ids, true); |
| 244 } |
196 void TestProtectSetParamsDirect(bool enable_external_auth, int cs, | 245 void TestProtectSetParamsDirect(bool enable_external_auth, int cs, |
197 const uint8_t* key1, int key1_len, const uint8_t* key2, int key2_len, | 246 const uint8_t* key1, int key1_len, const uint8_t* key2, int key2_len, |
198 const std::string& cs_name) { | 247 const std::string& cs_name) { |
199 EXPECT_EQ(key1_len, key2_len); | 248 EXPECT_EQ(key1_len, key2_len); |
200 EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs)); | 249 EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs)); |
201 if (enable_external_auth) { | 250 if (enable_external_auth) { |
202 f1_.EnableExternalAuth(); | 251 f1_.EnableExternalAuth(); |
203 f2_.EnableExternalAuth(); | 252 f2_.EnableExternalAuth(); |
204 } | 253 } |
205 EXPECT_TRUE(f1_.SetRtpParams(cs, key1, key1_len, cs, key2, key2_len)); | 254 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)); | 255 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)); | 256 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)); | 257 EXPECT_TRUE(f2_.SetRtcpParams(cs, key2, key2_len, cs, key1, key1_len)); |
209 EXPECT_TRUE(f1_.IsActive()); | 258 EXPECT_TRUE(f1_.IsActive()); |
210 EXPECT_TRUE(f2_.IsActive()); | 259 EXPECT_TRUE(f2_.IsActive()); |
211 if (rtc::IsGcmCryptoSuite(cs)) { | 260 if (rtc::IsGcmCryptoSuite(cs)) { |
212 EXPECT_FALSE(f1_.IsExternalAuthActive()); | 261 EXPECT_FALSE(f1_.IsExternalAuthActive()); |
213 EXPECT_FALSE(f2_.IsExternalAuthActive()); | 262 EXPECT_FALSE(f2_.IsExternalAuthActive()); |
214 } else if (enable_external_auth) { | 263 } else if (enable_external_auth) { |
215 EXPECT_TRUE(f1_.IsExternalAuthActive()); | 264 EXPECT_TRUE(f1_.IsExternalAuthActive()); |
216 EXPECT_TRUE(f2_.IsExternalAuthActive()); | 265 EXPECT_TRUE(f2_.IsExternalAuthActive()); |
217 } | 266 } |
218 TestProtectUnprotect(cs_name, cs_name); | 267 TestProtectUnprotect(cs_name, cs_name); |
219 } | 268 } |
| 269 void TestProtectSetParamsDirectHeaderEncryption(int cs, |
| 270 const uint8_t* key1, int key1_len, const uint8_t* key2, int key2_len, |
| 271 const std::string& cs_name) { |
| 272 std::vector<int> encrypted_headers; |
| 273 encrypted_headers.push_back(1); |
| 274 // Don't encrypt header ids 2 and 3. |
| 275 encrypted_headers.push_back(4); |
| 276 EXPECT_EQ(key1_len, key2_len); |
| 277 EXPECT_EQ(cs_name, rtc::SrtpCryptoSuiteToName(cs)); |
| 278 f1_.SetEncryptedHeaderExtensionIds(CS_LOCAL, encrypted_headers); |
| 279 f1_.SetEncryptedHeaderExtensionIds(CS_REMOTE, encrypted_headers); |
| 280 f2_.SetEncryptedHeaderExtensionIds(CS_LOCAL, encrypted_headers); |
| 281 f2_.SetEncryptedHeaderExtensionIds(CS_REMOTE, encrypted_headers); |
| 282 EXPECT_TRUE(f1_.SetRtpParams(cs, key1, key1_len, cs, key2, key2_len)); |
| 283 EXPECT_TRUE(f2_.SetRtpParams(cs, key2, key2_len, cs, key1, key1_len)); |
| 284 EXPECT_TRUE(f1_.IsActive()); |
| 285 EXPECT_TRUE(f2_.IsActive()); |
| 286 EXPECT_FALSE(f1_.IsExternalAuthActive()); |
| 287 EXPECT_FALSE(f2_.IsExternalAuthActive()); |
| 288 TestProtectUnprotectHeaderEncryption(cs_name, cs_name, encrypted_headers); |
| 289 } |
220 cricket::SrtpFilter f1_; | 290 cricket::SrtpFilter f1_; |
221 cricket::SrtpFilter f2_; | 291 cricket::SrtpFilter f2_; |
222 int sequence_number_; | 292 int sequence_number_; |
223 }; | 293 }; |
224 | 294 |
225 // Test that we can set up the session and keys properly. | 295 // Test that we can set up the session and keys properly. |
226 TEST_F(SrtpFilterTest, TestGoodSetupOneCipherSuite) { | 296 TEST_F(SrtpFilterTest, TestGoodSetupOneCipherSuite) { |
227 EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); | 297 EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); |
228 EXPECT_FALSE(f1_.IsActive()); | 298 EXPECT_FALSE(f1_.IsActive()); |
229 EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); | 299 EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 }; | 682 }; |
613 | 683 |
614 // Test directly setting the params with AES_CM_128_HMAC_SHA1_80. | 684 // Test directly setting the params with AES_CM_128_HMAC_SHA1_80. |
615 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_80) { | 685 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_80) { |
616 bool enable_external_auth = GetParam(); | 686 bool enable_external_auth = GetParam(); |
617 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_80, | 687 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_80, |
618 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, | 688 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, |
619 CS_AES_CM_128_HMAC_SHA1_80); | 689 CS_AES_CM_128_HMAC_SHA1_80); |
620 } | 690 } |
621 | 691 |
| 692 TEST_F(SrtpFilterTest, |
| 693 TestProtectSetParamsDirectHeaderEncryption_AES_CM_128_HMAC_SHA1_80) { |
| 694 TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AES128_CM_SHA1_80, |
| 695 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, |
| 696 CS_AES_CM_128_HMAC_SHA1_80); |
| 697 } |
| 698 |
622 // Test directly setting the params with AES_CM_128_HMAC_SHA1_32. | 699 // Test directly setting the params with AES_CM_128_HMAC_SHA1_32. |
623 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_32) { | 700 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_AES_CM_128_HMAC_SHA1_32) { |
624 bool enable_external_auth = GetParam(); | 701 bool enable_external_auth = GetParam(); |
625 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_32, | 702 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AES128_CM_SHA1_32, |
626 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, | 703 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, |
627 CS_AES_CM_128_HMAC_SHA1_32); | 704 CS_AES_CM_128_HMAC_SHA1_32); |
628 } | 705 } |
629 | 706 |
| 707 TEST_F(SrtpFilterTest, |
| 708 TestProtectSetParamsDirectHeaderEncryption_AES_CM_128_HMAC_SHA1_32) { |
| 709 TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AES128_CM_SHA1_32, |
| 710 kTestKey1, kTestKeyLen, kTestKey2, kTestKeyLen, |
| 711 CS_AES_CM_128_HMAC_SHA1_32); |
| 712 } |
| 713 |
630 // Test directly setting the params with SRTP_AEAD_AES_128_GCM. | 714 // Test directly setting the params with SRTP_AEAD_AES_128_GCM. |
631 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_128_GCM) { | 715 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_128_GCM) { |
632 bool enable_external_auth = GetParam(); | 716 bool enable_external_auth = GetParam(); |
633 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AEAD_AES_128_GCM, | 717 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AEAD_AES_128_GCM, |
634 kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2, kTestKeyGcm128Len, | 718 kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2, kTestKeyGcm128Len, |
635 CS_AEAD_AES_128_GCM); | 719 CS_AEAD_AES_128_GCM); |
636 } | 720 } |
637 | 721 |
| 722 TEST_F(SrtpFilterTest, |
| 723 TestProtectSetParamsDirectHeaderEncryption_SRTP_AEAD_AES_128_GCM) { |
| 724 TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AEAD_AES_128_GCM, |
| 725 kTestKeyGcm128_1, kTestKeyGcm128Len, kTestKeyGcm128_2, kTestKeyGcm128Len, |
| 726 CS_AEAD_AES_128_GCM); |
| 727 } |
| 728 |
638 // Test directly setting the params with SRTP_AEAD_AES_256_GCM. | 729 // Test directly setting the params with SRTP_AEAD_AES_256_GCM. |
639 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_256_GCM) { | 730 TEST_P(SrtpFilterProtectSetParamsDirectTest, Test_SRTP_AEAD_AES_256_GCM) { |
640 bool enable_external_auth = GetParam(); | 731 bool enable_external_auth = GetParam(); |
641 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AEAD_AES_256_GCM, | 732 TestProtectSetParamsDirect(enable_external_auth, rtc::SRTP_AEAD_AES_256_GCM, |
642 kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2, kTestKeyGcm256Len, | 733 kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2, kTestKeyGcm256Len, |
643 CS_AEAD_AES_256_GCM); | 734 CS_AEAD_AES_256_GCM); |
644 } | 735 } |
645 | 736 |
| 737 TEST_F(SrtpFilterTest, |
| 738 TestProtectSetParamsDirectHeaderEncryption_SRTP_AEAD_AES_256_GCM) { |
| 739 TestProtectSetParamsDirectHeaderEncryption(rtc::SRTP_AEAD_AES_256_GCM, |
| 740 kTestKeyGcm256_1, kTestKeyGcm256Len, kTestKeyGcm256_2, kTestKeyGcm256Len, |
| 741 CS_AEAD_AES_256_GCM); |
| 742 } |
| 743 |
646 // Run all tests both with and without external auth enabled. | 744 // Run all tests both with and without external auth enabled. |
647 INSTANTIATE_TEST_CASE_P(ExternalAuth, | 745 INSTANTIATE_TEST_CASE_P(ExternalAuth, |
648 SrtpFilterProtectSetParamsDirectTest, | 746 SrtpFilterProtectSetParamsDirectTest, |
649 ::testing::Values(true, false)); | 747 ::testing::Values(true, false)); |
650 | 748 |
651 // Test directly setting the params with bogus keys. | 749 // Test directly setting the params with bogus keys. |
652 TEST_F(SrtpFilterTest, TestSetParamsKeyTooShort) { | 750 TEST_F(SrtpFilterTest, TestSetParamsKeyTooShort) { |
653 EXPECT_FALSE(f1_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, | 751 EXPECT_FALSE(f1_.SetRtpParams(rtc::SRTP_AES128_CM_SHA1_80, kTestKey1, |
654 kTestKeyLen - 1, rtc::SRTP_AES128_CM_SHA1_80, | 752 kTestKeyLen - 1, rtc::SRTP_AES128_CM_SHA1_80, |
655 kTestKey1, kTestKeyLen - 1)); | 753 kTestKey1, kTestKeyLen - 1)); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 | 932 |
835 // Go back to normal sequence nubmer. | 933 // Go back to normal sequence nubmer. |
836 // NOTE: without the fix in libsrtp, this would fail. This is because | 934 // NOTE: without the fix in libsrtp, this would fail. This is because |
837 // without the fix, the loop above would keep incrementing local sequence | 935 // without the fix, the loop above would keep incrementing local sequence |
838 // number in libsrtp, eventually the new sequence number would go out side | 936 // number in libsrtp, eventually the new sequence number would go out side |
839 // of the window. | 937 // of the window. |
840 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2, seqnum_small + 1); | 938 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_) + 2, seqnum_small + 1); |
841 EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), | 939 EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_), |
842 &out_len)); | 940 &out_len)); |
843 } | 941 } |
OLD | NEW |