зеркало из https://github.com/mozilla/gecko-dev.git
93 строки
3.4 KiB
C++
93 строки
3.4 KiB
C++
/* -*- 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
|
|
|
|
#include "mozilla/InitializedOnce.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIOutputStream.h"
|
|
#include "nsTArray.h"
|
|
|
|
#include "EncryptedBlock.h"
|
|
|
|
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;
|
|
|
|
// 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 WriteSegments(nsReadSegmentFun aReader, void* aClosure,
|
|
uint32_t aCount, uint32_t* _retval) override;
|
|
};
|
|
|
|
} // namespace mozilla::dom::quota
|
|
|
|
#endif
|