tor-browser

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

ClearKeyStorage.cpp (5805B)


      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 "ClearKeyStorage.h"
     18 
     19 #include <assert.h>
     20 // This include is required in order for content_decryption_module to work
     21 // on Unix systems.
     22 
     23 #include <vector>
     24 
     25 #include "ClearKeyUtils.h"
     26 #include "content_decryption_module.h"
     27 
     28 using namespace cdm;
     29 
     30 using std::function;
     31 using std::string;
     32 using std::vector;
     33 
     34 class WriteRecordClient : public FileIOClient {
     35 public:
     36  /*
     37   * This function will take the memory ownership of the parameters and
     38   * delete them when done.
     39   */
     40  static void Write(Host_11* aHost, string& aRecordName,
     41                    const vector<uint8_t>& aData, function<void()>&& aOnSuccess,
     42                    function<void()>&& aOnFailure) {
     43    WriteRecordClient* client = new WriteRecordClient(
     44        aData, std::move(aOnSuccess), std::move(aOnFailure));
     45    client->Do(aRecordName, aHost);
     46  }
     47 
     48  void OnOpenComplete(Status aStatus) override {
     49    // If we hit an error, fail.
     50    if (aStatus != Status::kSuccess) {
     51      Done(aStatus);
     52    } else if (mFileIO) {  // Otherwise, write our data to the file.
     53      mFileIO->Write(mData.data(), mData.size());
     54    }
     55  }
     56 
     57  void OnReadComplete(Status aStatus, const uint8_t* aData,
     58                      uint32_t aDataSize) override {
     59    // This function should never be called, we only ever write data with this
     60    // client.
     61    assert(false);
     62  }
     63 
     64  void OnWriteComplete(Status aStatus) override { Done(aStatus); }
     65 
     66 private:
     67  explicit WriteRecordClient(const vector<uint8_t>& aData,
     68                             function<void()>&& aOnSuccess,
     69                             function<void()>&& aOnFailure)
     70      : mFileIO(nullptr),
     71        mOnSuccess(std::move(aOnSuccess)),
     72        mOnFailure(std::move(aOnFailure)),
     73        mData(aData) {}
     74 
     75  void Do(const string& aName, Host_11* aHost) {
     76    // Initialize the FileIO.
     77    mFileIO = aHost->CreateFileIO(this);
     78    mFileIO->Open(aName.c_str(), aName.size());
     79  }
     80 
     81  void Done(cdm::FileIOClient::Status aStatus) {
     82    // Note: Call Close() before running continuation, in case the
     83    // continuation tries to open the same record; if we call Close()
     84    // after running the continuation, the Close() call will arrive
     85    // just after the Open() call succeeds, immediately closing the
     86    // record we just opened.
     87    if (mFileIO) {
     88      mFileIO->Close();
     89    }
     90 
     91    if (IO_SUCCEEDED(aStatus)) {
     92      mOnSuccess();
     93    } else {
     94      mOnFailure();
     95    }
     96 
     97    delete this;
     98  }
     99 
    100  FileIO* mFileIO = nullptr;
    101 
    102  function<void()> mOnSuccess;
    103  function<void()> mOnFailure;
    104 
    105  const vector<uint8_t> mData;
    106 };
    107 
    108 void WriteData(Host_11* aHost, string& aRecordName,
    109               const vector<uint8_t>& aData, function<void()>&& aOnSuccess,
    110               function<void()>&& aOnFailure) {
    111  WriteRecordClient::Write(aHost, aRecordName, aData, std::move(aOnSuccess),
    112                           std::move(aOnFailure));
    113 }
    114 
    115 class ReadRecordClient : public FileIOClient {
    116 public:
    117  /*
    118   * This function will take the memory ownership of the parameters and
    119   * delete them when done.
    120   */
    121  static void Read(Host_11* aHost, string& aRecordName,
    122                   function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
    123                   function<void()>&& aOnFailure) {
    124    (new ReadRecordClient(std::move(aOnSuccess), std::move(aOnFailure)))
    125        ->Do(aRecordName, aHost);
    126  }
    127 
    128  void OnOpenComplete(Status aStatus) override {
    129    auto err = aStatus;
    130    if (aStatus != Status::kSuccess) {
    131      Done(err, nullptr, 0);
    132    } else {
    133      mFileIO->Read();
    134    }
    135  }
    136 
    137  void OnReadComplete(Status aStatus, const uint8_t* aData,
    138                      uint32_t aDataSize) override {
    139    Done(aStatus, aData, aDataSize);
    140  }
    141 
    142  void OnWriteComplete(Status aStatus) override {
    143    // We should never reach here, this client only ever reads data.
    144    assert(false);
    145  }
    146 
    147 private:
    148  explicit ReadRecordClient(
    149      function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
    150      function<void()>&& aOnFailure)
    151      : mFileIO(nullptr),
    152        mOnSuccess(std::move(aOnSuccess)),
    153        mOnFailure(std::move(aOnFailure)) {}
    154 
    155  void Do(const string& aName, Host_11* aHost) {
    156    mFileIO = aHost->CreateFileIO(this);
    157    mFileIO->Open(aName.c_str(), aName.size());
    158  }
    159 
    160  void Done(cdm::FileIOClient::Status aStatus, const uint8_t* aData,
    161            uint32_t aDataSize) {
    162    // Note: Call Close() before running continuation, in case the
    163    // continuation tries to open the same record; if we call Close()
    164    // after running the continuation, the Close() call will arrive
    165    // just after the Open() call succeeds, immediately closing the
    166    // record we just opened.
    167    if (mFileIO) {
    168      mFileIO->Close();
    169    }
    170 
    171    if (IO_SUCCEEDED(aStatus)) {
    172      mOnSuccess(aData, aDataSize);
    173    } else {
    174      mOnFailure();
    175    }
    176 
    177    delete this;
    178  }
    179 
    180  FileIO* mFileIO = nullptr;
    181 
    182  function<void(const uint8_t*, uint32_t)> mOnSuccess;
    183  function<void()> mOnFailure;
    184 };
    185 
    186 void ReadData(Host_11* aHost, string& aRecordName,
    187              function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
    188              function<void()>&& aOnFailure) {
    189  ReadRecordClient::Read(aHost, aRecordName, std::move(aOnSuccess),
    190                         std::move(aOnFailure));
    191 }