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
11 #include "EncryptedBlock.h"
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"
22 #include "nsICloneableInputStream.h"
23 #include "nsIIPCSerializableInputStream.h"
24 #include "nsIInputStream.h"
25 #include "nsISeekableStream.h"
26 #include "nsISupports.h"
27 #include "nsITellableStream.h"
34 namespace mozilla::dom::quota
{
36 class DecryptingInputStreamBase
: public nsIInputStream
,
37 public nsISeekableStream
,
38 public nsICloneableInputStream
,
39 public nsIIPCSerializableInputStream
{
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
,
53 uint32_t* aTransferables
) override
;
56 DecryptingInputStreamBase(MovingNotNull
<nsCOMPtr
<nsIInputStream
>> aBaseStream
,
59 // For deserialization only.
60 DecryptingInputStreamBase() = default;
62 virtual ~DecryptingInputStreamBase() = default;
64 void Init(MovingNotNull
<nsCOMPtr
<nsIInputStream
>> aBaseStream
,
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
>>>
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().
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
{
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
101 DecryptingInputStream(MovingNotNull
<nsCOMPtr
<nsIInputStream
>> aBaseStream
,
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
;
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
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