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