diff options
Diffstat (limited to 'dom/quota/EncryptingOutputStream.h')
-rw-r--r-- | dom/quota/EncryptingOutputStream.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/dom/quota/EncryptingOutputStream.h b/dom/quota/EncryptingOutputStream.h new file mode 100644 index 0000000000..9a23037731 --- /dev/null +++ b/dom/quota/EncryptingOutputStream.h @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_quota_EncryptingOutputStream_h +#define mozilla_dom_quota_EncryptingOutputStream_h + +// Local includes +#include "EncryptedBlock.h" // for EncryptedBlock + +// Global includes +#include <cstddef> +#include <cstdint> +#include "ErrorList.h" +#include "mozilla/InitializedOnce.h" +#include "mozilla/Maybe.h" +#include "mozilla/NotNull.h" +#include "nsCOMPtr.h" +#include "nsIOutputStream.h" +#include "nsISupports.h" +#include "nsTArray.h" +#include "nscore.h" + +class nsIInputStream; +class nsIRandomGenerator; + +namespace mozilla::dom::quota { +class EncryptingOutputStreamBase : public nsIOutputStream { + public: + NS_DECL_THREADSAFE_ISUPPORTS + + NS_IMETHOD Write(const char* aBuf, uint32_t aCount, uint32_t* _retval) final; + NS_IMETHOD WriteFrom(nsIInputStream* aFromStream, uint32_t aCount, + uint32_t* _retval) final; + NS_IMETHOD IsNonBlocking(bool* _retval) final; + + protected: + EncryptingOutputStreamBase(nsCOMPtr<nsIOutputStream> aBaseStream, + size_t aBlockSize); + + virtual ~EncryptingOutputStreamBase() = default; + + nsresult WriteAll(const char* aBuf, uint32_t aCount, + uint32_t* aBytesWrittenOut); + + InitializedOnce<const NotNull<nsCOMPtr<nsIOutputStream>>> mBaseStream; + const size_t mBlockSize; +}; + +// Wraps another nsIOutputStream using the CipherStrategy to encrypt it a +// page-based manner. Essentially, the CipherStrategy is not actually +// necessarily doing encryption, but any transformation to a page requiring some +// fixed-size reserved size per page. +// +// Paired with DecryptingInputStream which can be used to read the data written +// to the underlying stream, using the same (or more generally, a compatible) +// CipherStrategy, when created with the same key (assuming a symmetric cipher +// is being used; in principle, an asymmetric cipher would probably also work). +template <typename CipherStrategy> +class EncryptingOutputStream final : public EncryptingOutputStreamBase { + public: + // Construct a new blocking output stream to encrypt data to + // the given base stream. The base stream must also be blocking. + // The encryption block size may optionally be set to a value + // up to kMaxBlockSize. + explicit EncryptingOutputStream(nsCOMPtr<nsIOutputStream> aBaseStream, + size_t aBlockSize, + typename CipherStrategy::KeyType aKey); + + private: + ~EncryptingOutputStream(); + + nsresult FlushToBaseStream(); + + bool EnsureBuffers(); + + CipherStrategy mCipherStrategy; + + // Buffer holding copied plain data. This must be copied here + // so that the encryption can be performed on a single flat buffer. + // XXX This is only necessary if the data written doesn't contain a portion of + // effective block size at a block boundary. + nsTArray<uint8_t> mBuffer; + + nsCOMPtr<nsIRandomGenerator> mRandomGenerator; + + // The next byte in the plain data to copy incoming data to. + size_t mNextByte = 0; + + // Buffer holding the resulting encrypted data. + using EncryptedBlockType = EncryptedBlock<CipherStrategy::BlockPrefixLength, + CipherStrategy::BasicBlockSize>; + Maybe<EncryptedBlockType> mEncryptedBlock; + + public: + NS_IMETHOD Close() override; + NS_IMETHOD Flush() override; + NS_IMETHOD StreamStatus() override; + NS_IMETHOD WriteSegments(nsReadSegmentFun aReader, void* aClosure, + uint32_t aCount, uint32_t* _retval) override; +}; + +} // namespace mozilla::dom::quota + +#endif |