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.
