[botan-devel] PEM_encode and ECDH_PrivateKey
lloyd at randombit.net
Wed Feb 1 18:11:21 EST 2012
On Wed, Feb 01, 2012 at 02:11:52PM -0800, Sean Cassidy wrote:
> I don't think the OID for ECDH is properly configured.
> OIDS::lookup("ECDH"), the algorithm name given in ecdh.h, results in
> an exception. Here is some code that exhibits this problem in v1.10.1
> on Ubuntu:
This is kind of a bug but also somewhat intentional. The issue is that
ANSI X9.62 in its infinite wisdom decided that the same format *and
the same OID* would be used to identify both ECDSA and ECDH keys. So
serializing an ECDH key is easy, just set the OID. The problem comes
when loading a key. There is no way to distinguish if it should be an
ECDSA or ECDH key. Lacking any good approach I punted and defined the
OID for ECDSA only on the theory that ECDH is rare.
There are a few solutions possible, none particularly appealing
- Define a new OID for ECDH. The optimal solution if you only care
about interoperating with botan, not so great if you need to
interact with a system that can't be configured with new OIDs.
Actually checking further it seems that this has already been
done: 184.108.40.206.12 is defined specifically for ECDH. However
a quick check shows virtually nobody uses/supports it :(
- Use the X9.62 OID for ECDH as well, with the understanding that
when you deserialize (eg PKCS8::load_key) a ECDH key you'll get
back an ECDSA key object and you'll have to transfer the values
into an ECDH key object before using it. This assumes you have some
additional contextual information at load time to know when this
- Flatten the ECC key hierarchy in the code, effectively merging
ECDSA and ECDH classes. This does solve the issue; I find it rather
distasteful but so it goes when you deal with standards. However
this couldn't happen in 1.10 as it would break ABI, so no quick fix
this way in any case.
Either of the first two cases you can do in your application code
right now. For instance to use the ECDSA OID, add this to your main
right after LibraryInitializer runs:
Library_State& botan_state = global_state();
const std::string ecdh_oid = "1.2.840.10045.2.1";
botan_state.set("oid2str", ecdh_oid, "ECDH");
botan_state.set("str2oid", "ECDH", ecdh_oid);
The same approach could be used for the 220.127.116.11.12 OID.
I think it's a gimme to support reading ECDH with the 18.104.22.168.12 OID
out of the box. Then people who want to signal specifically ECDH can
easily do so. (Ideally with an easier to understand API than the one
I'm using above to set the ECDH OID). Beyond that, I'm still unsure
what exactly the best long term solution may be.
You're apparently the first person who has come up against this (or at
least the first to mention it), so any comments about what you're
trying to do in the larger sense, what systems you want to interop
with, etc would act as increasing my ECDH user sample set from 0 to 1,
a substantial improvement.
More information about the botan-devel