Hi Ben,

I needed some time to take a look at the sources and docs. I'll break
comments into logical sections so this does not appear as a massive
run-on.

==========

> apply a "workaround" and save the key to a string
Don't use a string since a std::string does not have a secure
allocator. Use a SecByteBlock or ByteQueue. (which uses a
SecByteBlock).

==========

Save [1] is the problem - it is not designed to work with pipelining
[2]. The first sign that a square peg is being pounded into a round
hole is that Save takes a BufferedTransformation reference, and not a
BufferedTransformation pointer. Another good indicator is Wei's use of
Save in the sources.

A typical example (search for the text ".Save"):

ByteQueue queue;
key.Save(queue);

Since ByteQueue is only a filter, the following do not work:

// Nope
ByteQueue queue(new Base64Encoder(new FileSink(filename, true /
*binary*/)));
key.Save(queue);

// Nope
ByteQueue queue;
queue.Attach(new Base64Encoder(new FileSink(filename, true /
*binary*/)));
key.Save(queue);

==========

The key.Save(FileSink(filename).Ref()) is shorthand that works because
FileSink offers the Ref method. Its the same as writing:

FileSink sink(filename);
key.Save(sink);

Off Topic: For C++0x compliant compilers, you will have a r-value
reference (and operator &&) [4], and won't need to worry about non-
const l-values. In fact, Ref exists because of the need for non-const
l-values (see the comments on Bufferedtransformation::Ref). This means
you will only need to write:
key.Save(FileSink(filename));

==========

> I can use all other filters that I've tested fine to save
> and load keys, but when using the base64encoder I
> have to apply a "workaround"
I *think* you have been running between the cracks because of
StringSource/StringSink. It just happened to work because of the way
the pieces fit together. When an Encoder is tossed into the mix, the
universe becomes unbalanced.

==========

You might be able to create a Transformation/Filter that appears to be
a Sink (to Save()) and a Source (to HexEncoder()). But it will be
another hack, and it probably won't be easy to do, and thoroughly
abuses Crypto++'s pipeline design [2] (just my humble opinion).

==========

To keep the pipelining paradigm, I think you need KeySource and
KeySink. With a KeySource, you would have something similar to:

KeySource(key, new Base64Encoder(new FileSink(filename)));

The above begs the question: what does a caller really want to do (or
expect)? Does he/she want to pump a PublicKeyInfo (or PrivateKeyInfo)
or the inner PublicKey (or PrivateKey). So KeySource and KeySink will
need at least a parameter to dictate whether Load/Save (includes OIDs
and useful for interop) is called or DEREncode/BERDecode (smaller,
useful internally if not interop'ing) is called.

Plus, you would need to differentiate between a PublicKeySource and
PrivateKeySource (ditto for sinks).

==========

AutoSeededRandomPool prng;
RSA::PrivateKey rsa;
rsa.GenerateRandomWithKeySize(prng, 2048);

ByteQueue key;
rsa.Save(key);

Base64Encoder encoder(new FileSink(filename.c_str()));
key.TransferTo(encoder);

Jeff

[1] http://www.cryptopp.com/docs/ref/class_p_k_c_s8_private_key.html
[2] http://www.cryptopp.com/wiki/Pipelining
[3] http://www2.research.att.com/~bs/C++0xFAQ.html

http://www.cryptopp.com/docs/ref/class_auto_seeded_random_pool.html
http://www.cryptopp.com/docs/ref/rsa_8h.html
http://www.cryptopp.com/docs/ref/class_byte_queue.html

On Oct 11, 8:54 pm, Ben Botto <[email protected]> wrote:
> Thanks for the response, Jeff.  This seems like a bug to me, should I
> report it as such?  Shouldn't I come up with the same base64 encoded
> string in both cases in the code above?  I can use all other filters
> that I've tested fine to save and load keys, but when using the
> base64encoder I have to apply a "workaround" and save the key to a
> string, then base64 encode it, which seems like incorrect behavior to
> me.
>
> [b]

-- 
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