-
Notifications
You must be signed in to change notification settings - Fork 18k
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
crypto/x509: Encode & decode ECDH only works for 1 out of 4 curves; P256, P384, P521 not working #71919
Comments
CC @golang/security |
This is intentional, made so for backwards compatibility, as ECDH support for ParsePKCS8PrivateKey was added later. Lines 95 to 100 in fba83cd
Possibly the docs of ParsePKCS8PrivateKey could be improved to mention that also. |
for context #56088 |
Looks like I was wrong in #56088 (comment) and didn't find the id-ecDH definition in RFC 5480, section 2.1.2. Note that id-ecDH (1.3.132.1.12) is an alternative to id-ecPublicKey (1.2.840.10045.2.1), NOT to the namedCurve parameter (e.g. 1.2.840.10045.3.1.7 for P-256) which is used with both. Supporting id-ecDH in ParsePKCS8PrivateKey should be straightforward. The question is whether we should switch MarshalPKCS8PrivateKey. For sure it would require a GODEBUG. How commonly supported is id-ecDH? If we generate encodings that round-trip for us but won't work with anything else, that's not great.
What a mess. Given how sparsely supported id-ecDH is, I am leaning towards not supporting it and just documenting the roundtrip issue better in ParsePKCS8PrivateKey, and mention what OID we use in MarshalPKCS8PrivateKey. |
Go version
go version go1.24.0 windows/amd64
Output of
go env
in your module/workspace:What did you do?
https://go.dev/play/p/r0_VyaLBFeL
What did you see happen?
Output from
go test
What did you expect to see?
I was expecting all of the tests to pass. Each test passes an ECDH or ECDSA private key through
x509.MarshalPKCS8PrivateKey
and thenx509.ParsePKCS8PrivateKey
. The decoded private key is expected to be the same type as the original.All 4 ECDSA tests pass. Only 1 ECDH test passes (i.e. X25519). The other 3 ECDH tests fail (i.e. P256, P384, P521). They pass in an ECDH private key, but the coded key is ECDSA instead of expected ECDH.
I log the PKCS#8 private keys as PEM in the tests. I copied the ECDH P256 PEM into an ASN.1 decoder (e.g. https://lapo.it/asn1js/). The expected OID is ECDH P256 (i.e. 1.3.132.1.12). Actual OID is ECDSA P256 (i.e. 1.2.840.10045.3.1.7), so it appears to be marshalled with the wrong OID. Here is a screenshot of the PEM from the ECDH P256 test, showing unexpected ECDSA OID.
I debugged into x509.MarshalPKCS8PrivateKey. For the ECDH P256 test, it picks the wrong OID. Here is a link to Go x509.go source where ECDH marshall picks its OID (i.e. 1.2.840.10045.3.1.7).
go/src/crypto/x509/x509.go
Lines 530 to 535 in fba83cd
I think it is a marshalling bug. The ECDH and ECDSA OIDs are meant to be distinct. However, it looks like they OIDs are mixed together in the code.
The text was updated successfully, but these errors were encountered: