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:
1
AUTHORS
1
AUTHORS
@ -37,5 +37,6 @@ Intel Corporation
|
|||||||
MIPS Technologies
|
MIPS Technologies
|
||||||
Mozilla Foundation
|
Mozilla Foundation
|
||||||
Opera Software ASA
|
Opera Software ASA
|
||||||
|
struktur AG
|
||||||
Temasys Communications
|
Temasys Communications
|
||||||
Vonage Holdings Corp.
|
Vonage Holdings Corp.
|
||||||
|
@ -66,6 +66,10 @@ static const SrtpCipherMapEntry kSrtpCipherMap[] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#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
|
// Implementation of NSPR methods
|
||||||
static PRStatus StreamClose(PRFileDesc *socket) {
|
static PRStatus StreamClose(PRFileDesc *socket) {
|
||||||
@ -866,6 +870,27 @@ SECStatus NSSStreamAdapter::GetClientAuthDataHook(void *arg, PRFileDesc *fd,
|
|||||||
return SECSuccess;
|
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
|
// RFC 5705 Key Exporter
|
||||||
bool NSSStreamAdapter::ExportKeyingMaterial(const std::string& label,
|
bool NSSStreamAdapter::ExportKeyingMaterial(const std::string& label,
|
||||||
const uint8* context,
|
const uint8* context,
|
||||||
@ -1011,6 +1036,10 @@ bool NSSStreamAdapter::HaveExporter() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string NSSStreamAdapter::GetDefaultSslCipher() {
|
||||||
|
return kDefaultSslCipher;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
|
||||||
#endif // HAVE_NSS_SSL_H
|
#endif // HAVE_NSS_SSL_H
|
||||||
|
@ -61,6 +61,8 @@ class NSSStreamAdapter : public SSLStreamAdapterHelper {
|
|||||||
size_t* written, int* error);
|
size_t* written, int* error);
|
||||||
void OnMessage(Message *msg);
|
void OnMessage(Message *msg);
|
||||||
|
|
||||||
|
virtual bool GetSslCipher(std::string* cipher);
|
||||||
|
|
||||||
// Key Extractor interface
|
// Key Extractor interface
|
||||||
virtual bool ExportKeyingMaterial(const std::string& label,
|
virtual bool ExportKeyingMaterial(const std::string& label,
|
||||||
const uint8* context,
|
const uint8* context,
|
||||||
@ -77,6 +79,7 @@ class NSSStreamAdapter : public SSLStreamAdapterHelper {
|
|||||||
static bool HaveDtls();
|
static bool HaveDtls();
|
||||||
static bool HaveDtlsSrtp();
|
static bool HaveDtlsSrtp();
|
||||||
static bool HaveExporter();
|
static bool HaveExporter();
|
||||||
|
static std::string GetDefaultSslCipher();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Override SSLStreamAdapter
|
// Override SSLStreamAdapter
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/tls1.h>
|
||||||
#include <openssl/x509v3.h>
|
#include <openssl/x509v3.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -56,6 +57,99 @@ static SrtpCipherMapEntry SrtpCipherMap[] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#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
|
// StreamBIO
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -222,6 +316,36 @@ bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
|
|||||||
return true;
|
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
|
// Key Extractor interface
|
||||||
bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
|
bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
|
||||||
const uint8* context,
|
const uint8* context,
|
||||||
@ -877,6 +1001,10 @@ bool OpenSSLStreamAdapter::HaveExporter() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string OpenSSLStreamAdapter::GetDefaultSslCipher() {
|
||||||
|
return kDefaultSslCipher;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
|
||||||
#endif // HAVE_OPENSSL_SSL_H
|
#endif // HAVE_OPENSSL_SSL_H
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
typedef struct ssl_st SSL;
|
typedef struct ssl_st SSL;
|
||||||
typedef struct ssl_ctx_st SSL_CTX;
|
typedef struct ssl_ctx_st SSL_CTX;
|
||||||
|
typedef struct ssl_cipher_st SSL_CIPHER;
|
||||||
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
||||||
|
|
||||||
namespace rtc {
|
namespace rtc {
|
||||||
@ -81,6 +82,11 @@ class OpenSSLStreamAdapter : public SSLStreamAdapter {
|
|||||||
virtual void Close();
|
virtual void Close();
|
||||||
virtual StreamState GetState() const;
|
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
|
// Key Extractor interface
|
||||||
virtual bool ExportKeyingMaterial(const std::string& label,
|
virtual bool ExportKeyingMaterial(const std::string& label,
|
||||||
const uint8* context,
|
const uint8* context,
|
||||||
@ -98,6 +104,7 @@ class OpenSSLStreamAdapter : public SSLStreamAdapter {
|
|||||||
static bool HaveDtls();
|
static bool HaveDtls();
|
||||||
static bool HaveDtlsSrtp();
|
static bool HaveDtlsSrtp();
|
||||||
static bool HaveExporter();
|
static bool HaveExporter();
|
||||||
|
static std::string GetDefaultSslCipher();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void OnEvent(StreamInterface* stream, int events, int err);
|
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::HaveDtls() { return false; }
|
||||||
bool SSLStreamAdapter::HaveDtlsSrtp() { return false; }
|
bool SSLStreamAdapter::HaveDtlsSrtp() { return false; }
|
||||||
bool SSLStreamAdapter::HaveExporter() { return false; }
|
bool SSLStreamAdapter::HaveExporter() { return false; }
|
||||||
|
std::string SSLStreamAdapter::GetDefaultSslCipher() {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
#elif SSL_USE_OPENSSL
|
#elif SSL_USE_OPENSSL
|
||||||
bool SSLStreamAdapter::HaveDtls() {
|
bool SSLStreamAdapter::HaveDtls() {
|
||||||
return OpenSSLStreamAdapter::HaveDtls();
|
return OpenSSLStreamAdapter::HaveDtls();
|
||||||
@ -60,6 +63,9 @@ bool SSLStreamAdapter::HaveDtlsSrtp() {
|
|||||||
bool SSLStreamAdapter::HaveExporter() {
|
bool SSLStreamAdapter::HaveExporter() {
|
||||||
return OpenSSLStreamAdapter::HaveExporter();
|
return OpenSSLStreamAdapter::HaveExporter();
|
||||||
}
|
}
|
||||||
|
std::string SSLStreamAdapter::GetDefaultSslCipher() {
|
||||||
|
return OpenSSLStreamAdapter::GetDefaultSslCipher();
|
||||||
|
}
|
||||||
#elif SSL_USE_NSS
|
#elif SSL_USE_NSS
|
||||||
bool SSLStreamAdapter::HaveDtls() {
|
bool SSLStreamAdapter::HaveDtls() {
|
||||||
return NSSStreamAdapter::HaveDtls();
|
return NSSStreamAdapter::HaveDtls();
|
||||||
@ -70,6 +76,9 @@ bool SSLStreamAdapter::HaveDtlsSrtp() {
|
|||||||
bool SSLStreamAdapter::HaveExporter() {
|
bool SSLStreamAdapter::HaveExporter() {
|
||||||
return NSSStreamAdapter::HaveExporter();
|
return NSSStreamAdapter::HaveExporter();
|
||||||
}
|
}
|
||||||
|
std::string SSLStreamAdapter::GetDefaultSslCipher() {
|
||||||
|
return NSSStreamAdapter::GetDefaultSslCipher();
|
||||||
|
}
|
||||||
#endif // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL && !SSL_USE_NSS
|
#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.
|
// chain. The returned certificate is owned by the caller.
|
||||||
virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0;
|
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
|
// Key Exporter interface from RFC 5705
|
||||||
// Arguments are:
|
// Arguments are:
|
||||||
// label -- the exporter label.
|
// label -- the exporter label.
|
||||||
@ -155,6 +161,10 @@ class SSLStreamAdapter : public StreamAdapterInterface {
|
|||||||
static bool HaveDtlsSrtp();
|
static bool HaveDtlsSrtp();
|
||||||
static bool HaveExporter();
|
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:
|
private:
|
||||||
// If true, the server certificate need not match the configured
|
// If true, the server certificate need not match the configured
|
||||||
// server_name, and in fact missing certificate authority and other
|
// server_name, and in fact missing certificate authority and other
|
||||||
|
@ -388,6 +388,13 @@ class SSLStreamAdapterTestBase : public testing::Test,
|
|||||||
return server_ssl_->GetPeerCertificate(cert);
|
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,
|
bool ExportKeyingMaterial(const char *label,
|
||||||
const unsigned char *context,
|
const unsigned char *context,
|
||||||
size_t context_len,
|
size_t context_len,
|
||||||
@ -939,3 +946,17 @@ TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
|
|||||||
rtc::SSLCertChain* server_peer_chain;
|
rtc::SSLCertChain* server_peer_chain;
|
||||||
ASSERT_FALSE(server_peer_cert->GetChain(&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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DtlsTransportChannelWrapper::GetSslCipher(std::string* cipher) {
|
||||||
|
if (dtls_state_ != STATE_OPEN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dtls_->GetSslCipher(cipher);
|
||||||
|
}
|
||||||
|
|
||||||
bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
|
bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
|
||||||
const std::string& digest_alg,
|
const std::string& digest_alg,
|
||||||
const uint8* digest,
|
const uint8* digest,
|
||||||
|
@ -150,6 +150,9 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl {
|
|||||||
virtual bool GetSslRole(rtc::SSLRole* role) const;
|
virtual bool GetSslRole(rtc::SSLRole* role) const;
|
||||||
virtual bool SetSslRole(rtc::SSLRole role);
|
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
|
// Once DTLS has been established, this method retrieves the certificate in
|
||||||
// use by the remote peer, for use in external identity verification.
|
// use by the remote peer, for use in external identity verification.
|
||||||
virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const;
|
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) {
|
void SendPackets(size_t channel, size_t size, size_t count, bool srtp) {
|
||||||
ASSERT(channel < channels_.size());
|
ASSERT(channel < channels_.size());
|
||||||
rtc::scoped_ptr<char[]> packet(new char[size]);
|
rtc::scoped_ptr<char[]> packet(new char[size]);
|
||||||
@ -433,6 +449,8 @@ class DtlsTransportChannelTest : public testing::Test {
|
|||||||
client1_.CheckSrtp("");
|
client1_.CheckSrtp("");
|
||||||
client2_.CheckSrtp("");
|
client2_.CheckSrtp("");
|
||||||
}
|
}
|
||||||
|
client1_.CheckSsl(rtc::SSLStreamAdapter::GetDefaultSslCipher());
|
||||||
|
client2_.CheckSsl(rtc::SSLStreamAdapter::GetDefaultSslCipher());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -246,6 +246,10 @@ class FakeTransportChannel : public TransportChannelImpl,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool GetSslCipher(std::string* cipher) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
||||||
if (!identity_)
|
if (!identity_)
|
||||||
return false;
|
return false;
|
||||||
|
@ -109,11 +109,16 @@ class P2PTransportChannel : public TransportChannelImpl,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find out which DTLS-SRTP cipher was negotiated
|
// Find out which DTLS-SRTP cipher was negotiated.
|
||||||
virtual bool GetSrtpCipher(std::string* cipher) {
|
virtual bool GetSrtpCipher(std::string* cipher) {
|
||||||
return false;
|
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.
|
// Returns false because the channel is not encrypted by default.
|
||||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
||||||
return false;
|
return false;
|
||||||
|
@ -114,11 +114,16 @@ class RawTransportChannel : public TransportChannelImpl,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find out which DTLS-SRTP cipher was negotiated
|
// Find out which DTLS-SRTP cipher was negotiated.
|
||||||
virtual bool GetSrtpCipher(std::string* cipher) {
|
virtual bool GetSrtpCipher(std::string* cipher) {
|
||||||
return false;
|
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.
|
// Returns false because the channel is not DTLS.
|
||||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const {
|
||||||
return false;
|
return false;
|
||||||
|
@ -454,9 +454,12 @@ bool Transport::GetStats_w(TransportStats* stats) {
|
|||||||
for (ChannelMap::iterator iter = channels_.begin();
|
for (ChannelMap::iterator iter = channels_.begin();
|
||||||
iter != channels_.end();
|
iter != channels_.end();
|
||||||
++iter) {
|
++iter) {
|
||||||
|
ChannelMapEntry& entry = iter->second;
|
||||||
TransportChannelStats substats;
|
TransportChannelStats substats;
|
||||||
substats.component = iter->second->component();
|
substats.component = entry->component();
|
||||||
if (!iter->second->GetStats(&substats.connection_infos)) {
|
entry->GetSrtpCipher(&substats.srtp_cipher);
|
||||||
|
entry->GetSslCipher(&substats.ssl_cipher);
|
||||||
|
if (!entry->GetStats(&substats.connection_infos)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
stats->channel_stats.push_back(substats);
|
stats->channel_stats.push_back(substats);
|
||||||
|
@ -106,6 +106,8 @@ typedef std::vector<ConnectionInfo> ConnectionInfos;
|
|||||||
struct TransportChannelStats {
|
struct TransportChannelStats {
|
||||||
int component;
|
int component;
|
||||||
ConnectionInfos connection_infos;
|
ConnectionInfos connection_infos;
|
||||||
|
std::string srtp_cipher;
|
||||||
|
std::string ssl_cipher;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Information about all the channels of a transport.
|
// 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.
|
// Sets up the ciphers to use for DTLS-SRTP.
|
||||||
virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers) = 0;
|
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;
|
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.
|
// Gets a copy of the local SSL identity, owned by the caller.
|
||||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const = 0;
|
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const = 0;
|
||||||
|
|
||||||
|
@ -186,6 +186,14 @@ bool TransportChannelProxy::GetSrtpCipher(std::string* cipher) {
|
|||||||
return impl_->GetSrtpCipher(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(
|
bool TransportChannelProxy::GetLocalIdentity(
|
||||||
rtc::SSLIdentity** identity) const {
|
rtc::SSLIdentity** identity) const {
|
||||||
ASSERT(rtc::Thread::Current() == worker_thread_);
|
ASSERT(rtc::Thread::Current() == worker_thread_);
|
||||||
|
@ -61,6 +61,7 @@ class TransportChannelProxy : public TransportChannel,
|
|||||||
virtual bool SetSslRole(rtc::SSLRole role);
|
virtual bool SetSslRole(rtc::SSLRole role);
|
||||||
virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers);
|
virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers);
|
||||||
virtual bool GetSrtpCipher(std::string* cipher);
|
virtual bool GetSrtpCipher(std::string* cipher);
|
||||||
|
virtual bool GetSslCipher(std::string* cipher);
|
||||||
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const;
|
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const;
|
||||||
virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const;
|
virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const;
|
||||||
virtual bool ExportKeyingMaterial(const std::string& label,
|
virtual bool ExportKeyingMaterial(const std::string& label,
|
||||||
|
Reference in New Issue
Block a user