Bug 996237 - Unit testing cipher suite selection happy path. r=ekr

This commit is contained in:
Martin Thomson 2014-07-31 10:47:00 -04:00
parent e68d6a644d
commit 442c1b12d2
4 changed files with 86 additions and 4 deletions

View File

@ -18,6 +18,7 @@
#include "nspr.h"
#include "nss.h"
#include "ssl.h"
#include "sslproto.h"
#include "nsThreadUtils.h"
#include "nsXPCOM.h"
@ -361,6 +362,14 @@ class TransportTestPeer : public sigslot::has_slots<> {
}
}
void SetupSrtp() {
// this mimics the setup we do elsewhere
std::vector<uint16_t> srtp_ciphers;
srtp_ciphers.push_back(SRTP_AES128_CM_HMAC_SHA1_80);
srtp_ciphers.push_back(SRTP_AES128_CM_HMAC_SHA1_32);
ASSERT_TRUE(NS_SUCCEEDED(dtls_->SetSrtpCiphers(srtp_ciphers)));
}
void ConnectSocket_s(TransportTestPeer *peer) {
nsresult res;
@ -536,6 +545,31 @@ class TransportTestPeer : public sigslot::has_slots<> {
size_t received() { return received_; }
uint16_t cipherSuite() const {
nsresult rv;
uint16_t cipher;
RUN_ON_THREAD(test_utils->sts_target(),
WrapRunnableRet(dtls_, &TransportLayerDtls::GetCipherSuite,
&cipher, &rv));
if (NS_FAILED(rv)) {
return TLS_NULL_WITH_NULL_NULL; // i.e., not good
}
return cipher;
}
uint16_t srtpCipher() const {
nsresult rv;
uint16_t cipher;
RUN_ON_THREAD(test_utils->sts_target(),
WrapRunnableRet(dtls_, &TransportLayerDtls::GetSrtpCipher,
&cipher, &rv));
if (NS_FAILED(rv)) {
return 0; // the SRTP equivalent of TLS_NULL_WITH_NULL_NULL
}
return cipher;
}
private:
std::string name_;
nsCOMPtr<nsIEventTarget> target_;
@ -587,6 +621,11 @@ class TransportTest : public ::testing::Test {
p2_ = new TransportTestPeer(target_, "P2");
}
void SetupSrtp() {
p1_->SetupSrtp();
p2_->SetupSrtp();
}
void SetDtlsPeer(int digests = 1, unsigned int damage = 0) {
p1_->SetDtlsPeer(p2_, digests, damage);
p2_->SetDtlsPeer(p1_, digests, damage);
@ -662,8 +701,30 @@ TEST_F(TransportTest, TestNoDtlsVerificationSettings) {
TEST_F(TransportTest, TestConnect) {
SetDtlsPeer();
ConnectSocket();
// check that everything was negotiated properly
ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, p1_->cipherSuite());
ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, p2_->cipherSuite());
// no SRTP on this one
ASSERT_EQ(0, p1_->srtpCipher());
ASSERT_EQ(0, p2_->srtpCipher());
}
TEST_F(TransportTest, TestConnectSrtp) {
SetupSrtp();
SetDtlsPeer();
ConnectSocket();
ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, p1_->cipherSuite());
ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, p2_->cipherSuite());
// SRTP is on
ASSERT_EQ(SRTP_AES128_CM_HMAC_SHA1_80, p1_->srtpCipher());
ASSERT_EQ(SRTP_AES128_CM_HMAC_SHA1_80, p2_->srtpCipher());
}
TEST_F(TransportTest, TestConnectDestroyFlowsMainThread) {
SetDtlsPeer();
ConnectSocket();

View File

@ -92,7 +92,7 @@ class TransportLayer : public sigslot::has_slots<> {
virtual void WasInserted() {}
virtual void SetState(State state, const char *file, unsigned line);
// Check if we are on the right thread
void CheckThread() {
void CheckThread() const {
NS_ABORT_IF_FALSE(CheckThreadInt(), "Wrong thread");
}
@ -105,7 +105,7 @@ class TransportLayer : public sigslot::has_slots<> {
private:
DISALLOW_COPY_ASSIGN(TransportLayer);
bool CheckThreadInt() {
bool CheckThreadInt() const {
bool on;
if (!target_) // OK if no thread set.

View File

@ -691,6 +691,25 @@ bool TransportLayerDtls::SetupCipherSuites(PRFileDesc* ssl_fd) const {
return true;
}
nsresult TransportLayerDtls::GetCipherSuite(uint16_t* cipherSuite) const {
CheckThread();
if (!cipherSuite) {
MOZ_MTLOG(ML_ERROR, LAYER_INFO << "GetCipherSuite passed a nullptr");
return NS_ERROR_NULL_POINTER;
}
if (state_ != TS_OPEN) {
return NS_ERROR_NOT_AVAILABLE;
}
SSLChannelInfo info;
SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &info, sizeof(info));
if (rv != SECSuccess) {
MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "GetCipherSuite can't get channel info");
return NS_ERROR_FAILURE;
}
*cipherSuite = info.cipherSuite;
return NS_OK;
}
void TransportLayerDtls::StateChange(TransportLayer *layer, State state) {
if (state <= state_) {
MOZ_MTLOG(ML_ERROR, "Lower layer state is going backwards from ours");
@ -902,7 +921,7 @@ nsresult TransportLayerDtls::SetSrtpCiphers(std::vector<uint16_t> ciphers) {
return NS_OK;
}
nsresult TransportLayerDtls::GetSrtpCipher(uint16_t *cipher) {
nsresult TransportLayerDtls::GetSrtpCipher(uint16_t *cipher) const {
CheckThread();
SECStatus rv = SSL_GetSRTPCipher(ssl_fd_, cipher);
if (rv != SECSuccess) {

View File

@ -73,8 +73,10 @@ class TransportLayerDtls : public TransportLayer {
const unsigned char *digest_value,
size_t digest_len);
nsresult GetCipherSuite(uint16_t* cipherSuite) const;
nsresult SetSrtpCiphers(std::vector<uint16_t> ciphers);
nsresult GetSrtpCipher(uint16_t *cipher);
nsresult GetSrtpCipher(uint16_t *cipher) const;
nsresult ExportKeyingMaterial(const std::string& label,
bool use_context,