Unify TLS cipher suite name handling
Move it away from the "proprietary" SSL_CIPHER_get_id and looking up the cipher based on that towards SSL_CIPHER_standard_name. SSL_CIPHER_get_id and the associated GetSslCipherSuite API is kept around for WebRTC.PeerConnection.SslCipherSuite.* UMA metrics and metrics compability (despite not yielding the IANA ids it promises). BUG=None Change-Id: Iaa357e3e31dc90abea688cf6ca10c0b40582ef38 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/363202 Reviewed-by: David Benjamin <davidben@webrtc.org> Commit-Queue: Philipp Hancke <phancke@meta.com> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43097}
This commit is contained in:
parent
20e4ce51df
commit
1831184330
@ -233,6 +233,13 @@ bool DtlsTransport::GetSslCipherSuite(int* cipher) {
|
||||
return dtls_->GetSslCipherSuite(cipher);
|
||||
}
|
||||
|
||||
std::optional<absl::string_view> DtlsTransport::GetTlsCipherSuiteName() const {
|
||||
if (dtls_state() != webrtc::DtlsTransportState::kConnected) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return dtls_->GetTlsCipherSuiteName();
|
||||
}
|
||||
|
||||
webrtc::RTCError DtlsTransport::SetRemoteParameters(
|
||||
absl::string_view digest_alg,
|
||||
const uint8_t* digest,
|
||||
|
||||
@ -169,6 +169,7 @@ class DtlsTransport : public DtlsTransportInternal {
|
||||
|
||||
// Find out which DTLS cipher was negotiated
|
||||
bool GetSslCipherSuite(int* cipher) override;
|
||||
std::optional<absl::string_view> GetTlsCipherSuiteName() const override;
|
||||
|
||||
// Once DTLS has been established, this method retrieves the certificate
|
||||
// chain in use by the remote peer, for use in external identity
|
||||
|
||||
@ -70,6 +70,7 @@ class DtlsTransportInternal : public rtc::PacketTransportInternal {
|
||||
// Finds out which DTLS cipher was negotiated.
|
||||
// TODO(zhihuang): Remove this once all dependencies implement this.
|
||||
virtual bool GetSslCipherSuite(int* cipher) = 0;
|
||||
virtual std::optional<absl::string_view> GetTlsCipherSuiteName() const = 0;
|
||||
|
||||
// Find out which signature algorithm was used by the peer. Returns values
|
||||
// from
|
||||
|
||||
@ -213,6 +213,10 @@ class FakeDtlsTransport : public DtlsTransportInternal {
|
||||
void SetSslCipherSuite(std::optional<int> cipher_suite) {
|
||||
ssl_cipher_suite_ = cipher_suite;
|
||||
}
|
||||
|
||||
std::optional<absl::string_view> GetTlsCipherSuiteName() const override {
|
||||
return "FakeTlsCipherSuite";
|
||||
}
|
||||
uint16_t GetSslPeerSignatureAlgorithm() const override { return 0; }
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override {
|
||||
return local_cert_;
|
||||
|
||||
@ -642,6 +642,7 @@ bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
|
||||
dtls_transport->GetSslVersionBytes(&substats.ssl_version_bytes);
|
||||
dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
|
||||
dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
|
||||
substats.tls_cipher_suite_name = dtls_transport->GetTlsCipherSuiteName();
|
||||
substats.dtls_state = dtls_transport->dtls_state();
|
||||
rtc::SSLRole dtls_role;
|
||||
if (dtls_transport->GetDtlsRole(&dtls_role)) {
|
||||
|
||||
@ -1012,13 +1012,10 @@ void LegacyStatsCollector::ExtractSessionInfo_s(SessionStats& session_stats) {
|
||||
StatsReport::kStatsValueNameSrtpCipher,
|
||||
rtc::SrtpCryptoSuiteToName(srtp_crypto_suite));
|
||||
}
|
||||
int ssl_cipher_suite = channel_iter.ssl_cipher_suite;
|
||||
if (ssl_cipher_suite != rtc::kTlsNullWithNullNull &&
|
||||
rtc::SSLStreamAdapter::SslCipherSuiteToName(ssl_cipher_suite)
|
||||
.length()) {
|
||||
if (channel_iter.tls_cipher_suite_name) {
|
||||
channel_report->AddString(
|
||||
StatsReport::kStatsValueNameDtlsCipher,
|
||||
rtc::SSLStreamAdapter::SslCipherSuiteToName(ssl_cipher_suite));
|
||||
std::string(*channel_iter.tls_cipher_suite_name));
|
||||
}
|
||||
|
||||
// Collect stats for non-pooled candidates. Note that the reports
|
||||
|
||||
@ -67,11 +67,6 @@ using ::testing::UnorderedElementsAre;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace internal {
|
||||
// This value comes from openssl/tls1.h
|
||||
static const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
|
||||
} // namespace internal
|
||||
|
||||
// Error return values
|
||||
const char kNotFound[] = "NOT FOUND";
|
||||
|
||||
@ -674,8 +669,7 @@ class LegacyStatsCollectorTest : public ::testing::Test {
|
||||
TransportChannelStats channel_stats;
|
||||
channel_stats.component = 1;
|
||||
channel_stats.srtp_crypto_suite = rtc::kSrtpAes128CmSha1_80;
|
||||
channel_stats.ssl_cipher_suite =
|
||||
internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
|
||||
channel_stats.tls_cipher_suite_name = "cipher_suite_for_test";
|
||||
pc->SetTransportStats(kTransportName, channel_stats);
|
||||
|
||||
// Fake certificate to report.
|
||||
@ -722,9 +716,7 @@ class LegacyStatsCollectorTest : public ::testing::Test {
|
||||
std::string dtls_cipher_suite =
|
||||
ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
|
||||
StatsReport::kStatsValueNameDtlsCipher);
|
||||
EXPECT_EQ(rtc::SSLStreamAdapter::SslCipherSuiteToName(
|
||||
internal::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
|
||||
dtls_cipher_suite);
|
||||
EXPECT_EQ(dtls_cipher_suite, "cipher_suite_for_test");
|
||||
std::string srtp_crypto_suite =
|
||||
ExtractStatsValue(StatsReport::kStatsReportTypeComponent, reports,
|
||||
StatsReport::kStatsValueNameSrtpCipher);
|
||||
|
||||
@ -1961,14 +1961,7 @@ void RTCStatsCollector::ProduceTransportStats_n(
|
||||
transport_stats->dtls_role = "unknown";
|
||||
}
|
||||
|
||||
if (channel_stats.ssl_cipher_suite != rtc::kTlsNullWithNullNull &&
|
||||
rtc::SSLStreamAdapter::SslCipherSuiteToName(
|
||||
channel_stats.ssl_cipher_suite)
|
||||
.length()) {
|
||||
transport_stats->dtls_cipher =
|
||||
rtc::SSLStreamAdapter::SslCipherSuiteToName(
|
||||
channel_stats.ssl_cipher_suite);
|
||||
}
|
||||
transport_stats->dtls_cipher = channel_stats.tls_cipher_suite_name;
|
||||
if (channel_stats.srtp_crypto_suite != rtc::kSrtpInvalidCryptoSuite &&
|
||||
rtc::SrtpCryptoSuiteToName(channel_stats.srtp_crypto_suite)
|
||||
.length()) {
|
||||
|
||||
@ -2942,8 +2942,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCTransportStatsWithCrypto) {
|
||||
"thelocalufrag";
|
||||
rtp_transport_channel_stats.ice_transport_stats.ice_state =
|
||||
IceTransportState::kConnected;
|
||||
// 0x2F is TLS_RSA_WITH_AES_128_CBC_SHA according to IANA
|
||||
rtp_transport_channel_stats.ssl_cipher_suite = 0x2F;
|
||||
rtp_transport_channel_stats.tls_cipher_suite_name =
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA";
|
||||
rtp_transport_channel_stats.srtp_crypto_suite = rtc::kSrtpAes128CmSha1_80;
|
||||
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats});
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ struct TransportChannelStats {
|
||||
int ssl_version_bytes = 0;
|
||||
int srtp_crypto_suite = rtc::kSrtpInvalidCryptoSuite;
|
||||
int ssl_cipher_suite = rtc::kTlsNullWithNullNull;
|
||||
std::optional<absl::string_view> tls_cipher_suite_name;
|
||||
std::optional<rtc::SSLRole> dtls_role;
|
||||
webrtc::DtlsTransportState dtls_state = webrtc::DtlsTransportState::kNew;
|
||||
IceTransportStats ice_transport_stats;
|
||||
|
||||
@ -63,12 +63,6 @@
|
||||
#error "webrtc requires at least OpenSSL version 1.1.0, to support DTLS-SRTP"
|
||||
#endif
|
||||
|
||||
// Defines for the TLS Cipher Suite Map.
|
||||
#define DEFINE_CIPHER_ENTRY_SSL3(name) \
|
||||
{ SSL3_CK_##name, "TLS_" #name }
|
||||
#define DEFINE_CIPHER_ENTRY_TLS1(name) \
|
||||
{ TLS1_CK_##name, "TLS_" #name }
|
||||
|
||||
namespace rtc {
|
||||
namespace {
|
||||
using ::webrtc::SafeTask;
|
||||
@ -93,68 +87,6 @@ constexpr SrtpCipherMapEntry kSrtpCipherMap[] = {
|
||||
{"SRTP_AEAD_AES_128_GCM", kSrtpAeadAes128Gcm},
|
||||
{"SRTP_AEAD_AES_256_GCM", kSrtpAeadAes256Gcm}};
|
||||
|
||||
#ifndef OPENSSL_IS_BORINGSSL
|
||||
// The "SSL_CIPHER_standard_name" function is only available in OpenSSL when
|
||||
// compiled with tracing, so we need to define the mapping manually here.
|
||||
constexpr SslCipherMapEntry kSslCipherMap[] = {
|
||||
// TLS v1.0 ciphersuites from RFC2246.
|
||||
DEFINE_CIPHER_ENTRY_SSL3(RSA_RC4_128_SHA),
|
||||
{SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
|
||||
|
||||
// AES ciphersuites from RFC3268.
|
||||
{TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
|
||||
{TLS1_CK_DHE_RSA_WITH_AES_128_SHA, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
|
||||
{TLS1_CK_RSA_WITH_AES_256_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA"},
|
||||
{TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
|
||||
|
||||
// ECC ciphersuites from RFC4492.
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_RC4_128_SHA),
|
||||
{TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
|
||||
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"},
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_CBC_SHA),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_CBC_SHA),
|
||||
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_RC4_128_SHA),
|
||||
{TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"},
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_CBC_SHA),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_CBC_SHA),
|
||||
|
||||
// TLS v1.2 ciphersuites.
|
||||
{TLS1_CK_RSA_WITH_AES_128_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"},
|
||||
{TLS1_CK_RSA_WITH_AES_256_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"},
|
||||
{TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
|
||||
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
|
||||
{TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
|
||||
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
|
||||
|
||||
// TLS v1.2 GCM ciphersuites from RFC5288.
|
||||
DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_128_GCM_SHA256),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_256_GCM_SHA384),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_128_GCM_SHA256),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_256_GCM_SHA384),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_128_GCM_SHA256),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_256_GCM_SHA384),
|
||||
|
||||
// ECDH HMAC based ciphersuites from RFC5289.
|
||||
{TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"},
|
||||
{TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"},
|
||||
{TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
|
||||
{TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
|
||||
|
||||
// ECDH GCM based ciphersuites from RFC5289.
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_GCM_SHA256),
|
||||
DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_GCM_SHA384),
|
||||
|
||||
{0, nullptr}};
|
||||
#endif // #ifndef OPENSSL_IS_BORINGSSL
|
||||
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
// Enabled by EnableTimeCallbackForTesting. Should never be set in production
|
||||
// code.
|
||||
@ -388,23 +320,14 @@ bool OpenSSLStreamAdapter::SetPeerCertificateDigest(
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string OpenSSLStreamAdapter::SslCipherSuiteToName(int cipher_suite) {
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
const SSL_CIPHER* ssl_cipher = SSL_get_cipher_by_value(cipher_suite);
|
||||
if (!ssl_cipher) {
|
||||
return std::string();
|
||||
std::optional<absl::string_view> OpenSSLStreamAdapter::GetTlsCipherSuiteName()
|
||||
const {
|
||||
if (state_ != SSL_CONNECTED) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return SSL_CIPHER_standard_name(ssl_cipher);
|
||||
#else
|
||||
const int openssl_cipher_id = 0x03000000L | cipher_suite;
|
||||
for (const SslCipherMapEntry* entry = kSslCipherMap; entry->rfc_name;
|
||||
++entry) {
|
||||
if (openssl_cipher_id == static_cast<int>(entry->openssl_id)) {
|
||||
return entry->rfc_name;
|
||||
}
|
||||
}
|
||||
return std::string();
|
||||
#endif
|
||||
|
||||
const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
|
||||
return SSL_CIPHER_standard_name(current_cipher);
|
||||
}
|
||||
|
||||
bool OpenSSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) {
|
||||
|
||||
@ -103,8 +103,7 @@ class OpenSSLStreamAdapter final : public SSLStreamAdapter,
|
||||
void Close() override;
|
||||
StreamState GetState() const override;
|
||||
|
||||
// TODO(guoweis): Move this away from a static class method.
|
||||
static std::string SslCipherSuiteToName(int crypto_suite);
|
||||
std::optional<absl::string_view> GetTlsCipherSuiteName() const override;
|
||||
|
||||
bool GetSslCipherSuite(int* cipher) override;
|
||||
[[deprecated("Use GetSslVersionBytes")]] SSLProtocolVersion GetSslVersion()
|
||||
|
||||
@ -119,9 +119,6 @@ bool SSLStreamAdapter::IsAcceptableCipher(absl::string_view cipher,
|
||||
KeyType key_type) {
|
||||
return OpenSSLStreamAdapter::IsAcceptableCipher(cipher, key_type);
|
||||
}
|
||||
std::string SSLStreamAdapter::SslCipherSuiteToName(int cipher_suite) {
|
||||
return OpenSSLStreamAdapter::SslCipherSuiteToName(cipher_suite);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Test only settings
|
||||
|
||||
@ -185,6 +185,9 @@ class SSLStreamAdapter : public StreamInterface {
|
||||
// Retrieves the IANA registration id of the cipher suite used for the
|
||||
// connection (e.g. 0x2F for "TLS_RSA_WITH_AES_128_CBC_SHA").
|
||||
virtual bool GetSslCipherSuite(int* cipher_suite);
|
||||
// Returns the name of the cipher suite used for the DTLS transport,
|
||||
// as defined in the "Description" column of the IANA cipher suite registry.
|
||||
virtual std::optional<absl::string_view> GetTlsCipherSuiteName() const = 0;
|
||||
|
||||
// Retrieves the enum value for SSL version.
|
||||
// Will return -1 until the version has been negotiated.
|
||||
@ -236,11 +239,6 @@ class SSLStreamAdapter : public StreamInterface {
|
||||
static bool IsAcceptableCipher(int cipher, KeyType key_type);
|
||||
static bool IsAcceptableCipher(absl::string_view cipher, KeyType key_type);
|
||||
|
||||
// TODO(guoweis): Move this away from a static class method. Currently this is
|
||||
// introduced such that any caller could depend on sslstreamadapter.h without
|
||||
// depending on specific SSL implementation.
|
||||
static std::string SslCipherSuiteToName(int cipher_suite);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Testing only member functions
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user