tor-browser

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

EncryptingOutputStream.h (3851B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_quota_EncryptingOutputStream_h
      8 #define mozilla_dom_quota_EncryptingOutputStream_h
      9 
     10 // Local includes
     11 #include "EncryptedBlock.h"  // for EncryptedBlock
     12 
     13 // Global includes
     14 #include <cstddef>
     15 #include <cstdint>
     16 
     17 #include "ErrorList.h"
     18 #include "mozilla/InitializedOnce.h"
     19 #include "mozilla/Maybe.h"
     20 #include "mozilla/NotNull.h"
     21 #include "nsCOMPtr.h"
     22 #include "nsIOutputStream.h"
     23 #include "nsISupports.h"
     24 #include "nsTArray.h"
     25 #include "nscore.h"
     26 
     27 class nsIInputStream;
     28 class nsIRandomGenerator;
     29 
     30 namespace mozilla::dom::quota {
     31 class EncryptingOutputStreamBase : public nsIOutputStream {
     32 public:
     33  NS_DECL_THREADSAFE_ISUPPORTS
     34 
     35  NS_IMETHOD Write(const char* aBuf, uint32_t aCount, uint32_t* _retval) final;
     36  NS_IMETHOD WriteFrom(nsIInputStream* aFromStream, uint32_t aCount,
     37                       uint32_t* _retval) final;
     38  NS_IMETHOD IsNonBlocking(bool* _retval) final;
     39 
     40 protected:
     41  EncryptingOutputStreamBase(nsCOMPtr<nsIOutputStream> aBaseStream,
     42                             size_t aBlockSize);
     43 
     44  virtual ~EncryptingOutputStreamBase() = default;
     45 
     46  nsresult WriteAll(const char* aBuf, uint32_t aCount,
     47                    uint32_t* aBytesWrittenOut);
     48 
     49  InitializedOnce<const NotNull<nsCOMPtr<nsIOutputStream>>> mBaseStream;
     50  const size_t mBlockSize;
     51 };
     52 
     53 // Wraps another nsIOutputStream using the CipherStrategy to encrypt it a
     54 // page-based manner. Essentially, the CipherStrategy is not actually
     55 // necessarily doing encryption, but any transformation to a page requiring some
     56 // fixed-size reserved size per page.
     57 //
     58 // Paired with DecryptingInputStream which can be used to read the data written
     59 // to the underlying stream, using the same (or more generally, a compatible)
     60 // CipherStrategy, when created with the same key (assuming a symmetric cipher
     61 // is being used; in principle, an asymmetric cipher would probably also work).
     62 template <typename CipherStrategy>
     63 class EncryptingOutputStream final : public EncryptingOutputStreamBase {
     64 public:
     65  // Construct a new blocking output stream to encrypt data to
     66  // the given base stream.  The base stream must also be blocking.
     67  // The encryption block size may optionally be set to a value
     68  // up to kMaxBlockSize.
     69  explicit EncryptingOutputStream(nsCOMPtr<nsIOutputStream> aBaseStream,
     70                                  size_t aBlockSize,
     71                                  typename CipherStrategy::KeyType aKey);
     72 
     73 private:
     74  ~EncryptingOutputStream();
     75 
     76  nsresult FlushToBaseStream();
     77 
     78  bool EnsureBuffers();
     79 
     80  CipherStrategy mCipherStrategy;
     81 
     82  // Buffer holding copied plain data.  This must be copied here
     83  // so that the encryption can be performed on a single flat buffer.
     84  // XXX This is only necessary if the data written doesn't contain a portion of
     85  // effective block size at a block boundary.
     86  nsTArray<uint8_t> mBuffer;
     87 
     88  nsCOMPtr<nsIRandomGenerator> mRandomGenerator;
     89 
     90  // The next byte in the plain data to copy incoming data to.
     91  size_t mNextByte = 0;
     92 
     93  // Buffer holding the resulting encrypted data.
     94  using EncryptedBlockType = EncryptedBlock<CipherStrategy::BlockPrefixLength,
     95                                            CipherStrategy::BasicBlockSize>;
     96  Maybe<EncryptedBlockType> mEncryptedBlock;
     97 
     98 public:
     99  NS_IMETHOD Close() override;
    100  NS_IMETHOD Flush() override;
    101  NS_IMETHOD StreamStatus() override;
    102  NS_IMETHOD WriteSegments(nsReadSegmentFun aReader, void* aClosure,
    103                           uint32_t aCount, uint32_t* _retval) override;
    104 };
    105 
    106 }  // namespace mozilla::dom::quota
    107 
    108 #endif