Hi Ben,

I'll be working from http://www.cryptopp.com/docs/ref/annotated.html,
which makes it easy to jump around the source files in a class-centric
manner. Unfortunately, some key typdefs, such as that of SecByteBlock,
is not in the annotated reference.

>   1) Because std::string does not have a secure allocator, I should
> assume that anything I put through a StringSink() has the potential to
> be compromised, and should therefor use a ByteQueue if I don't want
> the data to be compromised, correct?
Not exactly. <secblock.h> offers SecBlock< T, A >, which is typef'd to
SecByteBlock. SecBlock< T, A > has the secure allocator. Any number of
objects use SecByteBlock. ByteQueue happens to be one of them.

> I'm still somewhat confused about how to save a key correctly.
You can do it one of two ways. You can use a pipeline or you can do it
the classical way. Under the covers, the pipeline does it the
classical way, which is to say the functional/procedural C way.

Pipeline:
StringSource(s1, new HexEncoder(new StringSink(s2)));
FileSource(f1, new HexEncoder(new FileSink(f2)));
StringSource(s, new HexEncoder(new FileSink(f)));
FileSource(f, new HexEncoder(new StringSink(s)));

Classical:
string s1, s2;
HexEncoder e;

e.Put(s1);
e.MessageEnd();

s2.resize(e.MaxRetrievable());
e.Get(s2.data(), s2.size());

> ... in my case I want to pipe the key through my AES filter
> first in case the file gets compromised.
Crypto++ already offers StreamTransformationFilter and
AuthenticatedEncryptionFilter (AuthenticatedDecryptionFilter). Both
filters work with block ciphers such as AES and modes such as CBC,
EAX, CCM, and GCM. The filters are documented in both the wiki and
annotated reference; and the wiki shows you how to use it.

> Was your last snippet of
> code intended to be the correct way?
Yes. What was broken?

> ...under the impression that I can only save to a Sink?
In the pipeline model, you can only save to a sink. But you also have
the classical way of doing things with Put/MessageEnd/Get.

> ByteQueue does not inherit from Sink.
Correct. But it is a BufferedTransfomation, which Save uses.

> I notice that if I call MessageEnd() on the BufferedTransformation
> that it works every time, but it is still incorrect?
You must call MessageEnd() because the objects don't auto-flush on
destruction. When using a 'pipeline' object, pumpAll controls the
behavior - if true, it calls PumpAll() which flushes any accumulated
data.

> The example still truncates the key, and throws the same BER
> decode error on load.
Works for me (lol... open source software joke). You are doing
something wrong. I got you started with a ByteQueueSource:

    ByteQueue queue;
    key.Save(queue);

    ByteQueueSource(queue, true /*pumpAll*/,
        new Base64Encoder(new FileSink(filename.c_str())));

You'll have to write your own ByteQueueSink - start by deriving from
Sink. For now, I just threw a Redirector in to break the ownership
chain and reused the old queue:

    FileSource(filename.c_str(), true /*pumpAll*/,
        new Base64Decoder(new Redirector(queue)));

    RSA::PrivateKey dup;
    dup.Load(queue);

Fetch the file from http://www.cryptopp.com/w/images/2/22/Persist_key.zip.

Jeff

On Oct 12, 10:10 pm, Ben Botto <[email protected]> wrote:
> Hi Jeff,
>   So here are the questions I came up with:
>
>   1) Because std::string does not have a secure allocator, I should
> assume that anything I put through a StringSink() has the potential to
> be compromised, and should therefor use a ByteQueue if I don't want
> the data to be compromised, correct?
>
>   2) I'm still somewhat confused about how to save a key correctly.
> If I want to save it directly to a file, I can do that fine with a
> FileSink, but in my case I want to pipe the key through my AES filter
> first in case the file gets compromised.  Was your last snippet of
> code intended to be the correct way?
>     a) ByteQueue does not inherit from Sink.  Your explanation put me
> under the impression that I can only save to a Sink?
>     b) The example still truncates the key, and throws the same BER
> decode error on load.
>
> I notice that if I call MessageEnd() on the BufferedTransformation
> that it works every time, but it is still incorrect?
>
> ---
> ByteQueue              holdKey;
> Base64Encoder          encoder(new FileSink("temp.key"));
> [...]
> privateKey.Save(holdKey);
> holdKey.TransferAllTo(encoder);
> encoder.MessageEnd(); /* Doesn't work without this. */
> /*
> // This also works as long as I call MessageEnd().
> privateKey.Save(encoder);
> encoder.MessageEnd();
> */
> ---
>
> Thanks for the help.
>
> [b]
>
> [SNIP]

-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.

Reply via email to