> Thanks for taking the time.... No problem. I remember when started with Crypto++. It was painful. At that time, we only had the FAQ-o-matic, the list, and a search engine. And it was not uncommon for no-responses from the list, and 0 search result :/
Self-help via Crypto++'s wiki is useful for those who know about it. It was a great idea by DJ, and luckily Wei found the time to get it added for the users. > http://www.cryptopp.com/wiki/Key_Format. I'm going to try and get this page fixed tonight. Lots of questions on formats, and saving/loading public and private keys. And lots of good answers by folks like Geoff Beier. Jeff On Oct 12, 7:55 pm, Ben Botto <[email protected]> wrote: > 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.htmlht... > > > 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.
