Reland "Set session error if SetLocal/RemoteDescription ever fails"
Original change's description:
> Set session error if SetLocal/RemoteDescription ever fails
>
> This changes SetLocalDescription/SetRemoteDescription to set a
> session error which will cause any future calls to fail early if
> there is an error when applying a session description.
>
> This is needed since until better error recovery is implemented
> failing a call to SetLocalDescription or SetRemoteDescription
> could leave the PeerConnection in an inconsistent state.
>
> Bug: chromium:800775
> Change-Id: If06fd73d6e902af15d072dc562bbe830d3b11ad5
> Reviewed-on: https://webrtc-review.googlesource.com/54061
> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
> Commit-Queue: Steve Anton <steveanton@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#22061}
Bug: chromium:800775
Change-Id: I0016108264e013452e9d34239c012baf23240e99
Reviewed-on: https://webrtc-review.googlesource.com/54720
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22067}
diff --git a/pc/peerconnection_crypto_unittest.cc b/pc/peerconnection_crypto_unittest.cc
index c6cfb90..b2f2469 100644
--- a/pc/peerconnection_crypto_unittest.cc
+++ b/pc/peerconnection_crypto_unittest.cc
@@ -672,6 +672,49 @@
ASSERT_TRUE(callee->SetRemoteDescription(std::move(answer)));
}
+// Tests that if the DTLS fingerprint is invalid then all future calls to
+// SetLocalDescription and SetRemoteDescription will fail due to a session
+// error.
+// This is a regression test for crbug.com/800775
+TEST_P(PeerConnectionCryptoTest, SessionErrorIfFingerprintInvalid) {
+ auto callee_certificate = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
+ auto other_certificate = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
+
+ auto caller = CreatePeerConnectionWithAudioVideo();
+ RTCConfiguration callee_config;
+ callee_config.enable_dtls_srtp.emplace(true);
+ callee_config.certificates.push_back(callee_certificate);
+ auto callee = CreatePeerConnectionWithAudioVideo(callee_config);
+
+ ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
+
+ // Create an invalid answer with the other certificate's fingerprint.
+ auto invalid_answer = callee->CreateAnswer();
+ auto* audio_content =
+ cricket::GetFirstAudioContent(invalid_answer->description());
+ ASSERT_TRUE(audio_content);
+ auto* audio_transport_info =
+ invalid_answer->description()->GetTransportInfoByName(
+ audio_content->name);
+ ASSERT_TRUE(audio_transport_info);
+ audio_transport_info->description.identity_fingerprint.reset(
+ rtc::SSLFingerprint::CreateFromCertificate(other_certificate));
+
+ // Set the invalid answer and expect a fingerprint error.
+ std::string error;
+ ASSERT_FALSE(callee->SetLocalDescription(std::move(invalid_answer), &error));
+ EXPECT_PRED_FORMAT2(AssertStringContains, error,
+ "Local fingerprint does not match identity.");
+
+ // Make sure that setting a valid remote offer or local answer also fails now.
+ ASSERT_FALSE(callee->SetRemoteDescription(caller->CreateOffer(), &error));
+ EXPECT_PRED_FORMAT2(AssertStringContains, error,
+ "Session error code: ERROR_CONTENT.");
+ ASSERT_FALSE(callee->SetLocalDescription(callee->CreateAnswer(), &error));
+ EXPECT_PRED_FORMAT2(AssertStringContains, error,
+ "Session error code: ERROR_CONTENT.");
+}
+
INSTANTIATE_TEST_CASE_P(PeerConnectionCryptoTest,
PeerConnectionCryptoTest,
Values(SdpSemantics::kPlanB,