Reland Change WebRTC SslCipher to be exposed as number only
This is to revert the change of https://codereview.webrtc.org/1380603005/ TBR=pthatcher@webrtc.org BUG=523033 Review URL: https://codereview.webrtc.org/1375543003 . Cr-Commit-Position: refs/heads/master@{#10126}
This commit is contained in:
parent
27dc29b0df
commit
456696a9c1
@ -37,10 +37,7 @@ FakeMetricsObserver::FakeMetricsObserver() {
|
||||
void FakeMetricsObserver::Reset() {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
counters_.clear();
|
||||
memset(int_histogram_samples_, 0, sizeof(int_histogram_samples_));
|
||||
for (std::string& type : string_histogram_samples_) {
|
||||
type.clear();
|
||||
}
|
||||
memset(histogram_samples_, 0, sizeof(histogram_samples_));
|
||||
}
|
||||
|
||||
void FakeMetricsObserver::IncrementEnumCounter(
|
||||
@ -52,43 +49,31 @@ void FakeMetricsObserver::IncrementEnumCounter(
|
||||
counters_.resize(type + 1);
|
||||
}
|
||||
auto& counters = counters_[type];
|
||||
if (counters.size() < static_cast<size_t>(counter_max)) {
|
||||
counters.resize(counter_max);
|
||||
}
|
||||
++counters[counter];
|
||||
}
|
||||
|
||||
void FakeMetricsObserver::AddHistogramSample(PeerConnectionMetricsName type,
|
||||
int value) {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
RTC_DCHECK_EQ(int_histogram_samples_[type], 0);
|
||||
int_histogram_samples_[type] = value;
|
||||
}
|
||||
|
||||
void FakeMetricsObserver::AddHistogramSample(PeerConnectionMetricsName type,
|
||||
const std::string& value) {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
string_histogram_samples_[type].assign(value);
|
||||
RTC_DCHECK_EQ(histogram_samples_[type], 0);
|
||||
histogram_samples_[type] = value;
|
||||
}
|
||||
|
||||
int FakeMetricsObserver::GetEnumCounter(PeerConnectionEnumCounterType type,
|
||||
int counter) const {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
RTC_CHECK(counters_.size() > static_cast<size_t>(type) &&
|
||||
counters_[type].size() > static_cast<size_t>(counter));
|
||||
return counters_[type][counter];
|
||||
RTC_CHECK(counters_.size() > static_cast<size_t>(type));
|
||||
const auto& it = counters_[type].find(counter);
|
||||
if (it == counters_[type].end()) {
|
||||
return 0;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int FakeMetricsObserver::GetIntHistogramSample(
|
||||
int FakeMetricsObserver::GetHistogramSample(
|
||||
PeerConnectionMetricsName type) const {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
return int_histogram_samples_[type];
|
||||
}
|
||||
|
||||
const std::string& FakeMetricsObserver::GetStringHistogramSample(
|
||||
PeerConnectionMetricsName type) const {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
return string_histogram_samples_[type];
|
||||
return histogram_samples_[type];
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -46,25 +46,21 @@ class FakeMetricsObserver : public MetricsObserverInterface {
|
||||
int counter_max) override;
|
||||
void AddHistogramSample(PeerConnectionMetricsName type,
|
||||
int value) override;
|
||||
void AddHistogramSample(PeerConnectionMetricsName type,
|
||||
const std::string& value) override;
|
||||
|
||||
// Accessors to be used by the tests.
|
||||
int GetEnumCounter(PeerConnectionEnumCounterType type, int counter) const;
|
||||
int GetIntHistogramSample(PeerConnectionMetricsName type) const;
|
||||
const std::string& GetStringHistogramSample(
|
||||
PeerConnectionMetricsName type) const;
|
||||
int GetHistogramSample(PeerConnectionMetricsName type) const;
|
||||
|
||||
protected:
|
||||
~FakeMetricsObserver() {}
|
||||
|
||||
private:
|
||||
rtc::ThreadChecker thread_checker_;
|
||||
// This is a 2 dimension array. The first index is the enum counter type. The
|
||||
// 2nd index is the counter of that particular enum counter type.
|
||||
std::vector<std::vector<int>> counters_;
|
||||
int int_histogram_samples_[kPeerConnectionMetricsName_Max];
|
||||
std::string string_histogram_samples_[kPeerConnectionMetricsName_Max];
|
||||
// The vector contains maps for each counter type. In the map, it's a mapping
|
||||
// from individual counter to its count, such that it's memory efficient when
|
||||
// comes to sparse enum types, like the SSL ciphers in the IANA registry.
|
||||
std::vector<std::map<int, int>> counters_;
|
||||
int histogram_samples_[kPeerConnectionMetricsName_Max];
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -1342,21 +1342,22 @@ TEST_F(JsepPeerConnectionP2PTestClient, GetDtls12None) {
|
||||
initializing_client()->pc()->RegisterUMAObserver(init_observer);
|
||||
LocalP2PTest();
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_10),
|
||||
initializing_client()->GetDtlsCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_10),
|
||||
init_observer->GetStringHistogramSample(webrtc::kAudioSslCipher));
|
||||
EXPECT_EQ_WAIT(rtc::SSLStreamAdapter::GetSslCipherSuiteName(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)),
|
||||
initializing_client()->GetDtlsCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(1, init_observer->GetEnumCounter(
|
||||
webrtc::kEnumCounterAudioSslCipher,
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)));
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
kDefaultSrtpCipher,
|
||||
initializing_client()->GetSrtpCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(
|
||||
kDefaultSrtpCipher,
|
||||
init_observer->GetStringHistogramSample(webrtc::kAudioSrtpCipher));
|
||||
EXPECT_EQ_WAIT(kDefaultSrtpCipher,
|
||||
initializing_client()->GetSrtpCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(1, init_observer->GetEnumCounter(
|
||||
webrtc::kEnumCounterAudioSrtpCipher,
|
||||
rtc::GetSrtpCryptoSuiteFromName(kDefaultSrtpCipher)));
|
||||
}
|
||||
|
||||
// Test that DTLS 1.2 is used if both ends support it.
|
||||
@ -1371,21 +1372,22 @@ TEST_F(JsepPeerConnectionP2PTestClient, GetDtls12Both) {
|
||||
initializing_client()->pc()->RegisterUMAObserver(init_observer);
|
||||
LocalP2PTest();
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_12),
|
||||
initializing_client()->GetDtlsCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_12),
|
||||
init_observer->GetStringHistogramSample(webrtc::kAudioSslCipher));
|
||||
EXPECT_EQ_WAIT(rtc::SSLStreamAdapter::GetSslCipherSuiteName(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_12, rtc::KT_DEFAULT)),
|
||||
initializing_client()->GetDtlsCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(1, init_observer->GetEnumCounter(
|
||||
webrtc::kEnumCounterAudioSslCipher,
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_12, rtc::KT_DEFAULT)));
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
kDefaultSrtpCipher,
|
||||
initializing_client()->GetSrtpCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(
|
||||
kDefaultSrtpCipher,
|
||||
init_observer->GetStringHistogramSample(webrtc::kAudioSrtpCipher));
|
||||
EXPECT_EQ_WAIT(kDefaultSrtpCipher,
|
||||
initializing_client()->GetSrtpCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(1, init_observer->GetEnumCounter(
|
||||
webrtc::kEnumCounterAudioSrtpCipher,
|
||||
rtc::GetSrtpCryptoSuiteFromName(kDefaultSrtpCipher)));
|
||||
}
|
||||
|
||||
// Test that DTLS 1.0 is used if the initator supports DTLS 1.2 and the
|
||||
@ -1401,21 +1403,22 @@ TEST_F(JsepPeerConnectionP2PTestClient, GetDtls12Init) {
|
||||
initializing_client()->pc()->RegisterUMAObserver(init_observer);
|
||||
LocalP2PTest();
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_10),
|
||||
initializing_client()->GetDtlsCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_10),
|
||||
init_observer->GetStringHistogramSample(webrtc::kAudioSslCipher));
|
||||
EXPECT_EQ_WAIT(rtc::SSLStreamAdapter::GetSslCipherSuiteName(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)),
|
||||
initializing_client()->GetDtlsCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(1, init_observer->GetEnumCounter(
|
||||
webrtc::kEnumCounterAudioSslCipher,
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)));
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
kDefaultSrtpCipher,
|
||||
initializing_client()->GetSrtpCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(
|
||||
kDefaultSrtpCipher,
|
||||
init_observer->GetStringHistogramSample(webrtc::kAudioSrtpCipher));
|
||||
EXPECT_EQ_WAIT(kDefaultSrtpCipher,
|
||||
initializing_client()->GetSrtpCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(1, init_observer->GetEnumCounter(
|
||||
webrtc::kEnumCounterAudioSrtpCipher,
|
||||
rtc::GetSrtpCryptoSuiteFromName(kDefaultSrtpCipher)));
|
||||
}
|
||||
|
||||
// Test that DTLS 1.0 is used if the initator supports DTLS 1.0 and the
|
||||
@ -1431,21 +1434,22 @@ TEST_F(JsepPeerConnectionP2PTestClient, GetDtls12Recv) {
|
||||
initializing_client()->pc()->RegisterUMAObserver(init_observer);
|
||||
LocalP2PTest();
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_10),
|
||||
initializing_client()->GetDtlsCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(rtc::SSL_PROTOCOL_DTLS_10),
|
||||
init_observer->GetStringHistogramSample(webrtc::kAudioSslCipher));
|
||||
EXPECT_EQ_WAIT(rtc::SSLStreamAdapter::GetSslCipherSuiteName(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)),
|
||||
initializing_client()->GetDtlsCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(1, init_observer->GetEnumCounter(
|
||||
webrtc::kEnumCounterAudioSslCipher,
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, rtc::KT_DEFAULT)));
|
||||
|
||||
EXPECT_EQ_WAIT(
|
||||
kDefaultSrtpCipher,
|
||||
initializing_client()->GetSrtpCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(
|
||||
kDefaultSrtpCipher,
|
||||
init_observer->GetStringHistogramSample(webrtc::kAudioSrtpCipher));
|
||||
EXPECT_EQ_WAIT(kDefaultSrtpCipher,
|
||||
initializing_client()->GetSrtpCipherStats(),
|
||||
kMaxWaitForStatsMs);
|
||||
EXPECT_EQ(1, init_observer->GetEnumCounter(
|
||||
webrtc::kEnumCounterAudioSrtpCipher,
|
||||
rtc::GetSrtpCryptoSuiteFromName(kDefaultSrtpCipher)));
|
||||
}
|
||||
|
||||
// This test sets up a call between two parties with audio, video and data.
|
||||
|
||||
@ -137,11 +137,16 @@ class MetricsObserverInterface : public rtc::RefCountInterface {
|
||||
int counter,
|
||||
int counter_max) {}
|
||||
|
||||
// This is used to handle sparse counters like SSL cipher suites.
|
||||
// TODO(guoweis): Remove the implementation once the dependency's interface
|
||||
// definition is updated.
|
||||
virtual void IncrementSparseEnumCounter(PeerConnectionEnumCounterType type,
|
||||
int counter) {
|
||||
IncrementEnumCounter(type, counter, 0 /* Ignored */);
|
||||
}
|
||||
|
||||
virtual void AddHistogramSample(PeerConnectionMetricsName type,
|
||||
int value) = 0;
|
||||
// TODO(jbauch): Make method abstract when it is implemented by Chromium.
|
||||
virtual void AddHistogramSample(PeerConnectionMetricsName type,
|
||||
const std::string& value) {}
|
||||
|
||||
protected:
|
||||
virtual ~MetricsObserverInterface() {}
|
||||
|
||||
@ -734,10 +734,12 @@ void StatsCollector::ExtractSessionInfo() {
|
||||
channel_report->AddString(StatsReport::kStatsValueNameSrtpCipher,
|
||||
srtp_cipher);
|
||||
}
|
||||
const std::string& ssl_cipher = channel_iter.ssl_cipher;
|
||||
if (!ssl_cipher.empty()) {
|
||||
channel_report->AddString(StatsReport::kStatsValueNameDtlsCipher,
|
||||
ssl_cipher);
|
||||
uint16_t ssl_cipher = channel_iter.ssl_cipher;
|
||||
if (ssl_cipher &&
|
||||
rtc::SSLStreamAdapter::GetSslCipherSuiteName(ssl_cipher).length()) {
|
||||
channel_report->AddString(
|
||||
StatsReport::kStatsValueNameDtlsCipher,
|
||||
rtc::SSLStreamAdapter::GetSslCipherSuiteName(ssl_cipher));
|
||||
}
|
||||
|
||||
int connection_id = 0;
|
||||
|
||||
@ -59,6 +59,11 @@ using webrtc::PeerConnectionInterface;
|
||||
using webrtc::StatsReport;
|
||||
using webrtc::StatsReports;
|
||||
|
||||
namespace {
|
||||
// This value comes from openssl/tls1.h
|
||||
const uint16_t TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
|
||||
} // namespace
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class ChannelManager;
|
||||
@ -647,7 +652,7 @@ class StatsCollectorTest : public testing::Test {
|
||||
cricket::TransportChannelStats channel_stats;
|
||||
channel_stats.component = 1;
|
||||
channel_stats.srtp_cipher = "the-srtp-cipher";
|
||||
channel_stats.ssl_cipher = "the-ssl-cipher";
|
||||
channel_stats.ssl_cipher = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
|
||||
|
||||
cricket::TransportStats transport_stats;
|
||||
transport_stats.transport_name = "audio";
|
||||
@ -716,7 +721,9 @@ class StatsCollectorTest : public testing::Test {
|
||||
StatsReport::kStatsReportTypeComponent,
|
||||
reports,
|
||||
StatsReport::kStatsValueNameDtlsCipher);
|
||||
EXPECT_EQ("the-ssl-cipher", dtls_cipher);
|
||||
EXPECT_EQ(rtc::SSLStreamAdapter::GetSslCipherSuiteName(
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
|
||||
dtls_cipher);
|
||||
std::string srtp_cipher = ExtractStatsValue(
|
||||
StatsReport::kStatsReportTypeComponent,
|
||||
reports,
|
||||
|
||||
@ -42,6 +42,13 @@ enum PeerConnectionEnumCounterType {
|
||||
// to the TURN server in the case of TURN candidates.
|
||||
kEnumCounterIceCandidatePairTypeUdp,
|
||||
kEnumCounterIceCandidatePairTypeTcp,
|
||||
|
||||
kEnumCounterAudioSrtpCipher,
|
||||
kEnumCounterAudioSslCipher,
|
||||
kEnumCounterVideoSrtpCipher,
|
||||
kEnumCounterVideoSslCipher,
|
||||
kEnumCounterDataSrtpCipher,
|
||||
kEnumCounterDataSslCipher,
|
||||
kPeerConnectionEnumCounterMax
|
||||
};
|
||||
|
||||
@ -78,12 +85,6 @@ enum PeerConnectionMetricsName {
|
||||
kTimeToConnect, // In milliseconds.
|
||||
kLocalCandidates_IPv4, // Number of IPv4 local candidates.
|
||||
kLocalCandidates_IPv6, // Number of IPv6 local candidates.
|
||||
kAudioSrtpCipher, // Name of SRTP cipher used in audio channel.
|
||||
kAudioSslCipher, // Name of SSL cipher used in audio channel.
|
||||
kVideoSrtpCipher, // Name of SRTP cipher used in video channel.
|
||||
kVideoSslCipher, // Name of SSL cipher used in video channel.
|
||||
kDataSrtpCipher, // Name of SRTP cipher used in data channel.
|
||||
kDataSslCipher, // Name of SSL cipher used in data channel.
|
||||
kPeerConnectionMetricsName_Max
|
||||
};
|
||||
|
||||
|
||||
@ -2149,32 +2149,33 @@ void WebRtcSession::ReportNegotiatedCiphers(
|
||||
}
|
||||
|
||||
const std::string& srtp_cipher = stats.channel_stats[0].srtp_cipher;
|
||||
const std::string& ssl_cipher = stats.channel_stats[0].ssl_cipher;
|
||||
if (srtp_cipher.empty() && ssl_cipher.empty()) {
|
||||
uint16_t ssl_cipher = stats.channel_stats[0].ssl_cipher;
|
||||
if (srtp_cipher.empty() && !ssl_cipher) {
|
||||
return;
|
||||
}
|
||||
|
||||
PeerConnectionMetricsName srtp_name;
|
||||
PeerConnectionMetricsName ssl_name;
|
||||
PeerConnectionEnumCounterType srtp_counter_type;
|
||||
PeerConnectionEnumCounterType ssl_counter_type;
|
||||
if (stats.transport_name == cricket::CN_AUDIO) {
|
||||
srtp_name = kAudioSrtpCipher;
|
||||
ssl_name = kAudioSslCipher;
|
||||
srtp_counter_type = kEnumCounterAudioSrtpCipher;
|
||||
ssl_counter_type = kEnumCounterAudioSslCipher;
|
||||
} else if (stats.transport_name == cricket::CN_VIDEO) {
|
||||
srtp_name = kVideoSrtpCipher;
|
||||
ssl_name = kVideoSslCipher;
|
||||
srtp_counter_type = kEnumCounterVideoSrtpCipher;
|
||||
ssl_counter_type = kEnumCounterVideoSslCipher;
|
||||
} else if (stats.transport_name == cricket::CN_DATA) {
|
||||
srtp_name = kDataSrtpCipher;
|
||||
ssl_name = kDataSslCipher;
|
||||
srtp_counter_type = kEnumCounterDataSrtpCipher;
|
||||
ssl_counter_type = kEnumCounterDataSslCipher;
|
||||
} else {
|
||||
RTC_NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!srtp_cipher.empty()) {
|
||||
metrics_observer_->AddHistogramSample(srtp_name, srtp_cipher);
|
||||
metrics_observer_->IncrementSparseEnumCounter(
|
||||
srtp_counter_type, rtc::GetSrtpCryptoSuiteFromName(srtp_cipher));
|
||||
}
|
||||
if (!ssl_cipher.empty()) {
|
||||
metrics_observer_->AddHistogramSample(ssl_name, ssl_cipher);
|
||||
if (ssl_cipher) {
|
||||
metrics_observer_->IncrementSparseEnumCounter(ssl_counter_type, ssl_cipher);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -816,9 +816,9 @@ bool BaseChannel::SetDtlsSrtpCiphers(TransportChannel *tc, bool rtcp) {
|
||||
// We always use the default SRTP ciphers for RTCP, but we may use different
|
||||
// ciphers for RTP depending on the media type.
|
||||
if (!rtcp) {
|
||||
GetSrtpCiphers(&ciphers);
|
||||
GetSrtpCryptoSuiteNames(&ciphers);
|
||||
} else {
|
||||
GetSupportedDefaultCryptoSuites(&ciphers);
|
||||
GetDefaultSrtpCryptoSuiteNames(&ciphers);
|
||||
}
|
||||
return tc->SetSrtpCiphers(ciphers);
|
||||
}
|
||||
@ -841,7 +841,7 @@ bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) {
|
||||
|
||||
std::string selected_cipher;
|
||||
|
||||
if (!channel->GetSrtpCipher(&selected_cipher)) {
|
||||
if (!channel->GetSrtpCryptoSuite(&selected_cipher)) {
|
||||
LOG(LS_ERROR) << "No DTLS-SRTP selected cipher";
|
||||
return false;
|
||||
}
|
||||
@ -1627,7 +1627,8 @@ void VoiceChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
|
||||
}
|
||||
}
|
||||
|
||||
void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
|
||||
void VoiceChannel::GetSrtpCryptoSuiteNames(
|
||||
std::vector<std::string>* ciphers) const {
|
||||
GetSupportedAudioCryptoSuites(ciphers);
|
||||
}
|
||||
|
||||
@ -2060,7 +2061,8 @@ void VideoChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
|
||||
}
|
||||
}
|
||||
|
||||
void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
|
||||
void VideoChannel::GetSrtpCryptoSuiteNames(
|
||||
std::vector<std::string>* ciphers) const {
|
||||
GetSupportedVideoCryptoSuites(ciphers);
|
||||
}
|
||||
|
||||
@ -2395,7 +2397,8 @@ void DataChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
|
||||
}
|
||||
}
|
||||
|
||||
void DataChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const {
|
||||
void DataChannel::GetSrtpCryptoSuiteNames(
|
||||
std::vector<std::string>* ciphers) const {
|
||||
GetSupportedDataCryptoSuites(ciphers);
|
||||
}
|
||||
|
||||
|
||||
@ -284,7 +284,8 @@ class BaseChannel
|
||||
|
||||
// Handled in derived classes
|
||||
// Get the SRTP ciphers to use for RTP media
|
||||
virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const = 0;
|
||||
virtual void GetSrtpCryptoSuiteNames(
|
||||
std::vector<std::string>* ciphers) const = 0;
|
||||
virtual void OnConnectionMonitorUpdate(ConnectionMonitor* monitor,
|
||||
const std::vector<ConnectionInfo>& infos) = 0;
|
||||
|
||||
@ -413,7 +414,7 @@ class VoiceChannel : public BaseChannel {
|
||||
bool GetStats_w(VoiceMediaInfo* stats);
|
||||
|
||||
virtual void OnMessage(rtc::Message* pmsg);
|
||||
virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
|
||||
virtual void GetSrtpCryptoSuiteNames(std::vector<std::string>* ciphers) const;
|
||||
virtual void OnConnectionMonitorUpdate(
|
||||
ConnectionMonitor* monitor, const std::vector<ConnectionInfo>& infos);
|
||||
virtual void OnMediaMonitorUpdate(
|
||||
@ -510,7 +511,7 @@ class VideoChannel : public BaseChannel {
|
||||
bool GetStats_w(VideoMediaInfo* stats);
|
||||
|
||||
virtual void OnMessage(rtc::Message* pmsg);
|
||||
virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
|
||||
virtual void GetSrtpCryptoSuiteNames(std::vector<std::string>* ciphers) const;
|
||||
virtual void OnConnectionMonitorUpdate(
|
||||
ConnectionMonitor* monitor, const std::vector<ConnectionInfo>& infos);
|
||||
virtual void OnMediaMonitorUpdate(
|
||||
@ -635,7 +636,7 @@ class DataChannel : public BaseChannel {
|
||||
virtual bool WantsPacket(bool rtcp, rtc::Buffer* packet);
|
||||
|
||||
virtual void OnMessage(rtc::Message* pmsg);
|
||||
virtual void GetSrtpCiphers(std::vector<std::string>* ciphers) const;
|
||||
virtual void GetSrtpCryptoSuiteNames(std::vector<std::string>* ciphers) const;
|
||||
virtual void OnConnectionMonitorUpdate(
|
||||
ConnectionMonitor* monitor, const std::vector<ConnectionInfo>& infos);
|
||||
virtual void OnMediaMonitorUpdate(
|
||||
|
||||
@ -1817,8 +1817,8 @@ void ChannelTest<VoiceTraits>::CreateContent(
|
||||
audio->set_rtcp_mux((flags & RTCP_MUX) != 0);
|
||||
if (flags & SECURE) {
|
||||
audio->AddCrypto(cricket::CryptoParams(
|
||||
1, cricket::CS_AES_CM_128_HMAC_SHA1_32,
|
||||
"inline:" + rtc::CreateRandomString(40), ""));
|
||||
1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
|
||||
"inline:" + rtc::CreateRandomString(40), std::string()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1887,8 +1887,8 @@ void ChannelTest<VideoTraits>::CreateContent(
|
||||
video->set_rtcp_mux((flags & RTCP_MUX) != 0);
|
||||
if (flags & SECURE) {
|
||||
video->AddCrypto(cricket::CryptoParams(
|
||||
1, cricket::CS_AES_CM_128_HMAC_SHA1_80,
|
||||
"inline:" + rtc::CreateRandomString(40), ""));
|
||||
1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
|
||||
"inline:" + rtc::CreateRandomString(40), std::string()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2580,7 +2580,7 @@ TEST_F(VideoChannelTest, TestApplyViewRequest) {
|
||||
// stream1: 0x0x0; stream2: 640x400x30
|
||||
request.static_video_views.clear();
|
||||
request.static_video_views.push_back(cricket::StaticVideoView(
|
||||
cricket::StreamSelector("", stream2.id), 640, 400, 30));
|
||||
cricket::StreamSelector(std::string(), stream2.id), 640, 400, 30));
|
||||
EXPECT_TRUE(channel1_->ApplyViewRequest(request));
|
||||
EXPECT_TRUE(media_channel1_->GetSendStreamFormat(kSsrc1, &send_format));
|
||||
EXPECT_EQ(0, send_format.width);
|
||||
@ -2641,8 +2641,8 @@ void ChannelTest<DataTraits>::CreateContent(
|
||||
data->set_rtcp_mux((flags & RTCP_MUX) != 0);
|
||||
if (flags & SECURE) {
|
||||
data->AddCrypto(cricket::CryptoParams(
|
||||
1, cricket::CS_AES_CM_128_HMAC_SHA1_32,
|
||||
"inline:" + rtc::CreateRandomString(40), ""));
|
||||
1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
|
||||
"inline:" + rtc::CreateRandomString(40), std::string()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -155,25 +155,24 @@ bool FindMatchingCrypto(const CryptoParamsVec& cryptos,
|
||||
void GetSupportedAudioCryptoSuites(
|
||||
std::vector<std::string>* crypto_suites) {
|
||||
#ifdef HAVE_SRTP
|
||||
crypto_suites->push_back(CS_AES_CM_128_HMAC_SHA1_32);
|
||||
crypto_suites->push_back(CS_AES_CM_128_HMAC_SHA1_80);
|
||||
crypto_suites->push_back(rtc::CS_AES_CM_128_HMAC_SHA1_32);
|
||||
crypto_suites->push_back(rtc::CS_AES_CM_128_HMAC_SHA1_80);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GetSupportedVideoCryptoSuites(
|
||||
std::vector<std::string>* crypto_suites) {
|
||||
GetSupportedDefaultCryptoSuites(crypto_suites);
|
||||
GetDefaultSrtpCryptoSuiteNames(crypto_suites);
|
||||
}
|
||||
|
||||
void GetSupportedDataCryptoSuites(
|
||||
std::vector<std::string>* crypto_suites) {
|
||||
GetSupportedDefaultCryptoSuites(crypto_suites);
|
||||
GetDefaultSrtpCryptoSuiteNames(crypto_suites);
|
||||
}
|
||||
|
||||
void GetSupportedDefaultCryptoSuites(
|
||||
std::vector<std::string>* crypto_suites) {
|
||||
void GetDefaultSrtpCryptoSuiteNames(std::vector<std::string>* crypto_suites) {
|
||||
#ifdef HAVE_SRTP
|
||||
crypto_suites->push_back(CS_AES_CM_128_HMAC_SHA1_80);
|
||||
crypto_suites->push_back(rtc::CS_AES_CM_128_HMAC_SHA1_80);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -188,8 +187,9 @@ static bool SelectCrypto(const MediaContentDescription* offer,
|
||||
|
||||
for (CryptoParamsVec::const_iterator i = cryptos.begin();
|
||||
i != cryptos.end(); ++i) {
|
||||
if (CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite ||
|
||||
(CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && !bundle)) {
|
||||
if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite ||
|
||||
(rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio &&
|
||||
!bundle)) {
|
||||
return CreateCryptoParams(i->tag, i->cipher_suite, crypto);
|
||||
}
|
||||
}
|
||||
|
||||
@ -550,7 +550,7 @@ const DataContentDescription* GetFirstDataContentDescription(
|
||||
void GetSupportedAudioCryptoSuites(std::vector<std::string>* crypto_suites);
|
||||
void GetSupportedVideoCryptoSuites(std::vector<std::string>* crypto_suites);
|
||||
void GetSupportedDataCryptoSuites(std::vector<std::string>* crypto_suites);
|
||||
void GetSupportedDefaultCryptoSuites(std::vector<std::string>* crypto_suites);
|
||||
void GetDefaultSrtpCryptoSuiteNames(std::vector<std::string>* crypto_suites);
|
||||
} // namespace cricket
|
||||
|
||||
#endif // TALK_SESSION_MEDIA_MEDIASESSION_H_
|
||||
|
||||
@ -84,8 +84,8 @@ using cricket::RtpHeaderExtension;
|
||||
using cricket::SEC_DISABLED;
|
||||
using cricket::SEC_ENABLED;
|
||||
using cricket::SEC_REQUIRED;
|
||||
using cricket::CS_AES_CM_128_HMAC_SHA1_32;
|
||||
using cricket::CS_AES_CM_128_HMAC_SHA1_80;
|
||||
using rtc::CS_AES_CM_128_HMAC_SHA1_32;
|
||||
using rtc::CS_AES_CM_128_HMAC_SHA1_80;
|
||||
|
||||
static const AudioCodec kAudioCodecs1[] = {
|
||||
AudioCodec(103, "ISAC", 16000, -1, 1, 6),
|
||||
|
||||
@ -73,8 +73,6 @@ extern "C" debug_module_t mod_aes_hmac;
|
||||
|
||||
namespace cricket {
|
||||
|
||||
const char CS_AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80";
|
||||
const char CS_AES_CM_128_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32";
|
||||
const int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3;
|
||||
const int SRTP_MASTER_KEY_KEY_LEN = 16;
|
||||
const int SRTP_MASTER_KEY_SALT_LEN = 14;
|
||||
@ -663,10 +661,10 @@ bool SrtpSession::SetKey(int type, const std::string& cs,
|
||||
srtp_policy_t policy;
|
||||
memset(&policy, 0, sizeof(policy));
|
||||
|
||||
if (cs == CS_AES_CM_128_HMAC_SHA1_80) {
|
||||
if (cs == rtc::CS_AES_CM_128_HMAC_SHA1_80) {
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
|
||||
} else if (cs == CS_AES_CM_128_HMAC_SHA1_32) {
|
||||
} else if (cs == rtc::CS_AES_CM_128_HMAC_SHA1_32) {
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32,
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80
|
||||
} else {
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/sigslotrepeater.h"
|
||||
#include "webrtc/base/sslstreamadapter.h"
|
||||
|
||||
// Forward declaration to avoid pulling in libsrtp headers here
|
||||
struct srtp_event_data_t;
|
||||
@ -47,13 +48,6 @@ struct srtp_policy_t;
|
||||
|
||||
namespace cricket {
|
||||
|
||||
// Cipher suite to use for SRTP. Typically a 80-bit HMAC will be used, except
|
||||
// in applications (voice) where the additional bandwidth may be significant.
|
||||
// A 80-bit HMAC is always used for SRTCP.
|
||||
// 128-bit AES with 80-bit SHA-1 HMAC.
|
||||
extern const char CS_AES_CM_128_HMAC_SHA1_80[];
|
||||
// 128-bit AES with 32-bit SHA-1 HMAC.
|
||||
extern const char CS_AES_CM_128_HMAC_SHA1_32[];
|
||||
// Key is 128 bits and salt is 112 bits == 30 bytes. B64 bloat => 40 bytes.
|
||||
extern const int SRTP_MASTER_KEY_BASE64_LEN;
|
||||
|
||||
|
||||
@ -40,8 +40,8 @@ extern "C" {
|
||||
#endif
|
||||
}
|
||||
|
||||
using cricket::CS_AES_CM_128_HMAC_SHA1_80;
|
||||
using cricket::CS_AES_CM_128_HMAC_SHA1_32;
|
||||
using rtc::CS_AES_CM_128_HMAC_SHA1_80;
|
||||
using rtc::CS_AES_CM_128_HMAC_SHA1_32;
|
||||
using cricket::CryptoParams;
|
||||
using cricket::CS_LOCAL;
|
||||
using cricket::CS_REMOTE;
|
||||
|
||||
@ -51,13 +51,13 @@ struct SrtpCipherMapEntry {
|
||||
|
||||
// This isn't elegant, but it's better than an external reference
|
||||
static SrtpCipherMapEntry SrtpCipherMap[] = {
|
||||
{"AES_CM_128_HMAC_SHA1_80", "SRTP_AES128_CM_SHA1_80"},
|
||||
{"AES_CM_128_HMAC_SHA1_32", "SRTP_AES128_CM_SHA1_32"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
{CS_AES_CM_128_HMAC_SHA1_80, "SRTP_AES128_CM_SHA1_80"},
|
||||
{CS_AES_CM_128_HMAC_SHA1_32, "SRTP_AES128_CM_SHA1_32"},
|
||||
{NULL, NULL}};
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_IS_BORINGSSL
|
||||
|
||||
// Cipher name table. Maps internal OpenSSL cipher ids to the RFC name.
|
||||
struct SslCipherMapEntry {
|
||||
uint32_t openssl_id;
|
||||
@ -139,32 +139,42 @@ static const SslCipherMapEntry kSslCipherMap[] = {
|
||||
};
|
||||
#endif // #ifndef OPENSSL_IS_BORINGSSL
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4309)
|
||||
#pragma warning(disable : 4310)
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
// Default cipher used between OpenSSL/BoringSSL stream adapters.
|
||||
// This needs to be updated when the default of the SSL library changes.
|
||||
static const char kDefaultSslCipher10[] =
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
|
||||
static const char kDefaultSslEcCipher10[] =
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
|
||||
|
||||
// static_cast<uint16_t> causes build warnings on windows platform.
|
||||
static uint16_t kDefaultSslCipher10 =
|
||||
static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA);
|
||||
static uint16_t kDefaultSslEcCipher10 =
|
||||
static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
static const char kDefaultSslCipher12[] =
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
|
||||
static const char kDefaultSslEcCipher12[] =
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
|
||||
static uint16_t kDefaultSslCipher12 =
|
||||
static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
|
||||
static uint16_t kDefaultSslEcCipher12 =
|
||||
static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
|
||||
// Fallback cipher for DTLS 1.2 if hardware-accelerated AES-GCM is unavailable.
|
||||
static const char kDefaultSslCipher12NoAesGcm[] =
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
|
||||
static const char kDefaultSslEcCipher12NoAesGcm[] =
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
|
||||
static uint16_t kDefaultSslCipher12NoAesGcm =
|
||||
static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305);
|
||||
static uint16_t kDefaultSslEcCipher12NoAesGcm =
|
||||
static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305);
|
||||
#else // !OPENSSL_IS_BORINGSSL
|
||||
// OpenSSL sorts differently than BoringSSL, so the default cipher doesn't
|
||||
// change between TLS 1.0 and TLS 1.2 with the current setup.
|
||||
static const char kDefaultSslCipher12[] =
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
|
||||
static const char kDefaultSslEcCipher12[] =
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
|
||||
static uint16_t kDefaultSslCipher12 =
|
||||
static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA);
|
||||
static uint16_t kDefaultSslEcCipher12 =
|
||||
static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// StreamBIO
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -338,9 +348,17 @@ bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_IS_BORINGSSL
|
||||
const char* OpenSSLStreamAdapter::GetRfcSslCipherName(
|
||||
const SSL_CIPHER* cipher) {
|
||||
std::string OpenSSLStreamAdapter::GetSslCipherSuiteName(uint16_t cipher) {
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
const SSL_CIPHER* ssl_cipher = SSL_get_cipher_by_value(cipher);
|
||||
if (!ssl_cipher) {
|
||||
return std::string();
|
||||
}
|
||||
char* cipher_name = SSL_CIPHER_get_rfc_name(ssl_cipher);
|
||||
std::string rfc_name = std::string(cipher_name);
|
||||
OPENSSL_free(cipher_name);
|
||||
return rfc_name;
|
||||
#else
|
||||
ASSERT(cipher != NULL);
|
||||
for (const SslCipherMapEntry* entry = kSslCipherMap; entry->rfc_name;
|
||||
++entry) {
|
||||
@ -348,11 +366,11 @@ const char* OpenSSLStreamAdapter::GetRfcSslCipherName(
|
||||
return entry->rfc_name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return std::string();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool OpenSSLStreamAdapter::GetSslCipher(std::string* cipher) {
|
||||
bool OpenSSLStreamAdapter::GetSslCipherSuite(uint16_t* cipher) {
|
||||
if (state_ != SSL_CONNECTED)
|
||||
return false;
|
||||
|
||||
@ -361,19 +379,7 @@ bool OpenSSLStreamAdapter::GetSslCipher(std::string* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
char* cipher_name = SSL_CIPHER_get_rfc_name(current_cipher);
|
||||
#else
|
||||
const char* cipher_name = GetRfcSslCipherName(current_cipher);
|
||||
#endif
|
||||
if (cipher_name == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*cipher = cipher_name;
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
OPENSSL_free(cipher_name);
|
||||
#endif
|
||||
*cipher = static_cast<uint16_t>(SSL_CIPHER_get_id(current_cipher));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1125,7 +1131,7 @@ bool OpenSSLStreamAdapter::HaveExporter() {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string OpenSSLStreamAdapter::GetDefaultSslCipher(
|
||||
uint16_t OpenSSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
SSLProtocolVersion version,
|
||||
KeyType key_type) {
|
||||
if (key_type == KT_RSA) {
|
||||
@ -1163,7 +1169,8 @@ std::string OpenSSLStreamAdapter::GetDefaultSslCipher(
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
return std::string();
|
||||
RTC_NOTREACHED();
|
||||
return kDefaultSslEcCipher12;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -87,12 +87,10 @@ class OpenSSLStreamAdapter : public SSLStreamAdapter {
|
||||
void Close() override;
|
||||
StreamState GetState() const override;
|
||||
|
||||
#ifndef OPENSSL_IS_BORINGSSL
|
||||
// Return the RFC (5246, 3268, etc.) cipher name for an OpenSSL cipher.
|
||||
static const char* GetRfcSslCipherName(const SSL_CIPHER* cipher);
|
||||
#endif
|
||||
// TODO(guoweis): Move this away from a static class method.
|
||||
static std::string GetSslCipherSuiteName(uint16_t cipher);
|
||||
|
||||
bool GetSslCipher(std::string* cipher) override;
|
||||
bool GetSslCipherSuite(uint16_t* cipher) override;
|
||||
|
||||
// Key Extractor interface
|
||||
bool ExportKeyingMaterial(const std::string& label,
|
||||
@ -110,8 +108,10 @@ class OpenSSLStreamAdapter : public SSLStreamAdapter {
|
||||
static bool HaveDtls();
|
||||
static bool HaveDtlsSrtp();
|
||||
static bool HaveExporter();
|
||||
static std::string GetDefaultSslCipher(SSLProtocolVersion version,
|
||||
KeyType key_type);
|
||||
|
||||
// TODO(guoweis): Move this away from a static class method.
|
||||
static uint16_t GetDefaultSslCipherForTest(SSLProtocolVersion version,
|
||||
KeyType key_type);
|
||||
|
||||
protected:
|
||||
void OnEvent(StreamInterface* stream, int events, int err) override;
|
||||
|
||||
@ -29,6 +29,19 @@
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// TODO(guoweis): Move this to SDP layer and use int form internally.
|
||||
// webrtc:5043.
|
||||
const char CS_AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80";
|
||||
const char CS_AES_CM_128_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32";
|
||||
|
||||
uint16_t GetSrtpCryptoSuiteFromName(const std::string& cipher) {
|
||||
if (cipher == CS_AES_CM_128_HMAC_SHA1_32)
|
||||
return SRTP_AES128_CM_SHA1_32;
|
||||
if (cipher == CS_AES_CM_128_HMAC_SHA1_80)
|
||||
return SRTP_AES128_CM_SHA1_80;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) {
|
||||
#if SSL_USE_SCHANNEL
|
||||
return NULL;
|
||||
@ -39,7 +52,7 @@ SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SSLStreamAdapter::GetSslCipher(std::string* cipher) {
|
||||
bool SSLStreamAdapter::GetSslCipherSuite(uint16_t* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -66,9 +79,10 @@ bool SSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
|
||||
bool SSLStreamAdapter::HaveDtls() { return false; }
|
||||
bool SSLStreamAdapter::HaveDtlsSrtp() { return false; }
|
||||
bool SSLStreamAdapter::HaveExporter() { return false; }
|
||||
std::string SSLStreamAdapter::GetDefaultSslCipher(SSLProtocolVersion version,
|
||||
KeyType key_type) {
|
||||
return std::string();
|
||||
uint16_t SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
SSLProtocolVersion version,
|
||||
KeyType key_type) {
|
||||
return 0;
|
||||
}
|
||||
#elif SSL_USE_OPENSSL
|
||||
bool SSLStreamAdapter::HaveDtls() {
|
||||
@ -80,9 +94,14 @@ bool SSLStreamAdapter::HaveDtlsSrtp() {
|
||||
bool SSLStreamAdapter::HaveExporter() {
|
||||
return OpenSSLStreamAdapter::HaveExporter();
|
||||
}
|
||||
std::string SSLStreamAdapter::GetDefaultSslCipher(SSLProtocolVersion version,
|
||||
KeyType key_type) {
|
||||
return OpenSSLStreamAdapter::GetDefaultSslCipher(version, key_type);
|
||||
uint16_t SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
SSLProtocolVersion version,
|
||||
KeyType key_type) {
|
||||
return OpenSSLStreamAdapter::GetDefaultSslCipherForTest(version, key_type);
|
||||
}
|
||||
|
||||
std::string SSLStreamAdapter::GetSslCipherSuiteName(uint16_t cipher) {
|
||||
return OpenSSLStreamAdapter::GetSslCipherSuiteName(cipher);
|
||||
}
|
||||
#endif // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL
|
||||
|
||||
|
||||
@ -19,6 +19,23 @@
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Constants for SRTP profiles.
|
||||
const uint16_t SRTP_AES128_CM_SHA1_80 = 0x0001;
|
||||
const uint16_t SRTP_AES128_CM_SHA1_32 = 0x0002;
|
||||
|
||||
// Cipher suite to use for SRTP. Typically a 80-bit HMAC will be used, except
|
||||
// in applications (voice) where the additional bandwidth may be significant.
|
||||
// A 80-bit HMAC is always used for SRTCP.
|
||||
// 128-bit AES with 80-bit SHA-1 HMAC.
|
||||
extern const char CS_AES_CM_128_HMAC_SHA1_80[];
|
||||
// 128-bit AES with 32-bit SHA-1 HMAC.
|
||||
extern const char CS_AES_CM_128_HMAC_SHA1_32[];
|
||||
|
||||
// Returns the DTLS-SRTP protection profile ID, as defined in
|
||||
// https://tools.ietf.org/html/rfc5764#section-4.1.2, for the given SRTP
|
||||
// Crypto-suite, as defined in https://tools.ietf.org/html/rfc4568#section-6.2
|
||||
uint16_t GetSrtpCryptoSuiteFromName(const std::string& cipher_rfc_name);
|
||||
|
||||
// SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS.
|
||||
// After SSL has been started, the stream will only open on successful
|
||||
// SSL verification of certificates, and the communication is
|
||||
@ -133,9 +150,9 @@ class SSLStreamAdapter : public StreamAdapterInterface {
|
||||
// chain. The returned certificate is owned by the caller.
|
||||
virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0;
|
||||
|
||||
// Retrieves the name of the cipher suite used for the connection
|
||||
// (e.g. "TLS_RSA_WITH_AES_128_CBC_SHA").
|
||||
virtual bool GetSslCipher(std::string* cipher);
|
||||
// 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(uint16_t* cipher);
|
||||
|
||||
// Key Exporter interface from RFC 5705
|
||||
// Arguments are:
|
||||
@ -167,9 +184,14 @@ class SSLStreamAdapter : public StreamAdapterInterface {
|
||||
|
||||
// Returns the default Ssl cipher used between streams of this class
|
||||
// for the given protocol version. This is used by the unit tests.
|
||||
// TODO(torbjorng@webrtc.org): Fix callers to avoid default parameter.
|
||||
static std::string GetDefaultSslCipher(SSLProtocolVersion version,
|
||||
KeyType key_type = KT_DEFAULT);
|
||||
// TODO(guoweis): Move this away from a static class method.
|
||||
static uint16_t GetDefaultSslCipherForTest(SSLProtocolVersion version,
|
||||
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 GetSslCipherSuiteName(uint16_t cipher);
|
||||
|
||||
private:
|
||||
// If true, the server certificate need not match the configured
|
||||
|
||||
@ -410,11 +410,11 @@ class SSLStreamAdapterTestBase : public testing::Test,
|
||||
return server_ssl_->GetPeerCertificate(cert);
|
||||
}
|
||||
|
||||
bool GetSslCipher(bool client, std::string *retval) {
|
||||
bool GetSslCipherSuite(bool client, uint16_t* retval) {
|
||||
if (client)
|
||||
return client_ssl_->GetSslCipher(retval);
|
||||
return client_ssl_->GetSslCipherSuite(retval);
|
||||
else
|
||||
return server_ssl_->GetSslCipher(retval);
|
||||
return server_ssl_->GetSslCipherSuite(retval);
|
||||
}
|
||||
|
||||
bool ExportKeyingMaterial(const char *label,
|
||||
@ -967,70 +967,70 @@ TEST_P(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
|
||||
|
||||
// Test getting the used DTLS ciphers.
|
||||
// DTLS 1.2 enabled for neither client nor server -> DTLS 1.0 will be used.
|
||||
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipher) {
|
||||
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuite) {
|
||||
MAYBE_SKIP_TEST(HaveDtls);
|
||||
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
|
||||
TestHandshake();
|
||||
|
||||
std::string client_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(true, &client_cipher));
|
||||
std::string server_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(false, &server_cipher));
|
||||
uint16_t client_cipher;
|
||||
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
||||
uint16_t server_cipher;
|
||||
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
||||
|
||||
ASSERT_EQ(client_cipher, server_cipher);
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipher(
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam())),
|
||||
server_cipher);
|
||||
}
|
||||
|
||||
// Test getting the used DTLS 1.2 ciphers.
|
||||
// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used.
|
||||
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherDtls12Both) {
|
||||
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Both) {
|
||||
MAYBE_SKIP_TEST(HaveDtls);
|
||||
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
|
||||
TestHandshake();
|
||||
|
||||
std::string client_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(true, &client_cipher));
|
||||
std::string server_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(false, &server_cipher));
|
||||
uint16_t client_cipher;
|
||||
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
||||
uint16_t server_cipher;
|
||||
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
||||
|
||||
ASSERT_EQ(client_cipher, server_cipher);
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipher(
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_12, ::testing::get<1>(GetParam())),
|
||||
server_cipher);
|
||||
}
|
||||
|
||||
// DTLS 1.2 enabled for client only -> DTLS 1.0 will be used.
|
||||
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherDtls12Client) {
|
||||
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Client) {
|
||||
MAYBE_SKIP_TEST(HaveDtls);
|
||||
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12);
|
||||
TestHandshake();
|
||||
|
||||
std::string client_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(true, &client_cipher));
|
||||
std::string server_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(false, &server_cipher));
|
||||
uint16_t client_cipher;
|
||||
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
||||
uint16_t server_cipher;
|
||||
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
||||
|
||||
ASSERT_EQ(client_cipher, server_cipher);
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipher(
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam())),
|
||||
server_cipher);
|
||||
}
|
||||
|
||||
// DTLS 1.2 enabled for server only -> DTLS 1.0 will be used.
|
||||
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherDtls12Server) {
|
||||
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Server) {
|
||||
MAYBE_SKIP_TEST(HaveDtls);
|
||||
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_10);
|
||||
TestHandshake();
|
||||
|
||||
std::string client_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(true, &client_cipher));
|
||||
std::string server_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(false, &server_cipher));
|
||||
uint16_t client_cipher;
|
||||
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
||||
uint16_t server_cipher;
|
||||
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
||||
|
||||
ASSERT_EQ(client_cipher, server_cipher);
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipher(
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
rtc::SSL_PROTOCOL_DTLS_10, ::testing::get<1>(GetParam())),
|
||||
server_cipher);
|
||||
}
|
||||
|
||||
@ -186,12 +186,12 @@ bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DtlsTransportChannelWrapper::GetSslCipher(std::string* cipher) {
|
||||
bool DtlsTransportChannelWrapper::GetSslCipherSuite(uint16_t* cipher) {
|
||||
if (dtls_state_ != STATE_OPEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return dtls_->GetSslCipher(cipher);
|
||||
return dtls_->GetSslCipherSuite(cipher);
|
||||
}
|
||||
|
||||
bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
|
||||
@ -330,7 +330,7 @@ bool DtlsTransportChannelWrapper::SetSrtpCiphers(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DtlsTransportChannelWrapper::GetSrtpCipher(std::string* cipher) {
|
||||
bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(std::string* cipher) {
|
||||
if (dtls_state_ != STATE_OPEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -135,13 +135,13 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl {
|
||||
bool SetSrtpCiphers(const std::vector<std::string>& ciphers) override;
|
||||
|
||||
// Find out which DTLS-SRTP cipher was negotiated
|
||||
bool GetSrtpCipher(std::string* cipher) override;
|
||||
bool GetSrtpCryptoSuite(std::string* cipher) override;
|
||||
|
||||
bool GetSslRole(rtc::SSLRole* role) const override;
|
||||
bool SetSslRole(rtc::SSLRole role) override;
|
||||
|
||||
// Find out which DTLS cipher was negotiated
|
||||
bool GetSslCipher(std::string* cipher) override;
|
||||
bool GetSslCipherSuite(uint16_t* cipher) override;
|
||||
|
||||
// Once DTLS has been established, this method retrieves the certificate in
|
||||
// use by the remote peer, for use in external identity verification.
|
||||
|
||||
@ -217,7 +217,7 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
channels_.begin(); it != channels_.end(); ++it) {
|
||||
std::string cipher;
|
||||
|
||||
bool rv = (*it)->GetSrtpCipher(&cipher);
|
||||
bool rv = (*it)->GetSrtpCryptoSuite(&cipher);
|
||||
if (negotiated_dtls_ && !expected_cipher.empty()) {
|
||||
ASSERT_TRUE(rv);
|
||||
|
||||
@ -228,13 +228,13 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
}
|
||||
}
|
||||
|
||||
void CheckSsl(const std::string& expected_cipher) {
|
||||
void CheckSsl(uint16_t expected_cipher) {
|
||||
for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
|
||||
channels_.begin(); it != channels_.end(); ++it) {
|
||||
std::string cipher;
|
||||
uint16_t cipher;
|
||||
|
||||
bool rv = (*it)->GetSslCipher(&cipher);
|
||||
if (negotiated_dtls_ && !expected_cipher.empty()) {
|
||||
bool rv = (*it)->GetSslCipherSuite(&cipher);
|
||||
if (negotiated_dtls_ && expected_cipher) {
|
||||
ASSERT_TRUE(rv);
|
||||
|
||||
ASSERT_EQ(cipher, expected_cipher);
|
||||
@ -463,10 +463,10 @@ class DtlsTransportChannelTest : public testing::Test {
|
||||
client1_.CheckSrtp("");
|
||||
client2_.CheckSrtp("");
|
||||
}
|
||||
client1_.CheckSsl(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(ssl_expected_version_));
|
||||
client2_.CheckSsl(
|
||||
rtc::SSLStreamAdapter::GetDefaultSslCipher(ssl_expected_version_));
|
||||
client1_.CheckSsl(rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
ssl_expected_version_, rtc::KT_DEFAULT));
|
||||
client2_.CheckSsl(rtc::SSLStreamAdapter::GetDefaultSslCipherForTest(
|
||||
ssl_expected_version_, rtc::KT_DEFAULT));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ class FakeTransportChannel : public TransportChannelImpl,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetSrtpCipher(std::string* cipher) override {
|
||||
bool GetSrtpCryptoSuite(std::string* cipher) override {
|
||||
if (!chosen_srtp_cipher_.empty()) {
|
||||
*cipher = chosen_srtp_cipher_;
|
||||
return true;
|
||||
@ -251,7 +251,7 @@ class FakeTransportChannel : public TransportChannelImpl,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetSslCipher(std::string* cipher) override { return false; }
|
||||
bool GetSslCipherSuite(uint16_t* cipher) override { return false; }
|
||||
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const {
|
||||
return local_cert_;
|
||||
|
||||
@ -111,10 +111,10 @@ class P2PTransportChannel : public TransportChannelImpl,
|
||||
}
|
||||
|
||||
// Find out which DTLS-SRTP cipher was negotiated.
|
||||
bool GetSrtpCipher(std::string* cipher) override { return false; }
|
||||
bool GetSrtpCryptoSuite(std::string* cipher) override { return false; }
|
||||
|
||||
// Find out which DTLS cipher was negotiated.
|
||||
bool GetSslCipher(std::string* cipher) override { return false; }
|
||||
bool GetSslCipherSuite(uint16_t* cipher) override { return false; }
|
||||
|
||||
// Returns null because the channel is not encrypted by default.
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override {
|
||||
|
||||
@ -307,8 +307,8 @@ bool Transport::GetStats(TransportStats* stats) {
|
||||
TransportChannelImpl* channel = kv.second;
|
||||
TransportChannelStats substats;
|
||||
substats.component = channel->component();
|
||||
channel->GetSrtpCipher(&substats.srtp_cipher);
|
||||
channel->GetSslCipher(&substats.ssl_cipher);
|
||||
channel->GetSrtpCryptoSuite(&substats.srtp_cipher);
|
||||
channel->GetSslCipherSuite(&substats.ssl_cipher);
|
||||
if (!channel->GetStats(&substats.connection_infos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -108,10 +108,10 @@ typedef std::vector<ConnectionInfo> ConnectionInfos;
|
||||
|
||||
// Information about a specific channel
|
||||
struct TransportChannelStats {
|
||||
int component;
|
||||
int component = 0;
|
||||
ConnectionInfos connection_infos;
|
||||
std::string srtp_cipher;
|
||||
std::string ssl_cipher;
|
||||
uint16_t ssl_cipher = 0;
|
||||
};
|
||||
|
||||
// Information about all the channels of a transport.
|
||||
|
||||
@ -106,10 +106,16 @@ class TransportChannel : public sigslot::has_slots<> {
|
||||
virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers) = 0;
|
||||
|
||||
// Finds out which DTLS-SRTP cipher was negotiated.
|
||||
virtual bool GetSrtpCipher(std::string* cipher) = 0;
|
||||
// TODO(guoweis): Remove this once all dependencies implement this.
|
||||
virtual bool GetSrtpCryptoSuite(std::string* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Finds out which DTLS cipher was negotiated.
|
||||
virtual bool GetSslCipher(std::string* cipher) = 0;
|
||||
// TODO(guoweis): Remove this once all dependencies implement this.
|
||||
virtual bool GetSslCipherSuite(uint16_t* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Gets the local RTCCertificate used for DTLS.
|
||||
virtual rtc::scoped_refptr<rtc::RTCCertificate>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user