Re-land: Add API to get negotiated SSL ciphers
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. The previously approved CL https://webrtc-codereview.appspot.com/26009004/ was reverted in https://webrtc-codereview.appspot.com/40689004/ due to compilation issues while rolling into Chromium. As the new method has landed in Chromium in https://crrev.com/bc321c76ace6e1d5a03440e554ccb207159802ec, this should be safe to land here now. BUG=3976 R=pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/37209004 Cr-Commit-Position: refs/heads/master@{#8343} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8343 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
76b4ac96cd
commit
3ee4fe5a94
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user