Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / quota / DecryptingInputStream.h
blob4720992f423cc5d05e73304e9f1a9a1b2831b65a
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/. */
7 #ifndef mozilla_dom_quota_DecryptingInputStream_h
8 #define mozilla_dom_quota_DecryptingInputStream_h
10 // Local includes
11 #include "EncryptedBlock.h"
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"
31 template <class T>
32 class nsCOMPtr;
34 namespace mozilla::dom::quota {
36 class DecryptingInputStreamBase : public nsIInputStream,
37 public nsISeekableStream,
38 public nsICloneableInputStream,
39 public nsIIPCSerializableInputStream {
40 public:
41 NS_DECL_THREADSAFE_ISUPPORTS
43 NS_IMETHOD Read(char* aBuf, uint32_t aCount, uint32_t* _retval) final;
44 NS_IMETHOD IsNonBlocking(bool* _retval) final;
46 NS_IMETHOD SetEOF() final;
48 using nsICloneableInputStream::GetCloneable;
49 NS_IMETHOD GetCloneable(bool* aCloneable) final;
51 void SerializedComplexity(uint32_t aMaxSize, uint32_t* aSizeUsed,
52 uint32_t* aPipes,
53 uint32_t* aTransferables) override;
55 protected:
56 DecryptingInputStreamBase(MovingNotNull<nsCOMPtr<nsIInputStream>> aBaseStream,
57 size_t aBlockSize);
59 // For deserialization only.
60 DecryptingInputStreamBase() = default;
62 virtual ~DecryptingInputStreamBase() = default;
64 void Init(MovingNotNull<nsCOMPtr<nsIInputStream>> aBaseStream,
65 size_t aBlockSize);
67 // Convenience routine to determine how many bytes of plain data
68 // we currently have in our buffer.
69 size_t PlainLength() const;
71 size_t EncryptedBufferLength() const;
73 LazyInitializedOnceEarlyDestructible<const NotNull<nsCOMPtr<nsIInputStream>>>
74 mBaseStream;
75 LazyInitializedOnce<const NotNull<nsISeekableStream*>> mBaseSeekableStream;
76 LazyInitializedOnce<const NotNull<nsICloneableInputStream*>>
77 mBaseCloneableInputStream;
78 LazyInitializedOnce<const NotNull<nsIIPCSerializableInputStream*>>
79 mBaseIPCSerializableInputStream;
81 // Number of bytes of plain data in mBuffer.
82 size_t mPlainBytes = 0;
84 // Next byte of mBuffer to return in ReadSegments().
85 size_t mNextByte = 0;
87 LazyInitializedOnceNotNull<const size_t> mBlockSize;
89 size_t mLastBlockLength = 0;
92 // Wraps another nsIInputStream which contains data written using
93 // EncryptingInputStream with a compatible CipherStategy and key. See the
94 // remarks on EncryptingOutputStream.
95 template <typename CipherStrategy>
96 class DecryptingInputStream final : public DecryptingInputStreamBase {
97 public:
98 // Construct a new blocking stream to decrypt the given base stream. The
99 // base stream must also be blocking. The base stream does not have to be
100 // buffered.
101 DecryptingInputStream(MovingNotNull<nsCOMPtr<nsIInputStream>> aBaseStream,
102 size_t aBlockSize,
103 typename CipherStrategy::KeyType aKey);
105 // For deserialization only.
106 explicit DecryptingInputStream();
108 NS_IMETHOD Close() override;
109 NS_IMETHOD Available(uint64_t* _retval) override;
110 NS_IMETHOD StreamStatus() override;
111 NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
112 uint32_t aCount, uint32_t* _retval) override;
114 NS_DECL_NSITELLABLESTREAM
116 NS_IMETHOD Seek(int32_t aWhence, int64_t aOffset) override;
118 NS_IMETHOD Clone(nsIInputStream** _retval) override;
120 void Serialize(mozilla::ipc::InputStreamParams& aParams, uint32_t aMaxSize,
121 uint32_t* aSizeUsed) override;
123 bool Deserialize(const mozilla::ipc::InputStreamParams& aParams) override;
125 private:
126 ~DecryptingInputStream();
128 // Parse the next chunk of data. This may populate mBuffer and set
129 // mBufferFillSize. This should not be called when mBuffer already
130 // contains data.
131 nsresult ParseNextChunk(uint32_t* aBytesReadOut);
133 // Convenience routine to Read() from the base stream until we get
134 // the given number of bytes or reach EOF.
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 due
142 // due to EOF (aBytesReadOut == 0), then NS_OK is returned.
143 // aBytesReadOut - An out parameter indicating how many bytes were read.
144 nsresult ReadAll(char* aBuf, uint32_t aCount, uint32_t aMinValidCount,
145 uint32_t* aBytesReadOut);
147 bool EnsureBuffers();
149 CipherStrategy mCipherStrategy;
150 LazyInitializedOnce<const typename CipherStrategy::KeyType> mKey;
152 // Buffer to hold encrypted data. Must copy here since we need a
153 // flat buffer to run the decryption process on.
154 using EncryptedBlockType = EncryptedBlock<CipherStrategy::BlockPrefixLength,
155 CipherStrategy::BasicBlockSize>;
156 Maybe<EncryptedBlockType> mEncryptedBlock;
158 // Buffer storing the resulting plain data.
159 nsTArray<uint8_t> mPlainBuffer;
162 } // namespace mozilla::dom::quota
164 #endif