Make DTLS role visible on DtlsTransport interface

This is important for writing tests that affect the DTLS role.

Bug: webrtc:13668
Change-Id: I5d9a93eca7996a8b74cdcfe412f59a85892e1ec1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/251389
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35971}
This commit is contained in:
Harald Alvestrand
2022-02-10 08:23:47 +00:00
committed by WebRTC LUCI CQ
parent e6aa6a8740
commit 316ab12821
4 changed files with 61 additions and 2 deletions

View File

@ -20,11 +20,27 @@ DtlsTransportInformation::DtlsTransportInformation(DtlsTransportState state)
DtlsTransportInformation::DtlsTransportInformation( DtlsTransportInformation::DtlsTransportInformation(
DtlsTransportState state, DtlsTransportState state,
absl::optional<DtlsTransportTlsRole> role,
absl::optional<int> tls_version, absl::optional<int> tls_version,
absl::optional<int> ssl_cipher_suite, absl::optional<int> ssl_cipher_suite,
absl::optional<int> srtp_cipher_suite, absl::optional<int> srtp_cipher_suite,
std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates) std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates)
: state_(state), : state_(state),
role_(role),
tls_version_(tls_version),
ssl_cipher_suite_(ssl_cipher_suite),
srtp_cipher_suite_(srtp_cipher_suite),
remote_ssl_certificates_(std::move(remote_ssl_certificates)) {}
// Deprecated version
DtlsTransportInformation::DtlsTransportInformation(
DtlsTransportState state,
absl::optional<int> tls_version,
absl::optional<int> ssl_cipher_suite,
absl::optional<int> srtp_cipher_suite,
std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates)
: state_(state),
role_(absl::nullopt),
tls_version_(tls_version), tls_version_(tls_version),
ssl_cipher_suite_(ssl_cipher_suite), ssl_cipher_suite_(ssl_cipher_suite),
srtp_cipher_suite_(srtp_cipher_suite), srtp_cipher_suite_(srtp_cipher_suite),
@ -33,6 +49,7 @@ DtlsTransportInformation::DtlsTransportInformation(
DtlsTransportInformation::DtlsTransportInformation( DtlsTransportInformation::DtlsTransportInformation(
const DtlsTransportInformation& c) const DtlsTransportInformation& c)
: state_(c.state()), : state_(c.state()),
role_(c.role_),
tls_version_(c.tls_version_), tls_version_(c.tls_version_),
ssl_cipher_suite_(c.ssl_cipher_suite_), ssl_cipher_suite_(c.ssl_cipher_suite_),
srtp_cipher_suite_(c.srtp_cipher_suite_), srtp_cipher_suite_(c.srtp_cipher_suite_),
@ -43,6 +60,7 @@ DtlsTransportInformation::DtlsTransportInformation(
DtlsTransportInformation& DtlsTransportInformation::operator=( DtlsTransportInformation& DtlsTransportInformation::operator=(
const DtlsTransportInformation& c) { const DtlsTransportInformation& c) {
state_ = c.state(); state_ = c.state();
role_ = c.role_;
tls_version_ = c.tls_version_; tls_version_ = c.tls_version_;
ssl_cipher_suite_ = c.ssl_cipher_suite_; ssl_cipher_suite_ = c.ssl_cipher_suite_;
srtp_cipher_suite_ = c.srtp_cipher_suite_; srtp_cipher_suite_ = c.srtp_cipher_suite_;

View File

@ -36,6 +36,11 @@ enum class DtlsTransportState {
kNumValues kNumValues
}; };
enum class DtlsTransportTlsRole {
kServer, // Other end sends CLIENT_HELLO
kClient // This end sends CLIENT_HELLO
};
// This object gives snapshot information about the changeable state of a // This object gives snapshot information about the changeable state of a
// DTLSTransport. // DTLSTransport.
class RTC_EXPORT DtlsTransportInformation { class RTC_EXPORT DtlsTransportInformation {
@ -44,10 +49,19 @@ class RTC_EXPORT DtlsTransportInformation {
explicit DtlsTransportInformation(DtlsTransportState state); explicit DtlsTransportInformation(DtlsTransportState state);
DtlsTransportInformation( DtlsTransportInformation(
DtlsTransportState state, DtlsTransportState state,
absl::optional<DtlsTransportTlsRole> role,
absl::optional<int> tls_version, absl::optional<int> tls_version,
absl::optional<int> ssl_cipher_suite, absl::optional<int> ssl_cipher_suite,
absl::optional<int> srtp_cipher_suite, absl::optional<int> srtp_cipher_suite,
std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates); std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates);
ABSL_DEPRECATED("Use version with role parameter")
DtlsTransportInformation(
DtlsTransportState state,
absl::optional<int> tls_version,
absl::optional<int> ssl_cipher_suite,
absl::optional<int> srtp_cipher_suite,
std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates);
// Copy and assign // Copy and assign
DtlsTransportInformation(const DtlsTransportInformation& c); DtlsTransportInformation(const DtlsTransportInformation& c);
DtlsTransportInformation& operator=(const DtlsTransportInformation& c); DtlsTransportInformation& operator=(const DtlsTransportInformation& c);
@ -57,6 +71,7 @@ class RTC_EXPORT DtlsTransportInformation {
default; default;
DtlsTransportState state() const { return state_; } DtlsTransportState state() const { return state_; }
absl::optional<DtlsTransportTlsRole> role() const { return role_; }
absl::optional<int> tls_version() const { return tls_version_; } absl::optional<int> tls_version() const { return tls_version_; }
absl::optional<int> ssl_cipher_suite() const { return ssl_cipher_suite_; } absl::optional<int> ssl_cipher_suite() const { return ssl_cipher_suite_; }
absl::optional<int> srtp_cipher_suite() const { return srtp_cipher_suite_; } absl::optional<int> srtp_cipher_suite() const { return srtp_cipher_suite_; }
@ -67,6 +82,7 @@ class RTC_EXPORT DtlsTransportInformation {
private: private:
DtlsTransportState state_; DtlsTransportState state_;
absl::optional<DtlsTransportTlsRole> role_;
absl::optional<int> tls_version_; absl::optional<int> tls_version_;
absl::optional<int> ssl_cipher_suite_; absl::optional<int> ssl_cipher_suite_;
absl::optional<int> srtp_cipher_suite_; absl::optional<int> srtp_cipher_suite_;

View File

@ -105,22 +105,35 @@ void DtlsTransport::UpdateInformation() {
if (internal_dtls_transport_->dtls_state() == if (internal_dtls_transport_->dtls_state() ==
DtlsTransportState::kConnected) { DtlsTransportState::kConnected) {
bool success = true; bool success = true;
rtc::SSLRole internal_role;
absl::optional<DtlsTransportTlsRole> role;
int ssl_cipher_suite; int ssl_cipher_suite;
int tls_version; int tls_version;
int srtp_cipher; int srtp_cipher;
success &= internal_dtls_transport_->GetDtlsRole(&internal_role);
if (success) {
switch (internal_role) {
case rtc::SSL_CLIENT:
role = DtlsTransportTlsRole::kServer;
break;
case rtc::SSL_SERVER:
role = DtlsTransportTlsRole::kClient;
break;
}
}
success &= internal_dtls_transport_->GetSslVersionBytes(&tls_version); success &= internal_dtls_transport_->GetSslVersionBytes(&tls_version);
success &= internal_dtls_transport_->GetSslCipherSuite(&ssl_cipher_suite); success &= internal_dtls_transport_->GetSslCipherSuite(&ssl_cipher_suite);
success &= internal_dtls_transport_->GetSrtpCryptoSuite(&srtp_cipher); success &= internal_dtls_transport_->GetSrtpCryptoSuite(&srtp_cipher);
if (success) { if (success) {
info_ = DtlsTransportInformation( info_ = DtlsTransportInformation(
internal_dtls_transport_->dtls_state(), tls_version, internal_dtls_transport_->dtls_state(), role, tls_version,
ssl_cipher_suite, srtp_cipher, ssl_cipher_suite, srtp_cipher,
internal_dtls_transport_->GetRemoteSSLCertChain()); internal_dtls_transport_->GetRemoteSSLCertChain());
} else { } else {
RTC_LOG(LS_ERROR) << "DtlsTransport in connected state has incomplete " RTC_LOG(LS_ERROR) << "DtlsTransport in connected state has incomplete "
"TLS information"; "TLS information";
info_ = DtlsTransportInformation( info_ = DtlsTransportInformation(
internal_dtls_transport_->dtls_state(), absl::nullopt, internal_dtls_transport_->dtls_state(), role, absl::nullopt,
absl::nullopt, absl::nullopt, absl::nullopt, absl::nullopt,
internal_dtls_transport_->GetRemoteSSLCertChain()); internal_dtls_transport_->GetRemoteSSLCertChain());
} }

View File

@ -120,6 +120,18 @@ TEST_F(DtlsTransportTest, CloseWhenClearing) {
kDefaultTimeout); kDefaultTimeout);
} }
TEST_F(DtlsTransportTest, RoleAppearsOnConnect) {
rtc::FakeSSLCertificate fake_certificate("fake data");
CreateTransport(&fake_certificate);
transport()->RegisterObserver(observer());
EXPECT_FALSE(transport()->Information().role());
CompleteDtlsHandshake();
ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
kDefaultTimeout);
EXPECT_TRUE(observer_.info_.role());
EXPECT_TRUE(transport()->Information().role());
}
TEST_F(DtlsTransportTest, CertificateAppearsOnConnect) { TEST_F(DtlsTransportTest, CertificateAppearsOnConnect) {
rtc::FakeSSLCertificate fake_certificate("fake data"); rtc::FakeSSLCertificate fake_certificate("fake data");
CreateTransport(&fake_certificate); CreateTransport(&fake_certificate);