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 plain 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 mPlainBuffer.
82 size_t mPlainBytes
= 0;
84 // Next byte of mPlainBuffer to return in ReadSegments().
87 LazyInitializedOnceNotNull
<const size_t> mBlockSize
;
90 // Wraps another nsIInputStream which contains data written using
91 // EncryptingOutputStream with a compatible CipherStategy and key. See the
92 // remarks on EncryptingOutputStream.
93 template <typename CipherStrategy
>
94 class DecryptingInputStream final
: public DecryptingInputStreamBase
{
96 // Construct a new blocking stream to decrypt the given base stream. The
97 // base stream must also be blocking. The base stream does not have to be
99 DecryptingInputStream(MovingNotNull
<nsCOMPtr
<nsIInputStream
>> aBaseStream
,
101 typename
CipherStrategy::KeyType aKey
);
103 // For deserialization only.
104 explicit DecryptingInputStream();
106 nsresult
BaseStreamStatus();
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 populates mPlainBuffer (until the
129 // stream position is at EOF).
130 nsresult
ParseNextChunk(bool aCheckAvailableBytes
, uint32_t* aBytesReadOut
);
132 // Convenience routine to Read() from the base stream until we get
133 // the given number of bytes or reach EOF.
135 // aBuf - The buffer to write the bytes into.
136 // aCount - Max number of bytes to read. If the stream closes
137 // fewer bytes my be read.
138 // aMinValidCount - A minimum expected number of bytes. If we find
139 // fewer than this many bytes, then return
140 // NS_ERROR_CORRUPTED_CONTENT. If nothing was read
141 // due due to EOF (aBytesReadOut == 0), then NS_OK is
143 // aCheckAvailableBytes - boolean flag controlling whether ReadAll should
144 // check available bytes before calling underlying
146 // aBytesReadOut - An out parameter indicating how many bytes were
148 nsresult
ReadAll(char* aBuf
, uint32_t aCount
, uint32_t aMinValidCount
,
149 bool aCheckAvailableBytes
, uint32_t* aBytesReadOut
);
151 bool EnsureBuffers();
153 // This method may change the current position in the stream.
154 nsresult
EnsureDecryptedStreamSize();
156 CipherStrategy mCipherStrategy
;
157 LazyInitializedOnce
<const typename
CipherStrategy::KeyType
> mKey
;
159 // Buffer to hold encrypted data. Must copy here since we need a
160 // flat buffer to run the decryption process on.
161 using EncryptedBlockType
= EncryptedBlock
<CipherStrategy::BlockPrefixLength
,
162 CipherStrategy::BasicBlockSize
>;
163 Maybe
<EncryptedBlockType
> mEncryptedBlock
;
165 // Buffer storing the resulting plain data.
166 nsTArray
<uint8_t> mPlainBuffer
;
168 LazyInitializedOnce
<const int64_t> mDecryptedStreamSize
;
171 } // namespace mozilla::dom::quota