Bug 996237 - Tests for cipher mismatch. r=ekr

This commit is contained in:
Martin Thomson 2014-08-04 11:50:00 -04:00
parent efdc5bd957
commit 9b8bbd109c
2 changed files with 84 additions and 7 deletions

View File

@ -9,6 +9,7 @@
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include "mozilla/UniquePtr.h"
@ -292,7 +293,9 @@ class TransportTestPeer : public sigslot::has_slots<> {
TransportLayerDtls::SERVER)),
streams_(), candidates_(),
peer_(nullptr),
gathering_complete_(false)
gathering_complete_(false),
enabled_cipersuites_(),
disabled_cipersuites_()
{
std::vector<NrIceStunServer> stun_servers;
UniquePtr<NrIceStunServer> server(NrIceStunServer::Create(
@ -368,6 +371,10 @@ class TransportTestPeer : public sigslot::has_slots<> {
srtp_ciphers.push_back(SRTP_AES128_CM_HMAC_SHA1_80);
srtp_ciphers.push_back(SRTP_AES128_CM_HMAC_SHA1_32);
SetSrtpCiphers(srtp_ciphers);
}
void SetSrtpCiphers(std::vector<uint16_t>& srtp_ciphers) {
ASSERT_TRUE(NS_SUCCEEDED(dtls_->SetSrtpCiphers(srtp_ciphers)));
}
@ -383,9 +390,22 @@ class TransportTestPeer : public sigslot::has_slots<> {
ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(lossy_));
ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(dtls_));
TweakCiphers(dtls_->internal_fd());
flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
}
void TweakCiphers(PRFileDesc* fd) {
for (auto it = enabled_cipersuites_.begin();
it != enabled_cipersuites_.end(); ++it) {
SSL_CipherPrefSet(fd, *it, PR_TRUE);
}
for (auto it = disabled_cipersuites_.begin();
it != disabled_cipersuites_.end(); ++it) {
SSL_CipherPrefSet(fd, *it, PR_FALSE);
}
}
void ConnectSocket(TransportTestPeer *peer) {
RUN_ON_THREAD(test_utils->sts_target(),
WrapRunnable(this, & TransportTestPeer::ConnectSocket_s,
@ -526,6 +546,12 @@ class TransportTestPeer : public sigslot::has_slots<> {
lossy_->SetInspector(Move(inspector));
}
void SetCipherSuiteChanges(const std::vector<uint16_t>& enableThese,
const std::vector<uint16_t>& disableThese) {
disabled_cipersuites_ = disableThese;
enabled_cipersuites_ = enableThese;
}
TransportLayer::State state() {
TransportLayer::State tstate;
@ -588,6 +614,8 @@ class TransportTestPeer : public sigslot::has_slots<> {
bool gathering_complete_;
unsigned char fingerprint_[TransportLayerDtls::kMaxDigestLength];
size_t fingerprint_len_;
std::vector<uint16_t> enabled_cipersuites_;
std::vector<uint16_t> disabled_cipersuites_;
};
@ -646,6 +674,9 @@ class TransportTest : public ::testing::Test {
ASSERT_TRUE_WAIT(p1_->connected(), 10000);
ASSERT_TRUE_WAIT(p2_->connected(), 10000);
ASSERT_EQ(p1_->cipherSuite(), p2_->cipherSuite());
ASSERT_EQ(p1_->srtpCipher(), p2_->srtpCipher());
}
void ConnectSocketExpectFail() {
@ -702,13 +733,11 @@ TEST_F(TransportTest, TestConnect) {
SetDtlsPeer();
ConnectSocket();
// check that everything was negotiated properly
// check that we got the right suite
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) {
@ -717,11 +746,9 @@ TEST_F(TransportTest, TestConnectSrtp) {
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());
}
@ -801,6 +828,54 @@ TEST_F(TransportTest, TestTransferIce) {
TransferTest(1);
}
// test the default configuration against a peer that supports only
// one of the mandatory-to-implement suites, which should succeed
static void ConfigureOneCipher(TransportTestPeer* peer, uint16_t suite) {
std::vector<uint16_t> justOne;
justOne.push_back(suite);
std::vector<uint16_t> everythingElse(SSL_GetImplementedCiphers(),
SSL_GetImplementedCiphers()
+ SSL_GetNumImplementedCiphers());
std::remove(everythingElse.begin(), everythingElse.end(), suite);
peer->SetCipherSuiteChanges(justOne, everythingElse);
}
TEST_F(TransportTest, TestCipherMismatch) {
SetDtlsPeer();
ConfigureOneCipher(p1_, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
ConfigureOneCipher(p2_, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
ConnectSocketExpectFail();
}
TEST_F(TransportTest, TestCipherMandatoryOnlyGcm) {
SetDtlsPeer();
ConfigureOneCipher(p1_, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
ConnectSocket();
ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, p1_->cipherSuite());
}
TEST_F(TransportTest, TestCipherMandatoryOnlyCbc) {
SetDtlsPeer();
ConfigureOneCipher(p1_, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
ConnectSocket();
ASSERT_EQ(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, p1_->cipherSuite());
}
TEST_F(TransportTest, TestSrtpMismatch) {
std::vector<uint16_t> setA;
setA.push_back(SRTP_AES128_CM_HMAC_SHA1_80);
std::vector<uint16_t> setB;
setB.push_back(SRTP_AES128_CM_HMAC_SHA1_32);
p1_->SetSrtpCiphers(setA);
p2_->SetSrtpCiphers(setB);
SetDtlsPeer();
ConnectSocket();
ASSERT_EQ(0, p1_->srtpCipher());
ASSERT_EQ(0, p2_->srtpCipher());
}
TEST(PushTests, LayerFail) {
mozilla::RefPtr<TransportFlow> flow = new TransportFlow();
nsresult rv;
@ -821,7 +896,6 @@ TEST(PushTests, LayerFail) {
ASSERT_EQ(true, destroyed1);
}
TEST(PushTests, LayersFail) {
mozilla::RefPtr<TransportFlow> flow = new TransportFlow();
nsresult rv;

View File

@ -98,6 +98,9 @@ class TransportLayerDtls : public TransportLayer {
void PacketReceived(TransportLayer* layer, const unsigned char *data,
size_t len);
// For testing use only. Returns the fd.
PRFileDesc* internal_fd() { CheckThread(); return ssl_fd_.rwget(); }
TRANSPORT_LAYER_ID("dtls")
private: