This class is essentially a filter for an existing ostream, allowing the user to encrypt data to that ostream using any of the usual ostream interface. More...
#include <DwmXChaCha20Poly1305Ostream.hh>
Inherits std::ostream.
Public Member Functions | |
| Ostream (std::ostream &os, const std::string &key) | |
Construct with a reference to the destination ostream os and the 32-byte encryption key. More... | |
| virtual | ~Ostream () |
| Destructor. | |
This class is essentially a filter for an existing ostream, allowing the user to encrypt data to that ostream using any of the usual ostream interface.
This hides all of the encryption details under the hood, except for the fact that the user will need to call flush() whenever they want data to be sent to the destination ostream. This is a consequence of needing an authenticated encryption scheme, and hence a need to encapsulate an initialization vector, encrypted data and a message authentication code. An instance of this class will buffer encrypted data internally until the flush() member is called. When flush() is called (which in the end will trigger the associated streambuf's sync()), we package up the initialization vector, a message length field, the encrypted data and the message authentication code and write it all to the destination ostream. Note that there is a 48 byte overhead each time we do this; a 24-byte initialization vector, an 8-byte length field and a 16-byte message authentication code. So instead of choosing a message demarcation under the hood, we leave it to the user of this class to decide when they'd like to flush the internal buffer. Note the implicit memory versus bandwidth tradeoff: flushing more frequently will reduce buffer memory consumption but cause an increase in on-the-wire overhead.
Since the C++ standard library does not include any socket abstractions, the first argument to the constructor of this class is often an asio::ip::tcp::iostream (in the boost namespace if you're using asio as bundled in Boost instead of standalone). It might also be an ofstream if we're writing encrypted data at rest. It could of course also be an ostringstream.
Note how tiny this code is; all of the real extensibility is in the std::streambuf, per the design of C++ iostreams.
|
inline |
Construct with a reference to the destination ostream os and the 32-byte encryption key.
Notice that all this does is call the base constructor with a new instance of an OutBuffer.