xref: /aosp_15_r20/external/webrtc/pc/peer_connection_crypto_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker #include <ostream>
15*d9f75844SAndroid Build Coastguard Worker #include <string>
16*d9f75844SAndroid Build Coastguard Worker #include <tuple>
17*d9f75844SAndroid Build Coastguard Worker #include <type_traits>
18*d9f75844SAndroid Build Coastguard Worker #include <utility>
19*d9f75844SAndroid Build Coastguard Worker #include <vector>
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/audio/audio_mixer.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_decoder_factory.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/builtin_audio_encoder_factory.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/create_peerconnection_factory.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/crypto/crypto_options.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/crypto_params.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/jsep.h"
29*d9f75844SAndroid Build Coastguard Worker #include "api/peer_connection_interface.h"
30*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h"
31*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_decoder_factory.h"
32*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/builtin_video_encoder_factory.h"
33*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_device/include/audio_device.h"
34*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/include/audio_processing.h"
35*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/fake_port_allocator.h"
36*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port_allocator.h"
37*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/transport_description.h"
38*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/transport_info.h"
39*d9f75844SAndroid Build Coastguard Worker #include "pc/media_protocol_names.h"
40*d9f75844SAndroid Build Coastguard Worker #include "pc/media_session.h"
41*d9f75844SAndroid Build Coastguard Worker #include "pc/peer_connection_wrapper.h"
42*d9f75844SAndroid Build Coastguard Worker #include "pc/sdp_utils.h"
43*d9f75844SAndroid Build Coastguard Worker #include "pc/session_description.h"
44*d9f75844SAndroid Build Coastguard Worker #include "pc/test/mock_peer_connection_observers.h"
45*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
46*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rtc_certificate.h"
47*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rtc_certificate_generator.h"
48*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_fingerprint.h"
49*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
50*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
51*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
52*d9f75844SAndroid Build Coastguard Worker #include "pc/test/android_test_initializer.h"
53*d9f75844SAndroid Build Coastguard Worker #endif
54*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_audio_capture_module.h"
55*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_rtc_certificate_generator.h"
56*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
57*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/virtual_socket_server.h"
58*d9f75844SAndroid Build Coastguard Worker 
59*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
60*d9f75844SAndroid Build Coastguard Worker 
61*d9f75844SAndroid Build Coastguard Worker using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
62*d9f75844SAndroid Build Coastguard Worker using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
63*d9f75844SAndroid Build Coastguard Worker using ::testing::Combine;
64*d9f75844SAndroid Build Coastguard Worker using ::testing::Values;
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker constexpr int kGenerateCertTimeout = 1000;
67*d9f75844SAndroid Build Coastguard Worker 
68*d9f75844SAndroid Build Coastguard Worker class PeerConnectionCryptoBaseTest : public ::testing::Test {
69*d9f75844SAndroid Build Coastguard Worker  protected:
70*d9f75844SAndroid Build Coastguard Worker   typedef std::unique_ptr<PeerConnectionWrapper> WrapperPtr;
71*d9f75844SAndroid Build Coastguard Worker 
PeerConnectionCryptoBaseTest(SdpSemantics sdp_semantics)72*d9f75844SAndroid Build Coastguard Worker   explicit PeerConnectionCryptoBaseTest(SdpSemantics sdp_semantics)
73*d9f75844SAndroid Build Coastguard Worker       : vss_(new rtc::VirtualSocketServer()),
74*d9f75844SAndroid Build Coastguard Worker         main_(vss_.get()),
75*d9f75844SAndroid Build Coastguard Worker         sdp_semantics_(sdp_semantics) {
76*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_ANDROID
77*d9f75844SAndroid Build Coastguard Worker     InitializeAndroidObjects();
78*d9f75844SAndroid Build Coastguard Worker #endif
79*d9f75844SAndroid Build Coastguard Worker     pc_factory_ = CreatePeerConnectionFactory(
80*d9f75844SAndroid Build Coastguard Worker         rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
81*d9f75844SAndroid Build Coastguard Worker         FakeAudioCaptureModule::Create(), CreateBuiltinAudioEncoderFactory(),
82*d9f75844SAndroid Build Coastguard Worker         CreateBuiltinAudioDecoderFactory(), CreateBuiltinVideoEncoderFactory(),
83*d9f75844SAndroid Build Coastguard Worker         CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
84*d9f75844SAndroid Build Coastguard Worker         nullptr /* audio_processing */);
85*d9f75844SAndroid Build Coastguard Worker   }
86*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection()87*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnection() {
88*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnection(RTCConfiguration());
89*d9f75844SAndroid Build Coastguard Worker   }
90*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection(const RTCConfiguration & config)91*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
92*d9f75844SAndroid Build Coastguard Worker     return CreatePeerConnection(config, nullptr);
93*d9f75844SAndroid Build Coastguard Worker   }
94*d9f75844SAndroid Build Coastguard Worker 
CreatePeerConnection(const RTCConfiguration & config,std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_gen)95*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnection(
96*d9f75844SAndroid Build Coastguard Worker       const RTCConfiguration& config,
97*d9f75844SAndroid Build Coastguard Worker       std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_gen) {
98*d9f75844SAndroid Build Coastguard Worker     auto fake_port_allocator = std::make_unique<cricket::FakePortAllocator>(
99*d9f75844SAndroid Build Coastguard Worker         rtc::Thread::Current(),
100*d9f75844SAndroid Build Coastguard Worker         std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get()));
101*d9f75844SAndroid Build Coastguard Worker     auto observer = std::make_unique<MockPeerConnectionObserver>();
102*d9f75844SAndroid Build Coastguard Worker     RTCConfiguration modified_config = config;
103*d9f75844SAndroid Build Coastguard Worker     modified_config.sdp_semantics = sdp_semantics_;
104*d9f75844SAndroid Build Coastguard Worker     PeerConnectionDependencies pc_dependencies(observer.get());
105*d9f75844SAndroid Build Coastguard Worker     pc_dependencies.allocator = std::move(fake_port_allocator);
106*d9f75844SAndroid Build Coastguard Worker     pc_dependencies.cert_generator = std::move(cert_gen);
107*d9f75844SAndroid Build Coastguard Worker     auto result = pc_factory_->CreatePeerConnectionOrError(
108*d9f75844SAndroid Build Coastguard Worker         modified_config, std::move(pc_dependencies));
109*d9f75844SAndroid Build Coastguard Worker     if (!result.ok()) {
110*d9f75844SAndroid Build Coastguard Worker       return nullptr;
111*d9f75844SAndroid Build Coastguard Worker     }
112*d9f75844SAndroid Build Coastguard Worker 
113*d9f75844SAndroid Build Coastguard Worker     observer->SetPeerConnectionInterface(result.value().get());
114*d9f75844SAndroid Build Coastguard Worker     return std::make_unique<PeerConnectionWrapper>(
115*d9f75844SAndroid Build Coastguard Worker         pc_factory_, result.MoveValue(), std::move(observer));
116*d9f75844SAndroid Build Coastguard Worker   }
117*d9f75844SAndroid Build Coastguard Worker 
118*d9f75844SAndroid Build Coastguard Worker   // Accepts the same arguments as CreatePeerConnection and adds default audio
119*d9f75844SAndroid Build Coastguard Worker   // and video tracks.
120*d9f75844SAndroid Build Coastguard Worker   template <typename... Args>
CreatePeerConnectionWithAudioVideo(Args &&...args)121*d9f75844SAndroid Build Coastguard Worker   WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
122*d9f75844SAndroid Build Coastguard Worker     auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
123*d9f75844SAndroid Build Coastguard Worker     if (!wrapper) {
124*d9f75844SAndroid Build Coastguard Worker       return nullptr;
125*d9f75844SAndroid Build Coastguard Worker     }
126*d9f75844SAndroid Build Coastguard Worker     wrapper->AddAudioTrack("a");
127*d9f75844SAndroid Build Coastguard Worker     wrapper->AddVideoTrack("v");
128*d9f75844SAndroid Build Coastguard Worker     return wrapper;
129*d9f75844SAndroid Build Coastguard Worker   }
130*d9f75844SAndroid Build Coastguard Worker 
AudioConnectionRole(cricket::SessionDescription * desc)131*d9f75844SAndroid Build Coastguard Worker   cricket::ConnectionRole& AudioConnectionRole(
132*d9f75844SAndroid Build Coastguard Worker       cricket::SessionDescription* desc) {
133*d9f75844SAndroid Build Coastguard Worker     return ConnectionRoleFromContent(desc, cricket::GetFirstAudioContent(desc));
134*d9f75844SAndroid Build Coastguard Worker   }
135*d9f75844SAndroid Build Coastguard Worker 
VideoConnectionRole(cricket::SessionDescription * desc)136*d9f75844SAndroid Build Coastguard Worker   cricket::ConnectionRole& VideoConnectionRole(
137*d9f75844SAndroid Build Coastguard Worker       cricket::SessionDescription* desc) {
138*d9f75844SAndroid Build Coastguard Worker     return ConnectionRoleFromContent(desc, cricket::GetFirstVideoContent(desc));
139*d9f75844SAndroid Build Coastguard Worker   }
140*d9f75844SAndroid Build Coastguard Worker 
ConnectionRoleFromContent(cricket::SessionDescription * desc,cricket::ContentInfo * content)141*d9f75844SAndroid Build Coastguard Worker   cricket::ConnectionRole& ConnectionRoleFromContent(
142*d9f75844SAndroid Build Coastguard Worker       cricket::SessionDescription* desc,
143*d9f75844SAndroid Build Coastguard Worker       cricket::ContentInfo* content) {
144*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(content);
145*d9f75844SAndroid Build Coastguard Worker     auto* transport_info = desc->GetTransportInfoByName(content->name);
146*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(transport_info);
147*d9f75844SAndroid Build Coastguard Worker     return transport_info->description.connection_role;
148*d9f75844SAndroid Build Coastguard Worker   }
149*d9f75844SAndroid Build Coastguard Worker 
150*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::VirtualSocketServer> vss_;
151*d9f75844SAndroid Build Coastguard Worker   rtc::AutoSocketServerThread main_;
152*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
153*d9f75844SAndroid Build Coastguard Worker   const SdpSemantics sdp_semantics_;
154*d9f75844SAndroid Build Coastguard Worker };
155*d9f75844SAndroid Build Coastguard Worker 
HaveDtlsFingerprint()156*d9f75844SAndroid Build Coastguard Worker SdpContentPredicate HaveDtlsFingerprint() {
157*d9f75844SAndroid Build Coastguard Worker   return [](const cricket::ContentInfo* content,
158*d9f75844SAndroid Build Coastguard Worker             const cricket::TransportInfo* transport) {
159*d9f75844SAndroid Build Coastguard Worker     return transport->description.identity_fingerprint != nullptr;
160*d9f75844SAndroid Build Coastguard Worker   };
161*d9f75844SAndroid Build Coastguard Worker }
162*d9f75844SAndroid Build Coastguard Worker 
HaveSdesCryptos()163*d9f75844SAndroid Build Coastguard Worker SdpContentPredicate HaveSdesCryptos() {
164*d9f75844SAndroid Build Coastguard Worker   return [](const cricket::ContentInfo* content,
165*d9f75844SAndroid Build Coastguard Worker             const cricket::TransportInfo* transport) {
166*d9f75844SAndroid Build Coastguard Worker     return !content->media_description()->cryptos().empty();
167*d9f75844SAndroid Build Coastguard Worker   };
168*d9f75844SAndroid Build Coastguard Worker }
169*d9f75844SAndroid Build Coastguard Worker 
HaveProtocol(const std::string & protocol)170*d9f75844SAndroid Build Coastguard Worker SdpContentPredicate HaveProtocol(const std::string& protocol) {
171*d9f75844SAndroid Build Coastguard Worker   return [protocol](const cricket::ContentInfo* content,
172*d9f75844SAndroid Build Coastguard Worker                     const cricket::TransportInfo* transport) {
173*d9f75844SAndroid Build Coastguard Worker     return content->media_description()->protocol() == protocol;
174*d9f75844SAndroid Build Coastguard Worker   };
175*d9f75844SAndroid Build Coastguard Worker }
176*d9f75844SAndroid Build Coastguard Worker 
HaveSdesGcmCryptos(size_t num_crypto_suites)177*d9f75844SAndroid Build Coastguard Worker SdpContentPredicate HaveSdesGcmCryptos(size_t num_crypto_suites) {
178*d9f75844SAndroid Build Coastguard Worker   return [num_crypto_suites](const cricket::ContentInfo* content,
179*d9f75844SAndroid Build Coastguard Worker                              const cricket::TransportInfo* transport) {
180*d9f75844SAndroid Build Coastguard Worker     const auto& cryptos = content->media_description()->cryptos();
181*d9f75844SAndroid Build Coastguard Worker     if (cryptos.size() != num_crypto_suites) {
182*d9f75844SAndroid Build Coastguard Worker       return false;
183*d9f75844SAndroid Build Coastguard Worker     }
184*d9f75844SAndroid Build Coastguard Worker     for (size_t i = 0; i < cryptos.size(); ++i) {
185*d9f75844SAndroid Build Coastguard Worker       if (cryptos[i].key_params.size() == 67U &&
186*d9f75844SAndroid Build Coastguard Worker           cryptos[i].cipher_suite == "AEAD_AES_256_GCM")
187*d9f75844SAndroid Build Coastguard Worker         return true;
188*d9f75844SAndroid Build Coastguard Worker     }
189*d9f75844SAndroid Build Coastguard Worker     return false;
190*d9f75844SAndroid Build Coastguard Worker   };
191*d9f75844SAndroid Build Coastguard Worker }
192*d9f75844SAndroid Build Coastguard Worker 
193*d9f75844SAndroid Build Coastguard Worker class PeerConnectionCryptoTest
194*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionCryptoBaseTest,
195*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<SdpSemantics> {
196*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionCryptoTest()197*d9f75844SAndroid Build Coastguard Worker   PeerConnectionCryptoTest() : PeerConnectionCryptoBaseTest(GetParam()) {}
198*d9f75844SAndroid Build Coastguard Worker };
199*d9f75844SAndroid Build Coastguard Worker 
RemoveSdesCryptos()200*d9f75844SAndroid Build Coastguard Worker SdpContentMutator RemoveSdesCryptos() {
201*d9f75844SAndroid Build Coastguard Worker   return [](cricket::ContentInfo* content, cricket::TransportInfo* transport) {
202*d9f75844SAndroid Build Coastguard Worker     content->media_description()->set_cryptos({});
203*d9f75844SAndroid Build Coastguard Worker   };
204*d9f75844SAndroid Build Coastguard Worker }
205*d9f75844SAndroid Build Coastguard Worker 
RemoveDtlsFingerprint()206*d9f75844SAndroid Build Coastguard Worker SdpContentMutator RemoveDtlsFingerprint() {
207*d9f75844SAndroid Build Coastguard Worker   return [](cricket::ContentInfo* content, cricket::TransportInfo* transport) {
208*d9f75844SAndroid Build Coastguard Worker     transport->description.identity_fingerprint.reset();
209*d9f75844SAndroid Build Coastguard Worker   };
210*d9f75844SAndroid Build Coastguard Worker }
211*d9f75844SAndroid Build Coastguard Worker 
212*d9f75844SAndroid Build Coastguard Worker // When DTLS is enabled, the SDP offer/answer should have a DTLS fingerprint and
213*d9f75844SAndroid Build Coastguard Worker // no SDES cryptos.
TEST_P(PeerConnectionCryptoTest,CorrectCryptoInOfferWhenDtlsEnabled)214*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsEnabled) {
215*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
216*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
217*d9f75844SAndroid Build Coastguard Worker 
218*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
219*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
220*d9f75844SAndroid Build Coastguard Worker 
221*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(offer->description()->contents().empty());
222*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveDtlsFingerprint(), offer->description()));
223*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), offer->description()));
224*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolDtlsSavpf),
225*d9f75844SAndroid Build Coastguard Worker                              offer->description()));
226*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,CorrectCryptoInAnswerWhenDtlsEnabled)227*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsEnabled) {
228*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
229*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
230*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
231*d9f75844SAndroid Build Coastguard Worker 
232*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(caller->CreateOffer());
233*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
234*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
235*d9f75844SAndroid Build Coastguard Worker 
236*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(answer->description()->contents().empty());
237*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveDtlsFingerprint(), answer->description()));
238*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), answer->description()));
239*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolDtlsSavpf),
240*d9f75844SAndroid Build Coastguard Worker                              answer->description()));
241*d9f75844SAndroid Build Coastguard Worker }
242*d9f75844SAndroid Build Coastguard Worker 
243*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_FUCHSIA)
244*d9f75844SAndroid Build Coastguard Worker // When DTLS is disabled, the SDP offer/answer should include SDES cryptos and
245*d9f75844SAndroid Build Coastguard Worker // should not have a DTLS fingerprint.
TEST_P(PeerConnectionCryptoTest,CorrectCryptoInOfferWhenDtlsDisabled)246*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsDisabled) {
247*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
248*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
249*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
250*d9f75844SAndroid Build Coastguard Worker 
251*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
252*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
253*d9f75844SAndroid Build Coastguard Worker 
254*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(offer->description()->contents().empty());
255*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), offer->description()));
256*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description()));
257*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf),
258*d9f75844SAndroid Build Coastguard Worker                              offer->description()));
259*d9f75844SAndroid Build Coastguard Worker }
260*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionCryptoTest,CorrectCryptoInAnswerWhenDtlsDisabled)261*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsDisabled) {
262*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
263*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
264*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
265*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
266*d9f75844SAndroid Build Coastguard Worker 
267*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(caller->CreateOffer());
268*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
269*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
270*d9f75844SAndroid Build Coastguard Worker 
271*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(answer->description()->contents().empty());
272*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), answer->description()));
273*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description()));
274*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf),
275*d9f75844SAndroid Build Coastguard Worker                              answer->description()));
276*d9f75844SAndroid Build Coastguard Worker }
277*d9f75844SAndroid Build Coastguard Worker 
278*d9f75844SAndroid Build Coastguard Worker // When encryption is disabled, the SDP offer/answer should have neither a DTLS
279*d9f75844SAndroid Build Coastguard Worker // fingerprint nor any SDES crypto options.
TEST_P(PeerConnectionCryptoTest,CorrectCryptoInOfferWhenEncryptionDisabled)280*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenEncryptionDisabled) {
281*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactoryInterface::Options options;
282*d9f75844SAndroid Build Coastguard Worker   options.disable_encryption = true;
283*d9f75844SAndroid Build Coastguard Worker   pc_factory_->SetOptions(options);
284*d9f75844SAndroid Build Coastguard Worker 
285*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
286*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
287*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
288*d9f75844SAndroid Build Coastguard Worker 
289*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
290*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
291*d9f75844SAndroid Build Coastguard Worker 
292*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(offer->description()->contents().empty());
293*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), offer->description()));
294*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description()));
295*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf),
296*d9f75844SAndroid Build Coastguard Worker                              offer->description()));
297*d9f75844SAndroid Build Coastguard Worker }
298*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionCryptoTest,CorrectCryptoInAnswerWhenEncryptionDisabled)299*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenEncryptionDisabled) {
300*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactoryInterface::Options options;
301*d9f75844SAndroid Build Coastguard Worker   options.disable_encryption = true;
302*d9f75844SAndroid Build Coastguard Worker   pc_factory_->SetOptions(options);
303*d9f75844SAndroid Build Coastguard Worker 
304*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
305*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
306*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
307*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
308*d9f75844SAndroid Build Coastguard Worker 
309*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(caller->CreateOffer());
310*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
311*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
312*d9f75844SAndroid Build Coastguard Worker 
313*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(answer->description()->contents().empty());
314*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), answer->description()));
315*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description()));
316*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf),
317*d9f75844SAndroid Build Coastguard Worker                              answer->description()));
318*d9f75844SAndroid Build Coastguard Worker }
319*d9f75844SAndroid Build Coastguard Worker 
320*d9f75844SAndroid Build Coastguard Worker // CryptoOptions has been promoted to RTCConfiguration. As such if it is ever
321*d9f75844SAndroid Build Coastguard Worker // set in the configuration it should overrite the settings set in the factory.
TEST_P(PeerConnectionCryptoTest,RTCConfigurationCryptoOptionOverridesFactory)322*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, RTCConfigurationCryptoOptionOverridesFactory) {
323*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactoryInterface::Options options;
324*d9f75844SAndroid Build Coastguard Worker   options.crypto_options.srtp.enable_gcm_crypto_suites = true;
325*d9f75844SAndroid Build Coastguard Worker   pc_factory_->SetOptions(options);
326*d9f75844SAndroid Build Coastguard Worker 
327*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
328*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
329*d9f75844SAndroid Build Coastguard Worker   CryptoOptions crypto_options;
330*d9f75844SAndroid Build Coastguard Worker   crypto_options.srtp.enable_gcm_crypto_suites = false;
331*d9f75844SAndroid Build Coastguard Worker   config.crypto_options = crypto_options;
332*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
333*d9f75844SAndroid Build Coastguard Worker 
334*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
335*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
336*d9f75844SAndroid Build Coastguard Worker 
337*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(offer->description()->contents().empty());
338*d9f75844SAndroid Build Coastguard Worker   // This should exist if GCM is enabled see CorrectCryptoInOfferWithSdesAndGcm
339*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description()));
340*d9f75844SAndroid Build Coastguard Worker }
341*d9f75844SAndroid Build Coastguard Worker 
342*d9f75844SAndroid Build Coastguard Worker // When DTLS is disabled and GCM cipher suites are enabled, the SDP offer/answer
343*d9f75844SAndroid Build Coastguard Worker // should have the correct ciphers in the SDES crypto options.
344*d9f75844SAndroid Build Coastguard Worker // With GCM cipher suites enabled, there will be 3 cryptos in the offer and 1
345*d9f75844SAndroid Build Coastguard Worker // in the answer.
TEST_P(PeerConnectionCryptoTest,CorrectCryptoInOfferWithSdesAndGcm)346*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWithSdesAndGcm) {
347*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactoryInterface::Options options;
348*d9f75844SAndroid Build Coastguard Worker   options.crypto_options.srtp.enable_gcm_crypto_suites = true;
349*d9f75844SAndroid Build Coastguard Worker   pc_factory_->SetOptions(options);
350*d9f75844SAndroid Build Coastguard Worker 
351*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
352*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
353*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
354*d9f75844SAndroid Build Coastguard Worker 
355*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
356*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
357*d9f75844SAndroid Build Coastguard Worker 
358*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(offer->description()->contents().empty());
359*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description()));
360*d9f75844SAndroid Build Coastguard Worker }
361*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionCryptoTest,CorrectCryptoInAnswerWithSdesAndGcm)362*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWithSdesAndGcm) {
363*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactoryInterface::Options options;
364*d9f75844SAndroid Build Coastguard Worker   options.crypto_options.srtp.enable_gcm_crypto_suites = true;
365*d9f75844SAndroid Build Coastguard Worker   pc_factory_->SetOptions(options);
366*d9f75844SAndroid Build Coastguard Worker 
367*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
368*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
369*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
370*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
371*d9f75844SAndroid Build Coastguard Worker 
372*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
373*d9f75844SAndroid Build Coastguard Worker   for (cricket::ContentInfo& content : offer->description()->contents()) {
374*d9f75844SAndroid Build Coastguard Worker     auto cryptos = content.media_description()->cryptos();
375*d9f75844SAndroid Build Coastguard Worker     cryptos.erase(cryptos.begin());  // Assumes that non-GCM is the default.
376*d9f75844SAndroid Build Coastguard Worker     content.media_description()->set_cryptos(cryptos);
377*d9f75844SAndroid Build Coastguard Worker   }
378*d9f75844SAndroid Build Coastguard Worker 
379*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(std::move(offer));
380*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
381*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
382*d9f75844SAndroid Build Coastguard Worker 
383*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(answer->description()->contents().empty());
384*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(1), answer->description()));
385*d9f75844SAndroid Build Coastguard Worker }
386*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionCryptoTest,CanSetSdesGcmRemoteOfferAndLocalAnswer)387*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CanSetSdesGcmRemoteOfferAndLocalAnswer) {
388*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactoryInterface::Options options;
389*d9f75844SAndroid Build Coastguard Worker   options.crypto_options.srtp.enable_gcm_crypto_suites = true;
390*d9f75844SAndroid Build Coastguard Worker   pc_factory_->SetOptions(options);
391*d9f75844SAndroid Build Coastguard Worker 
392*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
393*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
394*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
395*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
396*d9f75844SAndroid Build Coastguard Worker 
397*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
398*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
399*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
400*d9f75844SAndroid Build Coastguard Worker 
401*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
402*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
403*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetLocalDescription(std::move(answer)));
404*d9f75844SAndroid Build Coastguard Worker }
405*d9f75844SAndroid Build Coastguard Worker 
406*d9f75844SAndroid Build Coastguard Worker // The following group tests that two PeerConnections can successfully exchange
407*d9f75844SAndroid Build Coastguard Worker // an offer/answer when DTLS is off and that they will refuse any offer/answer
408*d9f75844SAndroid Build Coastguard Worker // applied locally/remotely if it does not include SDES cryptos.
TEST_P(PeerConnectionCryptoTest,ExchangeOfferAnswerWhenSdesOn)409*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenSdesOn) {
410*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
411*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
412*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
413*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
414*d9f75844SAndroid Build Coastguard Worker 
415*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
416*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
417*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
418*d9f75844SAndroid Build Coastguard Worker 
419*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswerAndSetAsLocal();
420*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
421*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
422*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,FailToSetLocalOfferWithNoCryptosWhenSdesOn)423*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, FailToSetLocalOfferWithNoCryptosWhenSdesOn) {
424*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
425*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
426*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
427*d9f75844SAndroid Build Coastguard Worker 
428*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
429*d9f75844SAndroid Build Coastguard Worker   SdpContentsForEach(RemoveSdesCryptos(), offer->description());
430*d9f75844SAndroid Build Coastguard Worker 
431*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->SetLocalDescription(std::move(offer)));
432*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,FailToSetRemoteOfferWithNoCryptosWhenSdesOn)433*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, FailToSetRemoteOfferWithNoCryptosWhenSdesOn) {
434*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
435*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
436*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
437*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
438*d9f75844SAndroid Build Coastguard Worker 
439*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
440*d9f75844SAndroid Build Coastguard Worker   SdpContentsForEach(RemoveSdesCryptos(), offer->description());
441*d9f75844SAndroid Build Coastguard Worker 
442*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer)));
443*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,FailToSetLocalAnswerWithNoCryptosWhenSdesOn)444*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, FailToSetLocalAnswerWithNoCryptosWhenSdesOn) {
445*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
446*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
447*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
448*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
449*d9f75844SAndroid Build Coastguard Worker 
450*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal());
451*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
452*d9f75844SAndroid Build Coastguard Worker   SdpContentsForEach(RemoveSdesCryptos(), answer->description());
453*d9f75844SAndroid Build Coastguard Worker 
454*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->SetLocalDescription(std::move(answer)));
455*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,FailToSetRemoteAnswerWithNoCryptosWhenSdesOn)456*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, FailToSetRemoteAnswerWithNoCryptosWhenSdesOn) {
457*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
458*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
459*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
460*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
461*d9f75844SAndroid Build Coastguard Worker 
462*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal());
463*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswerAndSetAsLocal();
464*d9f75844SAndroid Build Coastguard Worker   SdpContentsForEach(RemoveSdesCryptos(), answer->description());
465*d9f75844SAndroid Build Coastguard Worker 
466*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer)));
467*d9f75844SAndroid Build Coastguard Worker }
468*d9f75844SAndroid Build Coastguard Worker #endif
469*d9f75844SAndroid Build Coastguard Worker 
470*d9f75844SAndroid Build Coastguard Worker // The following group tests that two PeerConnections can successfully exchange
471*d9f75844SAndroid Build Coastguard Worker // an offer/answer when DTLS is on and that they will refuse any offer/answer
472*d9f75844SAndroid Build Coastguard Worker // applied locally/remotely if it does not include a DTLS fingerprint.
TEST_P(PeerConnectionCryptoTest,ExchangeOfferAnswerWhenDtlsOn)473*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenDtlsOn) {
474*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
475*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
476*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
477*d9f75844SAndroid Build Coastguard Worker 
478*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
479*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
480*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
481*d9f75844SAndroid Build Coastguard Worker 
482*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswerAndSetAsLocal();
483*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
484*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
485*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,FailToSetLocalOfferWithNoFingerprintWhenDtlsOn)486*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest,
487*d9f75844SAndroid Build Coastguard Worker        FailToSetLocalOfferWithNoFingerprintWhenDtlsOn) {
488*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
489*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
490*d9f75844SAndroid Build Coastguard Worker 
491*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
492*d9f75844SAndroid Build Coastguard Worker   SdpContentsForEach(RemoveDtlsFingerprint(), offer->description());
493*d9f75844SAndroid Build Coastguard Worker 
494*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->SetLocalDescription(std::move(offer)));
495*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,FailToSetRemoteOfferWithNoFingerprintWhenDtlsOn)496*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest,
497*d9f75844SAndroid Build Coastguard Worker        FailToSetRemoteOfferWithNoFingerprintWhenDtlsOn) {
498*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
499*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
500*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
501*d9f75844SAndroid Build Coastguard Worker 
502*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOffer();
503*d9f75844SAndroid Build Coastguard Worker   SdpContentsForEach(RemoveDtlsFingerprint(), offer->description());
504*d9f75844SAndroid Build Coastguard Worker 
505*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer)));
506*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,FailToSetLocalAnswerWithNoFingerprintWhenDtlsOn)507*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest,
508*d9f75844SAndroid Build Coastguard Worker        FailToSetLocalAnswerWithNoFingerprintWhenDtlsOn) {
509*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
510*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
511*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
512*d9f75844SAndroid Build Coastguard Worker 
513*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal());
514*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer();
515*d9f75844SAndroid Build Coastguard Worker   SdpContentsForEach(RemoveDtlsFingerprint(), answer->description());
516*d9f75844SAndroid Build Coastguard Worker }
TEST_P(PeerConnectionCryptoTest,FailToSetRemoteAnswerWithNoFingerprintWhenDtlsOn)517*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest,
518*d9f75844SAndroid Build Coastguard Worker        FailToSetRemoteAnswerWithNoFingerprintWhenDtlsOn) {
519*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
520*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
521*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
522*d9f75844SAndroid Build Coastguard Worker 
523*d9f75844SAndroid Build Coastguard Worker   callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal());
524*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswerAndSetAsLocal();
525*d9f75844SAndroid Build Coastguard Worker   SdpContentsForEach(RemoveDtlsFingerprint(), answer->description());
526*d9f75844SAndroid Build Coastguard Worker 
527*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer)));
528*d9f75844SAndroid Build Coastguard Worker }
529*d9f75844SAndroid Build Coastguard Worker 
530*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_FUCHSIA)
531*d9f75844SAndroid Build Coastguard Worker // Test that an offer/answer can be exchanged when encryption is disabled.
TEST_P(PeerConnectionCryptoTest,ExchangeOfferAnswerWhenNoEncryption)532*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenNoEncryption) {
533*d9f75844SAndroid Build Coastguard Worker   PeerConnectionFactoryInterface::Options options;
534*d9f75844SAndroid Build Coastguard Worker   options.disable_encryption = true;
535*d9f75844SAndroid Build Coastguard Worker   pc_factory_->SetOptions(options);
536*d9f75844SAndroid Build Coastguard Worker 
537*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
538*d9f75844SAndroid Build Coastguard Worker   config.enable_dtls_srtp.emplace(false);
539*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(config);
540*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(config);
541*d9f75844SAndroid Build Coastguard Worker 
542*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
543*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
544*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
545*d9f75844SAndroid Build Coastguard Worker 
546*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswerAndSetAsLocal();
547*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
548*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
549*d9f75844SAndroid Build Coastguard Worker }
550*d9f75844SAndroid Build Coastguard Worker #endif
551*d9f75844SAndroid Build Coastguard Worker 
552*d9f75844SAndroid Build Coastguard Worker // Tests that a DTLS call can be established when the certificate is specified
553*d9f75844SAndroid Build Coastguard Worker // in the PeerConnection config and no certificate generator is specified.
TEST_P(PeerConnectionCryptoTest,ExchangeOfferAnswerWhenDtlsCertificateInConfig)554*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest,
555*d9f75844SAndroid Build Coastguard Worker        ExchangeOfferAnswerWhenDtlsCertificateInConfig) {
556*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration caller_config;
557*d9f75844SAndroid Build Coastguard Worker   caller_config.certificates.push_back(
558*d9f75844SAndroid Build Coastguard Worker       FakeRTCCertificateGenerator::GenerateCertificate());
559*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo(caller_config);
560*d9f75844SAndroid Build Coastguard Worker 
561*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration callee_config;
562*d9f75844SAndroid Build Coastguard Worker   callee_config.certificates.push_back(
563*d9f75844SAndroid Build Coastguard Worker       FakeRTCCertificateGenerator::GenerateCertificate());
564*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(callee_config);
565*d9f75844SAndroid Build Coastguard Worker 
566*d9f75844SAndroid Build Coastguard Worker   auto offer = caller->CreateOfferAndSetAsLocal();
567*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(offer);
568*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
569*d9f75844SAndroid Build Coastguard Worker 
570*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswerAndSetAsLocal();
571*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(answer);
572*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
573*d9f75844SAndroid Build Coastguard Worker }
574*d9f75844SAndroid Build Coastguard Worker 
575*d9f75844SAndroid Build Coastguard Worker // The following parameterized test verifies that CreateOffer/CreateAnswer
576*d9f75844SAndroid Build Coastguard Worker // returns successfully (or with failure if the underlying certificate generator
577*d9f75844SAndroid Build Coastguard Worker // fails) no matter when the DTLS certificate is generated. If multiple
578*d9f75844SAndroid Build Coastguard Worker // CreateOffer/CreateAnswer calls are made while waiting for the certificate,
579*d9f75844SAndroid Build Coastguard Worker // they all finish after the certificate is generated.
580*d9f75844SAndroid Build Coastguard Worker 
581*d9f75844SAndroid Build Coastguard Worker // Whether the certificate will be generated before calling CreateOffer or
582*d9f75844SAndroid Build Coastguard Worker // while CreateOffer is executing.
583*d9f75844SAndroid Build Coastguard Worker enum class CertGenTime { kBefore, kDuring };
operator <<(std::ostream & out,CertGenTime value)584*d9f75844SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, CertGenTime value) {
585*d9f75844SAndroid Build Coastguard Worker   switch (value) {
586*d9f75844SAndroid Build Coastguard Worker     case CertGenTime::kBefore:
587*d9f75844SAndroid Build Coastguard Worker       return out << "before";
588*d9f75844SAndroid Build Coastguard Worker     case CertGenTime::kDuring:
589*d9f75844SAndroid Build Coastguard Worker       return out << "during";
590*d9f75844SAndroid Build Coastguard Worker     default:
591*d9f75844SAndroid Build Coastguard Worker       return out << "unknown";
592*d9f75844SAndroid Build Coastguard Worker   }
593*d9f75844SAndroid Build Coastguard Worker }
594*d9f75844SAndroid Build Coastguard Worker 
595*d9f75844SAndroid Build Coastguard Worker // Whether the fake certificate generator will produce a certificate or fail.
596*d9f75844SAndroid Build Coastguard Worker enum class CertGenResult { kSucceed, kFail };
operator <<(std::ostream & out,CertGenResult value)597*d9f75844SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, CertGenResult value) {
598*d9f75844SAndroid Build Coastguard Worker   switch (value) {
599*d9f75844SAndroid Build Coastguard Worker     case CertGenResult::kSucceed:
600*d9f75844SAndroid Build Coastguard Worker       return out << "succeed";
601*d9f75844SAndroid Build Coastguard Worker     case CertGenResult::kFail:
602*d9f75844SAndroid Build Coastguard Worker       return out << "fail";
603*d9f75844SAndroid Build Coastguard Worker     default:
604*d9f75844SAndroid Build Coastguard Worker       return out << "unknown";
605*d9f75844SAndroid Build Coastguard Worker   }
606*d9f75844SAndroid Build Coastguard Worker }
607*d9f75844SAndroid Build Coastguard Worker 
608*d9f75844SAndroid Build Coastguard Worker class PeerConnectionCryptoDtlsCertGenTest
609*d9f75844SAndroid Build Coastguard Worker     : public PeerConnectionCryptoBaseTest,
610*d9f75844SAndroid Build Coastguard Worker       public ::testing::WithParamInterface<std::tuple<SdpSemantics,
611*d9f75844SAndroid Build Coastguard Worker                                                       SdpType,
612*d9f75844SAndroid Build Coastguard Worker                                                       CertGenTime,
613*d9f75844SAndroid Build Coastguard Worker                                                       CertGenResult,
614*d9f75844SAndroid Build Coastguard Worker                                                       size_t>> {
615*d9f75844SAndroid Build Coastguard Worker  protected:
PeerConnectionCryptoDtlsCertGenTest()616*d9f75844SAndroid Build Coastguard Worker   PeerConnectionCryptoDtlsCertGenTest()
617*d9f75844SAndroid Build Coastguard Worker       : PeerConnectionCryptoBaseTest(std::get<0>(GetParam())) {
618*d9f75844SAndroid Build Coastguard Worker     sdp_type_ = std::get<1>(GetParam());
619*d9f75844SAndroid Build Coastguard Worker     cert_gen_time_ = std::get<2>(GetParam());
620*d9f75844SAndroid Build Coastguard Worker     cert_gen_result_ = std::get<3>(GetParam());
621*d9f75844SAndroid Build Coastguard Worker     concurrent_calls_ = std::get<4>(GetParam());
622*d9f75844SAndroid Build Coastguard Worker   }
623*d9f75844SAndroid Build Coastguard Worker 
624*d9f75844SAndroid Build Coastguard Worker   SdpType sdp_type_;
625*d9f75844SAndroid Build Coastguard Worker   CertGenTime cert_gen_time_;
626*d9f75844SAndroid Build Coastguard Worker   CertGenResult cert_gen_result_;
627*d9f75844SAndroid Build Coastguard Worker   size_t concurrent_calls_;
628*d9f75844SAndroid Build Coastguard Worker };
629*d9f75844SAndroid Build Coastguard Worker 
TEST_P(PeerConnectionCryptoDtlsCertGenTest,TestCertificateGeneration)630*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoDtlsCertGenTest, TestCertificateGeneration) {
631*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration config;
632*d9f75844SAndroid Build Coastguard Worker   auto owned_fake_certificate_generator =
633*d9f75844SAndroid Build Coastguard Worker       std::make_unique<FakeRTCCertificateGenerator>();
634*d9f75844SAndroid Build Coastguard Worker   auto* fake_certificate_generator = owned_fake_certificate_generator.get();
635*d9f75844SAndroid Build Coastguard Worker   fake_certificate_generator->set_should_fail(cert_gen_result_ ==
636*d9f75844SAndroid Build Coastguard Worker                                               CertGenResult::kFail);
637*d9f75844SAndroid Build Coastguard Worker   fake_certificate_generator->set_should_wait(cert_gen_time_ ==
638*d9f75844SAndroid Build Coastguard Worker                                               CertGenTime::kDuring);
639*d9f75844SAndroid Build Coastguard Worker   WrapperPtr pc;
640*d9f75844SAndroid Build Coastguard Worker   if (sdp_type_ == SdpType::kOffer) {
641*d9f75844SAndroid Build Coastguard Worker     pc = CreatePeerConnectionWithAudioVideo(
642*d9f75844SAndroid Build Coastguard Worker         config, std::move(owned_fake_certificate_generator));
643*d9f75844SAndroid Build Coastguard Worker   } else {
644*d9f75844SAndroid Build Coastguard Worker     auto caller = CreatePeerConnectionWithAudioVideo(config);
645*d9f75844SAndroid Build Coastguard Worker     pc = CreatePeerConnectionWithAudioVideo(
646*d9f75844SAndroid Build Coastguard Worker         config, std::move(owned_fake_certificate_generator));
647*d9f75844SAndroid Build Coastguard Worker     pc->SetRemoteDescription(caller->CreateOfferAndSetAsLocal());
648*d9f75844SAndroid Build Coastguard Worker   }
649*d9f75844SAndroid Build Coastguard Worker   if (cert_gen_time_ == CertGenTime::kBefore) {
650*d9f75844SAndroid Build Coastguard Worker     ASSERT_TRUE_WAIT(fake_certificate_generator->generated_certificates() +
651*d9f75844SAndroid Build Coastguard Worker                              fake_certificate_generator->generated_failures() >
652*d9f75844SAndroid Build Coastguard Worker                          0,
653*d9f75844SAndroid Build Coastguard Worker                      kGenerateCertTimeout);
654*d9f75844SAndroid Build Coastguard Worker   } else {
655*d9f75844SAndroid Build Coastguard Worker     ASSERT_EQ(fake_certificate_generator->generated_certificates(), 0);
656*d9f75844SAndroid Build Coastguard Worker     fake_certificate_generator->set_should_wait(false);
657*d9f75844SAndroid Build Coastguard Worker   }
658*d9f75844SAndroid Build Coastguard Worker   std::vector<rtc::scoped_refptr<MockCreateSessionDescriptionObserver>>
659*d9f75844SAndroid Build Coastguard Worker       observers;
660*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < concurrent_calls_; i++) {
661*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer =
662*d9f75844SAndroid Build Coastguard Worker         rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
663*d9f75844SAndroid Build Coastguard Worker     observers.push_back(observer);
664*d9f75844SAndroid Build Coastguard Worker     if (sdp_type_ == SdpType::kOffer) {
665*d9f75844SAndroid Build Coastguard Worker       pc->pc()->CreateOffer(observer.get(),
666*d9f75844SAndroid Build Coastguard Worker                             PeerConnectionInterface::RTCOfferAnswerOptions());
667*d9f75844SAndroid Build Coastguard Worker     } else {
668*d9f75844SAndroid Build Coastguard Worker       pc->pc()->CreateAnswer(observer.get(),
669*d9f75844SAndroid Build Coastguard Worker                              PeerConnectionInterface::RTCOfferAnswerOptions());
670*d9f75844SAndroid Build Coastguard Worker     }
671*d9f75844SAndroid Build Coastguard Worker   }
672*d9f75844SAndroid Build Coastguard Worker   for (auto& observer : observers) {
673*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE_WAIT(observer->called(), 1000);
674*d9f75844SAndroid Build Coastguard Worker     if (cert_gen_result_ == CertGenResult::kSucceed) {
675*d9f75844SAndroid Build Coastguard Worker       EXPECT_TRUE(observer->result());
676*d9f75844SAndroid Build Coastguard Worker     } else {
677*d9f75844SAndroid Build Coastguard Worker       EXPECT_FALSE(observer->result());
678*d9f75844SAndroid Build Coastguard Worker     }
679*d9f75844SAndroid Build Coastguard Worker   }
680*d9f75844SAndroid Build Coastguard Worker }
681*d9f75844SAndroid Build Coastguard Worker 
682*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
683*d9f75844SAndroid Build Coastguard Worker     PeerConnectionCryptoTest,
684*d9f75844SAndroid Build Coastguard Worker     PeerConnectionCryptoDtlsCertGenTest,
685*d9f75844SAndroid Build Coastguard Worker     Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
686*d9f75844SAndroid Build Coastguard Worker             Values(SdpType::kOffer, SdpType::kAnswer),
687*d9f75844SAndroid Build Coastguard Worker             Values(CertGenTime::kBefore, CertGenTime::kDuring),
688*d9f75844SAndroid Build Coastguard Worker             Values(CertGenResult::kSucceed, CertGenResult::kFail),
689*d9f75844SAndroid Build Coastguard Worker             Values(1, 3)));
690*d9f75844SAndroid Build Coastguard Worker 
691*d9f75844SAndroid Build Coastguard Worker // Test that we can create and set an answer correctly when different
692*d9f75844SAndroid Build Coastguard Worker // SSL roles have been negotiated for different transports.
693*d9f75844SAndroid Build Coastguard Worker // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=4525
TEST_P(PeerConnectionCryptoTest,CreateAnswerWithDifferentSslRoles)694*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, CreateAnswerWithDifferentSslRoles) {
695*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
696*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo();
697*d9f75844SAndroid Build Coastguard Worker 
698*d9f75844SAndroid Build Coastguard Worker   RTCOfferAnswerOptions options_no_bundle;
699*d9f75844SAndroid Build Coastguard Worker   options_no_bundle.use_rtp_mux = false;
700*d9f75844SAndroid Build Coastguard Worker 
701*d9f75844SAndroid Build Coastguard Worker   // First, negotiate different SSL roles for audio and video.
702*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
703*d9f75844SAndroid Build Coastguard Worker   auto answer = callee->CreateAnswer(options_no_bundle);
704*d9f75844SAndroid Build Coastguard Worker 
705*d9f75844SAndroid Build Coastguard Worker   AudioConnectionRole(answer->description()) = cricket::CONNECTIONROLE_ACTIVE;
706*d9f75844SAndroid Build Coastguard Worker   VideoConnectionRole(answer->description()) = cricket::CONNECTIONROLE_PASSIVE;
707*d9f75844SAndroid Build Coastguard Worker 
708*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
709*d9f75844SAndroid Build Coastguard Worker       callee->SetLocalDescription(CloneSessionDescription(answer.get())));
710*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
711*d9f75844SAndroid Build Coastguard Worker 
712*d9f75844SAndroid Build Coastguard Worker   // Now create an offer in the reverse direction, and ensure the initial
713*d9f75844SAndroid Build Coastguard Worker   // offerer responds with an answer with the correct SSL roles.
714*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateOfferAndSetAsLocal()));
715*d9f75844SAndroid Build Coastguard Worker   answer = caller->CreateAnswer(options_no_bundle);
716*d9f75844SAndroid Build Coastguard Worker 
717*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
718*d9f75844SAndroid Build Coastguard Worker             AudioConnectionRole(answer->description()));
719*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::CONNECTIONROLE_ACTIVE,
720*d9f75844SAndroid Build Coastguard Worker             VideoConnectionRole(answer->description()));
721*d9f75844SAndroid Build Coastguard Worker 
722*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
723*d9f75844SAndroid Build Coastguard Worker       caller->SetLocalDescription(CloneSessionDescription(answer.get())));
724*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(answer)));
725*d9f75844SAndroid Build Coastguard Worker 
726*d9f75844SAndroid Build Coastguard Worker   // Lastly, start BUNDLE-ing on "audio", expecting that the "passive" role of
727*d9f75844SAndroid Build Coastguard Worker   // audio is transferred over to video in the answer that completes the BUNDLE
728*d9f75844SAndroid Build Coastguard Worker   // negotiation.
729*d9f75844SAndroid Build Coastguard Worker   RTCOfferAnswerOptions options_bundle;
730*d9f75844SAndroid Build Coastguard Worker   options_bundle.use_rtp_mux = true;
731*d9f75844SAndroid Build Coastguard Worker 
732*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateOfferAndSetAsLocal()));
733*d9f75844SAndroid Build Coastguard Worker   answer = caller->CreateAnswer(options_bundle);
734*d9f75844SAndroid Build Coastguard Worker 
735*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
736*d9f75844SAndroid Build Coastguard Worker             AudioConnectionRole(answer->description()));
737*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
738*d9f75844SAndroid Build Coastguard Worker             VideoConnectionRole(answer->description()));
739*d9f75844SAndroid Build Coastguard Worker 
740*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(
741*d9f75844SAndroid Build Coastguard Worker       caller->SetLocalDescription(CloneSessionDescription(answer.get())));
742*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(std::move(answer)));
743*d9f75844SAndroid Build Coastguard Worker }
744*d9f75844SAndroid Build Coastguard Worker 
745*d9f75844SAndroid Build Coastguard Worker // Tests that if the DTLS fingerprint is invalid then all future calls to
746*d9f75844SAndroid Build Coastguard Worker // SetLocalDescription and SetRemoteDescription will fail due to a session
747*d9f75844SAndroid Build Coastguard Worker // error.
748*d9f75844SAndroid Build Coastguard Worker // This is a regression test for crbug.com/800775
TEST_P(PeerConnectionCryptoTest,SessionErrorIfFingerprintInvalid)749*d9f75844SAndroid Build Coastguard Worker TEST_P(PeerConnectionCryptoTest, SessionErrorIfFingerprintInvalid) {
750*d9f75844SAndroid Build Coastguard Worker   auto callee_certificate = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
751*d9f75844SAndroid Build Coastguard Worker   auto other_certificate = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
752*d9f75844SAndroid Build Coastguard Worker 
753*d9f75844SAndroid Build Coastguard Worker   auto caller = CreatePeerConnectionWithAudioVideo();
754*d9f75844SAndroid Build Coastguard Worker   RTCConfiguration callee_config;
755*d9f75844SAndroid Build Coastguard Worker   callee_config.certificates.push_back(callee_certificate);
756*d9f75844SAndroid Build Coastguard Worker   auto callee = CreatePeerConnectionWithAudioVideo(callee_config);
757*d9f75844SAndroid Build Coastguard Worker 
758*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
759*d9f75844SAndroid Build Coastguard Worker 
760*d9f75844SAndroid Build Coastguard Worker   // Create an invalid answer with the other certificate's fingerprint.
761*d9f75844SAndroid Build Coastguard Worker   auto valid_answer = callee->CreateAnswer();
762*d9f75844SAndroid Build Coastguard Worker   auto invalid_answer = CloneSessionDescription(valid_answer.get());
763*d9f75844SAndroid Build Coastguard Worker   auto* audio_content =
764*d9f75844SAndroid Build Coastguard Worker       cricket::GetFirstAudioContent(invalid_answer->description());
765*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(audio_content);
766*d9f75844SAndroid Build Coastguard Worker   auto* audio_transport_info =
767*d9f75844SAndroid Build Coastguard Worker       invalid_answer->description()->GetTransportInfoByName(
768*d9f75844SAndroid Build Coastguard Worker           audio_content->name);
769*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(audio_transport_info);
770*d9f75844SAndroid Build Coastguard Worker   audio_transport_info->description.identity_fingerprint =
771*d9f75844SAndroid Build Coastguard Worker       rtc::SSLFingerprint::CreateFromCertificate(*other_certificate);
772*d9f75844SAndroid Build Coastguard Worker 
773*d9f75844SAndroid Build Coastguard Worker   // Set the invalid answer and expect a fingerprint error.
774*d9f75844SAndroid Build Coastguard Worker   std::string error;
775*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(callee->SetLocalDescription(std::move(invalid_answer), &error));
776*d9f75844SAndroid Build Coastguard Worker   EXPECT_PRED_FORMAT2(AssertStringContains, error,
777*d9f75844SAndroid Build Coastguard Worker                       "Local fingerprint does not match identity.");
778*d9f75844SAndroid Build Coastguard Worker 
779*d9f75844SAndroid Build Coastguard Worker   // Make sure that setting a valid remote offer or local answer also fails now.
780*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(callee->SetRemoteDescription(caller->CreateOffer(), &error));
781*d9f75844SAndroid Build Coastguard Worker   EXPECT_PRED_FORMAT2(AssertStringContains, error,
782*d9f75844SAndroid Build Coastguard Worker                       "Session error code: ERROR_CONTENT.");
783*d9f75844SAndroid Build Coastguard Worker   ASSERT_FALSE(callee->SetLocalDescription(std::move(valid_answer), &error));
784*d9f75844SAndroid Build Coastguard Worker   EXPECT_PRED_FORMAT2(AssertStringContains, error,
785*d9f75844SAndroid Build Coastguard Worker                       "Session error code: ERROR_CONTENT.");
786*d9f75844SAndroid Build Coastguard Worker }
787*d9f75844SAndroid Build Coastguard Worker 
788*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(PeerConnectionCryptoTest,
789*d9f75844SAndroid Build Coastguard Worker                          PeerConnectionCryptoTest,
790*d9f75844SAndroid Build Coastguard Worker                          Values(SdpSemantics::kPlanB_DEPRECATED,
791*d9f75844SAndroid Build Coastguard Worker                                 SdpSemantics::kUnifiedPlan));
792*d9f75844SAndroid Build Coastguard Worker 
793*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
794