-
-
Notifications
You must be signed in to change notification settings - Fork 9.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EC keys: i2d_PublicKey and d2i_PublicKey not working as expected #16989
Comments
Is this possibly the same things as #16977? If it is, please try to the fix for it and see if that makes things better. |
Nope. Applying the patch in #16983 doesn't change this behaviour. When debugging into the failure, the problem is here, called via Line 64 in ff3e450
|
FWIW below a somewhat "hardcore" way around the problem: With this helper function:
one can replace the PARAM code and get the "bug reproducer code" to not fail in
Output:
|
In my mind The documentation describing what d2i_PublicKey is supposed to do is .... brief :-) In reference to
And,
But this description cannot simply be applied to But there is no type specific format for EC public keys. This strange behaviour of Further the conversion of So, now its unclear what should be done (and in what branches). Possibilities:
In addition to all of the above we need to decide whether provider support should be added to master and whether it should be backported to 3.0 (as tracked in issue #16896) |
Thanks for the assessment and options, @mattcaswell! FWIW, options 2-4 indeed would break our hybrid (classic/EC+PQ/QSC) implementation(s): FYI see what we do here for the OpenSSL1.1.1 fork and here and here what's in the OpenSSL3 provider. |
From what I've seen and could read of other libraries and online docs is that EC Public Keys are just a dump of a curve point without the curve id (ANSI X9.62/X9.63 from SEC1 format). While you can convert an X.509 SPKI into an EC public key, you can't do the reverse because you've lost some information. You need to be able to tell which curve it came from. My understanding of this thread is that is what i2o_PublicKey does, but the o2i will not work. I assume it's possible with openssl to manually rebuild an EC public key internally if you supply the point + the curve information like other libraries provide. After which you could dump it into a know format like X.509 SPKI. It would also be great if the ''type-specific" formats would state which format we are talking about in the docs somewhere. I checked and I couldn't find it. In the code it's really hard to track all of this in the macro over macro generic code generation that happens. Maybe there's a trick to figure it out quickly. |
If I read that correctly - are you saying that other libraries do the same as us for a type specific EC Public Key, i.e. just dump the raw public key (without the curve data) and wrap it up in a PEM file? AFAIK this isn't standardised anywhere and I was just assuming it was an OpenSSL aberration. |
In turn, I personally wouldn't rule out the possibility that other(library developer)'s aimed for compatibility with OpenSSL -- especially in the absence of an authoritative standard. |
I was working on a piece of H/W which stores public keys in DER this way (all keys are from curve p-256) and it uses wolfssl's wc_ecc_import_x963_ex to import the key. This function requires that you specify the curve from which the parameters come from. I was looking for comparable code in openssl to do something similar but I couldn't find it until I stumbled on this discussion. |
Ah, ok. Is it actually DER or is it just binary data? What OpenSSL does it output the raw binary representation of the EC Point and then wraps that up in a PEM file. The binary representation of an EC Point is actually standardised (in X9.62). That same standard says that the DER representation of an EC Point has the binary EC point wrapped up in an ASN.1 OCTET STRING - which OpenSSL is not doing in this case. OpenSSL is using the PEM headers "EC PUBLIC KEY" which I also don't think are standardised anywhere. So, it sounds to me like OpenSSL really is doing its own thing here. I doubt this PEM format is widely supported. AFAIK you can't persuade the OpenSSL command line tools to emit this format, and they won't consume it either. |
OTC: We should either make the round trip back work or document that it doesn't work (perhaps adding an error in this case). Further investigation is required. |
I am looking at this and IMO the testcase in the opening post could be made to work if we downgraded the key in d2i_PublicKey via evp_pkey_copy_downgraded. The problem is how to deal with the old provider based key in the parameter. Should it be simply left out dangling but then the testcase would have to explicitly free it. Or should d2i_PublicKey free it by itself? But that semantics is not documented anywhere. |
It seems to be intentional that it is not possible to use
i2d_PublicKey
andd2i_PublicKey
to encode and decode an EC EVP_PKEY in immediate succession. Is that understanding correct? Understandable as the EC parameters don't go into the encoded data, right?Reading #14258 confirmed this; thus I followed the advice given by @t8m using the code below, but to no avail:
d2i_PublicKey
keeps failing.Is that a bug or should the code below read differently to work?
This happens with OpenSSL3 built on master ("OpenSSL 3.1.0-dev (Library: OpenSSL 3.1.0-dev )") and "gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) "
The text was updated successfully, but these errors were encountered: