This CL adds an API to the SSL stream adapters and transport channels to get the SSL cipher that was negotiated with the remote peer.
BUG=3976 R=davidben@chromium.org, juberti@webrtc.org, pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/26009004 Cr-Commit-Position: refs/heads/master@{#8275} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8275 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
63da1dd972
commit
1d11c8202b
1
AUTHORS
1
AUTHORS
@ -37,5 +37,6 @@ Intel Corporation
|
||||
MIPS Technologies
|
||||
Mozilla Foundation
|
||||
Opera Software ASA
|
||||
struktur AG
|
||||
Temasys Communications
|
||||
Vonage Holdings Corp.
|
||||
|
@ -66,6 +66,10 @@ static const SrtpCipherMapEntry kSrtpCipherMap[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
// Default cipher used between NSS stream adapters.
|
||||
// This needs to be updated when the default of the SSL library changes.
|
||||
static const char kDefaultSslCipher[] = "TLS_RSA_WITH_AES_128_CBC_SHA";
|
||||
|
||||
|
||||
// Implementation of NSPR methods
|
||||
static PRStatus StreamClose(PRFileDesc *socket) {
|
||||
@ -866,6 +870,27 @@ SECStatus NSSStreamAdapter::GetClientAuthDataHook(void *arg, PRFileDesc *fd,
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
bool NSSStreamAdapter::GetSslCipher(std::string* cipher) {
|
||||
ASSERT(state_ == SSL_CONNECTED);
|
||||
if (state_ != SSL_CONNECTED)
|
||||
return false;
|
||||
|
||||
SSLChannelInfo channel_info;
|
||||
SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &channel_info,
|
||||
sizeof(channel_info));
|
||||
if (rv == SECFailure)
|
||||
return false;
|
||||
|
||||
SSLCipherSuiteInfo ciphersuite_info;
|
||||
rv = SSL_GetCipherSuiteInfo(channel_info.cipherSuite, &ciphersuite_info,
|
||||
sizeof(ciphersuite_info));
|
||||
if (rv == SECFailure)
|
||||
return false;
|
||||
|
||||
*cipher = ciphersuite_info.cipherSuiteName;
|
||||
return true;
|
||||
}
|
||||
|
||||
// RFC 5705 Key Exporter
|
||||
bool NSSStreamAdapter::ExportKeyingMaterial(const std::string& label,
|
||||
const uint8* context,
|
||||
@ -1011,6 +1036,10 @@ bool NSSStreamAdapter::HaveExporter() {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string NSSStreamAdapter::GetDefaultSslCipher() {
|
||||
return kDefaultSslCipher;
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // HAVE_NSS_SSL_H
|
||||
|
@ -61,6 +61,8 @@ class NSSStreamAdapter : public SSLStreamAdapterHelper {
|
||||
size_t* written, int* error);
|
||||
void OnMessage(Message *msg);
|
||||
|
||||
virtual bool GetSslCipher(std::string* cipher);
|
||||
|
||||
// Key Extractor interface
|
||||
virtual bool ExportKeyingMaterial(const std::string& label,
|
||||
const uint8* context,
|
||||
@ -77,6 +79,7 @@ class NSSStreamAdapter : public SSLStreamAdapterHelper {
|
||||
static bool HaveDtls();
|
||||
static bool HaveDtlsSrtp();
|
||||
static bool HaveExporter();
|
||||
static std::string GetDefaultSslCipher();
|
||||
|
||||
protected:
|
||||
// Override SSLStreamAdapter
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/tls1.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include <vector>
|
||||
@ -56,6 +57,99 @@ static SrtpCipherMapEntry SrtpCipherMap[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
// Cipher name table. Maps internal OpenSSL cipher ids to the RFC name.
|
||||
struct SslCipherMapEntry {
|
||||
uint32_t openssl_id;
|
||||
const char* rfc_name;
|
||||
};
|
||||
|
||||
#define DEFINE_CIPHER_ENTRY_SSL3(name) {SSL3_CK_##name, "TLS_"#name}
|
||||
#define DEFINE_CIPHER_ENTRY_TLS1(name) {TLS1_CK_##name, "TLS_"#name}
|
||||
|
||||
// There currently is no method available to get a RFC-compliant name for a
|
||||
// cipher suite from BoringSSL, so we need to define the mapping manually here.
|
||||
// This should go away once BoringSSL supports "SSL_CIPHER_standard_name"
|
||||
// (as available in OpenSSL if compiled with tracing enabled) or a similar
|
||||
// method.
|
||||
static const 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),
|
||||
|
||||
#ifdef OPENSSL_IS_BORINGSSL
|
||||
{TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
|
||||
{TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305,
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"},
|
||||
{TLS1_CK_DHE_RSA_CHACHA20_POLY1305,
|
||||
"TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
|
||||
#endif
|
||||
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
// Default cipher used between OpenSSL/BoringSSL stream adapters.
|
||||
// This needs to be updated when the default of the SSL library changes.
|
||||
static const char kDefaultSslCipher[] = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// StreamBIO
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -222,6 +316,36 @@ bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* OpenSSLStreamAdapter::GetRfcSslCipherName(
|
||||
const SSL_CIPHER* cipher) {
|
||||
ASSERT(cipher != NULL);
|
||||
for (const SslCipherMapEntry* entry = kSslCipherMap; entry->rfc_name;
|
||||
++entry) {
|
||||
if (cipher->id == entry->openssl_id) {
|
||||
return entry->rfc_name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool OpenSSLStreamAdapter::GetSslCipher(std::string* cipher) {
|
||||
if (state_ != SSL_CONNECTED)
|
||||
return false;
|
||||
|
||||
const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
|
||||
if (current_cipher == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* cipher_name = GetRfcSslCipherName(current_cipher);
|
||||
if (cipher_name == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*cipher = cipher_name;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Key Extractor interface
|
||||
bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
|
||||
const uint8* context,
|
||||
@ -877,6 +1001,10 @@ bool OpenSSLStreamAdapter::HaveExporter() {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string OpenSSLStreamAdapter::GetDefaultSslCipher() {
|
||||
return kDefaultSslCipher;
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // HAVE_OPENSSL_SSL_H
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
typedef struct ssl_cipher_st SSL_CIPHER;
|
||||
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
||||
|
||||
namespace rtc {
|
||||
@ -81,6 +82,11 @@ class OpenSSLStreamAdapter : public SSLStreamAdapter {
|
||||
virtual void Close();
|
||||
virtual StreamState GetState() const;
|
||||
|
||||
// Return the RFC (5246, 3268, etc.) cipher name for an OpenSSL cipher.
|
||||
static const char* GetRfcSslCipherName(const SSL_CIPHER* cipher);
|
||||
|
||||
virtual bool GetSslCipher(std::string* cipher);
|
||||
|
||||
// Key Extractor interface
|
||||
virtual bool ExportKeyingMaterial(const std::string& label,
|
||||
const uint8* context,
|
||||
@ -98,6 +104,7 @@ class OpenSSLStreamAdapter : public SSLStreamAdapter {
|
||||
static bool HaveDtls();
|
||||
static bool HaveDtlsSrtp();
|
||||
static bool HaveExporter();
|
||||
static std::string GetDefaultSslCipher();
|
||||
|
||||
protected:
|
||||
virtual void OnEvent(StreamInterface* stream, int events, int err);
|
||||
|
@ -50,6 +50,9 @@ SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) {
|
||||
bool SSLStreamAdapter::HaveDtls() { return false; }
|
||||
bool SSLStreamAdapter::HaveDtlsSrtp() { return false; }
|
||||
bool SSLStreamAdapter::HaveExporter() { return false; }
|
||||
std::string SSLStreamAdapter::GetDefaultSslCipher() {
|
||||
return std::string();
|
||||
}
|
||||
#elif SSL_USE_OPENSSL
|
||||
bool SSLStreamAdapter::HaveDtls() {
|
||||
return OpenSSLStreamAdapter::HaveDtls();
|
||||
@ -60,6 +63,9 @@ bool SSLStreamAdapter::HaveDtlsSrtp() {
|
||||
bool SSLStreamAdapter::HaveExporter() {
|
||||
return OpenSSLStreamAdapter::HaveExporter();
|
||||
}
|
||||
std::string SSLStreamAdapter::GetDefaultSslCipher() {
|
||||
return OpenSSLStreamAdapter::GetDefaultSslCipher();
|
||||
}
|
||||
#elif SSL_USE_NSS
|
||||
bool SSLStreamAdapter::HaveDtls() {
|
||||
return NSSStreamAdapter::HaveDtls();
|
||||
@ -70,6 +76,9 @@ bool SSLStreamAdapter::HaveDtlsSrtp() {
|
||||
bool SSLStreamAdapter::HaveExporter() {
|
||||
return NSSStreamAdapter::HaveExporter();
|
||||
}
|
||||
std::string SSLStreamAdapter::GetDefaultSslCipher() {
|
||||
return NSSStreamAdapter::GetDefaultSslCipher();
|
||||
}
|
||||
#endif // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL && !SSL_USE_NSS
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -119,6 +119,12 @@ 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) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Key Exporter interface from RFC 5705
|
||||
// Arguments are:
|
||||
// label -- the exporter label.
|
||||
@ -155,6 +161,10 @@ class SSLStreamAdapter : public StreamAdapterInterface {
|
||||
static bool HaveDtlsSrtp();
|
||||
static bool HaveExporter();
|
||||
|
||||
// Returns the default Ssl cipher used between streams of this class.
|
||||
// This is used by the unit tests.
|
||||
static std::string GetDefaultSslCipher();
|
||||
|
||||
private:
|
||||
// If true, the server certificate need not match the configured
|
||||
// server_name, and in fact missing certificate authority and other
|
||||
|
@ -388,6 +388,13 @@ class SSLStreamAdapterTestBase : public testing::Test,
|
||||
return server_ssl_->GetPeerCertificate(cert);
|
||||
}
|
||||
|
||||
bool GetSslCipher(bool client, std::string *retval) {
|
||||
if (client)
|
||||
return client_ssl_->GetSslCipher(retval);
|
||||
else
|
||||
return server_ssl_->GetSslCipher(retval);
|
||||
}
|
||||
|
||||
bool ExportKeyingMaterial(const char *label,
|
||||
const unsigned char *context,
|
||||
size_t context_len,
|
||||
@ -939,3 +946,17 @@ TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
|
||||
rtc::SSLCertChain* server_peer_chain;
|
||||
ASSERT_FALSE(server_peer_cert->GetChain(&server_peer_chain));
|
||||
}
|
||||
|
||||
// Test getting the used DTLS ciphers.
|
||||
TEST_F(SSLStreamAdapterTestDTLS, TestGetSslCipher) {
|
||||
MAYBE_SKIP_TEST(HaveDtls);
|
||||
TestHandshake();
|
||||
|
||||
std::string client_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(true, &client_cipher));
|
||||
std::string server_cipher;
|
||||
ASSERT_TRUE(GetSslCipher(false, &server_cipher));
|
||||
|
||||
ASSERT_EQ(client_cipher, server_cipher);
|
||||
ASSERT_EQ(rtc::SSLStreamAdapter::GetDefaultSslCipher(), client_cipher);
|
||||
}
|
||||
|
@ -186,6 +186,14 @@ bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DtlsTransportChannelWrapper::GetSslCipher(std::string* cipher) {
|
||||
if (dtls_state_ != STATE_OPEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return dtls_->GetSslCipher(cipher);
|
||||
}
|
||||
|
||||
bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
|
||||
const std::string& digest_alg,
|
||||
const uint8* digest,
|
||||
|
@ -150,6 +150,9 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl {
|
||||
virtual bool GetSslRole(rtc::SSLRole* role) const;
|
||||
virtual bool SetSslRole(rtc::SSLRole role);
|
||||
|
||||
// Find out which DTLS cipher was negotiated
|
||||
virtual bool GetSslCipher(std::string* cipher);
|
||||
|
||||
// Once DTLS has been established, this method retrieves the certificate in
|
||||
// use by the remote peer, for use in external identity verification.
|
||||
virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const;
|
||||
|
@ -213,6 +213,22 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
}
|
||||
}
|
||||
|
||||
void CheckSsl(const std::string& expected_cipher) {
|
||||
for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
|
||||
channels_.begin(); it != channels_.end(); ++it) {
|
||||
std::string cipher;
|
||||
|
||||
bool rv = (*it)->GetSslCipher(&cipher);
|
||||
if (negotiated_dtls_ && !expected_cipher.empty()) {
|
||||
ASSERT_TRUE(rv);
|
||||
|
||||
ASSERT_EQ(cipher, expected_cipher);
|
||||
} else {
|
||||
ASSERT_FALSE(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendPackets(size_t channel, size_t size, size_t count, bool srtp) {
|
||||
ASSERT(channel < channels_.size());
|
||||
rtc::scoped_ptr<char[]> packet(new char[size]);
|
||||
@ -433,6 +449,8 @@ class DtlsTransportChannelTest : public testing::Test {
|
||||
client1_.CheckSrtp("");
|
||||
client2_.CheckSrtp("");
|
||||
}
|
||||
client1_.CheckSsl(rtc::SSLStreamAdapter::GetDefaultSslCipher());
|
||||
client2_.CheckSsl(rtc::SSLStreamAdapter::GetDefaultSslCipher());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -246,6 +246,10 @@ class FakeTransportChannel : public TransportChannelImpl,
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool GetSslCipher(std::string* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
||||
if (!identity_)
|
||||
return false;
|
||||
|
@ -109,11 +109,16 @@ class P2PTransportChannel : public TransportChannelImpl,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find out which DTLS-SRTP cipher was negotiated
|
||||
// Find out which DTLS-SRTP cipher was negotiated.
|
||||
virtual bool GetSrtpCipher(std::string* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find out which DTLS cipher was negotiated.
|
||||
virtual bool GetSslCipher(std::string* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns false because the channel is not encrypted by default.
|
||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
||||
return false;
|
||||
|
@ -114,11 +114,16 @@ class RawTransportChannel : public TransportChannelImpl,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find out which DTLS-SRTP cipher was negotiated
|
||||
// Find out which DTLS-SRTP cipher was negotiated.
|
||||
virtual bool GetSrtpCipher(std::string* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find out which DTLS cipher was negotiated.
|
||||
virtual bool GetSslCipher(std::string* cipher) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns false because the channel is not DTLS.
|
||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
||||
return false;
|
||||
|
@ -454,9 +454,12 @@ bool Transport::GetStats_w(TransportStats* stats) {
|
||||
for (ChannelMap::iterator iter = channels_.begin();
|
||||
iter != channels_.end();
|
||||
++iter) {
|
||||
ChannelMapEntry& entry = iter->second;
|
||||
TransportChannelStats substats;
|
||||
substats.component = iter->second->component();
|
||||
if (!iter->second->GetStats(&substats.connection_infos)) {
|
||||
substats.component = entry->component();
|
||||
entry->GetSrtpCipher(&substats.srtp_cipher);
|
||||
entry->GetSslCipher(&substats.ssl_cipher);
|
||||
if (!entry->GetStats(&substats.connection_infos)) {
|
||||
return false;
|
||||
}
|
||||
stats->channel_stats.push_back(substats);
|
||||
|
@ -106,6 +106,8 @@ typedef std::vector<ConnectionInfo> ConnectionInfos;
|
||||
struct TransportChannelStats {
|
||||
int component;
|
||||
ConnectionInfos connection_infos;
|
||||
std::string srtp_cipher;
|
||||
std::string ssl_cipher;
|
||||
};
|
||||
|
||||
// Information about all the channels of a transport.
|
||||
|
@ -100,9 +100,12 @@ class TransportChannel : public sigslot::has_slots<> {
|
||||
// Sets up the ciphers to use for DTLS-SRTP.
|
||||
virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers) = 0;
|
||||
|
||||
// Finds out which DTLS-SRTP cipher was negotiated
|
||||
// Finds out which DTLS-SRTP cipher was negotiated.
|
||||
virtual bool GetSrtpCipher(std::string* cipher) = 0;
|
||||
|
||||
// Finds out which DTLS cipher was negotiated.
|
||||
virtual bool GetSslCipher(std::string* cipher) = 0;
|
||||
|
||||
// Gets a copy of the local SSL identity, owned by the caller.
|
||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const = 0;
|
||||
|
||||
|
@ -186,6 +186,14 @@ bool TransportChannelProxy::GetSrtpCipher(std::string* cipher) {
|
||||
return impl_->GetSrtpCipher(cipher);
|
||||
}
|
||||
|
||||
bool TransportChannelProxy::GetSslCipher(std::string* cipher) {
|
||||
ASSERT(rtc::Thread::Current() == worker_thread_);
|
||||
if (!impl_) {
|
||||
return false;
|
||||
}
|
||||
return impl_->GetSslCipher(cipher);
|
||||
}
|
||||
|
||||
bool TransportChannelProxy::GetLocalIdentity(
|
||||
rtc::SSLIdentity** identity) const {
|
||||
ASSERT(rtc::Thread::Current() == worker_thread_);
|
||||
|
@ -61,6 +61,7 @@ class TransportChannelProxy : public TransportChannel,
|
||||
virtual bool SetSslRole(rtc::SSLRole role);
|
||||
virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers);
|
||||
virtual bool GetSrtpCipher(std::string* cipher);
|
||||
virtual bool GetSslCipher(std::string* cipher);
|
||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const;
|
||||
virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const;
|
||||
virtual bool ExportKeyingMaterial(const std::string& label,
|
||||
|
Loading…
x
Reference in New Issue
Block a user