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]

On Oct 12, 6:02 pm, Jeffrey Walton <[email protected]> wrote:
> >   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.

Reply via email to