Jeff, Thanks for taking the time to give me such a thorough response. This clears up a lot for me. You're right about what I was doing with the HexEncoder just "slipping through the cracks." Your examples and links were exactly what I needed.
Thanks again! [b] On Oct 12, 4:27 pm, Jeffrey Walton <[email protected]> wrote: > 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.htmlhttp://www.cryptopp.com/docs/ref/rsa_8h.htmlhttp://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.
