1254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org/*
2254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * libjingle
3254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * Copyright 2015 Google Inc.
4254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *
5254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * Redistribution and use in source and binary forms, with or without
6254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * modification, are permitted provided that the following conditions are met:
7254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *
8254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
9254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *     this list of conditions and the following disclaimer.
10254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
11254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *     this list of conditions and the following disclaimer in the documentation
12254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *     and/or other materials provided with the distribution.
13254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *  3. The name of the author may not be used to endorse or promote products
14254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *     derived from this software without specific prior written permission.
15254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org *
16254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26254840692ef450d94d6a4b075eb139bb34305ec0jiayl@webrtc.org */
2761e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
2861e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org#include "talk/app/webrtc/dtlsidentitystore.h"
2961e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
3061e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
3161e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org#include "webrtc/base/gunit.h"
3261e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org#include "webrtc/base/logging.h"
3361e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org#include "webrtc/base/ssladapter.h"
3461e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
355e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boströmusing webrtc::DtlsIdentityStoreImpl;
3661e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
3761e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.orgstatic const int kTimeoutMs = 10000;
3861e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
3961e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.orgclass MockDtlsIdentityRequestObserver :
405e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström    public webrtc::DtlsIdentityRequestObserver {
4161e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org public:
4261e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  MockDtlsIdentityRequestObserver()
4361e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org      : call_back_called_(false), last_request_success_(false) {}
4461e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  void OnFailure(int error) override {
4561e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    EXPECT_FALSE(call_back_called_);
4661e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    call_back_called_ = true;
4761e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    last_request_success_ = false;
4861e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
4961e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  void OnSuccess(const std::string& der_cert,
505e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström                 const std::string& der_private_key) override {
5161e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    LOG(LS_WARNING) << "The string version of OnSuccess is called unexpectedly";
5261e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    EXPECT_TRUE(false);
5361e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
545e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  void OnSuccess(rtc::scoped_ptr<rtc::SSLIdentity> identity) override {
5561e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    EXPECT_FALSE(call_back_called_);
5661e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    call_back_called_ = true;
5761e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    last_request_success_ = true;
5861e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
5961e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
6061e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  void Reset() {
6161e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    call_back_called_ = false;
6261e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    last_request_success_ = false;
6361e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
6461e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
6561e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  bool LastRequestSucceeded() const {
6661e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    return call_back_called_ && last_request_success_;
6761e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
6861e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
6961e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  bool call_back_called() const {
7061e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    return call_back_called_;
7161e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
7261e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
7361e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org private:
7461e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  bool call_back_called_;
7561e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  bool last_request_success_;
7661e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org};
7761e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
7861e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.orgclass DtlsIdentityStoreTest : public testing::Test {
7961e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org protected:
8061e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  DtlsIdentityStoreTest()
81d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org      : worker_thread_(new rtc::Thread()),
825e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström        store_(new DtlsIdentityStoreImpl(rtc::Thread::Current(),
835e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström                                         worker_thread_.get())),
8461e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org        observer_(
8561e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org            new rtc::RefCountedObject<MockDtlsIdentityRequestObserver>()) {
8691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_CHECK(worker_thread_->Start());
8761e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
8861e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  ~DtlsIdentityStoreTest() {}
8961e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
9061e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  static void SetUpTestCase() {
9161e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    rtc::InitializeSSL();
9261e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
9361e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  static void TearDownTestCase() {
9461e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org    rtc::CleanupSSL();
9561e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  }
9661e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
97d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org  rtc::scoped_ptr<rtc::Thread> worker_thread_;
985e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  rtc::scoped_ptr<DtlsIdentityStoreImpl> store_;
9961e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  rtc::scoped_refptr<MockDtlsIdentityRequestObserver> observer_;
10061e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org};
10161e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
1025e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik BoströmTEST_F(DtlsIdentityStoreTest, RequestIdentitySuccessRSA) {
1035e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  EXPECT_TRUE_WAIT(store_->HasFreeIdentityForTesting(rtc::KT_RSA), kTimeoutMs);
10461e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
1055e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  store_->RequestIdentity(rtc::KT_RSA, observer_.get());
10661e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org  EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
10761e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org
1085e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  EXPECT_TRUE_WAIT(store_->HasFreeIdentityForTesting(rtc::KT_RSA), kTimeoutMs);
109d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org
110d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org  observer_->Reset();
111d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org
112d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org  // Verifies that the callback is async when a free identity is ready.
1135e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  store_->RequestIdentity(rtc::KT_RSA, observer_.get());
114d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org  EXPECT_FALSE(observer_->call_back_called());
115d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org  EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
116d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org}
117d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org
1185e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik BoströmTEST_F(DtlsIdentityStoreTest, RequestIdentitySuccessECDSA) {
1195e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  // Since store currently does not preemptively generate free ECDSA identities
1205e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  // we do not invoke HasFreeIdentityForTesting between requests.
121d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org
1225e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  store_->RequestIdentity(rtc::KT_ECDSA, observer_.get());
1235e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
1245e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström
1255e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  observer_->Reset();
1265e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström
1275e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  // Verifies that the callback is async when a free identity is ready.
1285e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  store_->RequestIdentity(rtc::KT_ECDSA, observer_.get());
1295e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  EXPECT_FALSE(observer_->call_back_called());
1305e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
1315e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström}
1325e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström
1335e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik BoströmTEST_F(DtlsIdentityStoreTest, DeleteStoreEarlyNoCrashRSA) {
1345e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  EXPECT_FALSE(store_->HasFreeIdentityForTesting(rtc::KT_RSA));
1355e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström
1365e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  store_->RequestIdentity(rtc::KT_RSA, observer_.get());
1375e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  store_.reset();
1385e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström
1395e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  worker_thread_->Stop();
1405e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  EXPECT_FALSE(observer_->call_back_called());
1415e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström}
1425e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström
1435e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik BoströmTEST_F(DtlsIdentityStoreTest, DeleteStoreEarlyNoCrashECDSA) {
1445e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  EXPECT_FALSE(store_->HasFreeIdentityForTesting(rtc::KT_ECDSA));
1455e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström
1465e56c5927e097f095aef2e9f7be49fd3d59221e1Henrik Boström  store_->RequestIdentity(rtc::KT_ECDSA, observer_.get());
147d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org  store_.reset();
148d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org
149d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org  worker_thread_->Stop();
150d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org  EXPECT_FALSE(observer_->call_back_called());
15161e00b0bcab899a32f14c1e2e0f4b7f316cc1f03jiayl@webrtc.org}
152d83f4eff84d872da3e38e1a61d669fc407ce7adfjiayl@webrtc.org
153