blob: f8f48bc1dc762209f48a2c410d1f0b1b22f689ca [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2012 The WebRTC Project Authors. All rights reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
jbauch555604a2016-04-26 03:13:22 -070011#include <memory>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000012#include <string>
13#include <vector>
14
kjellanderf4752772016-03-02 05:42:30 -080015#include "webrtc/p2p/base/p2pconstants.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000016#include "webrtc/p2p/base/transportdescription.h"
17#include "webrtc/p2p/base/transportdescriptionfactory.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020018#include "webrtc/rtc_base/fakesslidentity.h"
19#include "webrtc/rtc_base/gunit.h"
20#include "webrtc/rtc_base/ssladapter.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000021
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000022using cricket::TransportDescriptionFactory;
23using cricket::TransportDescription;
24using cricket::TransportOptions;
25
26class TransportDescriptionFactoryTest : public testing::Test {
27 public:
28 TransportDescriptionFactoryTest()
jbauch555604a2016-04-26 03:13:22 -070029 : cert1_(rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
30 new rtc::FakeSSLIdentity("User1")))),
31 cert2_(rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
32 new rtc::FakeSSLIdentity("User2")))) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000033
Peter Thatcher7cbd1882015-09-17 18:54:52 -070034 void CheckDesc(const TransportDescription* desc,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000035 const std::string& opt, const std::string& ice_ufrag,
36 const std::string& ice_pwd, const std::string& dtls_alg) {
37 ASSERT_TRUE(desc != NULL);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000038 EXPECT_EQ(!opt.empty(), desc->HasOption(opt));
39 if (ice_ufrag.empty() && ice_pwd.empty()) {
40 EXPECT_EQ(static_cast<size_t>(cricket::ICE_UFRAG_LENGTH),
41 desc->ice_ufrag.size());
42 EXPECT_EQ(static_cast<size_t>(cricket::ICE_PWD_LENGTH),
43 desc->ice_pwd.size());
44 } else {
45 EXPECT_EQ(ice_ufrag, desc->ice_ufrag);
46 EXPECT_EQ(ice_pwd, desc->ice_pwd);
47 }
48 if (dtls_alg.empty()) {
49 EXPECT_TRUE(desc->identity_fingerprint.get() == NULL);
50 } else {
51 ASSERT_TRUE(desc->identity_fingerprint.get() != NULL);
52 EXPECT_EQ(desc->identity_fingerprint->algorithm, dtls_alg);
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06 +000053 EXPECT_GT(desc->identity_fingerprint->digest.size(), 0U);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054 }
55 }
56
57 // This test ice restart by doing two offer answer exchanges. On the second
58 // exchange ice is restarted. The test verifies that the ufrag and password
59 // in the offer and answer is changed.
60 // If |dtls| is true, the test verifies that the finger print is not changed.
61 void TestIceRestart(bool dtls) {
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070062 SetDtls(dtls);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000063 cricket::TransportOptions options;
64 // The initial offer / answer exchange.
jbauch555604a2016-04-26 03:13:22 -070065 std::unique_ptr<TransportDescription> offer(f1_.CreateOffer(options, NULL));
66 std::unique_ptr<TransportDescription> answer(
deadbeefb7892532017-02-22 19:35:18 -080067 f2_.CreateAnswer(offer.get(), options, true, NULL));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000068
69 // Create an updated offer where we restart ice.
70 options.ice_restart = true;
jbauch555604a2016-04-26 03:13:22 -070071 std::unique_ptr<TransportDescription> restart_offer(
72 f1_.CreateOffer(options, offer.get()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000073
74 VerifyUfragAndPasswordChanged(dtls, offer.get(), restart_offer.get());
75
76 // Create a new answer. The transport ufrag and password is changed since
77 // |options.ice_restart == true|
jbauch555604a2016-04-26 03:13:22 -070078 std::unique_ptr<TransportDescription> restart_answer(
deadbeefb7892532017-02-22 19:35:18 -080079 f2_.CreateAnswer(restart_offer.get(), options, true, answer.get()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000080 ASSERT_TRUE(restart_answer.get() != NULL);
81
82 VerifyUfragAndPasswordChanged(dtls, answer.get(), restart_answer.get());
83 }
84
85 void VerifyUfragAndPasswordChanged(bool dtls,
86 const TransportDescription* org_desc,
87 const TransportDescription* restart_desc) {
88 EXPECT_NE(org_desc->ice_pwd, restart_desc->ice_pwd);
89 EXPECT_NE(org_desc->ice_ufrag, restart_desc->ice_ufrag);
90 EXPECT_EQ(static_cast<size_t>(cricket::ICE_UFRAG_LENGTH),
91 restart_desc->ice_ufrag.size());
92 EXPECT_EQ(static_cast<size_t>(cricket::ICE_PWD_LENGTH),
93 restart_desc->ice_pwd.size());
94 // If DTLS is enabled, make sure the finger print is unchanged.
95 if (dtls) {
96 EXPECT_FALSE(
97 org_desc->identity_fingerprint->GetRfc4572Fingerprint().empty());
98 EXPECT_EQ(org_desc->identity_fingerprint->GetRfc4572Fingerprint(),
99 restart_desc->identity_fingerprint->GetRfc4572Fingerprint());
100 }
101 }
102
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700103 void TestIceRenomination(bool dtls) {
104 SetDtls(dtls);
105
106 cricket::TransportOptions options;
107 // The initial offer / answer exchange.
108 std::unique_ptr<TransportDescription> offer(
109 f1_.CreateOffer(options, nullptr));
110 std::unique_ptr<TransportDescription> answer(
deadbeefb7892532017-02-22 19:35:18 -0800111 f2_.CreateAnswer(offer.get(), options, true, nullptr));
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700112 VerifyRenomination(offer.get(), false);
113 VerifyRenomination(answer.get(), false);
114
115 options.enable_ice_renomination = true;
116 std::unique_ptr<TransportDescription> renomination_offer(
117 f1_.CreateOffer(options, offer.get()));
118 VerifyRenomination(renomination_offer.get(), true);
119
deadbeefb7892532017-02-22 19:35:18 -0800120 std::unique_ptr<TransportDescription> renomination_answer(f2_.CreateAnswer(
121 renomination_offer.get(), options, true, answer.get()));
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700122 VerifyRenomination(renomination_answer.get(), true);
123 }
124
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000125 protected:
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700126 void VerifyRenomination(TransportDescription* desc,
127 bool renomination_expected) {
128 ASSERT_TRUE(desc != nullptr);
129 std::vector<std::string>& options = desc->transport_options;
deadbeef30952b42017-04-21 02:41:29 -0700130 auto iter = std::find(options.begin(), options.end(), "renomination");
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700131 EXPECT_EQ(renomination_expected, iter != options.end());
132 }
133
134 void SetDtls(bool dtls) {
135 if (dtls) {
136 f1_.set_secure(cricket::SEC_ENABLED);
137 f2_.set_secure(cricket::SEC_ENABLED);
138 f1_.set_certificate(cert1_);
139 f2_.set_certificate(cert2_);
140 } else {
141 f1_.set_secure(cricket::SEC_DISABLED);
142 f2_.set_secure(cricket::SEC_DISABLED);
143 }
144 }
145
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000146 TransportDescriptionFactory f1_;
147 TransportDescriptionFactory f2_;
Henrik Boström3a14bf32015-08-31 09:27:58 +0200148
149 rtc::scoped_refptr<rtc::RTCCertificate> cert1_;
150 rtc::scoped_refptr<rtc::RTCCertificate> cert2_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000151};
152
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700153TEST_F(TransportDescriptionFactoryTest, TestOfferDefault) {
jbauch555604a2016-04-26 03:13:22 -0700154 std::unique_ptr<TransportDescription> desc(
155 f1_.CreateOffer(TransportOptions(), NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700156 CheckDesc(desc.get(), "", "", "", "");
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000157}
158
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700159TEST_F(TransportDescriptionFactoryTest, TestOfferDtls) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000160 f1_.set_secure(cricket::SEC_ENABLED);
Henrik Boström3a14bf32015-08-31 09:27:58 +0200161 f1_.set_certificate(cert1_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000162 std::string digest_alg;
Henrik Boström3a14bf32015-08-31 09:27:58 +0200163 ASSERT_TRUE(cert1_->ssl_certificate().GetSignatureDigestAlgorithm(
164 &digest_alg));
jbauch555604a2016-04-26 03:13:22 -0700165 std::unique_ptr<TransportDescription> desc(
166 f1_.CreateOffer(TransportOptions(), NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700167 CheckDesc(desc.get(), "", "", "", digest_alg);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000168 // Ensure it also works with SEC_REQUIRED.
169 f1_.set_secure(cricket::SEC_REQUIRED);
170 desc.reset(f1_.CreateOffer(TransportOptions(), NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700171 CheckDesc(desc.get(), "", "", "", digest_alg);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000172}
173
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700174// Test generating an offer with DTLS fails with no identity.
175TEST_F(TransportDescriptionFactoryTest, TestOfferDtlsWithNoIdentity) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000176 f1_.set_secure(cricket::SEC_ENABLED);
jbauch555604a2016-04-26 03:13:22 -0700177 std::unique_ptr<TransportDescription> desc(
178 f1_.CreateOffer(TransportOptions(), NULL));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000179 ASSERT_TRUE(desc.get() == NULL);
180}
181
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700182// Test updating an offer with DTLS to pick ICE.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000183// The ICE credentials should stay the same in the new offer.
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700184TEST_F(TransportDescriptionFactoryTest, TestOfferDtlsReofferDtls) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000185 f1_.set_secure(cricket::SEC_ENABLED);
Henrik Boström3a14bf32015-08-31 09:27:58 +0200186 f1_.set_certificate(cert1_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000187 std::string digest_alg;
Henrik Boström3a14bf32015-08-31 09:27:58 +0200188 ASSERT_TRUE(cert1_->ssl_certificate().GetSignatureDigestAlgorithm(
189 &digest_alg));
jbauch555604a2016-04-26 03:13:22 -0700190 std::unique_ptr<TransportDescription> old_desc(
191 f1_.CreateOffer(TransportOptions(), NULL));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000192 ASSERT_TRUE(old_desc.get() != NULL);
jbauch555604a2016-04-26 03:13:22 -0700193 std::unique_ptr<TransportDescription> desc(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000194 f1_.CreateOffer(TransportOptions(), old_desc.get()));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700195 CheckDesc(desc.get(), "",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000196 old_desc->ice_ufrag, old_desc->ice_pwd, digest_alg);
197}
198
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700199TEST_F(TransportDescriptionFactoryTest, TestAnswerDefault) {
jbauch555604a2016-04-26 03:13:22 -0700200 std::unique_ptr<TransportDescription> offer(
201 f1_.CreateOffer(TransportOptions(), NULL));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000202 ASSERT_TRUE(offer.get() != NULL);
jbauch555604a2016-04-26 03:13:22 -0700203 std::unique_ptr<TransportDescription> desc(
deadbeefb7892532017-02-22 19:35:18 -0800204 f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700205 CheckDesc(desc.get(), "", "", "", "");
deadbeefb7892532017-02-22 19:35:18 -0800206 desc.reset(f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700207 CheckDesc(desc.get(), "", "", "", "");
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000208}
209
210// Test that we can update an answer properly; ICE credentials shouldn't change.
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700211TEST_F(TransportDescriptionFactoryTest, TestReanswer) {
jbauch555604a2016-04-26 03:13:22 -0700212 std::unique_ptr<TransportDescription> offer(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000213 f1_.CreateOffer(TransportOptions(), NULL));
214 ASSERT_TRUE(offer.get() != NULL);
jbauch555604a2016-04-26 03:13:22 -0700215 std::unique_ptr<TransportDescription> old_desc(
deadbeefb7892532017-02-22 19:35:18 -0800216 f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000217 ASSERT_TRUE(old_desc.get() != NULL);
jbauch555604a2016-04-26 03:13:22 -0700218 std::unique_ptr<TransportDescription> desc(
deadbeefb7892532017-02-22 19:35:18 -0800219 f2_.CreateAnswer(offer.get(), TransportOptions(), true, old_desc.get()));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000220 ASSERT_TRUE(desc.get() != NULL);
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700221 CheckDesc(desc.get(), "",
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000222 old_desc->ice_ufrag, old_desc->ice_pwd, "");
223}
224
225// Test that we handle answering an offer with DTLS with no DTLS.
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700226TEST_F(TransportDescriptionFactoryTest, TestAnswerDtlsToNoDtls) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000227 f1_.set_secure(cricket::SEC_ENABLED);
Henrik Boström3a14bf32015-08-31 09:27:58 +0200228 f1_.set_certificate(cert1_);
jbauch555604a2016-04-26 03:13:22 -0700229 std::unique_ptr<TransportDescription> offer(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000230 f1_.CreateOffer(TransportOptions(), NULL));
231 ASSERT_TRUE(offer.get() != NULL);
jbauch555604a2016-04-26 03:13:22 -0700232 std::unique_ptr<TransportDescription> desc(
deadbeefb7892532017-02-22 19:35:18 -0800233 f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700234 CheckDesc(desc.get(), "", "", "", "");
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000235}
236
237// Test that we handle answering an offer without DTLS if we have DTLS enabled,
238// but fail if we require DTLS.
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700239TEST_F(TransportDescriptionFactoryTest, TestAnswerNoDtlsToDtls) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000240 f2_.set_secure(cricket::SEC_ENABLED);
Henrik Boström3a14bf32015-08-31 09:27:58 +0200241 f2_.set_certificate(cert2_);
jbauch555604a2016-04-26 03:13:22 -0700242 std::unique_ptr<TransportDescription> offer(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000243 f1_.CreateOffer(TransportOptions(), NULL));
244 ASSERT_TRUE(offer.get() != NULL);
jbauch555604a2016-04-26 03:13:22 -0700245 std::unique_ptr<TransportDescription> desc(
deadbeefb7892532017-02-22 19:35:18 -0800246 f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700247 CheckDesc(desc.get(), "", "", "", "");
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000248 f2_.set_secure(cricket::SEC_REQUIRED);
deadbeefb7892532017-02-22 19:35:18 -0800249 desc.reset(f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000250 ASSERT_TRUE(desc.get() == NULL);
251}
252
253// Test that we handle answering an DTLS offer with DTLS, both if we have
254// DTLS enabled and required.
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700255TEST_F(TransportDescriptionFactoryTest, TestAnswerDtlsToDtls) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000256 f1_.set_secure(cricket::SEC_ENABLED);
Henrik Boström3a14bf32015-08-31 09:27:58 +0200257 f1_.set_certificate(cert1_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000258
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000259 f2_.set_secure(cricket::SEC_ENABLED);
Henrik Boström3a14bf32015-08-31 09:27:58 +0200260 f2_.set_certificate(cert2_);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000261 // f2_ produces the answer that is being checked in this test, so the
Henrik Boström3a14bf32015-08-31 09:27:58 +0200262 // answer must contain fingerprint lines with cert2_'s digest algorithm.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000263 std::string digest_alg2;
Henrik Boström3a14bf32015-08-31 09:27:58 +0200264 ASSERT_TRUE(cert2_->ssl_certificate().GetSignatureDigestAlgorithm(
265 &digest_alg2));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000266
jbauch555604a2016-04-26 03:13:22 -0700267 std::unique_ptr<TransportDescription> offer(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000268 f1_.CreateOffer(TransportOptions(), NULL));
269 ASSERT_TRUE(offer.get() != NULL);
jbauch555604a2016-04-26 03:13:22 -0700270 std::unique_ptr<TransportDescription> desc(
deadbeefb7892532017-02-22 19:35:18 -0800271 f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700272 CheckDesc(desc.get(), "", "", "", digest_alg2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000273 f2_.set_secure(cricket::SEC_REQUIRED);
deadbeefb7892532017-02-22 19:35:18 -0800274 desc.reset(f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL));
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700275 CheckDesc(desc.get(), "", "", "", digest_alg2);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000276}
277
278// Test that ice ufrag and password is changed in an updated offer and answer
279// if |TransportDescriptionOptions::ice_restart| is true.
280TEST_F(TransportDescriptionFactoryTest, TestIceRestart) {
281 TestIceRestart(false);
282}
283
284// Test that ice ufrag and password is changed in an updated offer and answer
285// if |TransportDescriptionOptions::ice_restart| is true and DTLS is enabled.
286TEST_F(TransportDescriptionFactoryTest, TestIceRestartWithDtls) {
287 TestIceRestart(true);
288}
Honghai Zhang4cedf2b2016-08-31 08:18:11 -0700289
290// Test that ice renomination is set in an updated offer and answer
291// if |TransportDescriptionOptions::enable_ice_renomination| is true.
292TEST_F(TransportDescriptionFactoryTest, TestIceRenomination) {
293 TestIceRenomination(false);
294}
295
296// Test that ice renomination is set in an updated offer and answer
297// if |TransportDescriptionOptions::enable_ice_renomination| is true and DTLS
298// is enabled.
299TEST_F(TransportDescriptionFactoryTest, TestIceRenominationWithDtls) {
300 TestIceRenomination(true);
301}
deadbeef30952b42017-04-21 02:41:29 -0700302
303// Test that offers and answers have ice-option:trickle.
304TEST_F(TransportDescriptionFactoryTest, AddsTrickleIceOption) {
305 cricket::TransportOptions options;
306 std::unique_ptr<TransportDescription> offer(
307 f1_.CreateOffer(options, nullptr));
308 EXPECT_TRUE(offer->HasOption("trickle"));
309 std::unique_ptr<TransportDescription> answer(
310 f2_.CreateAnswer(offer.get(), options, true, nullptr));
311 EXPECT_TRUE(answer->HasOption("trickle"));
312}