ECC CSRs with explicit params

For interoperability it makes the most sense to include the curve parameters in the CSR with an ECC (elliptic curve) certificate. This way, a capable agent can validate a signature without foreknowledge of the key’s curve.

Let’s Encrypt seems to balk, though, at such CSRs?

-----BEGIN CERTIFICATE REQUEST-----
MIICtDCCAjcCAQAwGzEZMBcGA1UEAwwQZmVsaXBlZ2FzcGVyLmNvbTCCAc0wggFlBgcqhkjOPQIB
MIIBWAIBATA8BgcqhkjOPQEBAjEA//////////////////////////////////////////7/////
AAAAAAAAAAD/////MHwEMP/////////////////////////////////////////+/////wAAAAAA
AAAA/////AQwszEvp+I+5+SYjgVr4/gtGRgdnG7+gUESAxQIj1ATh1rGVjmNii7RnSqFyO3T7Crv
AxYAQVJSQVkoMHg3ZjkwODJhYTBiZjgpBGEEqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU
KjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0Hb0omhR86doxE7XwuMAKYLHOHX6B
nXpDHXyQ6g5fAjEA////////////////////////////////x2NNgfQ3Ld9YGg2ySLCneuzsGWrM
xSlzAgEBA2IABA2wobToSb4SLxFmMW0q9wUlsv7I5RiWd6Ls9jnmXWi4P6JvpeENZcvQvMA5HRhS
/6EU3482KkfCc15MaWZvTtq3xM/+WgZphQBchME9lIbZQRTsbtnk9ek1wiAKEQaD16BEMEIGCSqG
SIb3DQEJDjE1MDMwMQYDVR0RBCowKIIQZmVsaXBlZ2FzcGVyLmNvbYIUd3d3LmZlbGlwZWdhc3Bl
ci5jb20wDAYIKoZIzj0EAwMFAANpADBmAjEAu9VlvkcS4rWnRbFPdaXUecW0gnTtt601HKXSk3lI
GJSKu8QjEd0LaQgBXpZQ6JSSAjEA/iN8wv543vhKn4ynrBtjSsoCQ+aiaFNcAkvFcnwfXZYyiyy6
UI8olAenbpp+V4jD
-----END CERTIFICATE REQUEST-----

The specific error that I get is:

Error parsing certificate request. Extensions in the CSR marked critical can cause this error: https://github.com/letsencrypt/boulder/issues/565 (The request message was malformed)” (400, “Bad Request”, urn:acme:error:malformed)

None of the extensions requested in the CSR is marked critical.

I'm not sure if this is a concern here. Publicly-trusted CAs are not allowed to accept just any public key type; right now, they're limited to RSA and some NIST curves. In other words, the CA software knows exactly which curves it's willing to accept anyway, so this flexibility is not particularly useful (and - worse - such a flexible implementation might be more error-prone). I'm pretty sure you'll at least need to add the named curve OID for whatever curve you're trying to use since that's what the CA server will use to identify the key type; not sure if the rest of the curve parameters will cause issues if you keep them in the CSR as well.

The CA software is relatively easy to update, and it’s trivial for CAs to compare given curve parameters against their white-list to verify a curve’s identity.

My thinking isn’t that arbitrary curves are desirable; the point is backward compatibility. If, for example, the powers-that-be decide that any of the brainpool curves that OpenSSL 1.0.2 knows about are acceptable, then any OpenSSL 1.0.1 clients out there will be unable to work with certs/CSRs that use this curve but identify it by name only.

I suppose the CA could just decide to issue the cert using the explicit parameters, too.

I don't think there's a big demand for this given the speed at which new curves are added to the Baseline Requirements. If and when this happens, I suppose it could be (carefully) implemented for those new curves. Meanwhile, I think it makes more sense to be conservative and rely on the OID (which is actually something Go's x509 library does in Let's Encrypt's case, rather than code in the CA software itself).

Not sure what client support for that looks like. Go certainly relies on the OID alone (relevant code at line 855); I'm not much of a C developer, but I think NSS does too.

1 Like

Given the state of library support, yes, you’re probably right; the flexibility of explicit curve parameters seems to be something that the format foresees as potentially useful but that no one has immediate plans to use.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.