10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2011, Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2011, RTFM, Inc.
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <set>
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
31cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/dtlstransport.h"
32cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/fakesession.h"
332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/common.h"
342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/dscp.h"
352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/gunit.h"
362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/helpers.h"
372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/scoped_ptr.h"
382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/ssladapter.h"
392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/sslidentity.h"
402a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/sslstreamadapter.h"
41cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/stringutils.h"
42cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/thread.h"
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define MAYBE_SKIP_TEST(feature)                    \
452a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  if (!(rtc::SSLStreamAdapter::feature())) {  \
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_INFO) << "Feature disabled... skipping"; \
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;                                         \
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80";
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kIceUfrag1[] = "TESTICEUFRAG0001";
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kIcePwd1[] = "TESTICEPWD00000000000001";
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const size_t kPacketNumOffset = 8;
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const size_t kPacketHeaderLen = 12;
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool IsRtpLeadByte(uint8 b) {
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return ((b & 0xC0) == 0x80);
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
60a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgusing cricket::ConnectionRole;
61a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
62a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgenum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 };
63a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass DtlsTestClient : public sigslot::has_slots<> {
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  DtlsTestClient(const std::string& name,
672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                 rtc::Thread* signaling_thread,
682a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                 rtc::Thread* worker_thread) :
690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      name_(name),
700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      signaling_thread_(signaling_thread),
710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      worker_thread_(worker_thread),
720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      protocol_(cricket::ICEPROTO_GOOGLE),
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      packet_size_(0),
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      use_dtls_srtp_(false),
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      negotiated_dtls_(false),
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      received_dtls_client_hello_(false),
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      received_dtls_server_hello_(false) {
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void SetIceProtocol(cricket::TransportProtocol proto) {
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    protocol_ = proto;
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CreateIdentity() {
832a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    identity_.reset(rtc::SSLIdentity::Generate(name_));
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
852a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::SSLIdentity* identity() { return identity_.get(); }
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void SetupSrtp() {
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(identity_.get() != NULL);
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    use_dtls_srtp_ = true;
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
90e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  void SetupChannels(int count, cricket::IceRole role) {
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>(
920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        signaling_thread_, worker_thread_, "dtls content name", NULL,
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        identity_.get()));
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    transport_->SetAsync(true);
95e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org    transport_->SetIceRole(role);
96e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org    transport_->SetIceTiebreaker(
97e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org        (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2);
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    transport_->SignalWritableState.connect(this,
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &DtlsTestClient::OnTransportWritableState);
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (int i = 0; i < count; ++i) {
1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      cricket::DtlsTransportChannelWrapper* channel =
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          static_cast<cricket::DtlsTransportChannelWrapper*>(
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org              transport_->CreateChannel(i));
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_TRUE(channel != NULL);
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      channel->SignalWritableState.connect(this,
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &DtlsTestClient::OnTransportChannelWritableState);
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      channel->SignalReadPacket.connect(this,
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &DtlsTestClient::OnTransportChannelReadPacket);
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      channels_.push_back(channel);
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Hook the raw packets so that we can verify they are encrypted.
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      channel->channel()->SignalReadPacket.connect(
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          this, &DtlsTestClient::OnFakeTransportChannelReadPacket);
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
117a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
118a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  cricket::Transport* transport() { return transport_.get(); }
119a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::FakeTransportChannel* GetFakeChannel(int component) {
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::TransportChannelImpl* ch = transport_->GetChannel(component);
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::DtlsTransportChannelWrapper* wrapper =
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        static_cast<cricket::DtlsTransportChannelWrapper*>(ch);
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return (wrapper) ?
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL;
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Offer DTLS if we have an identity; pass in a remote fingerprint only if
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // both sides support DTLS.
130a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  void Negotiate(DtlsTestClient* peer, cricket::ContentAction action,
131a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                 ConnectionRole local_role, ConnectionRole remote_role,
132a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                 int flags) {
133a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    Negotiate(identity_.get(), (identity_) ? peer->identity_.get() : NULL,
134a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org              action, local_role, remote_role, flags);
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Allow any DTLS configuration to be specified (including invalid ones).
1382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  void Negotiate(rtc::SSLIdentity* local_identity,
1392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                 rtc::SSLIdentity* remote_identity,
140a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                 cricket::ContentAction action,
141a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                 ConnectionRole local_role,
142a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                 ConnectionRole remote_role,
143a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                 int flags) {
1442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint;
1452a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::SSLFingerprint> remote_fingerprint;
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (local_identity) {
1472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      local_fingerprint.reset(rtc::SSLFingerprint::Create(
1482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org          rtc::DIGEST_SHA_1, local_identity));
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_TRUE(local_fingerprint.get() != NULL);
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (remote_identity) {
1522a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      remote_fingerprint.reset(rtc::SSLFingerprint::Create(
1532a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org          rtc::DIGEST_SHA_1, remote_identity));
1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_TRUE(remote_fingerprint.get() != NULL);
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
156a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
157a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    if (use_dtls_srtp_ && !(flags & NF_REOFFER)) {
158a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      // SRTP ciphers will be set only in the beginning.
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org           channels_.begin(); it != channels_.end(); ++it) {
1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        std::vector<std::string> ciphers;
1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ciphers.push_back(AES_CM_128_HMAC_SHA1_80);
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ASSERT_TRUE((*it)->SetSrtpCiphers(ciphers));
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string transport_type = (protocol_ == cricket::ICEPROTO_GOOGLE) ?
1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::NS_GINGLE_P2P : cricket::NS_JINGLE_ICE_UDP;
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::TransportDescription local_desc(
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        transport_type, std::vector<std::string>(), kIceUfrag1, kIcePwd1,
171a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org        cricket::ICEMODE_FULL, local_role,
172a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org         // If remote if the offerer and has no DTLS support, answer will be
173a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org        // without any fingerprint.
174a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org        (action == cricket::CA_ANSWER && !remote_identity) ?
175a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org            NULL : local_fingerprint.get(),
1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::Candidates());
177a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::TransportDescription remote_desc(
1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        transport_type, std::vector<std::string>(), kIceUfrag1, kIcePwd1,
180a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org        cricket::ICEMODE_FULL, remote_role, remote_fingerprint.get(),
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::Candidates());
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
183a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true;
184a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    // If |expect_success| is false, expect SRTD or SLTD to fail when
185a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    // content action is CA_ANSWER.
186a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    if (action == cricket::CA_OFFER) {
187a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      ASSERT_TRUE(transport_->SetLocalTransportDescription(
188f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org          local_desc, cricket::CA_OFFER, NULL));
189a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      ASSERT_EQ(expect_success, transport_->SetRemoteTransportDescription(
190f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org          remote_desc, cricket::CA_ANSWER, NULL));
191a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    } else {
192a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      ASSERT_TRUE(transport_->SetRemoteTransportDescription(
193f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org          remote_desc, cricket::CA_OFFER, NULL));
194a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      ASSERT_EQ(expect_success, transport_->SetLocalTransportDescription(
195f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org          local_desc, cricket::CA_ANSWER, NULL));
196a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    }
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    negotiated_dtls_ = (local_identity && remote_identity);
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool Connect(DtlsTestClient* peer) {
2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    transport_->ConnectChannels();
2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    transport_->SetDestination(peer->transport_.get());
2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool writable() const { return transport_->writable(); }
2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2082a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  void CheckRole(rtc::SSLRole role) {
2092a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    if (role == rtc::SSL_CLIENT) {
2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_FALSE(received_dtls_client_hello_);
2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_TRUE(received_dtls_server_hello_);
2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_TRUE(received_dtls_client_hello_);
2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_FALSE(received_dtls_server_hello_);
2157162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    }
2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2177162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org
2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CheckSrtp(const std::string& expected_cipher) {
2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it =
2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org           channels_.begin(); it != channels_.end(); ++it) {
2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      std::string cipher;
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      bool rv = (*it)->GetSrtpCipher(&cipher);
2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (negotiated_dtls_ && !expected_cipher.empty()) {
2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ASSERT_TRUE(rv);
2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ASSERT_EQ(cipher, expected_cipher);
2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      } else {
2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ASSERT_FALSE(rv);
2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void SendPackets(size_t channel, size_t size, size_t count, bool srtp) {
2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(channel < channels_.size());
2362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<char[]> packet(new char[size]);
2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t sent = 0;
2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    do {
2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Fill the packet with a known value and a sequence number to check
2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // against, and make sure that it doesn't look like DTLS.
2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      memset(packet.get(), sent & 0xff, size);
2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      packet[0] = (srtp) ? 0x80 : 0x00;
2432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::SetBE32(packet.get() + kPacketNumOffset,
2441a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org                         static_cast<uint32>(sent));
2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Only set the bypass flag if we've activated DTLS.
2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      int flags = (identity_.get() && srtp) ? cricket::PF_SRTP_BYPASS : 0;
2482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::PacketOptions packet_options;
249391247d05a663265807c400947ab6eb01ae3d690mallinath@webrtc.org      int rv = channels_[channel]->SendPacket(
250f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org          packet.get(), size, packet_options, flags);
2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_GT(rv, 0);
2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT_EQ(size, static_cast<size_t>(rv));
2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ++sent;
2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } while (sent < count);
2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
257ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org  int SendInvalidSrtpPacket(size_t channel, size_t size) {
258ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org    ASSERT(channel < channels_.size());
2592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<char[]> packet(new char[size]);
260ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org    // Fill the packet with 0 to form an invalid SRTP packet.
261ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org    memset(packet.get(), 0, size);
262ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org
2632a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::PacketOptions packet_options;
264ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org    return channels_[channel]->SendPacket(
265ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org        packet.get(), size, packet_options, cricket::PF_SRTP_BYPASS);
266ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org  }
267ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org
2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void ExpectPackets(size_t channel, size_t size) {
2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    packet_size_ = size;
2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    received_.clear();
2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  size_t NumPacketsReceived() {
2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return received_.size();
2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool VerifyPacket(const char* data, size_t size, uint32* out_num) {
2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (size != packet_size_ ||
2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        (data[0] != 0 && static_cast<uint8>(data[0]) != 0x80)) {
2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2822a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    uint32 packet_num = rtc::GetBE32(data + kPacketNumOffset);
2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (size_t i = kPacketHeaderLen; i < size; ++i) {
2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (static_cast<uint8>(data[i]) != (packet_num & 0xff)) {
2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return false;
2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (out_num) {
2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *out_num = packet_num;
2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool VerifyEncryptedPacket(const char* data, size_t size) {
2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // This is an encrypted data packet; let's make sure it's mostly random;
2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // less than 10% of the bytes should be equal to the cleartext packet.
2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (size <= packet_size_) {
2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2992a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    uint32 packet_num = rtc::GetBE32(data + kPacketNumOffset);
3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int num_matches = 0;
3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (size_t i = kPacketNumOffset; i < size; ++i) {
3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (static_cast<uint8>(data[i]) == (packet_num & 0xff)) {
3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ++num_matches;
3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return (num_matches < ((static_cast<int>(size) - 5) / 10));
3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Transport callbacks
3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnTransportWritableState(cricket::Transport* transport) {
3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_INFO) << name_ << ": is writable";
3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Transport channel callbacks
3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnTransportChannelWritableState(cricket::TransportChannel* channel) {
3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_INFO) << name_ << ": Channel '" << channel->component()
3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 << "' is writable";
3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnTransportChannelReadPacket(cricket::TransportChannel* channel,
3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    const char* data, size_t size,
3222a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                                    const rtc::PacketTime& packet_time,
3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    int flags) {
3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    uint32 packet_num = 0;
3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(VerifyPacket(data, size, &packet_num));
3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    received_.insert(packet_num);
3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Only DTLS-SRTP packets should have the bypass flag set.
3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int expected_flags = (identity_.get() && IsRtpLeadByte(data[0])) ?
3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::PF_SRTP_BYPASS : 0;
3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_EQ(expected_flags, flags);
3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Hook into the raw packet stream to make sure DTLS packets are encrypted.
3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnFakeTransportChannelReadPacket(cricket::TransportChannel* channel,
3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                        const char* data, size_t size,
3362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                                        const rtc::PacketTime& time,
3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                        int flags) {
3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Flags shouldn't be set on the underlying TransportChannel packets.
3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_EQ(0, flags);
3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Look at the handshake packets to see what role we played.
3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Check that non-handshake packets are DTLS data or SRTP bypass.
3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (negotiated_dtls_) {
3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (data[0] == 22 && size > 17) {
3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if (data[13] == 1) {
3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          received_dtls_client_hello_ = true;
3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        } else if (data[13] == 2) {
3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          received_dtls_server_hello_ = true;
3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      } else if (!(data[0] >= 20 && data[0] <= 22)) {
3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0]));
3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if (data[0] == 23) {
3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          ASSERT_TRUE(VerifyEncryptedPacket(data, size));
3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        } else if (IsRtpLeadByte(data[0])) {
3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          ASSERT_TRUE(VerifyPacket(data, size, NULL));
3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
3587162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    }
3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private:
3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string name_;
3632a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Thread* signaling_thread_;
3642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Thread* worker_thread_;
3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::TransportProtocol protocol_;
3662a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLIdentity> identity_;
3672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<cricket::FakeTransport> transport_;
3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::vector<cricket::DtlsTransportChannelWrapper*> channels_;
3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  size_t packet_size_;
3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::set<int> received_;
3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool use_dtls_srtp_;
3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool negotiated_dtls_;
3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool received_dtls_client_hello_;
3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool received_dtls_server_hello_;
3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass DtlsTransportChannelTest : public testing::Test {
3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static void SetUpTestCase() {
3812a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::InitializeSSL();
3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3847162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  static void TearDownTestCase() {
3852a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::CleanupSSL();
3867162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  }
3877162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org
3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  DtlsTransportChannelTest() :
3892a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      client1_("P1", rtc::Thread::Current(),
3902a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org               rtc::Thread::Current()),
3912a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      client2_("P2", rtc::Thread::Current(),
3922a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org               rtc::Thread::Current()),
3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      channel_ct_(1),
3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      use_dtls_(false),
3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      use_dtls_srtp_(false) {
3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void SetChannelCount(size_t channel_ct) {
3991a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org    channel_ct_ = static_cast<int>(channel_ct);
4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void PrepareDtls(bool c1, bool c2) {
4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (c1) {
4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client1_.CreateIdentity();
4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (c2) {
4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client2_.CreateIdentity();
4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (c1 && c2)
4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      use_dtls_ = true;
4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void PrepareDtlsSrtp(bool c1, bool c2) {
4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!use_dtls_)
4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (c1)
4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client1_.SetupSrtp();
4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (c2)
4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client2_.SetupSrtp();
4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (c1 && c2)
4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      use_dtls_srtp_ = true;
4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
424a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) {
425a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    Negotiate(client1_role, client2_role);
4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool rv = client1_.Connect(&client2_);
4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(rv);
4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!rv)
4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000);
4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!client1_.writable() || !client2_.writable())
4340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
4350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Check that we used the right roles.
4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (use_dtls_) {
4382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::SSLRole client1_ssl_role =
439a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (client1_role == cricket::CONNECTIONROLE_ACTIVE ||
440a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org           (client2_role == cricket::CONNECTIONROLE_PASSIVE &&
441a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org            client1_role == cricket::CONNECTIONROLE_ACTPASS)) ?
4422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org              rtc::SSL_CLIENT : rtc::SSL_SERVER;
443a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
4442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::SSLRole client2_ssl_role =
445a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (client2_role == cricket::CONNECTIONROLE_ACTIVE ||
446a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org           (client1_role == cricket::CONNECTIONROLE_PASSIVE &&
447a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org            client2_role == cricket::CONNECTIONROLE_ACTPASS)) ?
4482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org              rtc::SSL_CLIENT : rtc::SSL_SERVER;
449a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
450a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      client1_.CheckRole(client1_ssl_role);
451a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      client2_.CheckRole(client2_ssl_role);
4520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Check that we negotiated the right ciphers.
4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (use_dtls_srtp_) {
4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client1_.CheckSrtp(AES_CM_128_HMAC_SHA1_80);
4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client2_.CheckSrtp(AES_CM_128_HMAC_SHA1_80);
4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client1_.CheckSrtp("");
4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client2_.CheckSrtp("");
4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
465a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
466a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  bool Connect() {
467a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    // By default, Client1 will be Server and Client2 will be Client.
468a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    return Connect(cricket::CONNECTIONROLE_ACTPASS,
469a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                   cricket::CONNECTIONROLE_ACTIVE);
470a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
471a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void Negotiate() {
473a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE);
474a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
475a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
476a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  void Negotiate(ConnectionRole client1_role, ConnectionRole client2_role) {
477a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING);
478a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED);
479a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    // Expect success from SLTD and SRTD.
480a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    client1_.Negotiate(&client2_, cricket::CA_OFFER,
481a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                       client1_role, client2_role, 0);
482a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    client2_.Negotiate(&client1_, cricket::CA_ANSWER,
483a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                       client2_role, client1_role, 0);
484a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
485a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
486a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Negotiate with legacy client |client2|. Legacy client doesn't use setup
487a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // attributes, except NONE.
488a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  void NegotiateWithLegacy() {
489e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org    client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING);
490e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org    client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED);
491a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    // Expect success from SLTD and SRTD.
492a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    client1_.Negotiate(&client2_, cricket::CA_OFFER,
493a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                       cricket::CONNECTIONROLE_ACTPASS,
494a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                       cricket::CONNECTIONROLE_NONE, 0);
495a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    client2_.Negotiate(&client1_, cricket::CA_ANSWER,
496a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                       cricket::CONNECTIONROLE_ACTIVE,
497a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                       cricket::CONNECTIONROLE_NONE, 0);
498a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
499a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
500a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  void Renegotiate(DtlsTestClient* reoffer_initiator,
501a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                   ConnectionRole client1_role, ConnectionRole client2_role,
502a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                   int flags) {
503a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    if (reoffer_initiator == &client1_) {
504a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      client1_.Negotiate(&client2_, cricket::CA_OFFER,
505a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                         client1_role, client2_role, flags);
506a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      client2_.Negotiate(&client1_, cricket::CA_ANSWER,
507a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                         client2_role, client1_role, flags);
508a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    } else {
509a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      client2_.Negotiate(&client1_, cricket::CA_OFFER,
510a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                         client2_role, client1_role, flags);
511a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      client1_.Negotiate(&client2_, cricket::CA_ANSWER,
512a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                         client1_role, client2_role, flags);
513a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    }
5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) {
5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_INFO) << "Expect packets, size=" << size;
5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    client2_.ExpectPackets(channel, size);
5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    client1_.SendPackets(channel, size, count, srtp);
5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ_WAIT(count, client2_.NumPacketsReceived(), 10000);
5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected:
5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  DtlsTestClient client1_;
5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  DtlsTestClient client2_;
5260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int channel_ct_;
5270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool use_dtls_;
5280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool use_dtls_srtp_;
5290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Test that transport negotiation of ICE, no DTLS works properly.
5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestChannelSetupIce) {
5330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  client1_.SetIceProtocol(cricket::ICEPROTO_RFC5245);
5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  client2_.SetIceProtocol(cricket::ICEPROTO_RFC5245);
5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Negotiate();
5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0);
5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0);
5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(channel1 != NULL);
5390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(channel2 != NULL);
540e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
541e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  EXPECT_EQ(1U, channel1->IceTiebreaker());
5420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(cricket::ICEPROTO_RFC5245, channel1->protocol());
5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag());
5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(kIcePwd1, channel1->ice_pwd());
545e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
546e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  EXPECT_EQ(2U, channel2->IceTiebreaker());
5470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(cricket::ICEPROTO_RFC5245, channel2->protocol());
5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Test that transport negotiation of GICE, no DTLS works properly.
5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestChannelSetupGice) {
5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  client1_.SetIceProtocol(cricket::ICEPROTO_GOOGLE);
5530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  client2_.SetIceProtocol(cricket::ICEPROTO_GOOGLE);
5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Negotiate();
5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0);
5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0);
5570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(channel1 != NULL);
5580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(channel2 != NULL);
559e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
560e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  EXPECT_EQ(1U, channel1->IceTiebreaker());
5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(cricket::ICEPROTO_GOOGLE, channel1->protocol());
5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag());
5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(kIcePwd1, channel1->ice_pwd());
564e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel2->GetIceRole());
565e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  EXPECT_EQ(2U, channel2->IceTiebreaker());
5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(cricket::ICEPROTO_GOOGLE, channel2->protocol());
5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Connect without DTLS, and transfer some data.
5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransfer) {
5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, false);
5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Create two channels without DTLS, and transfer some data.
5760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferTwoChannels) {
5770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetChannelCount(2);
5780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, false);
5800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(1, 1000, 100, false);
5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Connect without DTLS, and transfer SRTP data.
5840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferSrtp) {
5850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, true);
5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Create two channels without DTLS, and transfer SRTP data.
5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferSrtpTwoChannels) {
5910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetChannelCount(2);
5920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
5930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, true);
5940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(1, 1000, 100, true);
5950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Connect with DTLS, and transfer some data.
5980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtls) {
5990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MAYBE_SKIP_TEST(HaveDtls);
6000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(true, true);
6010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, false);
6030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Create two channels with DTLS, and transfer some data.
6060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsTwoChannels) {
6070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MAYBE_SKIP_TEST(HaveDtls);
6080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetChannelCount(2);
6090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(true, true);
6100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, false);
6120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(1, 1000, 100, false);
6130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Connect with A doing DTLS and B not, and transfer some data.
6160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsRejected) {
6170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(true, false);
6180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, false);
6200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Connect with B doing DTLS and A not, and transfer some data.
6230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsNotOffered) {
6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(false, true);
6250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, false);
6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Connect with DTLS, negotiate DTLS-SRTP, and transfer SRTP using bypass.
6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtp) {
6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
6320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(true, true);
6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtlsSrtp(true, true);
6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, true);
6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
638ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org// Connect with DTLS-SRTP, transfer an invalid SRTP packet, and expects -1
639ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org// returned.
640ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsInvalidSrtpPacket) {
641ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org  MAYBE_SKIP_TEST(HaveDtls);
642ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org  PrepareDtls(true, true);
643ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org  PrepareDtlsSrtp(true, true);
644ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org  ASSERT_TRUE(Connect());
645ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org  int result = client1_.SendInvalidSrtpPacket(0, 100);
646ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org  ASSERT_EQ(-1, result);
647ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org}
6480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Connect with DTLS. A does DTLS-SRTP but B does not.
6500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpRejected) {
6510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
6520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(true, true);
6530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtlsSrtp(true, false);
6540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Connect with DTLS. B does DTLS-SRTP but A does not.
6580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpNotOffered) {
6590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
6600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(true, true);
6610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtlsSrtp(false, true);
6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Create two channels with DTLS, negotiate DTLS-SRTP, and transfer bypass SRTP.
6660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpTwoChannels) {
6670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
6680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetChannelCount(2);
6690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(true, true);
6700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtlsSrtp(true, true);
6710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, true);
6730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(1, 1000, 100, true);
6740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Create a single channel with DTLS, and send normal data and SRTP data on it.
6770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpDemux) {
6780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
6790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtls(true, true);
6800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareDtlsSrtp(true, true);
6810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_TRUE(Connect());
6820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, false);
6830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTransfer(0, 1000, 100, true);
6840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
685a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
686a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// Testing when the remote is passive.
687a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgTEST_F(DtlsTransportChannelTest, TestTransferDtlsAnswererIsPassive) {
688a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
689a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  SetChannelCount(2);
690a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtls(true, true);
691a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtlsSrtp(true, true);
692a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
693a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                      cricket::CONNECTIONROLE_PASSIVE));
694a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(0, 1000, 100, true);
695a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(1, 1000, 100, true);
696a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
697a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
698a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// Testing with the legacy DTLS client which doesn't use setup attribute.
699a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// In this case legacy is the answerer.
700a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgTEST_F(DtlsTransportChannelTest, TestDtlsSetupWithLegacyAsAnswerer) {
701a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
702a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtls(true, true);
703a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  NegotiateWithLegacy();
7042a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::SSLRole channel1_role;
7052a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::SSLRole channel2_role;
706a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  EXPECT_TRUE(client1_.transport()->GetSslRole(&channel1_role));
707a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  EXPECT_TRUE(client2_.transport()->GetSslRole(&channel2_role));
7082a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  EXPECT_EQ(rtc::SSL_SERVER, channel1_role);
7092a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  EXPECT_EQ(rtc::SSL_CLIENT, channel2_role);
710a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
711a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
712a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// Testing re offer/answer after the session is estbalished. Roles will be
713a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// kept same as of the previous negotiation.
714a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgTEST_F(DtlsTransportChannelTest, TestDtlsReOfferFromOfferer) {
715a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
716a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  SetChannelCount(2);
717a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtls(true, true);
718a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtlsSrtp(true, true);
719a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Initial role for client1 is ACTPASS and client2 is ACTIVE.
720a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
721a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                      cricket::CONNECTIONROLE_ACTIVE));
722a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(0, 1000, 100, true);
723a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(1, 1000, 100, true);
724a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Using input roles for the re-offer.
725a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS,
726a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org              cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER);
727a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(0, 1000, 100, true);
728a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(1, 1000, 100, true);
729a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
730a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
731a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgTEST_F(DtlsTransportChannelTest, TestDtlsReOfferFromAnswerer) {
732a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
733a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  SetChannelCount(2);
734a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtls(true, true);
735a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtlsSrtp(true, true);
736a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Initial role for client1 is ACTPASS and client2 is ACTIVE.
737a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
738a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                      cricket::CONNECTIONROLE_ACTIVE));
739a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(0, 1000, 100, true);
740a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(1, 1000, 100, true);
741a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Using input roles for the re-offer.
742a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  Renegotiate(&client2_, cricket::CONNECTIONROLE_PASSIVE,
743a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org              cricket::CONNECTIONROLE_ACTPASS, NF_REOFFER);
744a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(0, 1000, 100, true);
745a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(1, 1000, 100, true);
746a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
747a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
748a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// Test that any change in role after the intial setup will result in failure.
749a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgTEST_F(DtlsTransportChannelTest, TestDtlsRoleReversal) {
750a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
751a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  SetChannelCount(2);
752a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtls(true, true);
753a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtlsSrtp(true, true);
754a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
755a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                      cricket::CONNECTIONROLE_PASSIVE));
756a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
757a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Renegotiate from client2 with actpass and client1 as active.
758a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  Renegotiate(&client2_, cricket::CONNECTIONROLE_ACTPASS,
759a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org              cricket::CONNECTIONROLE_ACTIVE,
760a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org              NF_REOFFER | NF_EXPECT_FAILURE);
761a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
762a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
763a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// Test that using different setup attributes which results in similar ssl
764a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// role as the initial negotiation will result in success.
765a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgTEST_F(DtlsTransportChannelTest, TestDtlsReOfferWithDifferentSetupAttr) {
766a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
767a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  SetChannelCount(2);
768a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtls(true, true);
769a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareDtlsSrtp(true, true);
770a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS,
771a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                      cricket::CONNECTIONROLE_PASSIVE));
772a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Renegotiate from client2 with actpass and client1 as active.
773a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  Renegotiate(&client2_, cricket::CONNECTIONROLE_ACTIVE,
774a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org              cricket::CONNECTIONROLE_ACTPASS, NF_REOFFER);
775a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(0, 1000, 100, true);
776a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  TestTransfer(1, 1000, 100, true);
777a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
77862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
779b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org// Test that re-negotiation can be started before the clients become connected
780b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org// in the first negotiation.
781b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.orgTEST_F(DtlsTransportChannelTest, TestRenegotiateBeforeConnect) {
782b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  MAYBE_SKIP_TEST(HaveDtlsSrtp);
783b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  SetChannelCount(2);
784b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  PrepareDtls(true, true);
785b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  PrepareDtlsSrtp(true, true);
786b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  Negotiate();
787b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org
788b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS,
789b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org              cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER);
790b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  bool rv = client1_.Connect(&client2_);
791b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  EXPECT_TRUE(rv);
792b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  EXPECT_TRUE_WAIT(client1_.writable() && client2_.writable(), 10000);
793b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org
794b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  TestTransfer(0, 1000, 100, true);
795b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org  TestTransfer(1, 1000, 100, true);
796b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org}
797b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org
79862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org// Test Certificates state after negotiation but before connection.
79962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgTEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) {
80062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  MAYBE_SKIP_TEST(HaveDtls);
80162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  PrepareDtls(true, true);
80262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  Negotiate();
80362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
8042a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLIdentity> identity1;
8052a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLIdentity> identity2;
8062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1;
8072a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2;
80862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
80962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // After negotiation, each side has a distinct local certificate, but still no
81062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // remote certificate, because connection has not yet occurred.
81162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept()));
81262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept()));
81362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_NE(identity1->certificate().ToPEMString(),
81462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org            identity2->certificate().ToPEMString());
81562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_FALSE(
81662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      client1_.transport()->GetRemoteCertificate(remote_cert1.accept()));
81762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_FALSE(remote_cert1 != NULL);
81862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_FALSE(
81962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      client2_.transport()->GetRemoteCertificate(remote_cert2.accept()));
82062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_FALSE(remote_cert2 != NULL);
82162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org}
82262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
82362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org// Test Certificates state after connection.
82462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgTEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) {
82562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  MAYBE_SKIP_TEST(HaveDtls);
82662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  PrepareDtls(true, true);
82762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_TRUE(Connect());
82862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
8292a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLIdentity> identity1;
8302a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLIdentity> identity2;
8312a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1;
8322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2;
83362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
83462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // After connection, each side has a distinct local certificate.
83562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept()));
83662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept()));
83762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_NE(identity1->certificate().ToPEMString(),
83862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org            identity2->certificate().ToPEMString());
83962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
84062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // Each side's remote certificate is the other side's local certificate.
84162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_TRUE(
84262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      client1_.transport()->GetRemoteCertificate(remote_cert1.accept()));
84362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_EQ(remote_cert1->ToPEMString(),
84462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org            identity2->certificate().ToPEMString());
84562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_TRUE(
84662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      client2_.transport()->GetRemoteCertificate(remote_cert2.accept()));
84762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT_EQ(remote_cert2->ToPEMString(),
84862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org            identity1->certificate().ToPEMString());
84962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org}
850