tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ClearKeyPersistence.cpp (4451B)


      1 /*
      2 * Copyright 2015, Mozilla Foundation and contributors
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 #include "ClearKeyPersistence.h"
     18 
     19 #include <assert.h>
     20 #include <stdint.h>
     21 #include <string.h>
     22 
     23 #include <sstream>
     24 
     25 #include "ClearKeySessionManager.h"
     26 #include "ClearKeyStorage.h"
     27 #include "ClearKeyUtils.h"
     28 #include "RefCounted.h"
     29 
     30 using namespace cdm;
     31 
     32 using std::function;
     33 using std::string;
     34 using std::stringstream;
     35 using std::vector;
     36 
     37 void ClearKeyPersistence::ReadAllRecordsFromIndex(
     38    function<void()>&& aOnComplete) {
     39  // Clear what we think the index file contains, we're about to read it again.
     40  mPersistentSessionIds.clear();
     41 
     42  // Hold a reference to the persistence manager, so it isn't released before
     43  // we try and use it.
     44  RefPtr<ClearKeyPersistence> self(this);
     45  function<void(const uint8_t*, uint32_t)> onIndexSuccess =
     46      [self, aOnComplete](const uint8_t* data, uint32_t size) {
     47        CK_LOGD("ClearKeyPersistence: Loaded index file!");
     48        const char* charData = (const char*)data;
     49 
     50        stringstream ss(string(charData, charData + size));
     51        string name;
     52        while (getline(ss, name)) {
     53          if (ClearKeyUtils::IsValidSessionId(name.data(), name.size())) {
     54            self->mPersistentSessionIds.insert(atoi(name.c_str()));
     55          }
     56        }
     57 
     58        self->mPersistentKeyState = PersistentKeyState::LOADED;
     59        aOnComplete();
     60      };
     61 
     62  function<void()> onIndexFailed = [self, aOnComplete]() {
     63    CK_LOGD(
     64        "ClearKeyPersistence: Failed to load index file (it might not exist");
     65    self->mPersistentKeyState = PersistentKeyState::LOADED;
     66    aOnComplete();
     67  };
     68 
     69  string filename = "index";
     70  ReadData(mHost, filename, std::move(onIndexSuccess),
     71           std::move(onIndexFailed));
     72 }
     73 
     74 void ClearKeyPersistence::WriteIndex() {
     75  function<void()> onIndexSuccess = []() {
     76    CK_LOGD("ClearKeyPersistence: Wrote index file");
     77  };
     78 
     79  function<void()> onIndexFail = []() {
     80    CK_LOGD("ClearKeyPersistence: Failed to write index file (this is bad)");
     81  };
     82 
     83  stringstream ss;
     84 
     85  for (const uint32_t& sessionId : mPersistentSessionIds) {
     86    ss << sessionId;
     87    ss << '\n';
     88  }
     89 
     90  string dataString = ss.str();
     91  uint8_t* dataArray = (uint8_t*)dataString.data();
     92  vector<uint8_t> data(dataArray, dataArray + dataString.size());
     93 
     94  string filename = "index";
     95  WriteData(mHost, filename, data, std::move(onIndexSuccess),
     96            std::move(onIndexFail));
     97 }
     98 
     99 ClearKeyPersistence::ClearKeyPersistence(Host_11* aHost) : mHost(aHost) {}
    100 
    101 void ClearKeyPersistence::EnsureInitialized(bool aPersistentStateAllowed,
    102                                            function<void()>&& aOnInitialized) {
    103  if (aPersistentStateAllowed &&
    104      mPersistentKeyState == PersistentKeyState::UNINITIALIZED) {
    105    mPersistentKeyState = LOADING;
    106    ReadAllRecordsFromIndex(std::move(aOnInitialized));
    107  } else {
    108    mPersistentKeyState = PersistentKeyState::LOADED;
    109    aOnInitialized();
    110  }
    111 }
    112 
    113 bool ClearKeyPersistence::IsLoaded() const {
    114  return mPersistentKeyState == PersistentKeyState::LOADED;
    115 }
    116 
    117 string ClearKeyPersistence::GetNewSessionId(SessionType aSessionType) {
    118  static uint32_t sNextSessionId = 1;
    119 
    120  // Ensure we don't re-use a session id that was persisted.
    121  while (Contains(mPersistentSessionIds, sNextSessionId)) {
    122    sNextSessionId++;
    123  }
    124 
    125  string sessionId;
    126  stringstream ss;
    127  ss << sNextSessionId;
    128  ss >> sessionId;
    129 
    130  if (aSessionType == SessionType::kPersistentLicense) {
    131    mPersistentSessionIds.insert(sNextSessionId);
    132 
    133    // Save the updated index file.
    134    WriteIndex();
    135  }
    136 
    137  sNextSessionId++;
    138 
    139  return sessionId;
    140 }
    141 
    142 bool ClearKeyPersistence::IsPersistentSessionId(const string& aSessionId) {
    143  return Contains(mPersistentSessionIds, atoi(aSessionId.c_str()));
    144 }
    145 
    146 void ClearKeyPersistence::PersistentSessionRemoved(string& aSessionId) {
    147  mPersistentSessionIds.erase(atoi(aSessionId.c_str()));
    148 
    149  // Update the index file.
    150  WriteIndex();
    151 }