tor-browser

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

DecryptingInputStream.h (6343B)


      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_DecryptingInputStream_h
      8 #define mozilla_dom_quota_DecryptingInputStream_h
      9 
     10 // Local includes
     11 #include "EncryptedBlock.h"
     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 "mozilla/ipc/InputStreamParams.h"
     22 #include "nsCOMPtr.h"
     23 #include "nsICloneableInputStream.h"
     24 #include "nsIIPCSerializableInputStream.h"
     25 #include "nsIInputStream.h"
     26 #include "nsISeekableStream.h"
     27 #include "nsISupports.h"
     28 #include "nsITellableStream.h"
     29 #include "nsTArray.h"
     30 #include "nscore.h"
     31 
     32 template <class T>
     33 class nsCOMPtr;
     34 
     35 namespace mozilla::dom::quota {
     36 
     37 class DecryptingInputStreamBase : public nsIInputStream,
     38                                  public nsISeekableStream,
     39                                  public nsICloneableInputStream,
     40                                  public nsIIPCSerializableInputStream {
     41 public:
     42  NS_DECL_THREADSAFE_ISUPPORTS
     43 
     44  NS_IMETHOD Read(char* aBuf, uint32_t aCount, uint32_t* _retval) final;
     45  NS_IMETHOD IsNonBlocking(bool* _retval) final;
     46 
     47  NS_IMETHOD SetEOF() final;
     48 
     49  using nsICloneableInputStream::GetCloneable;
     50  NS_IMETHOD GetCloneable(bool* aCloneable) final;
     51 
     52  void SerializedComplexity(uint32_t aMaxSize, uint32_t* aSizeUsed,
     53                            uint32_t* aPipes,
     54                            uint32_t* aTransferables) override;
     55 
     56 protected:
     57  DecryptingInputStreamBase(MovingNotNull<nsCOMPtr<nsIInputStream>> aBaseStream,
     58                            size_t aBlockSize);
     59 
     60  // For deserialization only.
     61  DecryptingInputStreamBase() = default;
     62 
     63  virtual ~DecryptingInputStreamBase() = default;
     64 
     65  void Init(MovingNotNull<nsCOMPtr<nsIInputStream>> aBaseStream,
     66            size_t aBlockSize);
     67 
     68  // Convenience routine to determine how many bytes of plain data
     69  // we currently have in our plain buffer.
     70  size_t PlainLength() const;
     71 
     72  size_t EncryptedBufferLength() const;
     73 
     74  LazyInitializedOnceEarlyDestructible<const NotNull<nsCOMPtr<nsIInputStream>>>
     75      mBaseStream;
     76  LazyInitializedOnce<const NotNull<nsISeekableStream*>> mBaseSeekableStream;
     77  LazyInitializedOnce<const NotNull<nsICloneableInputStream*>>
     78      mBaseCloneableInputStream;
     79  LazyInitializedOnce<const NotNull<nsIIPCSerializableInputStream*>>
     80      mBaseIPCSerializableInputStream;
     81 
     82  // Number of bytes of plain data in mPlainBuffer.
     83  size_t mPlainBytes = 0;
     84 
     85  // Next byte of mPlainBuffer to return in ReadSegments().
     86  size_t mNextByte = 0;
     87 
     88  LazyInitializedOnceNotNull<const size_t> mBlockSize;
     89 };
     90 
     91 // Wraps another nsIInputStream which contains data written using
     92 // EncryptingOutputStream with a compatible CipherStategy and key. See the
     93 // remarks on EncryptingOutputStream.
     94 template <typename CipherStrategy>
     95 class DecryptingInputStream final : public DecryptingInputStreamBase {
     96 public:
     97  // Construct a new blocking stream to decrypt the given base stream.  The
     98  // base stream must also be blocking.  The base stream does not have to be
     99  // buffered.
    100  DecryptingInputStream(MovingNotNull<nsCOMPtr<nsIInputStream>> aBaseStream,
    101                        size_t aBlockSize,
    102                        typename CipherStrategy::KeyType aKey);
    103 
    104  // For deserialization only.
    105  explicit DecryptingInputStream();
    106 
    107  nsresult BaseStreamStatus();
    108 
    109  NS_IMETHOD Close() override;
    110  NS_IMETHOD Available(uint64_t* _retval) override;
    111  NS_IMETHOD StreamStatus() override;
    112  NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
    113                          uint32_t aCount, uint32_t* _retval) override;
    114 
    115  NS_DECL_NSITELLABLESTREAM
    116 
    117  NS_IMETHOD Seek(int32_t aWhence, int64_t aOffset) override;
    118 
    119  NS_IMETHOD Clone(nsIInputStream** _retval) override;
    120 
    121  void Serialize(mozilla::ipc::InputStreamParams& aParams, uint32_t aMaxSize,
    122                 uint32_t* aSizeUsed) override;
    123 
    124  bool Deserialize(const mozilla::ipc::InputStreamParams& aParams) override;
    125 
    126 private:
    127  ~DecryptingInputStream();
    128 
    129  // Parse the next chunk of data.  This populates mPlainBuffer (until the
    130  // stream position is at EOF).
    131  nsresult ParseNextChunk(bool aCheckAvailableBytes, uint32_t* aBytesReadOut);
    132 
    133  // Convenience routine to Read() from the base stream until we get
    134  // the given number of bytes or reach EOF.
    135  //
    136  // aBuf                   - The buffer to write the bytes into.
    137  // aCount                 - Max number of bytes to read. If the stream closes
    138  //                          fewer bytes my be read.
    139  // aMinValidCount         - A minimum expected number of bytes.  If we find
    140  //                          fewer than this many bytes, then return
    141  //                          NS_ERROR_CORRUPTED_CONTENT.  If nothing was read
    142  //                          due due to EOF (aBytesReadOut == 0), then NS_OK is
    143  //                          returned.
    144  // aCheckAvailableBytes   - boolean flag controlling whether ReadAll should
    145  //                          check available bytes before calling underlying
    146  //                          Read method.
    147  // aBytesReadOut          - An out parameter indicating how many bytes were
    148  // 			      read.
    149  nsresult ReadAll(char* aBuf, uint32_t aCount, uint32_t aMinValidCount,
    150                   bool aCheckAvailableBytes, uint32_t* aBytesReadOut);
    151 
    152  bool EnsureBuffers();
    153 
    154  // This method may change the current position in the stream.
    155  nsresult EnsureDecryptedStreamSize();
    156 
    157  CipherStrategy mCipherStrategy;
    158  LazyInitializedOnce<const typename CipherStrategy::KeyType> mKey;
    159 
    160  // Buffer to hold encrypted data.  Must copy here since we need a
    161  // flat buffer to run the decryption process on.
    162  using EncryptedBlockType = EncryptedBlock<CipherStrategy::BlockPrefixLength,
    163                                            CipherStrategy::BasicBlockSize>;
    164  Maybe<EncryptedBlockType> mEncryptedBlock;
    165 
    166  // Buffer storing the resulting plain data.
    167  nsTArray<uint8_t> mPlainBuffer;
    168 
    169  LazyInitializedOnce<const int64_t> mDecryptedStreamSize;
    170 };
    171 
    172 }  // namespace mozilla::dom::quota
    173 
    174 #endif