Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / dtlstransportchannel_unittest.cc
1 /*
2  * libjingle
3  * Copyright 2011, Google Inc.
4  * 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 #include <set>
30
31 #include "talk/base/common.h"
32 #include "talk/base/dscp.h"
33 #include "talk/base/gunit.h"
34 #include "talk/base/helpers.h"
35 #include "talk/base/scoped_ptr.h"
36 #include "talk/base/stringutils.h"
37 #include "talk/base/thread.h"
38 #include "talk/p2p/base/fakesession.h"
39 #include "talk/base/ssladapter.h"
40 #include "talk/base/sslidentity.h"
41 #include "talk/base/sslstreamadapter.h"
42 #include "talk/p2p/base/dtlstransport.h"
43
44 #define MAYBE_SKIP_TEST(feature)                    \
45   if (!(talk_base::SSLStreamAdapter::feature())) {  \
46     LOG(LS_INFO) << "Feature disabled... skipping"; \
47     return;                                         \
48   }
49
50 static const char AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80";
51 static const char kIceUfrag1[] = "TESTICEUFRAG0001";
52 static const char kIcePwd1[] = "TESTICEPWD00000000000001";
53 static const size_t kPacketNumOffset = 8;
54 static const size_t kPacketHeaderLen = 12;
55
56 static bool IsRtpLeadByte(uint8 b) {
57   return ((b & 0xC0) == 0x80);
58 }
59
60 using cricket::ConnectionRole;
61
62 enum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 };
63
64 class DtlsTestClient : public sigslot::has_slots<> {
65  public:
66   DtlsTestClient(const std::string& name,
67                  talk_base::Thread* signaling_thread,
68                  talk_base::Thread* worker_thread) :
69       name_(name),
70       signaling_thread_(signaling_thread),
71       worker_thread_(worker_thread),
72       protocol_(cricket::ICEPROTO_GOOGLE),
73       packet_size_(0),
74       use_dtls_srtp_(false),
75       negotiated_dtls_(false),
76       received_dtls_client_hello_(false),
77       received_dtls_server_hello_(false) {
78   }
79   void SetIceProtocol(cricket::TransportProtocol proto) {
80     protocol_ = proto;
81   }
82   void CreateIdentity() {
83     identity_.reset(talk_base::SSLIdentity::Generate(name_));
84   }
85   talk_base::SSLIdentity* identity() { return identity_.get(); }
86   void SetupSrtp() {
87     ASSERT(identity_.get() != NULL);
88     use_dtls_srtp_ = true;
89   }
90   void SetupChannels(int count, cricket::IceRole role) {
91     transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>(
92         signaling_thread_, worker_thread_, "dtls content name", NULL,
93         identity_.get()));
94     transport_->SetAsync(true);
95     transport_->SetIceRole(role);
96     transport_->SetIceTiebreaker(
97         (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2);
98     transport_->SignalWritableState.connect(this,
99         &DtlsTestClient::OnTransportWritableState);
100
101     for (int i = 0; i < count; ++i) {
102       cricket::DtlsTransportChannelWrapper* channel =
103           static_cast<cricket::DtlsTransportChannelWrapper*>(
104               transport_->CreateChannel(i));
105       ASSERT_TRUE(channel != NULL);
106       channel->SignalWritableState.connect(this,
107         &DtlsTestClient::OnTransportChannelWritableState);
108       channel->SignalReadPacket.connect(this,
109         &DtlsTestClient::OnTransportChannelReadPacket);
110       channels_.push_back(channel);
111
112       // Hook the raw packets so that we can verify they are encrypted.
113       channel->channel()->SignalReadPacket.connect(
114           this, &DtlsTestClient::OnFakeTransportChannelReadPacket);
115     }
116   }
117
118   cricket::Transport* transport() { return transport_.get(); }
119
120   cricket::FakeTransportChannel* GetFakeChannel(int component) {
121     cricket::TransportChannelImpl* ch = transport_->GetChannel(component);
122     cricket::DtlsTransportChannelWrapper* wrapper =
123         static_cast<cricket::DtlsTransportChannelWrapper*>(ch);
124     return (wrapper) ?
125         static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL;
126   }
127
128   // Offer DTLS if we have an identity; pass in a remote fingerprint only if
129   // both sides support DTLS.
130   void Negotiate(DtlsTestClient* peer, cricket::ContentAction action,
131                  ConnectionRole local_role, ConnectionRole remote_role,
132                  int flags) {
133     Negotiate(identity_.get(), (identity_) ? peer->identity_.get() : NULL,
134               action, local_role, remote_role, flags);
135   }
136
137   // Allow any DTLS configuration to be specified (including invalid ones).
138   void Negotiate(talk_base::SSLIdentity* local_identity,
139                  talk_base::SSLIdentity* remote_identity,
140                  cricket::ContentAction action,
141                  ConnectionRole local_role,
142                  ConnectionRole remote_role,
143                  int flags) {
144     talk_base::scoped_ptr<talk_base::SSLFingerprint> local_fingerprint;
145     talk_base::scoped_ptr<talk_base::SSLFingerprint> remote_fingerprint;
146     if (local_identity) {
147       local_fingerprint.reset(talk_base::SSLFingerprint::Create(
148           talk_base::DIGEST_SHA_1, local_identity));
149       ASSERT_TRUE(local_fingerprint.get() != NULL);
150     }
151     if (remote_identity) {
152       remote_fingerprint.reset(talk_base::SSLFingerprint::Create(
153           talk_base::DIGEST_SHA_1, remote_identity));
154       ASSERT_TRUE(remote_fingerprint.get() != NULL);
155     }
156
157     if (use_dtls_srtp_ && !(flags & NF_REOFFER)) {
158       // SRTP ciphers will be set only in the beginning.
159       for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
160            channels_.begin(); it != channels_.end(); ++it) {
161         std::vector<std::string> ciphers;
162         ciphers.push_back(AES_CM_128_HMAC_SHA1_80);
163         ASSERT_TRUE((*it)->SetSrtpCiphers(ciphers));
164       }
165     }
166
167     std::string transport_type = (protocol_ == cricket::ICEPROTO_GOOGLE) ?
168         cricket::NS_GINGLE_P2P : cricket::NS_JINGLE_ICE_UDP;
169     cricket::TransportDescription local_desc(
170         transport_type, std::vector<std::string>(), kIceUfrag1, kIcePwd1,
171         cricket::ICEMODE_FULL, local_role,
172          // If remote if the offerer and has no DTLS support, answer will be
173         // without any fingerprint.
174         (action == cricket::CA_ANSWER && !remote_identity) ?
175             NULL : local_fingerprint.get(),
176         cricket::Candidates());
177
178     cricket::TransportDescription remote_desc(
179         transport_type, std::vector<std::string>(), kIceUfrag1, kIcePwd1,
180         cricket::ICEMODE_FULL, remote_role, remote_fingerprint.get(),
181         cricket::Candidates());
182
183     bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true;
184     // If |expect_success| is false, expect SRTD or SLTD to fail when
185     // content action is CA_ANSWER.
186     if (action == cricket::CA_OFFER) {
187       ASSERT_TRUE(transport_->SetLocalTransportDescription(
188           local_desc, cricket::CA_OFFER, NULL));
189       ASSERT_EQ(expect_success, transport_->SetRemoteTransportDescription(
190           remote_desc, cricket::CA_ANSWER, NULL));
191     } else {
192       ASSERT_TRUE(transport_->SetRemoteTransportDescription(
193           remote_desc, cricket::CA_OFFER, NULL));
194       ASSERT_EQ(expect_success, transport_->SetLocalTransportDescription(
195           local_desc, cricket::CA_ANSWER, NULL));
196     }
197     negotiated_dtls_ = (local_identity && remote_identity);
198   }
199
200   bool Connect(DtlsTestClient* peer) {
201     transport_->ConnectChannels();
202     transport_->SetDestination(peer->transport_.get());
203     return true;
204   }
205
206   bool writable() const { return transport_->writable(); }
207
208   void CheckRole(talk_base::SSLRole role) {
209     if (role == talk_base::SSL_CLIENT) {
210       ASSERT_FALSE(received_dtls_client_hello_);
211       ASSERT_TRUE(received_dtls_server_hello_);
212     } else {
213       ASSERT_TRUE(received_dtls_client_hello_);
214       ASSERT_FALSE(received_dtls_server_hello_);
215     }
216   }
217
218   void CheckSrtp(const std::string& expected_cipher) {
219     for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
220            channels_.begin(); it != channels_.end(); ++it) {
221       std::string cipher;
222
223       bool rv = (*it)->GetSrtpCipher(&cipher);
224       if (negotiated_dtls_ && !expected_cipher.empty()) {
225         ASSERT_TRUE(rv);
226
227         ASSERT_EQ(cipher, expected_cipher);
228       } else {
229         ASSERT_FALSE(rv);
230       }
231     }
232   }
233
234   void SendPackets(size_t channel, size_t size, size_t count, bool srtp) {
235     ASSERT(channel < channels_.size());
236     talk_base::scoped_ptr<char[]> packet(new char[size]);
237     size_t sent = 0;
238     do {
239       // Fill the packet with a known value and a sequence number to check
240       // against, and make sure that it doesn't look like DTLS.
241       memset(packet.get(), sent & 0xff, size);
242       packet[0] = (srtp) ? 0x80 : 0x00;
243       talk_base::SetBE32(packet.get() + kPacketNumOffset,
244                          static_cast<uint32>(sent));
245
246       // Only set the bypass flag if we've activated DTLS.
247       int flags = (identity_.get() && srtp) ? cricket::PF_SRTP_BYPASS : 0;
248       talk_base::PacketOptions packet_options;
249       int rv = channels_[channel]->SendPacket(
250           packet.get(), size, packet_options, flags);
251       ASSERT_GT(rv, 0);
252       ASSERT_EQ(size, static_cast<size_t>(rv));
253       ++sent;
254     } while (sent < count);
255   }
256
257   int SendInvalidSrtpPacket(size_t channel, size_t size) {
258     ASSERT(channel < channels_.size());
259     talk_base::scoped_ptr<char[]> packet(new char[size]);
260     // Fill the packet with 0 to form an invalid SRTP packet.
261     memset(packet.get(), 0, size);
262
263     talk_base::PacketOptions packet_options;
264     return channels_[channel]->SendPacket(
265         packet.get(), size, packet_options, cricket::PF_SRTP_BYPASS);
266   }
267
268   void ExpectPackets(size_t channel, size_t size) {
269     packet_size_ = size;
270     received_.clear();
271   }
272
273   size_t NumPacketsReceived() {
274     return received_.size();
275   }
276
277   bool VerifyPacket(const char* data, size_t size, uint32* out_num) {
278     if (size != packet_size_ ||
279         (data[0] != 0 && static_cast<uint8>(data[0]) != 0x80)) {
280       return false;
281     }
282     uint32 packet_num = talk_base::GetBE32(data + kPacketNumOffset);
283     for (size_t i = kPacketHeaderLen; i < size; ++i) {
284       if (static_cast<uint8>(data[i]) != (packet_num & 0xff)) {
285         return false;
286       }
287     }
288     if (out_num) {
289       *out_num = packet_num;
290     }
291     return true;
292   }
293   bool VerifyEncryptedPacket(const char* data, size_t size) {
294     // This is an encrypted data packet; let's make sure it's mostly random;
295     // less than 10% of the bytes should be equal to the cleartext packet.
296     if (size <= packet_size_) {
297       return false;
298     }
299     uint32 packet_num = talk_base::GetBE32(data + kPacketNumOffset);
300     int num_matches = 0;
301     for (size_t i = kPacketNumOffset; i < size; ++i) {
302       if (static_cast<uint8>(data[i]) == (packet_num & 0xff)) {
303         ++num_matches;
304       }
305     }
306     return (num_matches < ((static_cast<int>(size) - 5) / 10));
307   }
308
309   // Transport callbacks
310   void OnTransportWritableState(cricket::Transport* transport) {
311     LOG(LS_INFO) << name_ << ": is writable";
312   }
313
314   // Transport channel callbacks
315   void OnTransportChannelWritableState(cricket::TransportChannel* channel) {
316     LOG(LS_INFO) << name_ << ": Channel '" << channel->component()
317                  << "' is writable";
318   }
319
320   void OnTransportChannelReadPacket(cricket::TransportChannel* channel,
321                                     const char* data, size_t size,
322                                     const talk_base::PacketTime& packet_time,
323                                     int flags) {
324     uint32 packet_num = 0;
325     ASSERT_TRUE(VerifyPacket(data, size, &packet_num));
326     received_.insert(packet_num);
327     // Only DTLS-SRTP packets should have the bypass flag set.
328     int expected_flags = (identity_.get() && IsRtpLeadByte(data[0])) ?
329         cricket::PF_SRTP_BYPASS : 0;
330     ASSERT_EQ(expected_flags, flags);
331   }
332
333   // Hook into the raw packet stream to make sure DTLS packets are encrypted.
334   void OnFakeTransportChannelReadPacket(cricket::TransportChannel* channel,
335                                         const char* data, size_t size,
336                                         const talk_base::PacketTime& time,
337                                         int flags) {
338     // Flags shouldn't be set on the underlying TransportChannel packets.
339     ASSERT_EQ(0, flags);
340
341     // Look at the handshake packets to see what role we played.
342     // Check that non-handshake packets are DTLS data or SRTP bypass.
343     if (negotiated_dtls_) {
344       if (data[0] == 22 && size > 17) {
345         if (data[13] == 1) {
346           received_dtls_client_hello_ = true;
347         } else if (data[13] == 2) {
348           received_dtls_server_hello_ = true;
349         }
350       } else if (!(data[0] >= 20 && data[0] <= 22)) {
351         ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0]));
352         if (data[0] == 23) {
353           ASSERT_TRUE(VerifyEncryptedPacket(data, size));
354         } else if (IsRtpLeadByte(data[0])) {
355           ASSERT_TRUE(VerifyPacket(data, size, NULL));
356         }
357       }
358     }
359   }
360
361  private:
362   std::string name_;
363   talk_base::Thread* signaling_thread_;
364   talk_base::Thread* worker_thread_;
365   cricket::TransportProtocol protocol_;
366   talk_base::scoped_ptr<talk_base::SSLIdentity> identity_;
367   talk_base::scoped_ptr<cricket::FakeTransport> transport_;
368   std::vector<cricket::DtlsTransportChannelWrapper*> channels_;
369   size_t packet_size_;
370   std::set<int> received_;
371   bool use_dtls_srtp_;
372   bool negotiated_dtls_;
373   bool received_dtls_client_hello_;
374   bool received_dtls_server_hello_;
375 };
376
377
378 class DtlsTransportChannelTest : public testing::Test {
379  public:
380   static void SetUpTestCase() {
381     talk_base::InitializeSSL();
382   }
383
384   static void TearDownTestCase() {
385     talk_base::CleanupSSL();
386   }
387
388   DtlsTransportChannelTest() :
389       client1_("P1", talk_base::Thread::Current(),
390                talk_base::Thread::Current()),
391       client2_("P2", talk_base::Thread::Current(),
392                talk_base::Thread::Current()),
393       channel_ct_(1),
394       use_dtls_(false),
395       use_dtls_srtp_(false) {
396   }
397
398   void SetChannelCount(size_t channel_ct) {
399     channel_ct_ = static_cast<int>(channel_ct);
400   }
401   void PrepareDtls(bool c1, bool c2) {
402     if (c1) {
403       client1_.CreateIdentity();
404     }
405     if (c2) {
406       client2_.CreateIdentity();
407     }
408     if (c1 && c2)
409       use_dtls_ = true;
410   }
411   void PrepareDtlsSrtp(bool c1, bool c2) {
412     if (!use_dtls_)
413       return;
414
415     if (c1)
416       client1_.SetupSrtp();
417     if (c2)
418       client2_.SetupSrtp();
419
420     if (c1 && c2)
421       use_dtls_srtp_ = true;
422   }
423
424   bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) {
425     Negotiate(client1_role, client2_role);
426
427     bool rv = client1_.Connect(&client2_);
428     EXPECT_TRUE(rv);
429     if (!rv)
430       return false;
431
432     EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000);
433     if (!client1_.writable() || !client2_.writable())
434       return false;
435
436     // Check that we used the right roles.
437     if (use_dtls_) {
438       talk_base::SSLRole client1_ssl_role =
439           (client1_role == cricket::CONNECTIONROLE_ACTIVE ||
440            (client2_role == cricket::CONNECTIONROLE_PASSIVE &&
441             client1_role == cricket::CONNECTIONROLE_ACTPASS)) ?
442               talk_base::SSL_CLIENT : talk_base::SSL_SERVER;
443
444       talk_base::SSLRole client2_ssl_role =
445           (client2_role == cricket::CONNECTIONROLE_ACTIVE ||
446            (client1_role == cricket::CONNECTIONROLE_PASSIVE &&
447             client2_role == cricket::CONNECTIONROLE_ACTPASS)) ?
448               talk_base::SSL_CLIENT : talk_base::SSL_SERVER;
449
450       client1_.CheckRole(client1_ssl_role);
451       client2_.CheckRole(client2_ssl_role);
452     }
453
454     // Check that we negotiated the right ciphers.
455     if (use_dtls_srtp_) {
456       client1_.CheckSrtp(AES_CM_128_HMAC_SHA1_80);
457       client2_.CheckSrtp(AES_CM_128_HMAC_SHA1_80);
458     } else {
459       client1_.CheckSrtp("");
460       client2_.CheckSrtp("");
461     }
462
463     return true;
464   }
465
466   bool Connect() {
467     // By default, Client1 will be Server and Client2 will be Client.
468     return Connect(cricket::CONNECTIONROLE_ACTPASS,
469                    cricket::CONNECTIONROLE_ACTIVE);
470   }
471
472   void Negotiate() {
473     Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE);
474   }
475
476   void Negotiate(ConnectionRole client1_role, ConnectionRole client2_role) {
477     client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING);
478     client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED);
479     // Expect success from SLTD and SRTD.
480     client1_.Negotiate(&client2_, cricket::CA_OFFER,
481                        client1_role, client2_role, 0);
482     client2_.Negotiate(&client1_, cricket::CA_ANSWER,
483                        client2_role, client1_role, 0);
484   }
485
486   // Negotiate with legacy client |client2|. Legacy client doesn't use setup
487   // attributes, except NONE.
488   void NegotiateWithLegacy() {
489     client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING);
490     client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED);
491     // Expect success from SLTD and SRTD.
492     client1_.Negotiate(&client2_, cricket::CA_OFFER,
493                        cricket::CONNECTIONROLE_ACTPASS,
494                        cricket::CONNECTIONROLE_NONE, 0);
495     client2_.Negotiate(&client1_, cricket::CA_ANSWER,
496                        cricket::CONNECTIONROLE_ACTIVE,
497                        cricket::CONNECTIONROLE_NONE, 0);
498   }
499
500   void Renegotiate(DtlsTestClient* reoffer_initiator,
501                    ConnectionRole client1_role, ConnectionRole client2_role,
502                    int flags) {
503     if (reoffer_initiator == &client1_) {
504       client1_.Negotiate(&client2_, cricket::CA_OFFER,
505                          client1_role, client2_role, flags);
506       client2_.Negotiate(&client1_, cricket::CA_ANSWER,
507                          client2_role, client1_role, flags);
508     } else {
509       client2_.Negotiate(&client1_, cricket::CA_OFFER,
510                          client2_role, client1_role, flags);
511       client1_.Negotiate(&client2_, cricket::CA_ANSWER,
512                          client1_role, client2_role, flags);
513     }
514   }
515
516   void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) {
517     LOG(LS_INFO) << "Expect packets, size=" << size;
518     client2_.ExpectPackets(channel, size);
519     client1_.SendPackets(channel, size, count, srtp);
520     EXPECT_EQ_WAIT(count, client2_.NumPacketsReceived(), 10000);
521   }
522
523  protected:
524   DtlsTestClient client1_;
525   DtlsTestClient client2_;
526   int channel_ct_;
527   bool use_dtls_;
528   bool use_dtls_srtp_;
529 };
530
531 // Test that transport negotiation of ICE, no DTLS works properly.
532 TEST_F(DtlsTransportChannelTest, TestChannelSetupIce) {
533   client1_.SetIceProtocol(cricket::ICEPROTO_RFC5245);
534   client2_.SetIceProtocol(cricket::ICEPROTO_RFC5245);
535   Negotiate();
536   cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0);
537   cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0);
538   ASSERT_TRUE(channel1 != NULL);
539   ASSERT_TRUE(channel2 != NULL);
540   EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
541   EXPECT_EQ(1U, channel1->IceTiebreaker());
542   EXPECT_EQ(cricket::ICEPROTO_RFC5245, channel1->protocol());
543   EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag());
544   EXPECT_EQ(kIcePwd1, channel1->ice_pwd());
545   EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
546   EXPECT_EQ(2U, channel2->IceTiebreaker());
547   EXPECT_EQ(cricket::ICEPROTO_RFC5245, channel2->protocol());
548 }
549
550 // Test that transport negotiation of GICE, no DTLS works properly.
551 TEST_F(DtlsTransportChannelTest, TestChannelSetupGice) {
552   client1_.SetIceProtocol(cricket::ICEPROTO_GOOGLE);
553   client2_.SetIceProtocol(cricket::ICEPROTO_GOOGLE);
554   Negotiate();
555   cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0);
556   cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0);
557   ASSERT_TRUE(channel1 != NULL);
558   ASSERT_TRUE(channel2 != NULL);
559   EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
560   EXPECT_EQ(1U, channel1->IceTiebreaker());
561   EXPECT_EQ(cricket::ICEPROTO_GOOGLE, channel1->protocol());
562   EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag());
563   EXPECT_EQ(kIcePwd1, channel1->ice_pwd());
564   EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
565   EXPECT_EQ(2U, channel2->IceTiebreaker());
566   EXPECT_EQ(cricket::ICEPROTO_GOOGLE, channel2->protocol());
567 }
568
569 // Connect without DTLS, and transfer some data.
570 TEST_F(DtlsTransportChannelTest, TestTransfer) {
571   ASSERT_TRUE(Connect());
572   TestTransfer(0, 1000, 100, false);
573 }
574
575 // Create two channels without DTLS, and transfer some data.
576 TEST_F(DtlsTransportChannelTest, TestTransferTwoChannels) {
577   SetChannelCount(2);
578   ASSERT_TRUE(Connect());
579   TestTransfer(0, 1000, 100, false);
580   TestTransfer(1, 1000, 100, false);
581 }
582
583 // Connect without DTLS, and transfer SRTP data.
584 TEST_F(DtlsTransportChannelTest, TestTransferSrtp) {
585   ASSERT_TRUE(Connect());
586   TestTransfer(0, 1000, 100, true);
587 }
588
589 // Create two channels without DTLS, and transfer SRTP data.
590 TEST_F(DtlsTransportChannelTest, TestTransferSrtpTwoChannels) {
591   SetChannelCount(2);
592   ASSERT_TRUE(Connect());
593   TestTransfer(0, 1000, 100, true);
594   TestTransfer(1, 1000, 100, true);
595 }
596
597 // Connect with DTLS, and transfer some data.
598 TEST_F(DtlsTransportChannelTest, TestTransferDtls) {
599   MAYBE_SKIP_TEST(HaveDtls);
600   PrepareDtls(true, true);
601   ASSERT_TRUE(Connect());
602   TestTransfer(0, 1000, 100, false);
603 }
604
605 // Create two channels with DTLS, and transfer some data.
606 TEST_F(DtlsTransportChannelTest, TestTransferDtlsTwoChannels) {
607   MAYBE_SKIP_TEST(HaveDtls);
608   SetChannelCount(2);
609   PrepareDtls(true, true);
610   ASSERT_TRUE(Connect());
611   TestTransfer(0, 1000, 100, false);
612   TestTransfer(1, 1000, 100, false);
613 }
614
615 // Connect with A doing DTLS and B not, and transfer some data.
616 TEST_F(DtlsTransportChannelTest, TestTransferDtlsRejected) {
617   PrepareDtls(true, false);
618   ASSERT_TRUE(Connect());
619   TestTransfer(0, 1000, 100, false);
620 }
621
622 // Connect with B doing DTLS and A not, and transfer some data.
623 TEST_F(DtlsTransportChannelTest, TestTransferDtlsNotOffered) {
624   PrepareDtls(false, true);
625   ASSERT_TRUE(Connect());
626   TestTransfer(0, 1000, 100, false);
627 }
628
629 // Connect with DTLS, negotiate DTLS-SRTP, and transfer SRTP using bypass.
630 TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtp) {
631   MAYBE_SKIP_TEST(HaveDtlsSrtp);
632   PrepareDtls(true, true);
633   PrepareDtlsSrtp(true, true);
634   ASSERT_TRUE(Connect());
635   TestTransfer(0, 1000, 100, true);
636 }
637
638 // Connect with DTLS-SRTP, transfer an invalid SRTP packet, and expects -1
639 // returned.
640 TEST_F(DtlsTransportChannelTest, TestTransferDtlsInvalidSrtpPacket) {
641   MAYBE_SKIP_TEST(HaveDtls);
642   PrepareDtls(true, true);
643   PrepareDtlsSrtp(true, true);
644   ASSERT_TRUE(Connect());
645   int result = client1_.SendInvalidSrtpPacket(0, 100);
646   ASSERT_EQ(-1, result);
647 }
648
649 // Connect with DTLS. A does DTLS-SRTP but B does not.
650 TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpRejected) {
651   MAYBE_SKIP_TEST(HaveDtlsSrtp);
652   PrepareDtls(true, true);
653   PrepareDtlsSrtp(true, false);
654   ASSERT_TRUE(Connect());
655 }
656
657 // Connect with DTLS. B does DTLS-SRTP but A does not.
658 TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpNotOffered) {
659   MAYBE_SKIP_TEST(HaveDtlsSrtp);
660   PrepareDtls(true, true);
661   PrepareDtlsSrtp(false, true);
662   ASSERT_TRUE(Connect());
663 }
664
665 // Create two channels with DTLS, negotiate DTLS-SRTP, and transfer bypass SRTP.
666 TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpTwoChannels) {
667   MAYBE_SKIP_TEST(HaveDtlsSrtp);
668   SetChannelCount(2);
669   PrepareDtls(true, true);
670   PrepareDtlsSrtp(true, true);
671   ASSERT_TRUE(Connect());
672   TestTransfer(0, 1000, 100, true);
673   TestTransfer(1, 1000, 100, true);
674 }
675
676 // Create a single channel with DTLS, and send normal data and SRTP data on it.
677 TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpDemux) {
678   MAYBE_SKIP_TEST(HaveDtlsSrtp);
679   PrepareDtls(true, true);
680   PrepareDtlsSrtp(true, true);
681   ASSERT_TRUE(Connect());
682   TestTransfer(0, 1000, 100, false);
683   TestTransfer(0, 1000, 100, true);
684 }
685
686 // Testing when the remote is passive.
687 TEST_F(DtlsTransportChannelTest, TestTransferDtlsAnswererIsPassive) {
688   MAYBE_SKIP_TEST(HaveDtlsSrtp);
689   SetChannelCount(2);
690   PrepareDtls(true, true);
691   PrepareDtlsSrtp(true, true);
692   ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
693                       cricket::CONNECTIONROLE_PASSIVE));
694   TestTransfer(0, 1000, 100, true);
695   TestTransfer(1, 1000, 100, true);
696 }
697
698 // Testing with the legacy DTLS client which doesn't use setup attribute.
699 // In this case legacy is the answerer.
700 TEST_F(DtlsTransportChannelTest, TestDtlsSetupWithLegacyAsAnswerer) {
701   MAYBE_SKIP_TEST(HaveDtlsSrtp);
702   PrepareDtls(true, true);
703   NegotiateWithLegacy();
704   talk_base::SSLRole channel1_role;
705   talk_base::SSLRole channel2_role;
706   EXPECT_TRUE(client1_.transport()->GetSslRole(&channel1_role));
707   EXPECT_TRUE(client2_.transport()->GetSslRole(&channel2_role));
708   EXPECT_EQ(talk_base::SSL_SERVER, channel1_role);
709   EXPECT_EQ(talk_base::SSL_CLIENT, channel2_role);
710 }
711
712 // Testing re offer/answer after the session is estbalished. Roles will be
713 // kept same as of the previous negotiation.
714 TEST_F(DtlsTransportChannelTest, TestDtlsReOfferFromOfferer) {
715   MAYBE_SKIP_TEST(HaveDtlsSrtp);
716   SetChannelCount(2);
717   PrepareDtls(true, true);
718   PrepareDtlsSrtp(true, true);
719   // Initial role for client1 is ACTPASS and client2 is ACTIVE.
720   ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
721                       cricket::CONNECTIONROLE_ACTIVE));
722   TestTransfer(0, 1000, 100, true);
723   TestTransfer(1, 1000, 100, true);
724   // Using input roles for the re-offer.
725   Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS,
726               cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER);
727   TestTransfer(0, 1000, 100, true);
728   TestTransfer(1, 1000, 100, true);
729 }
730
731 TEST_F(DtlsTransportChannelTest, TestDtlsReOfferFromAnswerer) {
732   MAYBE_SKIP_TEST(HaveDtlsSrtp);
733   SetChannelCount(2);
734   PrepareDtls(true, true);
735   PrepareDtlsSrtp(true, true);
736   // Initial role for client1 is ACTPASS and client2 is ACTIVE.
737   ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
738                       cricket::CONNECTIONROLE_ACTIVE));
739   TestTransfer(0, 1000, 100, true);
740   TestTransfer(1, 1000, 100, true);
741   // Using input roles for the re-offer.
742   Renegotiate(&client2_, cricket::CONNECTIONROLE_PASSIVE,
743               cricket::CONNECTIONROLE_ACTPASS, NF_REOFFER);
744   TestTransfer(0, 1000, 100, true);
745   TestTransfer(1, 1000, 100, true);
746 }
747
748 // Test that any change in role after the intial setup will result in failure.
749 TEST_F(DtlsTransportChannelTest, TestDtlsRoleReversal) {
750   MAYBE_SKIP_TEST(HaveDtlsSrtp);
751   SetChannelCount(2);
752   PrepareDtls(true, true);
753   PrepareDtlsSrtp(true, true);
754   ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
755                       cricket::CONNECTIONROLE_PASSIVE));
756
757   // Renegotiate from client2 with actpass and client1 as active.
758   Renegotiate(&client2_, cricket::CONNECTIONROLE_ACTPASS,
759               cricket::CONNECTIONROLE_ACTIVE,
760               NF_REOFFER | NF_EXPECT_FAILURE);
761 }
762
763 // Test that using different setup attributes which results in similar ssl
764 // role as the initial negotiation will result in success.
765 TEST_F(DtlsTransportChannelTest, TestDtlsReOfferWithDifferentSetupAttr) {
766   MAYBE_SKIP_TEST(HaveDtlsSrtp);
767   SetChannelCount(2);
768   PrepareDtls(true, true);
769   PrepareDtlsSrtp(true, true);
770   ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
771                       cricket::CONNECTIONROLE_PASSIVE));
772   // Renegotiate from client2 with actpass and client1 as active.
773   Renegotiate(&client2_, cricket::CONNECTIONROLE_ACTIVE,
774               cricket::CONNECTIONROLE_ACTPASS, NF_REOFFER);
775   TestTransfer(0, 1000, 100, true);
776   TestTransfer(1, 1000, 100, true);
777 }
778
779 // Test that re-negotiation can be started before the clients become connected
780 // in the first negotiation.
781 TEST_F(DtlsTransportChannelTest, TestRenegotiateBeforeConnect) {
782   MAYBE_SKIP_TEST(HaveDtlsSrtp);
783   SetChannelCount(2);
784   PrepareDtls(true, true);
785   PrepareDtlsSrtp(true, true);
786   Negotiate();
787
788   Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS,
789               cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER);
790   bool rv = client1_.Connect(&client2_);
791   EXPECT_TRUE(rv);
792   EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000);
793
794   TestTransfer(0, 1000, 100, true);
795   TestTransfer(1, 1000, 100, true);
796 }
797
798 // Test Certificates state after negotiation but before connection.
799 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) {
800   MAYBE_SKIP_TEST(HaveDtls);
801   PrepareDtls(true, true);
802   Negotiate();
803
804   talk_base::scoped_ptr<talk_base::SSLIdentity> identity1;
805   talk_base::scoped_ptr<talk_base::SSLIdentity> identity2;
806   talk_base::scoped_ptr<talk_base::SSLCertificate> remote_cert1;
807   talk_base::scoped_ptr<talk_base::SSLCertificate> remote_cert2;
808
809   // After negotiation, each side has a distinct local certificate, but still no
810   // remote certificate, because connection has not yet occurred.
811   ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept()));
812   ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept()));
813   ASSERT_NE(identity1->certificate().ToPEMString(),
814             identity2->certificate().ToPEMString());
815   ASSERT_FALSE(
816       client1_.transport()->GetRemoteCertificate(remote_cert1.accept()));
817   ASSERT_FALSE(remote_cert1 != NULL);
818   ASSERT_FALSE(
819       client2_.transport()->GetRemoteCertificate(remote_cert2.accept()));
820   ASSERT_FALSE(remote_cert2 != NULL);
821 }
822
823 // Test Certificates state after connection.
824 TEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) {
825   MAYBE_SKIP_TEST(HaveDtls);
826   PrepareDtls(true, true);
827   ASSERT_TRUE(Connect());
828
829   talk_base::scoped_ptr<talk_base::SSLIdentity> identity1;
830   talk_base::scoped_ptr<talk_base::SSLIdentity> identity2;
831   talk_base::scoped_ptr<talk_base::SSLCertificate> remote_cert1;
832   talk_base::scoped_ptr<talk_base::SSLCertificate> remote_cert2;
833
834   // After connection, each side has a distinct local certificate.
835   ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept()));
836   ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept()));
837   ASSERT_NE(identity1->certificate().ToPEMString(),
838             identity2->certificate().ToPEMString());
839
840   // Each side's remote certificate is the other side's local certificate.
841   ASSERT_TRUE(
842       client1_.transport()->GetRemoteCertificate(remote_cert1.accept()));
843   ASSERT_EQ(remote_cert1->ToPEMString(),
844             identity2->certificate().ToPEMString());
845   ASSERT_TRUE(
846       client2_.transport()->GetRemoteCertificate(remote_cert2.accept()));
847   ASSERT_EQ(remote_cert2->ToPEMString(),
848             identity1->certificate().ToPEMString());
849 }