| Index: webrtc/base/sslstreamadapter_unittest.cc
|
| diff --git a/webrtc/base/sslstreamadapter_unittest.cc b/webrtc/base/sslstreamadapter_unittest.cc
|
| index 341e09ff1e7e1ef46aafff695b8352807dd00bf3..9e156c0b3c1df82c0c3791edd6888080c31e4516 100644
|
| --- a/webrtc/base/sslstreamadapter_unittest.cc
|
| +++ b/webrtc/base/sslstreamadapter_unittest.cc
|
| @@ -325,36 +325,44 @@ class SSLStreamAdapterTestBase : public testing::Test,
|
| }
|
| }
|
|
|
| - void SetPeerIdentitiesByDigest(bool correct) {
|
| - unsigned char digest[20];
|
| - size_t digest_len;
|
| + void SetPeerIdentitiesByDigest(bool correct, bool expect_success) {
|
| + unsigned char server_digest[20];
|
| + size_t server_digest_len;
|
| + unsigned char client_digest[20];
|
| + size_t client_digest_len;
|
| bool rv;
|
| + rtc::SSLPeerCertificateDigestError err;
|
| + rtc::SSLPeerCertificateDigestError expected_err =
|
| + expect_success
|
| + ? rtc::SSLPeerCertificateDigestError::NONE
|
| + : rtc::SSLPeerCertificateDigestError::VERIFICATION_FAILED;
|
|
|
| LOG(LS_INFO) << "Setting peer identities by digest";
|
|
|
| - rv = server_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
|
| - digest, 20,
|
| - &digest_len);
|
| + rv = server_identity_->certificate().ComputeDigest(
|
| + rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len);
|
| ASSERT_TRUE(rv);
|
| + rv = client_identity_->certificate().ComputeDigest(
|
| + rtc::DIGEST_SHA_1, client_digest, 20, &client_digest_len);
|
| + ASSERT_TRUE(rv);
|
| +
|
| if (!correct) {
|
| LOG(LS_INFO) << "Setting bogus digest for server cert";
|
| - digest[0]++;
|
| + server_digest[0]++;
|
| }
|
| - rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
|
| - digest_len);
|
| - ASSERT_TRUE(rv);
|
| + rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, server_digest,
|
| + server_digest_len, &err);
|
| + EXPECT_EQ(expected_err, err);
|
| + EXPECT_EQ(expect_success, rv);
|
|
|
| -
|
| - rv = client_identity_->certificate().ComputeDigest(rtc::DIGEST_SHA_1,
|
| - digest, 20, &digest_len);
|
| - ASSERT_TRUE(rv);
|
| if (!correct) {
|
| LOG(LS_INFO) << "Setting bogus digest for client cert";
|
| - digest[0]++;
|
| + client_digest[0]++;
|
| }
|
| - rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
|
| - digest_len);
|
| - ASSERT_TRUE(rv);
|
| + rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, client_digest,
|
| + client_digest_len, &err);
|
| + EXPECT_EQ(expected_err, err);
|
| + EXPECT_EQ(expect_success, rv);
|
|
|
| identities_set_ = true;
|
| }
|
| @@ -379,7 +387,7 @@ class SSLStreamAdapterTestBase : public testing::Test,
|
| }
|
|
|
| if (!identities_set_)
|
| - SetPeerIdentitiesByDigest(true);
|
| + SetPeerIdentitiesByDigest(true, true);
|
|
|
| // Start the handshake
|
| int rv;
|
| @@ -402,6 +410,57 @@ class SSLStreamAdapterTestBase : public testing::Test,
|
| }
|
| }
|
|
|
| + // This tests that the handshake can complete before the identity is
|
| + // verified, and the identity will be verified after the fact.
|
| + void TestHandshakeWithDelayedIdentity(bool valid_identity) {
|
| + server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : rtc::SSL_MODE_TLS);
|
| + client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : rtc::SSL_MODE_TLS);
|
| +
|
| + if (!dtls_) {
|
| + // Make sure we simulate a reliable network for TLS.
|
| + // This is just a check to make sure that people don't write wrong
|
| + // tests.
|
| + ASSERT((mtu_ == 1460) && (loss_ == 0) && (lose_first_packet_ == 0));
|
| + }
|
| +
|
| + // Start the handshake
|
| + int rv;
|
| +
|
| + server_ssl_->SetServerRole();
|
| + rv = server_ssl_->StartSSL();
|
| + ASSERT_EQ(0, rv);
|
| +
|
| + rv = client_ssl_->StartSSL();
|
| + ASSERT_EQ(0, rv);
|
| +
|
| + // Now run the handshake.
|
| + EXPECT_TRUE_WAIT(
|
| + client_ssl_->IsTlsConnected() && server_ssl_->IsTlsConnected(),
|
| + handshake_wait_);
|
| +
|
| + // Until the identity has been verified, the state should still be
|
| + // SS_OPENING and writes should return SR_BLOCK.
|
| + EXPECT_EQ(rtc::SS_OPENING, client_ssl_->GetState());
|
| + EXPECT_EQ(rtc::SS_OPENING, server_ssl_->GetState());
|
| + unsigned char packet[1];
|
| + size_t sent;
|
| + EXPECT_EQ(rtc::SR_BLOCK, client_ssl_->Write(&packet, 1, &sent, 0));
|
| + EXPECT_EQ(rtc::SR_BLOCK, server_ssl_->Write(&packet, 1, &sent, 0));
|
| +
|
| + // If we set an invalid identity at this point, SetPeerCertificateDigest
|
| + // should return false.
|
| + SetPeerIdentitiesByDigest(valid_identity, valid_identity);
|
| + // State should then transition to SS_OPEN or SS_CLOSED based on validation
|
| + // of the identity.
|
| + if (valid_identity) {
|
| + EXPECT_EQ(rtc::SS_OPEN, client_ssl_->GetState());
|
| + EXPECT_EQ(rtc::SS_OPEN, server_ssl_->GetState());
|
| + } else {
|
| + EXPECT_EQ(rtc::SS_CLOSED, client_ssl_->GetState());
|
| + EXPECT_EQ(rtc::SS_CLOSED, server_ssl_->GetState());
|
| + }
|
| + }
|
| +
|
| rtc::StreamResult DataWritten(SSLDummyStreamBase *from, const void *data,
|
| size_t data_len, size_t *written,
|
| int *error) {
|
| @@ -849,10 +908,55 @@ TEST_P(SSLStreamAdapterTestTLS, ReadWriteAfterClose) {
|
|
|
| // Test a handshake with a bogus peer digest
|
| TEST_P(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
|
| - SetPeerIdentitiesByDigest(false);
|
| + SetPeerIdentitiesByDigest(false, true);
|
| TestHandshake(false);
|
| };
|
|
|
| +TEST_P(SSLStreamAdapterTestTLS, TestTLSDelayedIdentity) {
|
| + TestHandshakeWithDelayedIdentity(true);
|
| +};
|
| +
|
| +TEST_P(SSLStreamAdapterTestTLS, TestTLSDelayedIdentityWithBogusDigest) {
|
| + TestHandshakeWithDelayedIdentity(false);
|
| +};
|
| +
|
| +// Test that the correct error is returned when SetPeerCertificateDigest is
|
| +// called with an unknown algorithm.
|
| +TEST_P(SSLStreamAdapterTestTLS,
|
| + TestSetPeerCertificateDigestWithUnknownAlgorithm) {
|
| + unsigned char server_digest[20];
|
| + size_t server_digest_len;
|
| + bool rv;
|
| + rtc::SSLPeerCertificateDigestError err;
|
| +
|
| + rv = server_identity_->certificate().ComputeDigest(
|
| + rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len);
|
| + ASSERT_TRUE(rv);
|
| +
|
| + rv = client_ssl_->SetPeerCertificateDigest("unknown algorithm", server_digest,
|
| + server_digest_len, &err);
|
| + EXPECT_EQ(rtc::SSLPeerCertificateDigestError::UNKNOWN_ALGORITHM, err);
|
| + EXPECT_FALSE(rv);
|
| +}
|
| +
|
| +// Test that the correct error is returned when SetPeerCertificateDigest is
|
| +// called with an invalid digest length.
|
| +TEST_P(SSLStreamAdapterTestTLS, TestSetPeerCertificateDigestWithInvalidLength) {
|
| + unsigned char server_digest[20];
|
| + size_t server_digest_len;
|
| + bool rv;
|
| + rtc::SSLPeerCertificateDigestError err;
|
| +
|
| + rv = server_identity_->certificate().ComputeDigest(
|
| + rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len);
|
| + ASSERT_TRUE(rv);
|
| +
|
| + rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, server_digest,
|
| + server_digest_len - 1, &err);
|
| + EXPECT_EQ(rtc::SSLPeerCertificateDigestError::INVALID_LENGTH, err);
|
| + EXPECT_FALSE(rv);
|
| +}
|
| +
|
| // Test moving a bunch of data
|
|
|
| // Basic tests: DTLS
|
| @@ -911,6 +1015,14 @@ TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) {
|
| TestTransfer(100);
|
| };
|
|
|
| +TEST_P(SSLStreamAdapterTestDTLS, TestDTLSDelayedIdentity) {
|
| + TestHandshakeWithDelayedIdentity(true);
|
| +};
|
| +
|
| +TEST_P(SSLStreamAdapterTestDTLS, TestDTLSDelayedIdentityWithBogusDigest) {
|
| + TestHandshakeWithDelayedIdentity(false);
|
| +};
|
| +
|
| // Test DTLS-SRTP with all high ciphers
|
| TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) {
|
| MAYBE_SKIP_TEST(HaveDtlsSrtp);
|
|
|