1 /* 2 * libjingle 3 * Copyright 2011, Google Inc. 4 * Portions Copyright 2011, RTFM, Inc. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 30 #include <algorithm> 31 #include <set> 32 #include <string> 33 34 #include "talk/base/gunit.h" 35 #include "talk/base/helpers.h" 36 #include "talk/base/scoped_ptr.h" 37 #include "talk/base/ssladapter.h" 38 #include "talk/base/sslconfig.h" 39 #include "talk/base/sslidentity.h" 40 #include "talk/base/sslstreamadapter.h" 41 #include "talk/base/stream.h" 42 43 static const int kBlockSize = 4096; 44 static const char kAES_CM_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80"; 45 static const char kAES_CM_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32"; 46 static const char kExporterLabel[] = "label"; 47 static const unsigned char kExporterContext[] = "context"; 48 static int kExporterContextLen = sizeof(kExporterContext); 49 50 static const char kRSA_PRIVATE_KEY_PEM[] = 51 "-----BEGIN RSA PRIVATE KEY-----\n" 52 "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n" 53 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" 54 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" 55 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n" 56 "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n" 57 "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n" 58 "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n" 59 "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n" 60 "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n" 61 "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n" 62 "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n" 63 "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n" 64 "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n" 65 "UCXiYxSsu20QNVw=\n" 66 "-----END RSA PRIVATE KEY-----\n"; 67 68 static const char kCERT_PEM[] = 69 "-----BEGIN CERTIFICATE-----\n" 70 "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n" 71 "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n" 72 "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n" 73 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" 74 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" 75 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n" 76 "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n" 77 "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n" 78 "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n" 79 "-----END CERTIFICATE-----\n"; 80 81 #define MAYBE_SKIP_TEST(feature) \ 82 if (!(talk_base::SSLStreamAdapter::feature())) { \ 83 LOG(LS_INFO) << "Feature disabled... skipping"; \ 84 return; \ 85 } 86 87 class SSLStreamAdapterTestBase; 88 89 class SSLDummyStream : public talk_base::StreamInterface, 90 public sigslot::has_slots<> { 91 public: 92 explicit SSLDummyStream(SSLStreamAdapterTestBase *test, 93 const std::string &side, 94 talk_base::FifoBuffer *in, 95 talk_base::FifoBuffer *out) : 96 test_(test), 97 side_(side), 98 in_(in), 99 out_(out), 100 first_packet_(true) { 101 in_->SignalEvent.connect(this, &SSLDummyStream::OnEventIn); 102 out_->SignalEvent.connect(this, &SSLDummyStream::OnEventOut); 103 } 104 105 virtual talk_base::StreamState GetState() const { return talk_base::SS_OPEN; } 106 107 virtual talk_base::StreamResult Read(void* buffer, size_t buffer_len, 108 size_t* read, int* error) { 109 talk_base::StreamResult r; 110 111 r = in_->Read(buffer, buffer_len, read, error); 112 if (r == talk_base::SR_BLOCK) 113 return talk_base::SR_BLOCK; 114 if (r == talk_base::SR_EOS) 115 return talk_base::SR_EOS; 116 117 if (r != talk_base::SR_SUCCESS) { 118 ADD_FAILURE(); 119 return talk_base::SR_ERROR; 120 } 121 122 return talk_base::SR_SUCCESS; 123 } 124 125 // Catch readability events on in and pass them up. 126 virtual void OnEventIn(talk_base::StreamInterface *stream, int sig, 127 int err) { 128 int mask = (talk_base::SE_READ | talk_base::SE_CLOSE); 129 130 if (sig & mask) { 131 LOG(LS_INFO) << "SSLDummyStream::OnEvent side=" << side_ << " sig=" 132 << sig << " forwarding upward"; 133 PostEvent(sig & mask, 0); 134 } 135 } 136 137 // Catch writeability events on out and pass them up. 138 virtual void OnEventOut(talk_base::StreamInterface *stream, int sig, 139 int err) { 140 if (sig & talk_base::SE_WRITE) { 141 LOG(LS_INFO) << "SSLDummyStream::OnEvent side=" << side_ << " sig=" 142 << sig << " forwarding upward"; 143 144 PostEvent(sig & talk_base::SE_WRITE, 0); 145 } 146 } 147 148 // Write to the outgoing FifoBuffer 149 talk_base::StreamResult WriteData(const void* data, size_t data_len, 150 size_t* written, int* error) { 151 return out_->Write(data, data_len, written, error); 152 } 153 154 // Defined later 155 virtual talk_base::StreamResult Write(const void* data, size_t data_len, 156 size_t* written, int* error); 157 158 virtual void Close() { 159 LOG(LS_INFO) << "Closing outbound stream"; 160 out_->Close(); 161 } 162 163 private: 164 SSLStreamAdapterTestBase *test_; 165 const std::string side_; 166 talk_base::FifoBuffer *in_; 167 talk_base::FifoBuffer *out_; 168 bool first_packet_; 169 }; 170 171 static const int kFifoBufferSize = 4096; 172 173 class SSLStreamAdapterTestBase : public testing::Test, 174 public sigslot::has_slots<> { 175 public: 176 SSLStreamAdapterTestBase(const std::string& client_cert_pem, 177 const std::string& client_private_key_pem, 178 bool dtls) : 179 client_buffer_(kFifoBufferSize), server_buffer_(kFifoBufferSize), 180 client_stream_( 181 new SSLDummyStream(this, "c2s", &client_buffer_, &server_buffer_)), 182 server_stream_( 183 new SSLDummyStream(this, "s2c", &server_buffer_, &client_buffer_)), 184 client_ssl_(talk_base::SSLStreamAdapter::Create(client_stream_)), 185 server_ssl_(talk_base::SSLStreamAdapter::Create(server_stream_)), 186 client_identity_(NULL), server_identity_(NULL), 187 delay_(0), mtu_(1460), loss_(0), lose_first_packet_(false), 188 damage_(false), dtls_(dtls), 189 handshake_wait_(5000), identities_set_(false) { 190 // Set use of the test RNG to get predictable loss patterns. 191 talk_base::SetRandomTestMode(true); 192 193 // Set up the slots 194 client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent); 195 server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent); 196 197 if (!client_cert_pem.empty() && !client_private_key_pem.empty()) { 198 client_identity_ = talk_base::SSLIdentity::FromPEMStrings( 199 client_private_key_pem, client_cert_pem); 200 } else { 201 client_identity_ = talk_base::SSLIdentity::Generate("client"); 202 } 203 server_identity_ = talk_base::SSLIdentity::Generate("server"); 204 205 client_ssl_->SetIdentity(client_identity_); 206 server_ssl_->SetIdentity(server_identity_); 207 } 208 209 ~SSLStreamAdapterTestBase() { 210 // Put it back for the next test. 211 talk_base::SetRandomTestMode(false); 212 } 213 214 static void SetUpTestCase() { 215 talk_base::InitializeSSL(); 216 } 217 218 static void TearDownTestCase() { 219 talk_base::CleanupSSL(); 220 } 221 222 // Recreate the client/server identities with the specified validity period. 223 // |not_before| and |not_after| are offsets from the current time in number 224 // of seconds. 225 void ResetIdentitiesWithValidity(int not_before, int not_after) { 226 client_stream_ = 227 new SSLDummyStream(this, "c2s", &client_buffer_, &server_buffer_); 228 server_stream_ = 229 new SSLDummyStream(this, "s2c", &server_buffer_, &client_buffer_); 230 231 client_ssl_.reset(talk_base::SSLStreamAdapter::Create(client_stream_)); 232 server_ssl_.reset(talk_base::SSLStreamAdapter::Create(server_stream_)); 233 234 client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent); 235 server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent); 236 237 talk_base::SSLIdentityParams client_params; 238 client_params.common_name = "client"; 239 client_params.not_before = not_before; 240 client_params.not_after = not_after; 241 client_identity_ = talk_base::SSLIdentity::GenerateForTest(client_params); 242 243 talk_base::SSLIdentityParams server_params; 244 server_params.common_name = "server"; 245 server_params.not_before = not_before; 246 server_params.not_after = not_after; 247 server_identity_ = talk_base::SSLIdentity::GenerateForTest(server_params); 248 249 client_ssl_->SetIdentity(client_identity_); 250 server_ssl_->SetIdentity(server_identity_); 251 } 252 253 virtual void OnEvent(talk_base::StreamInterface *stream, int sig, int err) { 254 LOG(LS_INFO) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig; 255 256 if (sig & talk_base::SE_READ) { 257 ReadData(stream); 258 } 259 260 if ((stream == client_ssl_.get()) && (sig & talk_base::SE_WRITE)) { 261 WriteData(); 262 } 263 } 264 265 void SetPeerIdentitiesByDigest(bool correct) { 266 unsigned char digest[20]; 267 size_t digest_len; 268 bool rv; 269 270 LOG(LS_INFO) << "Setting peer identities by digest"; 271 272 rv = server_identity_->certificate().ComputeDigest(talk_base::DIGEST_SHA_1, 273 digest, 20, 274 &digest_len); 275 ASSERT_TRUE(rv); 276 if (!correct) { 277 LOG(LS_INFO) << "Setting bogus digest for server cert"; 278 digest[0]++; 279 } 280 rv = client_ssl_->SetPeerCertificateDigest(talk_base::DIGEST_SHA_1, digest, 281 digest_len); 282 ASSERT_TRUE(rv); 283 284 285 rv = client_identity_->certificate().ComputeDigest(talk_base::DIGEST_SHA_1, 286 digest, 20, &digest_len); 287 ASSERT_TRUE(rv); 288 if (!correct) { 289 LOG(LS_INFO) << "Setting bogus digest for client cert"; 290 digest[0]++; 291 } 292 rv = server_ssl_->SetPeerCertificateDigest(talk_base::DIGEST_SHA_1, digest, 293 digest_len); 294 ASSERT_TRUE(rv); 295 296 identities_set_ = true; 297 } 298 299 void TestHandshake(bool expect_success = true) { 300 server_ssl_->SetMode(dtls_ ? talk_base::SSL_MODE_DTLS : 301 talk_base::SSL_MODE_TLS); 302 client_ssl_->SetMode(dtls_ ? talk_base::SSL_MODE_DTLS : 303 talk_base::SSL_MODE_TLS); 304 305 if (!dtls_) { 306 // Make sure we simulate a reliable network for TLS. 307 // This is just a check to make sure that people don't write wrong 308 // tests. 309 ASSERT((mtu_ == 1460) && (loss_ == 0) && (lose_first_packet_ == 0)); 310 } 311 312 if (!identities_set_) 313 SetPeerIdentitiesByDigest(true); 314 315 // Start the handshake 316 int rv; 317 318 server_ssl_->SetServerRole(); 319 rv = server_ssl_->StartSSLWithPeer(); 320 ASSERT_EQ(0, rv); 321 322 rv = client_ssl_->StartSSLWithPeer(); 323 ASSERT_EQ(0, rv); 324 325 // Now run the handshake 326 if (expect_success) { 327 EXPECT_TRUE_WAIT((client_ssl_->GetState() == talk_base::SS_OPEN) 328 && (server_ssl_->GetState() == talk_base::SS_OPEN), 329 handshake_wait_); 330 } else { 331 EXPECT_TRUE_WAIT(client_ssl_->GetState() == talk_base::SS_CLOSED, 332 handshake_wait_); 333 } 334 } 335 336 talk_base::StreamResult DataWritten(SSLDummyStream *from, const void *data, 337 size_t data_len, size_t *written, 338 int *error) { 339 // Randomly drop loss_ percent of packets 340 if (talk_base::CreateRandomId() % 100 < static_cast<uint32>(loss_)) { 341 LOG(LS_INFO) << "Randomly dropping packet, size=" << data_len; 342 *written = data_len; 343 return talk_base::SR_SUCCESS; 344 } 345 if (dtls_ && (data_len > mtu_)) { 346 LOG(LS_INFO) << "Dropping packet > mtu, size=" << data_len; 347 *written = data_len; 348 return talk_base::SR_SUCCESS; 349 } 350 351 // Optionally damage application data (type 23). Note that we don't damage 352 // handshake packets and we damage the last byte to keep the header 353 // intact but break the MAC. 354 if (damage_ && (*static_cast<const unsigned char *>(data) == 23)) { 355 std::vector<char> buf(data_len); 356 357 LOG(LS_INFO) << "Damaging packet"; 358 359 memcpy(&buf[0], data, data_len); 360 buf[data_len - 1]++; 361 362 return from->WriteData(&buf[0], data_len, written, error); 363 } 364 365 return from->WriteData(data, data_len, written, error); 366 } 367 368 void SetDelay(int delay) { 369 delay_ = delay; 370 } 371 int GetDelay() { return delay_; } 372 373 void SetLoseFirstPacket(bool lose) { 374 lose_first_packet_ = lose; 375 } 376 bool GetLoseFirstPacket() { return lose_first_packet_; } 377 378 void SetLoss(int percent) { 379 loss_ = percent; 380 } 381 382 void SetDamage() { 383 damage_ = true; 384 } 385 386 void SetMtu(size_t mtu) { 387 mtu_ = mtu; 388 } 389 390 void SetHandshakeWait(int wait) { 391 handshake_wait_ = wait; 392 } 393 394 void SetDtlsSrtpCiphers(const std::vector<std::string> &ciphers, 395 bool client) { 396 if (client) 397 client_ssl_->SetDtlsSrtpCiphers(ciphers); 398 else 399 server_ssl_->SetDtlsSrtpCiphers(ciphers); 400 } 401 402 bool GetDtlsSrtpCipher(bool client, std::string *retval) { 403 if (client) 404 return client_ssl_->GetDtlsSrtpCipher(retval); 405 else 406 return server_ssl_->GetDtlsSrtpCipher(retval); 407 } 408 409 bool GetPeerCertificate(bool client, talk_base::SSLCertificate** cert) { 410 if (client) 411 return client_ssl_->GetPeerCertificate(cert); 412 else 413 return server_ssl_->GetPeerCertificate(cert); 414 } 415 416 bool ExportKeyingMaterial(const char *label, 417 const unsigned char *context, 418 size_t context_len, 419 bool use_context, 420 bool client, 421 unsigned char *result, 422 size_t result_len) { 423 if (client) 424 return client_ssl_->ExportKeyingMaterial(label, 425 context, context_len, 426 use_context, 427 result, result_len); 428 else 429 return server_ssl_->ExportKeyingMaterial(label, 430 context, context_len, 431 use_context, 432 result, result_len); 433 } 434 435 // To be implemented by subclasses. 436 virtual void WriteData() = 0; 437 virtual void ReadData(talk_base::StreamInterface *stream) = 0; 438 virtual void TestTransfer(int size) = 0; 439 440 protected: 441 talk_base::FifoBuffer client_buffer_; 442 talk_base::FifoBuffer server_buffer_; 443 SSLDummyStream *client_stream_; // freed by client_ssl_ destructor 444 SSLDummyStream *server_stream_; // freed by server_ssl_ destructor 445 talk_base::scoped_ptr<talk_base::SSLStreamAdapter> client_ssl_; 446 talk_base::scoped_ptr<talk_base::SSLStreamAdapter> server_ssl_; 447 talk_base::SSLIdentity *client_identity_; // freed by client_ssl_ destructor 448 talk_base::SSLIdentity *server_identity_; // freed by server_ssl_ destructor 449 int delay_; 450 size_t mtu_; 451 int loss_; 452 bool lose_first_packet_; 453 bool damage_; 454 bool dtls_; 455 int handshake_wait_; 456 bool identities_set_; 457 }; 458 459 class SSLStreamAdapterTestTLS : public SSLStreamAdapterTestBase { 460 public: 461 SSLStreamAdapterTestTLS() : 462 SSLStreamAdapterTestBase("", "", false) { 463 }; 464 465 // Test data transfer for TLS 466 virtual void TestTransfer(int size) { 467 LOG(LS_INFO) << "Starting transfer test with " << size << " bytes"; 468 // Create some dummy data to send. 469 size_t received; 470 471 send_stream_.ReserveSize(size); 472 for (int i = 0; i < size; ++i) { 473 char ch = static_cast<char>(i); 474 send_stream_.Write(&ch, 1, NULL, NULL); 475 } 476 send_stream_.Rewind(); 477 478 // Prepare the receive stream. 479 recv_stream_.ReserveSize(size); 480 481 // Start sending 482 WriteData(); 483 484 // Wait for the client to close 485 EXPECT_TRUE_WAIT(server_ssl_->GetState() == talk_base::SS_CLOSED, 10000); 486 487 // Now check the data 488 recv_stream_.GetSize(&received); 489 490 EXPECT_EQ(static_cast<size_t>(size), received); 491 EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(), 492 recv_stream_.GetBuffer(), size)); 493 } 494 495 void WriteData() { 496 size_t position, tosend, size; 497 talk_base::StreamResult rv; 498 size_t sent; 499 char block[kBlockSize]; 500 501 send_stream_.GetSize(&size); 502 if (!size) 503 return; 504 505 for (;;) { 506 send_stream_.GetPosition(&position); 507 if (send_stream_.Read(block, sizeof(block), &tosend, NULL) != 508 talk_base::SR_EOS) { 509 rv = client_ssl_->Write(block, tosend, &sent, 0); 510 511 if (rv == talk_base::SR_SUCCESS) { 512 send_stream_.SetPosition(position + sent); 513 LOG(LS_VERBOSE) << "Sent: " << position + sent; 514 } else if (rv == talk_base::SR_BLOCK) { 515 LOG(LS_VERBOSE) << "Blocked..."; 516 send_stream_.SetPosition(position); 517 break; 518 } else { 519 ADD_FAILURE(); 520 break; 521 } 522 } else { 523 // Now close 524 LOG(LS_INFO) << "Wrote " << position << " bytes. Closing"; 525 client_ssl_->Close(); 526 break; 527 } 528 } 529 }; 530 531 virtual void ReadData(talk_base::StreamInterface *stream) { 532 char buffer[1600]; 533 size_t bread; 534 int err2; 535 talk_base::StreamResult r; 536 537 for (;;) { 538 r = stream->Read(buffer, sizeof(buffer), &bread, &err2); 539 540 if (r == talk_base::SR_ERROR || r == talk_base::SR_EOS) { 541 // Unfortunately, errors are the way that the stream adapter 542 // signals close in OpenSSL 543 stream->Close(); 544 return; 545 } 546 547 if (r == talk_base::SR_BLOCK) 548 break; 549 550 ASSERT_EQ(talk_base::SR_SUCCESS, r); 551 LOG(LS_INFO) << "Read " << bread; 552 553 recv_stream_.Write(buffer, bread, NULL, NULL); 554 } 555 } 556 557 private: 558 talk_base::MemoryStream send_stream_; 559 talk_base::MemoryStream recv_stream_; 560 }; 561 562 class SSLStreamAdapterTestDTLS : public SSLStreamAdapterTestBase { 563 public: 564 SSLStreamAdapterTestDTLS() : 565 SSLStreamAdapterTestBase("", "", true), 566 packet_size_(1000), count_(0), sent_(0) { 567 } 568 569 SSLStreamAdapterTestDTLS(const std::string& cert_pem, 570 const std::string& private_key_pem) : 571 SSLStreamAdapterTestBase(cert_pem, private_key_pem, true), 572 packet_size_(1000), count_(0), sent_(0) { 573 } 574 575 virtual void WriteData() { 576 unsigned char *packet = new unsigned char[1600]; 577 578 do { 579 memset(packet, sent_ & 0xff, packet_size_); 580 *(reinterpret_cast<uint32_t *>(packet)) = sent_; 581 582 size_t sent; 583 int rv = client_ssl_->Write(packet, packet_size_, &sent, 0); 584 if (rv == talk_base::SR_SUCCESS) { 585 LOG(LS_VERBOSE) << "Sent: " << sent_; 586 sent_++; 587 } else if (rv == talk_base::SR_BLOCK) { 588 LOG(LS_VERBOSE) << "Blocked..."; 589 break; 590 } else { 591 ADD_FAILURE(); 592 break; 593 } 594 } while (sent_ < count_); 595 596 delete [] packet; 597 } 598 599 virtual void ReadData(talk_base::StreamInterface *stream) { 600 unsigned char buffer[2000]; 601 size_t bread; 602 int err2; 603 talk_base::StreamResult r; 604 605 for (;;) { 606 r = stream->Read(buffer, 2000, &bread, &err2); 607 608 if (r == talk_base::SR_ERROR) { 609 // Unfortunately, errors are the way that the stream adapter 610 // signals close right now 611 stream->Close(); 612 return; 613 } 614 615 if (r == talk_base::SR_BLOCK) 616 break; 617 618 ASSERT_EQ(talk_base::SR_SUCCESS, r); 619 LOG(LS_INFO) << "Read " << bread; 620 621 // Now parse the datagram 622 ASSERT_EQ(packet_size_, bread); 623 unsigned char* ptr_to_buffer = buffer; 624 uint32_t packet_num = *(reinterpret_cast<uint32_t *>(ptr_to_buffer)); 625 626 for (size_t i = 4; i < packet_size_; i++) { 627 ASSERT_EQ((packet_num & 0xff), buffer[i]); 628 } 629 received_.insert(packet_num); 630 } 631 } 632 633 virtual void TestTransfer(int count) { 634 count_ = count; 635 636 WriteData(); 637 638 EXPECT_TRUE_WAIT(sent_ == count_, 10000); 639 LOG(LS_INFO) << "sent_ == " << sent_; 640 641 if (damage_) { 642 WAIT(false, 2000); 643 EXPECT_EQ(0U, received_.size()); 644 } else if (loss_ == 0) { 645 EXPECT_EQ_WAIT(static_cast<size_t>(sent_), received_.size(), 1000); 646 } else { 647 LOG(LS_INFO) << "Sent " << sent_ << " packets; received " << 648 received_.size(); 649 } 650 }; 651 652 private: 653 size_t packet_size_; 654 int count_; 655 int sent_; 656 std::set<int> received_; 657 }; 658 659 660 talk_base::StreamResult SSLDummyStream::Write(const void* data, size_t data_len, 661 size_t* written, int* error) { 662 *written = data_len; 663 664 LOG(LS_INFO) << "Writing to loopback " << data_len; 665 666 if (first_packet_) { 667 first_packet_ = false; 668 if (test_->GetLoseFirstPacket()) { 669 LOG(LS_INFO) << "Losing initial packet of length " << data_len; 670 return talk_base::SR_SUCCESS; 671 } 672 } 673 674 return test_->DataWritten(this, data, data_len, written, error); 675 676 return talk_base::SR_SUCCESS; 677 }; 678 679 class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS { 680 public: 681 SSLStreamAdapterTestDTLSFromPEMStrings() : 682 SSLStreamAdapterTestDTLS(kCERT_PEM, kRSA_PRIVATE_KEY_PEM) { 683 } 684 }; 685 686 // Basic tests: TLS 687 688 // Test that we cannot read/write if we have not yet handshaked. 689 // This test only applies to NSS because OpenSSL has passthrough 690 // semantics for I/O before the handshake is started. 691 #if SSL_USE_NSS 692 TEST_F(SSLStreamAdapterTestTLS, TestNoReadWriteBeforeConnect) { 693 talk_base::StreamResult rv; 694 char block[kBlockSize]; 695 size_t dummy; 696 697 rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL); 698 ASSERT_EQ(talk_base::SR_BLOCK, rv); 699 700 rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL); 701 ASSERT_EQ(talk_base::SR_BLOCK, rv); 702 } 703 #endif 704 705 706 // Test that we can make a handshake work 707 TEST_F(SSLStreamAdapterTestTLS, TestTLSConnect) { 708 TestHandshake(); 709 }; 710 711 // Test transfer -- trivial 712 TEST_F(SSLStreamAdapterTestTLS, TestTLSTransfer) { 713 TestHandshake(); 714 TestTransfer(100000); 715 }; 716 717 // Test read-write after close. 718 TEST_F(SSLStreamAdapterTestTLS, ReadWriteAfterClose) { 719 TestHandshake(); 720 TestTransfer(100000); 721 client_ssl_->Close(); 722 723 talk_base::StreamResult rv; 724 char block[kBlockSize]; 725 size_t dummy; 726 727 // It's an error to write after closed. 728 rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL); 729 ASSERT_EQ(talk_base::SR_ERROR, rv); 730 731 // But after closed read gives you EOS. 732 rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL); 733 ASSERT_EQ(talk_base::SR_EOS, rv); 734 }; 735 736 // Test a handshake with a bogus peer digest 737 TEST_F(SSLStreamAdapterTestTLS, TestTLSBogusDigest) { 738 SetPeerIdentitiesByDigest(false); 739 TestHandshake(false); 740 }; 741 742 // Test moving a bunch of data 743 744 // Basic tests: DTLS 745 // Test that we can make a handshake work 746 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSConnect) { 747 MAYBE_SKIP_TEST(HaveDtls); 748 TestHandshake(); 749 }; 750 751 // Test that we can make a handshake work if the first packet in 752 // each direction is lost. This gives us predictable loss 753 // rather than having to tune random 754 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacket) { 755 MAYBE_SKIP_TEST(HaveDtls); 756 SetLoseFirstPacket(true); 757 TestHandshake(); 758 }; 759 760 // Test a handshake with loss and delay 761 TEST_F(SSLStreamAdapterTestDTLS, 762 TestDTLSConnectWithLostFirstPacketDelay2s) { 763 MAYBE_SKIP_TEST(HaveDtls); 764 SetLoseFirstPacket(true); 765 SetDelay(2000); 766 SetHandshakeWait(20000); 767 TestHandshake(); 768 }; 769 770 // Test a handshake with small MTU 771 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSConnectWithSmallMtu) { 772 MAYBE_SKIP_TEST(HaveDtls); 773 SetMtu(700); 774 SetHandshakeWait(20000); 775 TestHandshake(); 776 }; 777 778 // Test transfer -- trivial 779 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSTransfer) { 780 MAYBE_SKIP_TEST(HaveDtls); 781 TestHandshake(); 782 TestTransfer(100); 783 }; 784 785 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSTransferWithLoss) { 786 MAYBE_SKIP_TEST(HaveDtls); 787 TestHandshake(); 788 SetLoss(10); 789 TestTransfer(100); 790 }; 791 792 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) { 793 MAYBE_SKIP_TEST(HaveDtls); 794 SetDamage(); // Must be called first because first packet 795 // write happens at end of handshake. 796 TestHandshake(); 797 TestTransfer(100); 798 }; 799 800 // Test DTLS-SRTP with all high ciphers 801 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) { 802 MAYBE_SKIP_TEST(HaveDtlsSrtp); 803 std::vector<std::string> high; 804 high.push_back(kAES_CM_HMAC_SHA1_80); 805 SetDtlsSrtpCiphers(high, true); 806 SetDtlsSrtpCiphers(high, false); 807 TestHandshake(); 808 809 std::string client_cipher; 810 ASSERT_TRUE(GetDtlsSrtpCipher(true, &client_cipher)); 811 std::string server_cipher; 812 ASSERT_TRUE(GetDtlsSrtpCipher(false, &server_cipher)); 813 814 ASSERT_EQ(client_cipher, server_cipher); 815 ASSERT_EQ(client_cipher, kAES_CM_HMAC_SHA1_80); 816 }; 817 818 // Test DTLS-SRTP with all low ciphers 819 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSSrtpLow) { 820 MAYBE_SKIP_TEST(HaveDtlsSrtp); 821 std::vector<std::string> low; 822 low.push_back(kAES_CM_HMAC_SHA1_32); 823 SetDtlsSrtpCiphers(low, true); 824 SetDtlsSrtpCiphers(low, false); 825 TestHandshake(); 826 827 std::string client_cipher; 828 ASSERT_TRUE(GetDtlsSrtpCipher(true, &client_cipher)); 829 std::string server_cipher; 830 ASSERT_TRUE(GetDtlsSrtpCipher(false, &server_cipher)); 831 832 ASSERT_EQ(client_cipher, server_cipher); 833 ASSERT_EQ(client_cipher, kAES_CM_HMAC_SHA1_32); 834 }; 835 836 837 // Test DTLS-SRTP with a mismatch -- should not converge 838 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSSrtpHighLow) { 839 MAYBE_SKIP_TEST(HaveDtlsSrtp); 840 std::vector<std::string> high; 841 high.push_back(kAES_CM_HMAC_SHA1_80); 842 std::vector<std::string> low; 843 low.push_back(kAES_CM_HMAC_SHA1_32); 844 SetDtlsSrtpCiphers(high, true); 845 SetDtlsSrtpCiphers(low, false); 846 TestHandshake(); 847 848 std::string client_cipher; 849 ASSERT_FALSE(GetDtlsSrtpCipher(true, &client_cipher)); 850 std::string server_cipher; 851 ASSERT_FALSE(GetDtlsSrtpCipher(false, &server_cipher)); 852 }; 853 854 // Test DTLS-SRTP with each side being mixed -- should select high 855 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSSrtpMixed) { 856 MAYBE_SKIP_TEST(HaveDtlsSrtp); 857 std::vector<std::string> mixed; 858 mixed.push_back(kAES_CM_HMAC_SHA1_80); 859 mixed.push_back(kAES_CM_HMAC_SHA1_32); 860 SetDtlsSrtpCiphers(mixed, true); 861 SetDtlsSrtpCiphers(mixed, false); 862 TestHandshake(); 863 864 std::string client_cipher; 865 ASSERT_TRUE(GetDtlsSrtpCipher(true, &client_cipher)); 866 std::string server_cipher; 867 ASSERT_TRUE(GetDtlsSrtpCipher(false, &server_cipher)); 868 869 ASSERT_EQ(client_cipher, server_cipher); 870 ASSERT_EQ(client_cipher, kAES_CM_HMAC_SHA1_80); 871 }; 872 873 // Test an exporter 874 TEST_F(SSLStreamAdapterTestDTLS, TestDTLSExporter) { 875 MAYBE_SKIP_TEST(HaveExporter); 876 TestHandshake(); 877 unsigned char client_out[20]; 878 unsigned char server_out[20]; 879 880 bool result; 881 result = ExportKeyingMaterial(kExporterLabel, 882 kExporterContext, kExporterContextLen, 883 true, true, 884 client_out, sizeof(client_out)); 885 ASSERT_TRUE(result); 886 887 result = ExportKeyingMaterial(kExporterLabel, 888 kExporterContext, kExporterContextLen, 889 true, false, 890 server_out, sizeof(server_out)); 891 ASSERT_TRUE(result); 892 893 ASSERT_TRUE(!memcmp(client_out, server_out, sizeof(client_out))); 894 } 895 896 // Test not yet valid certificates are not rejected. 897 TEST_F(SSLStreamAdapterTestDTLS, TestCertNotYetValid) { 898 MAYBE_SKIP_TEST(HaveDtls); 899 long one_day = 60 * 60 * 24; 900 // Make the certificates not valid until one day later. 901 ResetIdentitiesWithValidity(one_day, one_day); 902 TestHandshake(); 903 } 904 905 // Test expired certificates are not rejected. 906 TEST_F(SSLStreamAdapterTestDTLS, TestCertExpired) { 907 MAYBE_SKIP_TEST(HaveDtls); 908 long one_day = 60 * 60 * 24; 909 // Make the certificates already expired. 910 ResetIdentitiesWithValidity(-one_day, -one_day); 911 TestHandshake(); 912 } 913 914 // Test data transfer using certs created from strings. 915 TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestTransfer) { 916 MAYBE_SKIP_TEST(HaveDtls); 917 TestHandshake(); 918 TestTransfer(100); 919 } 920 921 // Test getting the remote certificate. 922 TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) { 923 MAYBE_SKIP_TEST(HaveDtls); 924 925 // Peer certificates haven't been received yet. 926 talk_base::scoped_ptr<talk_base::SSLCertificate> client_peer_cert; 927 ASSERT_FALSE(GetPeerCertificate(true, client_peer_cert.accept())); 928 ASSERT_FALSE(client_peer_cert != NULL); 929 930 talk_base::scoped_ptr<talk_base::SSLCertificate> server_peer_cert; 931 ASSERT_FALSE(GetPeerCertificate(false, server_peer_cert.accept())); 932 ASSERT_FALSE(server_peer_cert != NULL); 933 934 TestHandshake(); 935 936 // The client should have a peer certificate after the handshake. 937 ASSERT_TRUE(GetPeerCertificate(true, client_peer_cert.accept())); 938 ASSERT_TRUE(client_peer_cert != NULL); 939 940 // It's not kCERT_PEM. 941 std::string client_peer_string = client_peer_cert->ToPEMString(); 942 ASSERT_NE(kCERT_PEM, client_peer_string); 943 944 // It must not have a chain, because the test certs are self-signed. 945 talk_base::SSLCertChain* client_peer_chain; 946 ASSERT_FALSE(client_peer_cert->GetChain(&client_peer_chain)); 947 948 // The server should have a peer certificate after the handshake. 949 ASSERT_TRUE(GetPeerCertificate(false, server_peer_cert.accept())); 950 ASSERT_TRUE(server_peer_cert != NULL); 951 952 // It's kCERT_PEM 953 ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString()); 954 955 // It must not have a chain, because the test certs are self-signed. 956 talk_base::SSLCertChain* server_peer_chain; 957 ASSERT_FALSE(server_peer_cert->GetChain(&server_peer_chain)); 958 } 959