Redirector
Documentation |
#include <cryptopp/filters.h>
|
A Redirector is a sink that does not own its attached transformation. A Redirector
will end an ownership chain, but still pass the data it receives to its referenced filter (the word attached was avoided in this particular case). Because the Redirector
does not ultimately own the attached transformation, a BufferedTransformation
reference is passed to the constructor rather than a pointer.
There are two applications of the Redirector
. First is to configure an intermediate object participating in a pipeline. For example, you would need a Redirector
to configure an encoder to disable padding. Second is to facilitate the retrieval of a result from an intermediate object that is participating in a pipeline. Most notable are the results from a HashVerificationFilter
, SignatureVerificationFilter
or AuthenticatedDecryptionFilter
.
Sources, filters and sinks are discussed at Pipelining. The pipeline article explains the design and shows you how to use them.
Constructor
There are two constructors available for a Redirector
since it is not possible to overload the constructor with a NULL
reference.
Redirector()
Initializes the Redirector
with a NULL
BufferedTransformation
and default Behavior
flags. The default flags is PASS_EVERYTHING
. This behavior is some what unique among filters in that most filters, when presented with a NULL
attachment, will create a MessageQueue
for internal use.
Redirector(BufferedTransformation &target, Behavior behavior=PASS_EVERYTHING)
target
is a BufferedTransformation, such as another filter or sink.
behavior
controls the Redirector
's behavior for passing data and signals. It can be a combination of the following:
DATA_ONLY
(0x00)PASS_SIGNALS
(0x01)PASS_WAIT_OBJECTS
(0x02)PASS_EVERYTHING
(PASS_SIGNALS
|PASS_WAIT_OBJECTS
)
Sample Programs
The following two sample programs show how to configure an object used in a pipeline; and how to retrieve an intermediate result from an object in a pipeline.
Configuration
The first example uses a Redirector
in a pipeline to allow for configuration options not available in a constructor. A Base64Encoder
does not allow a library user to specify padding, so it must be done through IsolatedInitialize
.
using CryptoPP::Name::Pad; using CryptoPP::Name::InsertLineBreaks; byte raw[] = { 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 }; string encoded, hexed; Base64Encoder encoder; AlgorithmParameters params = MakeParameters(Pad(), false)(InsertLineBreaks(), false); encoder.IsolatedInitialize(params); encoder.Attach(new StringSink( encoded )); ArraySource as(raw, sizeof(raw), true, new Redirector(encoder)); cout << encoded << endl; StringSource ss(encoded, true, new Base64Decoder(new HexEncoder(new StringSink(hexed)))); cout << hexed << endl;
A run of the program produces the following:
$ ./cryptopp-test.exe /+7dzLuqmYh3ZlVEMyIRAP/u3cy7qpmId2ZVRDMiEQD/7t3Mu6qZiHdmVUQzIhEA/+7dzLuqmYh3ZlVEMyIRAA FFEEDDCCBBAA99887766554433221100FFEEDDCCBBAA99887766554433221100FFEEDDCCBBAA99887766554433221100FFEEDDCCBBAA99887766554433221100
For a more complete discussion of the example, see NameValuePairs
.
Intermediate Result
In the second example below, the Redirector
takes a reference to an object, and not a pointer to an object. The AuthenticatedDecryptionFilter
will survive to the result to be fetched.
const int TAG_SIZE = 12; CCM< AES, TAG_SIZE >::Decryption dec; dec.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) ); ... AuthenticatedDecryptionFilter df( dec, new StringSink( recovered ) ); // AuthenticatedDecryptionFilter // Cipher text includes the MAC tag StringSource ss( cipher, true, new Redirector( df ) ); // StringSource // If the object does not throw, here's the only // opportunity to check the data's integrity bool b = df.GetLastResult(); if( true == b ) { cout << recovered << endl; }