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 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 using cricket::NS_JINGLE_RTP; | 66 using cricket::NS_JINGLE_RTP; |
67 using cricket::MEDIA_TYPE_AUDIO; | 67 using cricket::MEDIA_TYPE_AUDIO; |
68 using cricket::MEDIA_TYPE_VIDEO; | 68 using cricket::MEDIA_TYPE_VIDEO; |
69 using cricket::MEDIA_TYPE_DATA; | 69 using cricket::MEDIA_TYPE_DATA; |
70 using cricket::RtpHeaderExtension; | 70 using cricket::RtpHeaderExtension; |
71 using cricket::SEC_DISABLED; | 71 using cricket::SEC_DISABLED; |
72 using cricket::SEC_ENABLED; | 72 using cricket::SEC_ENABLED; |
73 using cricket::SEC_REQUIRED; | 73 using cricket::SEC_REQUIRED; |
74 using rtc::CS_AES_CM_128_HMAC_SHA1_32; | 74 using rtc::CS_AES_CM_128_HMAC_SHA1_32; |
75 using rtc::CS_AES_CM_128_HMAC_SHA1_80; | 75 using rtc::CS_AES_CM_128_HMAC_SHA1_80; |
| 76 using rtc::CS_AEAD_AES_128_GCM; |
| 77 using rtc::CS_AEAD_AES_256_GCM; |
76 | 78 |
77 static const AudioCodec kAudioCodecs1[] = { | 79 static const AudioCodec kAudioCodecs1[] = { |
78 AudioCodec(103, "ISAC", 16000, -1, 1), | 80 AudioCodec(103, "ISAC", 16000, -1, 1), |
79 AudioCodec(102, "iLBC", 8000, 13300, 1), | 81 AudioCodec(102, "iLBC", 8000, 13300, 1), |
80 AudioCodec(0, "PCMU", 8000, 64000, 1), | 82 AudioCodec(0, "PCMU", 8000, 64000, 1), |
81 AudioCodec(8, "PCMA", 8000, 64000, 1), | 83 AudioCodec(8, "PCMA", 8000, 64000, 1), |
82 AudioCodec(117, "red", 8000, 0, 1), | 84 AudioCodec(117, "red", 8000, 0, 1), |
83 AudioCodec(107, "CN", 48000, 0, 1)}; | 85 AudioCodec(107, "CN", 48000, 0, 1)}; |
84 | 86 |
85 static const AudioCodec kAudioCodecs2[] = { | 87 static const AudioCodec kAudioCodecs2[] = { |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 const cricket::AudioContentDescription* audio_content_desc = | 439 const cricket::AudioContentDescription* audio_content_desc = |
438 static_cast<const cricket::AudioContentDescription*>(description); | 440 static_cast<const cricket::AudioContentDescription*>(description); |
439 ASSERT(audio_content_desc != NULL); | 441 ASSERT(audio_content_desc != NULL); |
440 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) { | 442 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) { |
441 if (audio_content_desc->codecs()[i].name == "CN") | 443 if (audio_content_desc->codecs()[i].name == "CN") |
442 return false; | 444 return false; |
443 } | 445 } |
444 return true; | 446 return true; |
445 } | 447 } |
446 | 448 |
| 449 void TestVideoGcmCipher(bool gcm_offer, bool gcm_answer) { |
| 450 MediaSessionOptions offer_opts; |
| 451 offer_opts.recv_video = true; |
| 452 offer_opts.crypto_options.enable_gcm_crypto_suites = gcm_offer; |
| 453 MediaSessionOptions answer_opts; |
| 454 answer_opts.recv_video = true; |
| 455 answer_opts.crypto_options.enable_gcm_crypto_suites = gcm_answer; |
| 456 f1_.set_secure(SEC_ENABLED); |
| 457 f2_.set_secure(SEC_ENABLED); |
| 458 rtc::scoped_ptr<SessionDescription> offer( |
| 459 f1_.CreateOffer(offer_opts, NULL)); |
| 460 ASSERT_TRUE(offer.get() != NULL); |
| 461 rtc::scoped_ptr<SessionDescription> answer( |
| 462 f2_.CreateAnswer(offer.get(), answer_opts, NULL)); |
| 463 const ContentInfo* ac = answer->GetContentByName("audio"); |
| 464 const ContentInfo* vc = answer->GetContentByName("video"); |
| 465 ASSERT_TRUE(ac != NULL); |
| 466 ASSERT_TRUE(vc != NULL); |
| 467 EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type); |
| 468 EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type); |
| 469 const AudioContentDescription* acd = |
| 470 static_cast<const AudioContentDescription*>(ac->description); |
| 471 const VideoContentDescription* vcd = |
| 472 static_cast<const VideoContentDescription*>(vc->description); |
| 473 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); |
| 474 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); |
| 475 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw |
| 476 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc |
| 477 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 478 if (gcm_offer && gcm_answer) { |
| 479 ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); |
| 480 } else { |
| 481 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); |
| 482 } |
| 483 EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); |
| 484 EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs()); |
| 485 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc |
| 486 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux |
| 487 if (gcm_offer && gcm_answer) { |
| 488 ASSERT_CRYPTO(vcd, 1U, CS_AEAD_AES_256_GCM); |
| 489 } else { |
| 490 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); |
| 491 } |
| 492 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); |
| 493 } |
| 494 |
447 protected: | 495 protected: |
448 MediaSessionDescriptionFactory f1_; | 496 MediaSessionDescriptionFactory f1_; |
449 MediaSessionDescriptionFactory f2_; | 497 MediaSessionDescriptionFactory f2_; |
450 TransportDescriptionFactory tdf1_; | 498 TransportDescriptionFactory tdf1_; |
451 TransportDescriptionFactory tdf2_; | 499 TransportDescriptionFactory tdf2_; |
452 }; | 500 }; |
453 | 501 |
454 // Create a typical audio offer, and ensure it matches what we expect. | 502 // Create a typical audio offer, and ensure it matches what we expect. |
455 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { | 503 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { |
456 f1_.set_secure(SEC_ENABLED); | 504 f1_.set_secure(SEC_ENABLED); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 static_cast<const AudioContentDescription*>(ac->description); | 798 static_cast<const AudioContentDescription*>(ac->description); |
751 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | 799 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); |
752 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); | 800 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); |
753 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc | 801 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc |
754 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw | 802 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw |
755 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 803 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
756 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 804 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); |
757 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), acd->protocol()); | 805 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), acd->protocol()); |
758 } | 806 } |
759 | 807 |
| 808 // Create a typical audio answer with GCM ciphers enabled, and ensure it |
| 809 // matches what we expect. |
| 810 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { |
| 811 f1_.set_secure(SEC_ENABLED); |
| 812 f2_.set_secure(SEC_ENABLED); |
| 813 MediaSessionOptions options; |
| 814 options.crypto_options.enable_gcm_crypto_suites = true; |
| 815 rtc::scoped_ptr<SessionDescription> offer( |
| 816 f1_.CreateOffer(options, NULL)); |
| 817 ASSERT_TRUE(offer.get() != NULL); |
| 818 rtc::scoped_ptr<SessionDescription> answer( |
| 819 f2_.CreateAnswer(offer.get(), options, NULL)); |
| 820 const ContentInfo* ac = answer->GetContentByName("audio"); |
| 821 const ContentInfo* vc = answer->GetContentByName("video"); |
| 822 ASSERT_TRUE(ac != NULL); |
| 823 ASSERT_TRUE(vc == NULL); |
| 824 EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type); |
| 825 const AudioContentDescription* acd = |
| 826 static_cast<const AudioContentDescription*>(ac->description); |
| 827 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); |
| 828 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); |
| 829 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc |
| 830 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw |
| 831 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 832 ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); |
| 833 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), acd->protocol()); |
| 834 } |
| 835 |
760 // Create a typical video answer, and ensure it matches what we expect. | 836 // Create a typical video answer, and ensure it matches what we expect. |
761 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { | 837 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { |
762 MediaSessionOptions opts; | 838 MediaSessionOptions opts; |
763 opts.recv_video = true; | 839 opts.recv_video = true; |
764 f1_.set_secure(SEC_ENABLED); | 840 f1_.set_secure(SEC_ENABLED); |
765 f2_.set_secure(SEC_ENABLED); | 841 f2_.set_secure(SEC_ENABLED); |
766 std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 842 std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); |
767 ASSERT_TRUE(offer.get() != NULL); | 843 ASSERT_TRUE(offer.get() != NULL); |
768 std::unique_ptr<SessionDescription> answer( | 844 std::unique_ptr<SessionDescription> answer( |
769 f2_.CreateAnswer(offer.get(), opts, NULL)); | 845 f2_.CreateAnswer(offer.get(), opts, NULL)); |
(...skipping 14 matching lines...) Expand all Loading... |
784 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 860 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
785 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 861 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); |
786 EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); | 862 EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); |
787 EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs()); | 863 EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs()); |
788 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc | 864 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc |
789 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux | 865 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux |
790 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); | 866 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); |
791 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); | 867 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); |
792 } | 868 } |
793 | 869 |
| 870 // Create a typical video answer with GCM ciphers enabled, and ensure it |
| 871 // matches what we expect. |
| 872 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcm) { |
| 873 TestVideoGcmCipher(true, true); |
| 874 } |
| 875 |
| 876 // Create a typical video answer with GCM ciphers enabled for the offer only, |
| 877 // and ensure it matches what we expect. |
| 878 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmOffer) { |
| 879 TestVideoGcmCipher(true, false); |
| 880 } |
| 881 |
| 882 // Create a typical video answer with GCM ciphers enabled for the answer only, |
| 883 // and ensure it matches what we expect. |
| 884 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmAnswer) { |
| 885 TestVideoGcmCipher(false, true); |
| 886 } |
| 887 |
794 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswer) { | 888 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswer) { |
795 MediaSessionOptions opts; | 889 MediaSessionOptions opts; |
796 opts.data_channel_type = cricket::DCT_RTP; | 890 opts.data_channel_type = cricket::DCT_RTP; |
797 f1_.set_secure(SEC_ENABLED); | 891 f1_.set_secure(SEC_ENABLED); |
798 f2_.set_secure(SEC_ENABLED); | 892 f2_.set_secure(SEC_ENABLED); |
799 std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); | 893 std::unique_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); |
800 ASSERT_TRUE(offer.get() != NULL); | 894 ASSERT_TRUE(offer.get() != NULL); |
801 std::unique_ptr<SessionDescription> answer( | 895 std::unique_ptr<SessionDescription> answer( |
802 f2_.CreateAnswer(offer.get(), opts, NULL)); | 896 f2_.CreateAnswer(offer.get(), opts, NULL)); |
803 const ContentInfo* ac = answer->GetContentByName("audio"); | 897 const ContentInfo* ac = answer->GetContentByName("audio"); |
(...skipping 13 matching lines...) Expand all Loading... |
817 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux | 911 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
818 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); | 912 ASSERT_CRYPTO(acd, 1U, CS_AES_CM_128_HMAC_SHA1_32); |
819 EXPECT_EQ(MEDIA_TYPE_DATA, vcd->type()); | 913 EXPECT_EQ(MEDIA_TYPE_DATA, vcd->type()); |
820 EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), vcd->codecs()); | 914 EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), vcd->codecs()); |
821 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc | 915 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc |
822 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux | 916 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux |
823 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); | 917 ASSERT_CRYPTO(vcd, 1U, CS_AES_CM_128_HMAC_SHA1_80); |
824 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); | 918 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); |
825 } | 919 } |
826 | 920 |
| 921 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerGcm) { |
| 922 MediaSessionOptions opts; |
| 923 opts.data_channel_type = cricket::DCT_RTP; |
| 924 opts.crypto_options.enable_gcm_crypto_suites = true; |
| 925 f1_.set_secure(SEC_ENABLED); |
| 926 f2_.set_secure(SEC_ENABLED); |
| 927 rtc::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL)); |
| 928 ASSERT_TRUE(offer.get() != NULL); |
| 929 rtc::scoped_ptr<SessionDescription> answer( |
| 930 f2_.CreateAnswer(offer.get(), opts, NULL)); |
| 931 const ContentInfo* ac = answer->GetContentByName("audio"); |
| 932 const ContentInfo* vc = answer->GetContentByName("data"); |
| 933 ASSERT_TRUE(ac != NULL); |
| 934 ASSERT_TRUE(vc != NULL); |
| 935 EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type); |
| 936 EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type); |
| 937 const AudioContentDescription* acd = |
| 938 static_cast<const AudioContentDescription*>(ac->description); |
| 939 const DataContentDescription* vcd = |
| 940 static_cast<const DataContentDescription*>(vc->description); |
| 941 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); |
| 942 EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs()); |
| 943 EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw |
| 944 EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc |
| 945 EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux |
| 946 ASSERT_CRYPTO(acd, 1U, CS_AEAD_AES_256_GCM); |
| 947 EXPECT_EQ(MEDIA_TYPE_DATA, vcd->type()); |
| 948 EXPECT_EQ(MAKE_VECTOR(kDataCodecsAnswer), vcd->codecs()); |
| 949 EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc |
| 950 EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux |
| 951 ASSERT_CRYPTO(vcd, 1U, CS_AEAD_AES_256_GCM); |
| 952 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf), vcd->protocol()); |
| 953 } |
| 954 |
827 // Verifies that the order of the media contents in the offer is preserved in | 955 // Verifies that the order of the media contents in the offer is preserved in |
828 // the answer. | 956 // the answer. |
829 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAnswerContentOrder) { | 957 TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAnswerContentOrder) { |
830 MediaSessionOptions opts; | 958 MediaSessionOptions opts; |
831 | 959 |
832 // Creates a data only offer. | 960 // Creates a data only offer. |
833 opts.recv_audio = false; | 961 opts.recv_audio = false; |
834 opts.data_channel_type = cricket::DCT_SCTP; | 962 opts.data_channel_type = cricket::DCT_SCTP; |
835 std::unique_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL)); | 963 std::unique_ptr<SessionDescription> offer1(f1_.CreateOffer(opts, NULL)); |
836 ASSERT_TRUE(offer1.get() != NULL); | 964 ASSERT_TRUE(offer1.get() != NULL); |
(...skipping 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 const ContentInfo* audio_content = GetFirstAudioContent(updated_offer.get()); | 2500 const ContentInfo* audio_content = GetFirstAudioContent(updated_offer.get()); |
2373 const ContentInfo* video_content = GetFirstVideoContent(updated_offer.get()); | 2501 const ContentInfo* video_content = GetFirstVideoContent(updated_offer.get()); |
2374 const ContentInfo* data_content = GetFirstDataContent(updated_offer.get()); | 2502 const ContentInfo* data_content = GetFirstDataContent(updated_offer.get()); |
2375 ASSERT_TRUE(audio_content != nullptr); | 2503 ASSERT_TRUE(audio_content != nullptr); |
2376 ASSERT_TRUE(video_content != nullptr); | 2504 ASSERT_TRUE(video_content != nullptr); |
2377 ASSERT_TRUE(data_content != nullptr); | 2505 ASSERT_TRUE(data_content != nullptr); |
2378 EXPECT_EQ("audio_modified", audio_content->name); | 2506 EXPECT_EQ("audio_modified", audio_content->name); |
2379 EXPECT_EQ("video_modified", video_content->name); | 2507 EXPECT_EQ("video_modified", video_content->name); |
2380 EXPECT_EQ("data_modified", data_content->name); | 2508 EXPECT_EQ("data_modified", data_content->name); |
2381 } | 2509 } |
OLD | NEW |